New Release – Chasing Forever

 

Blurb:

Jordyn has longed to make her relationship with best friend Diego more than platonic. Her body drips with need to know what it would feel like to have his lips kissing every inch of her
skin. Desire to wrap her legs around his waist and plunge into deep waters with him fills her every dream.

Diego is one with the ocean. His passion is surfing and chasing that ultimate wave. He doesn’t have time for a relationship. Or does he?

A storm is brewing and when a tragedy occurs, Diego and Jordyn need to decide if they’re both chasing the same dreams.

 

An Excerpt From: CHASING
FOREVER

Copyright © AMBER
SKYZE, 2011

All Rights Reserved, Ellora’s Cave Publishing, Inc.

Chapter One

 

Jordyn sat on the beach towel watching
Diego riding out the waves. Her pulse raced. He knew he shouldn’t be out there.
Hurricane Ivan was heading inland and the weatherman had warned of the dangerous
undertow. She’d attempted to chase a few waves, but once she’d swum a few yards
she knew it was a mistake. She’d quickly swum back to shore and waited while her
best friend tried to prove he was smarter than the ocean.

The waters
had turned mean and ugly over the last twenty minutes and the sky was an ominous
gray. The hurricane was moving closer. A breeze came in off the water and a
chill passed through her body. She’d unzipped her wet suit down to her waist,
exposing her bikini top when she exited the water. She should cover up again in
case the rains poured down.

She
scanned the waters. Someone on a Jet Ski buzzed around, stopping every so often
to take some pictures. She hoped he would keep away from the jagged rocks. The
razor-sharp rocks were Jordyn’s bigger fear with Diego
being out on the water. One wrong move and a wave could drag him under and throw
him against the rocks, ending his life.

Jet skis
were prohibited at any time on this part of the beach, but it didn’t stop them,
especially on a day like today. They’d swarm around the surfers—in this case,
just Diego—hoping to get a great shot of him nailing a thirty-foot
wave.

Hopefully that’s all he
catches
.

She
scanned the beach looking for any other fools. People with cameras hoping to
click the ideal picture of the perfect storm peppered the
sand.

“Dumbasses,” she muttered. What did
that make her? She was on the beach too. Why had she allowed Diego to convince
her this was a good idea?

“Because
I’m a fool too.” She buried her foot in the sand and watched how the tiny
particles glided between her toes. If she was smart she’d grab her board, jump
in her Jeep and hightail it back to her place. Common sense flew out the window
when it came to Diego, because she was head over heels in love with
him.

Too bad he doesn’t feel the
same
. He loved her
like a sister he’d said a few too many times, especially on drunken
occasions.

If she’d
had a nickel for all the times he’d said, “If you weren’t like a sister to me,
I’d fuck you.”

How her
pussy moistened with the thought. A few times she’d been tempted to sock him one
and other times she’d wanted to tackle him and show him the woman inside waiting
for him to fill that void deep within.

Instead
she’d sat back and
waited.

 

 

// 0)
avglsflyover.hide(null, 1);

var phishLinks = [];
for (var i=0; i 0)
{
var prev = ‘1’;
if ( engine.type == ‘inline’ )
prev = ‘0’;
searchshield.avgCallFunc(doc, ‘GetPhishingResults’, prev);
}
else if (links.length > 0 && engine.type != ‘inline’)
{
searchshield.avgCallFunc(doc, ‘FinalScanComplete’);
}
},
stop: function(){
if (searchshield.avgSearchMonitor.timeoutID)
{
window.clearTimeout(searchshield.avgSearchMonitor.timeoutID);
delete searchshield.avgSearchMonitor.timeoutID;
}
}
};
searchshield.avgProcessSearch = function (doc)
{
// doc may be about:Tabs or about:Blank
if (!doc)
return;

// init search object (not declared or is null)
if (typeof xplSearch === ‘undefined’ || null === xplSearch)
xplSearch = new searchshield.Search();

xplSearch.doc = doc;
xplSearch.href = xplSearch.doc.location.href;
xplSearch.uri = searchshield.parseLink(xplSearch.href);

if (!searchshield.clockUrl)
searchshield.clockUrl = searchshield.avgCallFunc(doc, ‘GetIconUrl’, ‘0’);

xplSearch.clockUrl = searchshield.clockUrl

if (!xplSearch.engines)
{
var aEng = xplSearch.getSearchNames();
var aEngLen = aEng.length;
for (var i=0; i < aEngLen; i++)
{
xplSearch.addEngine(new searchshield[aEng[i]+'SearchEngine'](xplSearch));
}
}

if (!xplSearch.engine)
{
var engLen = xplSearch.engines.length;
for (var i = 0; i < engLen; i++)
{
if (xplSearch.engines[i].validSearch())
{
xplSearch.engine = xplSearch.engines[i];
break;
}
}
}

if (!xplSearch.engine)
return;

// set verdict display config
xplSearch.engine.setRatingsConfig(doc);

// init the alert popup
searchshield.initPopupAlert(doc);

// start search monitor
searchshield.avgSearchMonitor.start(doc, xplSearch.engine);

// attach click handlers for popup alerts
doc.body.detachEvent("onclick", searchshield.blockClick);
doc.body.attachEvent("onclick", searchshield.blockClick);

doc.body.detachEvent("ondblclick", searchshield.blockClick);
doc.body.attachEvent("ondblclick", searchshield.blockClick);
};
searchshield.avgGetSearchLinks = function (doc, engine)
{
if (!engine)
{
// restart page monitor
searchshield.avgPageMonitor.start(doc);
return;
}

var alltags = doc.getElementsByTagName('*');

for (var i = 0; i < alltags.length; i++)
{
if (alltags[i].getAttribute('avglschecked'))
continue;

// ignore linked resources
if ((alltags[i].tagName) && (alltags[i].tagName == 'LINK'))
continue;

// ignore in-page bookmarks and javascript
if ((!alltags[i].href) ||
(alltags[i].href.charAt(0) == '#') || // in-page bookmark
(alltags[i].href.indexOf("javascript") == 0))
continue;

// ignore verdicts
if (alltags[i].id && (alltags[i].id.indexOf("XPLSS_") != -1))
continue;

// ignore flyover anchors
if (alltags[i].href && (alltags[i].href.indexOf("linkscanner:") == 0 || alltags[i].href.indexOf("avgthreatlabs.com") != -1))
continue;

var href = engine.includeLink(alltags[i]);
if (!href)
continue;

var newNode = engine.search.addLink(alltags[i], href);
engine.addImage(newNode, engine.search.clockUrl, false);
}

// recursivesly process all frames
var docFrames = doc.frames;
if (docFrames && engine.processFrames)
{
for (var j = 0; j < docFrames.length; j++)
{
var attr;
var frameDoc;
try {
attr = docFrames[j].frameElement.className;
frameDoc = docFrames[j].document;
}
catch(err){}

//TODO: make frame processing an engine function or at least make exclusions an engine property
// 'editable' frame it's probably a gmail reply
if (attr && (attr.indexOf("editable") != -1))
continue;

if (frameDoc)
searchshield.avgGetSearchLinks(frameDoc, engine);
}
}

return engine.search.links;
};
searchshield.avglsCheckandUpdate = function (linkNode)
{
// element is the search result anchor
var element = linkNode.element;
var href = linkNode.href;

if (!xplSearch)
return;

var result = searchshield.avgCallFunc(xplSearch.doc, 'CheckSite', href, element.href);
if (result == null)
return;

var resultParse = result.split('::');

var phishing = resultParse[0]; // if phishing then rest of array does not exist.

if (phishing == 1)
return true;

if (resultParse.length -1) ? avglschecked.substring(0, sPos) : null;
var split = (sPos > -1) ? avglschecked.substring(sPos+1) : null;
if (hash && split && split != searchshield.VERISIGN_SPLIT_NOTEST)
{
// check updated verdict anchor for verisign domain
var d = event.srcElement.ownerDocument;
if (d.getElementById(“LXPLSS_” + hash + “U” + searchshield.SCORE_SS_VERISIGN))
{
searchshield.avgCallFunc(d, “RecordVSClick”, hash, d.location.href);
}
}
}

var link = anchor.href;
var verdict = searchshield.getAvgImage(anchor);
var score = -1;
var img_id = ”;
if (verdict != null)
{
score = verdict.score;
img_id = verdict.rawId;
}

// show popup alert (upper left)
if ((score >= searchshield.SCORE_SS_CAUTION) && (score <= searchshield.SCORE_SS_WARNING))
{
// prevent this click from going any further
var search_hash = searchshield.avgCallFunc(document, 'GetHash', document.location.href);
searchshield.ShowPopupAlert(document, link, img_id, search_hash);

// if possible, stop the event from going any further
searchshield.cancelEvent(event);
return false;
}

return true;
};

// called by native to update phishing links
searchshield.updatePhishingLinks = function (results)
{

if (!results)
return;

if (!xplSearch)
return;

var engine = xplSearch.engine;
var resultParse = results.split("::");
var resultsLength = resultParse[0];

for (var i=0; i < resultsLength; i++)
{
var idx = i*7;
var hash = resultParse[idx+1];
var score = resultParse[idx+2];
var new_image = resultParse[idx+3];
var alt_image = resultParse[idx+4];
var flyover = resultParse[idx+5];
var click_thru= resultParse[idx+6];
var altClick_thru = resultParse[idx+7];

engine.updateImage(hash, xplSearch.searchHash, score, new_image, alt_image, flyover, click_thru, altClick_thru);
}
};
searchshield.getAvgImage = function (element)
{
var obj = {};
obj.img = xplSearch.engine.getImgElement(element);
obj.score = -1;

//parse the score from the id
if (obj.img != null && obj.img.id)
{
var pos = !!obj.img.id ? obj.img.id.indexOf('U') + 1 : -1;
obj.score = (pos < 1) ? -1 : obj.img.id.charAt(pos);
obj.rawId = obj.img.id.substring(0,pos-1);
}

return obj;
};
searchshield.GetScannedLink = function (link)
{
if (!xplSearch || !(xplSearch.links instanceof Array))
return link;

// look for the link we scanned based on original element
for (var i = 0; i < xplSearch.links.length; i++)
{
if (xplSearch.links[i].element.href == link)
return xplSearch.links[i].href;
}
// else return the incoming link
return link;
};
searchshield.previouslyScanned = function (links, hash)
{
for (var i = 0; i < links.length; i++)
{
if ((links[i] != null) && (links[i].hash != null) &&
(links[i].hash == hash) && (links[i].checked == true))
return true;
}
return false;
};
searchshield.initPopupAlert = function (doc)
{
// check if it exists first
if (doc.getElementById("XPLSS_PopupAlert"))
return;

// create a div to use for the popup itself, hide for now
var popup_div = doc.createElement("DIV");
popup_div.setAttribute("id", "XPLSS_PopupAlert");
popup_div.style.position = "absolute";
popup_div.style.zIndex = "10000";
doc.body.appendChild(popup_div);
};
searchshield.initFlyover = function (doc, engine)
{
// create in top doc only
if (doc !== window.top.document)
doc = window.top.document;

// check if it exists first
if ((doc == null) || (doc.getElementById("XPLSS_Flyover")))
return;

// create a div to use for the flyover itself, hide for now
var flyover_div = doc.createElement("DIV");
flyover_div.setAttribute("id", "XPLSS_Flyover");
flyover_div.style.position = "absolute";
flyover_div.style.zIndex = "10000";
doc.body.appendChild(flyover_div);

// create a layer for the image
var trans_div = doc.createElement("DIV");
trans_div.setAttribute("id", "XPLSS_Trans");
trans_div.style.position = "absolute";
trans_div.style.zIndex = "9999";
doc.body.appendChild(trans_div);
};
searchshield.ShowPopupAlert = function (doc, link, hash, search)
{
// build the content
var popup_content = searchshield.avgCallFunc(doc, 'BuildPopupAlert', hash, search);
if (popup_content == null || popup_content == "")
return;

// get the div
var div = doc.getElementById("XPLSS_PopupAlert");
div.innerHTML = searchshield.CleanupHTML(popup_content);

// set position, account for scrolling
var zoom = searchshield.zoomLevel();
var pageOffsetX = Math.round(doc.documentElement.scrollLeft/zoom);
var pageOffsetY = Math.round(doc.documentElement.scrollTop/zoom);

div.style.left = 10 + pageOffsetX + "px";
div.style.top = 10 + pageOffsetY + "px";

// TODO: the event handler function doesn't exist so, is this even necessary?
//div.attachEvent("onmouseout", HidePopupAlert);

// set the link
//var data = doc.getElementById("avgalertpopurl");
//if (data)
// data.innerHTML = escape(link);

// set visibility
div.style.visibility = "visible";

//navigate to the link after timed delay
// TODO: Bug 31707 – make this open a new tab/window
setTimeout(function(){doc.location.assign(link)}, 3000);
};
searchshield.avgCallFunc = function (doc, name /*, param1…, paramN*/)
{
// get the data element
var avg_ls_data = (typeof gAvgDataElement !== 'undefined') ? gAvgDataElement : doc.getElementById("avglsdata");

if ((avg_ls_data == null) || (name == null))
return;

// save the data element
gAvgDataElement = avg_ls_data;

// for some reason you can't fire and event on an element with no parent node
if (avg_ls_data.parentNode == null)
return;

// set the attributes
avg_ls_data.setAttribute("function", name);

// set variable length of optional parameter attributes
var pcnt = 0;
for (var i=2; i < arguments.length; i++)
avg_ls_data.setAttribute("param"+(++pcnt), arguments[i]);

avg_ls_data.fireEvent("onrowenter");

// get the result
return avg_ls_data.getAttribute("result");
};

// general use functions – begin
// DOM Functions
searchshield.getAnchorNode = function (node, filterFunc)
{
// filterFunc should return a boolean
if (!filterFunc || !filterFunc instanceof Function)
return null;

// go up the dom tree starting at node and look for anchor
// before hitting a header, div or table element
while ((node != null) &&
(node.tagName != null) &&
(node.tagName != "A"))
{
if (filterFunc(node))
{
node = null;
break;
}
node = node.parentNode;
}

return node;
};
searchshield.getDocuments = function (frame, frameArray)
{ // recursively get all embedded frames/docs
frameArray.push(frame.document);
var frames = frame.frames;
for (var i = 0; i < frames.length; i++)
{
// recurse on each frame
searchshield.getDocuments(frames[i], frameArray);
}
return frameArray;
};
searchshield.NextSiblingNode = function (element)
{
var TEXTNODE = 3;
var ParentNode = element.parentNode;

if (!ParentNode)
return;

var NextSibling = ParentNode.nextSibling;
while (NextSibling)
{
if (NextSibling.nodeType != TEXTNODE)
return NextSibling;

NextSibling = NextSibling.nextSibling;
}

return;
};
searchshield.getParentNodeByAttribute = function (attrName, attrValue, node, maxDepth)
{
if (!node)
return null;

var maxLoop = maxDepth ? maxDepth : 1;
var pNode = node.parentNode;

if (!pNode)
return null;

for(; 0 < maxLoop; maxLoop–)
{
if ((pNode[attrName]) &&
(pNode[attrName].toLowerCase() === attrValue.toLowerCase()))
{
return pNode;
}

pNode = pNode.parentNode;
if (!pNode)
return null;
}

return null;
};
searchshield.getParentNodeByClassName = function (className, node, maxDepth)
{
return searchshield.getParentNodeByAttribute("className", className, node, maxDepth);
};
searchshield.getParentNodeById = function (id, node, maxDepth)
{
return searchshield.getParentNodeByAttribute("id", id, node, maxDepth);
};
searchshield.getParentNodeByTagName = function (tagName, node, attrName)
{ // find parent node by tag name and optional attribute name

if (!tagName || !node || !node.parentNode)
return null;

tagName = tagName.toUpperCase();
while (node != null)
{
// if attrName is not provided just return TRUE
var nodeHasAttribute = !!attrName ? !!node[attrName] : true;
if ((node.tagName == tagName) && (nodeHasAttribute))
return node;

node = node.parentNode;
}

// no div
return null;
};
searchshield.getTopLevelDocument = function (doc)
{ // return the top level document for the given doc, could be itself

// TODO: determine a method of doing this for IE, if necessary

// don't check about:blank
if (doc && ((doc.location.href == "about:blank") || (doc.location.href == "about:Tabs")))
return doc;

// Check if already a top level document
for (var i = 0; i < gBrowser.browsers.length; i++)
{
if (doc == gBrowser.browsers[i].contentDocument)
return doc;
}

// Not a top level, check all frames
var documents;
for (var j = 0; j < gBrowser.browsers.length; j++)
{
// get all docs for each browser
documents = searchshield.getDocuments(gBrowser.browsers[j].contentWindow, new Array());
for (var k = 0; k < documents.length; k++)
{
// check if doc is from current browser
if (doc == documents[k])
{
// it is, return the top level doc for this browser
return gBrowser.browsers[j].contentDocument;
}
}
}

return doc;
};
searchshield.getTopLevelWindow = function ()
{
// TODO: determine a method of doing this for IE, if necessary
return mediator.getMostRecentWindow("navigator:browser");
};

//Event functions
searchshield.addListener = function (object, evtType, listener, useCapture)
{
useCapture = !!useCapture;

if (object.addEventListener)
{
object.addEventListener(evtType, listener, useCapture);
return true;
}
else if (object.attachEvent)
{
object.attachEvent("on"+evtType, listener);
return true;
}

return false;
};
searchshield.cancelEvent = function (event)
{
event.cancelBubble = true;
event.returnValue = false;
};
searchshield.doEvent = function (evtObj, evtTarget, evtName, evtType, bubbles, cancelable)
{
bubbles = !!bubbles;
cancelable = !!cancelable;

if (document.createEvent)
{
var evt = document.createEvent("Events");
evt.initEvent(evtName, bubbles, cancelable);
evtTarget.dispatchEvent(evt);
return true;
}
else if (document.createEventObject)
{
var evt = document.createEventObject(evtObj);
evtTarget.fireEvent("on" + evtType, evt);
return true;
}

return false;
};
searchshield.removeListener = function (object, evtType, listener, useCapture)
{
useCapture = !!useCapture;

if (object.removeEventListener)
{
object.removeEventListener(evtType, listener, useCapture);
return true;
}
else if (object.detachEvent)
{
object.detachEvent(evtType, listener);
return true;
}

return false;
};

// HTML functions
searchshield.CleanupHTML = function (data)
{
if (data == null)
return data;

// cleanup html data, replace any new lines
data = data.replace(/\r/g, "");
data = data.replace(/\n/g, "");
// escape any single quotes
data = data.replace(/'/g, "\\'");

return data;
};
searchshield.removeHtmlTags = function (str)
{
var re = new RegExp('(]+>)’,’g’);
var strStr = new String(str);
if (!!strStr)
return strStr.replace(re, ”);
else
return str;

};

// Browser functions
searchshield.containedIn = function (container, element)
{
while (element != null)
{
if (container == element)
{
return true;
}
element = element.parentNode;
}
return false;
};
searchshield.elementSize = function (element)
{
//returns an array [sizeX, sizeY]

var elemX;
var elemY;

elemX = parseInt(element.offsetWidth);
elemY = parseInt(element.offsetHeight)

return [elemX, elemY];
};
searchshield.GetFullBoundingRect = function (element)
{
if (!element) return;

// get bounding rect for incoming element
var elementRect = element.getBoundingClientRect();
var nextImg = null;
var nextImgRect = null;

// first check for another non-TextNode element after this one
var siblingElement = searchshield.NextSiblingNode(element);
if ( siblingElement &&
siblingElement.firstChild &&
siblingElement.id &&
siblingElement.id.indexOf(“XPLSS_”) != -1)
{
nextImg = siblingElement.firstChild;
nextImgRect = nextImg.getBoundingClientRect();
}
else
{
return elementRect;
}

if ((nextImgRect.top >= elementRect.bottom) &&
(nextImgRect.left <= elementRect.left))
{ // images appear to be on seperate lines
return elementRect;
}

// else merge the rects together into a new one
var newRect = new function() { this.top=0; this.left=0; this.right=0; this.bottom=0; this.mid=0;};
newRect.top = Math.min(elementRect.top, nextImgRect.top);
newRect.left= Math.min(elementRect.left, nextImgRect.left);
newRect.right=Math.max(elementRect.right, nextImgRect.right);
newRect.bottom=Math.max(elementRect.bottom, nextImgRect.bottom);
newRect.mid = Math.min(elementRect.right, nextImgRect.left);

return newRect;
};
searchshield.offsetLeft = function (element)
{
var offset = 0;
while (element)
{
offset += element.offsetLeft;
element = element.offsetParent;
}

return offset;
};
searchshield.offsetTop = function (element)
{
var offset = 0;
while (element)
{
offset += element.offsetTop;
element = element.offsetParent;
}

return offset;
};
searchshield.scrollSize = function (imageElem)
{
// returns an array [scrollX, scrollY, hasParentFrame]

var scrollX;
var scrollY;
var hasParentFrame;

// firefox
if (window.pageXOffset && window.pageYOffset)
{
scrollX = window.pageXOffset;
scrollY = window.pageYOffset;
}
else if (document.documentElement || document.body)
{
scrollX = document.documentElement.scrollLeft || document.body.scrollLeft;
scrollY = document.documentElement.scrollTop || document.body.scrollTop;

if (imageElem)
{
var frames = document.frames;
if (frames)
{
for (var i=0; i < frames.length; i++)
{
var img;
try {
img = frames[i].document.getElementById(imageElem.id);
}
catch(domErr){}

if (img != null)
{
scrollX = frames[i].document.documentElement.scrollLeft;
scrollY = frames[i].document.documentElement.scrollTop;
hasParentFrame = true;
break;
}
}
}
}
}
else
{
scrollX = 0;
scrollY = 0;
}

return [parseInt(scrollX,10), parseInt(scrollY,10), hasParentFrame];
};
searchshield.viewPortSize = function ()
{
// returns an array [width, height, scrollYWidth], where scrollYWidth is always 0 for IE

var scrollXWidth = 19;
var scrollYWidth = 0; // 0 for Microsoft IE
var scrollBarX = false;
var windowX;
var windowY;

// firefox
if (window.innerWidth && window.innerHeight)
{
//TODO: validate this block if implemented for firefox

windowX = window.innerWidth – scrollXWidth;
windowY = window.innerHeight;

try
{
scrollYWidth = Math.floor(Math.abs(window.innerHeight – document.documentElement.clientHeight)) + 1;
scrollBarX = (document.documentElement.clientWidth < document.documentElement.scrollWidth);
}
catch(err){}

if (scrollBarX && !scrollYWidth)
scrollYWidth = 18; //normally 17 (+1 top border)

}
else if (document.documentElement || document.body)
{
windowX = (document.documentElement.clientWidth || document.body.clientWidth) – scrollXWidth;
windowY = document.documentElement.clientHeight || document.body.clientHeight;
}
else
{
windowX = 0;
windowY = 0;
}

return [windowX, windowY, scrollYWidth];
};
searchshield.zoomLevel = function ()
{
var level = 1;
if (document.body.getBoundingClientRect) {
// rect is only in physical pixel size before IE8
var rect = document.body.getBoundingClientRect();
level = Math.round (((rect.right – rect.left) / (document.body.offsetWidth)) * 100) / 100;
}

return level;
};

// Href functions
searchshield.checkUrl = function (url)
{ // cleanup a url, make sure there is a protocol on the front for scanning
try {
// trim
url = url.replace(/^\s+/, "").replace(/\s+$/, "");

// if no protocol, add http:// to it
if (url.indexOf("://") == -1)
url = "http://&quot; + url;
}
catch(err){}

return url;
};
searchshield.DoesURLContain = function (url, contain)
{
if ((url == null) || (url.length < 1))
return false;

// breakup the url to check
var parts = url.split('/');
if (parts.length -1)
return true;

return false;
};
searchshield.FilterUrl = function (url, filter)
{
if (!url || (url.length < 1))
return false;

if (!filter || !(filter instanceof Array))
return false;

var parts = url.split('/');
if ((parts == null) || (parts.length < 3))
return false;

var domain = parts[2];
for (var i = 0; i = 3))
{
return parts[2].toLowerCase();
}
}

return url;
};
searchshield.getUrlContents = function (url)
{
if (url == null)
return null;

// don’t query if local url
if (url.indexOf(“linkscanner://”) != -1)
return null;

try
{
req = new XMLHttpRequest();
req.open(“GET”, url, false);
req.send(null);
if (req.status == 200)
return req.responseText;
else
return null;
}
catch (err)
{
// nothing to do
return null;
}
};
searchshield.parseLink = function (href, simpleMode)
{
var uri = {};
var parameter = {
complex: {
pattern: /^(?:([a-z]+):(?:([a-z]*):)?\/\/)?(?:([^:@]*)(?::([^:@]*))?@)?((?:[a-z0-9_-]+\.)+[a-z]{2,})(?::(\d+))?(?:([^:\?\#]+))?(?:\?([^\#]+))?(?:\#([^\s]+))?$/i,
element: [‘source’,’scheme’,’subscheme’,’user’,’pass’,’host’,’port’,’path’,’query’,’fragment’]
},
simple: {
pattern: /^(?:([a-z]+):\/\/)?((?:[a-z0-9_-]+\.)+[a-z]{2,})(?:\/)([^:\?]+)?(?:([\?|\#])([^\?]+))?$/i,
element: [‘source’,’scheme’,’host’,’path’,’delimiter’,’query’]
}
};
var mode = simpleMode !== false ? ‘simple’ : ‘complex’;
var pattern = parameter[mode].pattern;
var element = parameter[mode].element;

if (!href)
return uri;

var matches = href.match(pattern);

if (matches)
{
// ——————–
// iterate over the matches array and populate uri properties
// using the respective element parameter as the name.
// NOTE: set raw property type as String to make inArray()
// work properly with instanceof.
// ——————–
for (var i=0; i < matches.length; i++)
uri[element[i]] = new String(matches[i] || "");

// ——————–
// create an array, hostArray, from host, for example,
// host="www.google.com" and hostArray=["www","google","com"]
// ——————–
uri.hostArray = uri.host.split(".");

// ——————–
// create an array, qsArray, from query, for example,
// query='hl=en&q=javascript&btnG=Search&aq=f&aqi=g10&aql=&oq=&gs_rfai='
// qsArray=[{hl:'en'},{q:javascript}, … ,(qs_rfai:''}]
//
// $0=entire match, $1=capture 1, $2=capture 2
// must include $0 even though it is unused so
// the replace works properly
// ——————–
uri.qsArray = [];
uri.query.replace(/(?:^|&)([^&=]*)=?([^&]*)/g,
function ($0, $1, $2) {
if ($1) uri.qsArray[$1] = $2;
}
);
}

//non-standard urls require a fail-safe that relies on simply splitting the href
function splitLink(href)
{
// split the href on '/'
var linkParts = href.split("/");

// need domain and path
if ((linkParts == null) || (linkParts.length < 2))
return false;

var uri = {
delimiter: (linkParts[3]).substring(0,1),
host: linkParts[2],
hostArray: (linkParts[2]).split('.'),
path: (linkParts[3]).substring(1),
qsArray: {},
query: '',
scheme: (linkParts[0]).substring(0, linkParts[0].length-1),
source: href
};

return uri;
}

if (!uri.host)
uri = splitLink(href);

return uri;
};

// general functions
searchshield.arrayKeys = function (array)
{
var keys = new Array();
for(k in array)
keys.push(k);

return keys;
};
searchshield.inArray = function (key, array, caseSensitive, exactMatch)
{
if (! array instanceof Array)
return false;

if (caseSensitive !== true)
caseSensitive = false;

if (exactMatch !== false)
exactMatch = true;

if (key instanceof String)
{
for (var i=0; i < array.length; i++)
{
var k = caseSensitive ? key.valueOf() : key.valueOf().toLowerCase();
var a = caseSensitive ? array[i] : array[i].toLowerCase();
if(exactMatch && k === a)
return true;
else if (!exactMatch && (-1 !== k.indexOf(a)))
return true;
}
}
else if (key instanceof Array)
{
for (var i=0; i < array.length; i++)
for (var j=0; j < key.length; j++)
{
var k = caseSensitive ? key[j] : key[j].toLowerCase();
var a = caseSensitive ? array[i] : array[i].toLowerCase();
if (exactMatch && k === a)
return true;
else if (!exactMatch && (-1 !== k.indexOf(a)))
return true;
}
}

return false;
};
// general use functions – end

// Search constructor
searchshield.Search = function()
{
this.doc = null;
this.engine = null;
this.engines = null;
this.links = null;
this.uri = null;
this.searchHash = null;
this.checkUrl = null;
this.useLocalImgs = null;
this.clockUrl = null;
// create engine list (actually key/value object will be used)
this.engineList = {};
};

searchshield.Search.prototype.getSearchNames = function()
{ // order is important
var names = [
'Google',
'AVGGoogle',
'AltaVista',
'AVGYahoo',
'Yahoo',
'Bing',
'MSN', // MSN redirects to BING
'Baidu',
'Earthlink',
'AOL',
'Ask',
'Yandex',
'Seznam',
'Webhledani',
'eBay',
///temp 'Digg',
'Slashdot',
'Twitter',
'GMail',
'Facebook'
];
return names;
};

searchshield.Search.prototype.detectEngine = function(href)
{
if (!href)
return;

var aEng = searchshield.Search.prototype.getSearchNames();
var aEngLen = aEng.length;
for (var i=0; i < aEngLen; i++)
{
if (searchshield[aEng[i] + 'SearchEngine'].prototype.validSearch(href))
return aEng[i];
}

return;
};

searchshield.Search.prototype.addEngine = function(engine)
{
if (!this.engines)
this.engines = new Array();

this.engines.push(engine);
};

searchshield.Search.prototype.addLink = function(inElement, inHref)
{
if (!this.links)
this.links = new Array();

var hrefHash;
try
{
hrefHash = searchshield.avgCallFunc(this.doc, 'GetHash', inHref);
}
catch (e){}

var newNode = {
element: inElement,
href: inHref,
hash: hrefHash,
search: this.searchHash
};

this.links.push(newNode);

return newNode;
}

// process the search result page after all search engines have been added
searchshield.Search.prototype.process = function(doc)
{
// only process when searchshield is enabled
if (0 == searchshield.avgCallFunc(doc, 'GetSearchEnabled'))
return;

this.doc = doc;
this.href = this.doc.location.href;
this.uri = searchshield.parseLink(this.href);

try
{
this.searchHash = searchshield.avgCallFunc(this.doc, 'GetHash', this.href);

// get any previously active engine
this.engine = this.engineList[this.searchHash.toString()];
}
catch (e) {}

/*

Process Steps:
1. Add all supported search engines
2. Identify the active search engine
3. Get all document links and add AVG images
*/

// STEP 1 – Add all supported search engines
if (!this.engines)
{
var aEng = xplSearch.getSearchNames();
var aEngLen = aEng.length;
for (var i=0; i < aEngLen; i++)
{
xplSearch.addEngine(new searchshield[aEng[i]+'SearchEngine'](this));
}
}

// search the engines if we didn't find one
if (!this.engine)
{
// STEP 2 – Identify the active search engine
var engLen = this.engines.length;
for (var i = 0; i < engLen; i++)
{
if (this.engines[i].validSearch())
{
this.engine = this.engines[i];
break;
}
}

// create a new engine instance to store
this.engineList[this.searchHash.toString()] = this.engine;

// init this search, if < 1 either an error or disabled
//var sdkInit = 0;
//try {
// sdkInit = xpl_sdk.SXPL_InitSearch(this.href);
//}
//catch(e){}
//if (sdkInit < 1)
// return false;
}

// return immediately if there is not an active search engine
if (!this.engine)
return false;

try {
// base url to check for icons
this.checkUrl = searchshield.avgCallFunc(this.doc, 'GetIconUrl', '1');

// check if using linked or local icons
this.useLocalImgs = !searchshield.getUrlContents(this.checkUrl);

// get the clock url
this.clockUrl = searchshield.avgCallFunc(this.doc, 'GetIconUrl', '0');
}
catch(e){}

// STEP 3 – Get all document links and add AVG images
var alltags = this.doc.getElementsByTagName("*"); // this method works for IE, FF and Chrome
for (var i=0; i -1))
{
return;
}

// mark search result anchor so it isn’t processed repeatedly
if (score == undefined)
element.setAttribute(“avglschecked”, hash + “S” + this.VeriSignSplit);

// create a new image
var img = doc.createElement(‘img’);
img.src = image;
img.id = “XPLSS_” + hash;
img.style.borderStyle = “none”;
img.style.margin = “0 3px”;

// for IE, specify these style attributes to prevent inadvertent inheritance from parent
if (img.width && img.height)
{
img.style.width = img.width + ‘px’;
img.style.height = img.height + ‘px’;
}

// apply custom element styles
this.updateElementStyle(img, this.addImageStyle);

// create the link element
var anchor = doc.createElement(“A”);
anchor.setAttribute(“id”, “LXPLSS_” + hash);

if ((hidden != null) && (hidden == true))
{ // hiding the parent will also hide its child nodes
anchor.style.display = “none”;
}

// Default anchor styles
//Over-ride possible border style with inline declaration
anchor.style.borderStyle = “none”;

// apply custom element styles
this.updateElementStyle(anchor, this.addAnchorStyle);

if (score == searchshield.SCORE_SS_VERISIGN)
{
anchor.style.textDecoration = “none”;
anchor.style.background = “none”;
}

// append the image to the link
anchor.appendChild(img);

// insert the node as either a sibling or a child
if (insertNode != null)
parentNode.insertBefore(anchor, insertNode);
else
parentNode.appendChild(anchor);

return anchor;
};
searchshield.SearchEngine.prototype.updateImage = function (hash, search, score, image, alt_image, flyover, click_thru, altClick_thru)
{
var updated = false;

var frameDoc = this.search.doc;
var docFrames = frameDoc.frames;
var frameElem;
if (docFrames && this.processFrames)
{
for (var i=0; i < docFrames.length; i++)
{
try {
if (docFrames[i].document.getElementById(hash))
{
frameElem = docFrames[i].frameElement;
frameDoc = docFrames[i].document;
break;
}
}
catch(err){}
}
}

while ((element = frameDoc.getElementById(hash)) != null)
{
// check configuration to determine if verdict display property
var showVerdict = true;
var nSeverity = Number(score – 1);
switch (nSeverity)
{
case searchshield.XPLCHECK_RESULT_SEV_LOW:
showVerdict = this.showLowRiskVerdicts;
break;
case searchshield.XPLCHECK_RESULT_SEV_MED:
showVerdict = this.showMedRiskVerdicts;
break;
case searchshield.XPLCHECK_RESULT_SEV_NONE:
showVerdict = this.showCleanVerdicts;
break;
default:
if (score == searchshield.SCORE_SS_VERISIGN)
showVerdict = this.showCleanVerdicts;
break;
}

// remove image if no url specified
if ((!showVerdict) || (image == null) || (image.length anchor->containerNodes…
while (cN && maxLoop–)
{
if (cN.tagName == “DIV” || cN.tagName == “SPAN”)
{
// get object height depending on ie document mode
var clientHeight = (cN.clientHeight == 0 ||
(this.search.doc.documentMode && this.search.doc.documentMode < 8)) ?
cN.offsetHeight :
cN.clientHeight;
scrl = cN.scrollHeight – clientHeight;
break;
}

cN = cN.parentNode;
}

if (0 eH)
eH = reduceBy;

var newDim = Math.ceil(eH*element.height);

element.height = newDim;
element.width = newDim;

element.style.height = newDim + “px”;
element.style.width = newDim + “px”;
}
}
catch(e){}
}

// set default style attributes
element.style.display = “”;

// if verisign icon showing move our icon up for better centering of the 2
// except for IE7 browser – it does not like this style
try {
var ieVersion = parseFloat(navigator.appVersion.split(“MSIE”)[1]);
if (alt_image && (alt_image.length > 0) && ieVersion != 7)
element.style.verticalAlign = “10%”;
}
catch(err){};

// apply custom element styles
this.updateElementStyle(element, this.updateImageStyle)

// update the click thru
var link = this.search.doc.getElementById(“L” + hash);
if (link)
{
link.href = click_thru;
link.id = link.id + “U” + score;
}

updated = true;

// add the alternate image if supplied BUT not on avg yahoo
if ((alt_image) &&
(alt_image.length > 0) &&
(!this.omitAltImage) &&
(this.VeriSignSplit != searchshield.VERISIGN_SPLIT_TESTB))
{

var vhash = hash.substring(hash.indexOf(“_”)+1);

// create a temporary link node
var tmp_node = {
element: element.parentNode,
href: altClick_thru,
hash: vhash + “VU” + score,
search: this.searchHash,
score: score
};

var altAnchor = this.addImage(tmp_node, alt_image, false);
if (altAnchor && altAnchor.firstChild)
{
altAnchor.firstChild.setAttribute(“onmouseover”, “”);
altAnchor.href = altClick_thru;
}
}
}

if (updated != false)
{
this.resizeFrame(frameElem);
return true;
}

return false;
};
searchshield.SearchEngine.prototype.updateElementStyle = function (element, elementStyle)
{
if (elementStyle)
{ // a NULL attribte value will unset it
for(attr in elementStyle)
{
try {
if (element.style.setAttribute)
element.style.setAttribute(attr, elementStyle[attr]);
else
element.style[attr] = elementStyle[attr];
} catch(err){}
}
}
};

searchshield.SearchEngine.prototype.resizeFrame = function (frameElem)
{ // resize frame to prevent unwanted scrolling after inserting verdicts

// ignore inline and non-frame engines
if ((this.type == ‘inline’) || (!this.processFrames))
return;

// ensure all required elements are available
if ((frameElem == null) || (frameElem.style == null) || (frameElem.contentWindow == null))
return;

// if frame is scrolling vertically then resize
var frameHeight = parseInt(frameElem.style.height, 10);
if (!isNaN(frameHeight) && (frameHeight < frameElem.contentWindow.document.body.scrollHeight))
frameElem.style.height = frameElem.contentWindow.document.body.scrollHeight + 'px';

return;
};

searchshield.SearchEngine.prototype.getImgElement = function (element)
{ // return an xpl img element associated with a given element
if (element == null)
return null;

// go up the parent tree looking for a header or div
while ( (element.parentNode != null) &&
(element.tagName.charAt(0) != "H") &&
(element.tagName.charAt(0) != "D") &&
(element.tagName.charAt(0) != "T") )
{
element = element.parentNode;
}

// if all the way to the top, nothing
if ((element.tagName == "HTML") || (element == null))
return null;

// get image tags, if none we are done
var imgTags = element.getElementsByTagName("IMG");
if ((imgTags == null) || (imgTags.Length < 1))
return null;

for (var i = 0; i = 5)
{ //if set to default then get config value
if (this.showCleanVerdicts === true)
this.showCleanVerdicts = (parseInt(parts[0]) == 1) ? true : false;

if (this.showLowRiskVerdicts === true)
this.showLowRiskVerdicts = (parseInt(parts[1]) == 1) ? true : false;

if (this.showMedRiskVerdicts === true)
this.showMedRiskVerdicts = (parseInt(parts[2]) == 1) ? true : false;

this.VeriSignSplit = (parseInt(parts[4]));
}

return true;
};

searchshield.SearchEngine.prototype.init_inline_ratings = function (doc)
{
if ((doc == null) || (doc.getElementById(“XPLSS_InlineFlyover”)))
return;

// create the popup box
var box = doc.createElement(“DIV”);
try {
box.setAttribute(“id”, “XPLSS_InlineFlyover”);
box.style.visibility = “hidden”;
box.style.left = “-5000px”;

box.style.position = “absolute”;
box.style.zIndex = “9999”;
box.style.padding = “0px 0px”;
box.style.marginLeft = “0px”;
box.style.marginTop = “0px”;
box.style.overflow = “hidden”;
box.style.wordWrap = “break-word”;
box.style.color = “black”;
box.style.fontSize = “10px”;
box.style.textAlign = “left”;
box.style.lineHeight = “130%”;

doc.body.appendChild(box);
box = null;
}
catch(boxErr){}
};

searchshield.SearchEngine.prototype.show_inline_ratings = function (doc, node, image)
{
var href = node.href;
var anchor = node.element;

if ((href == null) || (href.length < 1))
return;

if (avglsinlineflyover.imageExists(anchor))
return;

// mark search result anchor so it isn't processed repeatedly
anchor.setAttribute("avglschecked", "1");

// get verdict
this.display_inline(doc, anchor, href, node, false);
};

searchshield.SearchEngine.prototype.display_inline = function (doc, anchor, href, node, update, min_severity)
{
// min_severity is the lowest severity to display, so setting it to
// 1 would not display safe icons

var results = searchshield.avgCallFunc(doc, 'MalsiteCheck', href);
if (results == null)
return;

var parts = results.split('::');

// need at least severity
if (parts == null)
return;

var nSeverity = parseInt(parts[0]);

if (!update && nSeverity == searchshield.XPLCHECK_RESULT_SEV_NONE)
{
var shortUrl = searchshield.FilterUrl(href, this.shortened_urls);
if (shortUrl)
{ // shortened url verdicts display later
var engine = this;
anchor.attachEvent("onmouseover", function(event){avglsinlineflyover.mouseOverHandler(event, doc, engine)}, false);
return;
}
}

// severity -1 signifies sb.dat load failure
if ( nSeverity == -1 )
nSeverity = searchshield.XPLCHECK_RESULT_SEV_NONE;

//blacklist url
var blShortUrl = false;
if (nSeverity == searchshield.XPLCHECK_RESULT_SEV_BLOCK)
{
var shortUrl = searchshield.FilterUrl(href, this.shortened_urls);
if (shortUrl)
blShortUrl = true;
}

// need xlated cat tag and category
if (parts.length < 3)
return;

// check the minimum to display
if ((min_severity != null) && (nSeverity 0 )
{
imageElem.setAttribute(“title”, “”);
imageElem.attachEvent(“onmouseover”, function(e){avglsinlineflyover.popup(e, html)});
imageElem.attachEvent(“onmouseout”, function(e){avglsinlineflyover.hide(e)});
}
}
};

// add the image to the page
searchshield.SearchEngine.prototype.add_inline_image = function (doc, anchor, nSeverity, aRisk, blShortUrl)
{
if (anchor == null || anchor.parentNode == null)
return null;

// get the proper insertion point for the image
var insertNode = anchor.nextSibling;
while ((insertNode != null) &&
(insertNode.tagName != null) &&
(insertNode.tagName == “SPAN”))
{
insertNode= insertNode.nextSibling;
}

// see if we already have an image anchor
if ((insertNode != null) &&
(insertNode.id != null) &&
(insertNode.id == “avg_ls_anch”))
{
return null;
}

var html = ”;
var image = this.inline.clockImage;
if (aRisk != null && nSeverity != null)
{
var riskCategory = aRisk[1];
var riskName = aRisk[2];
var bgColor = this.inline.color.background[nSeverity];
var borderColor = this.inline.color.border[nSeverity];
image = this.inline.image[nSeverity];

var blUrl;
if (blShortUrl)
{
var aRiskName = riskName.split(‘:’);
var sUrl = searchshield.checkUrl(aRiskName[1]);

blUrl = {};
blUrl.riskNameLabel = aRiskName[0] + ‘: ‘;
blUrl.riskCategory = riskCategory;
blUrl.bgColor = bgColor;
blUrl.borderColor = borderColor;
blUrl.sUrl = sUrl;
}
else
{
html = avglsinlineflyover.build(riskCategory, riskName, bgColor, borderColor);
}
}

doc = anchor.ownerDocument;

var img = doc.createElement(“img”);
img.src = image;
img.setAttribute(“id”,”avg_ls_image”);
img.style.width = “12px”;
img.style.border = “none”;
img.style.padding = “0 3px”;
img.style.margin = “0”;
img.style.display = “inline”;

if ((html && html.length > 0) || (blUrl != undefined))
{
img.setAttribute(“title”, “”);
img.attachEvent(“onmouseover”, function(e){avglsinlineflyover.popup(e, html, blUrl)});
img.attachEvent(“onmouseout”, function(e){avglsinlineflyover.hide(e)});
}

// create the link element
var newAnchor = doc.createElement(“A”);
newAnchor.setAttribute(“id”, “avg_ls_anch”);

newAnchor.appendChild(img);
img = null;

// insert the node as either a sibling or a child
if (insertNode != null)
anchor.parentNode.insertBefore(newAnchor, insertNode);
else
anchor.parentNode.appendChild(newAnchor);

return newAnchor;

};
//////////////// SEARCH ENGINE ////////////////

/////////////// GOOGLE SEARCH ENGINE ///////////////
searchshield.GoogleSearchEngine = function(search)
{
searchshield.SearchEngine.call(this, search);
this.onlyPrimaries = false;
};
searchshield.GoogleSearchEngine.prototype = new searchshield.SearchEngine();
searchshield.GoogleSearchEngine.prototype.constructor = searchshield.GoogleSearchEngine;
searchshield.GoogleSearchEngine.prototype.name = “google”; // the name by which the search engine is known (always lowercase)
searchshield.GoogleSearchEngine.prototype.validSearch = function(href) {

var uri;
if (typeof(this.search) === ‘undefined’ || null === this.search)
uri = searchshield.parseLink(href);
else
uri = this.search.uri;

if(!uri || !uri.host)
return false;

var hostMatch = false;
var domain = uri.host;

// re stitch the uri path and query elements to
// use existing logic
var path = uri.path + uri.delimiter + uri.query;

// Domains valid for google searches, must start with ‘.’
var valid_domains = new Array(“.google.co”, “.mozilla.co”);

// For Google the host must match:
// .google.com OR
// .google.co.XX where XX is a country code
// .google.XX where XX is a country code
// Where any subdomain can come before the top level domain
var domLen = valid_domains.length;
for (var i = 0; i -1)
{
if (domain.charAt(tldPos + valid_domain_len) == ‘m’)
hostMatch = true;
else if ((domain.charAt(tldPos + valid_domain_len) == ‘.’) && ((domainLen – tldPos) == valid_domain_len+3))
hostMatch = true;
}
else
{
// get the form .google. to check the length of
var dot_pos = valid_domains[i].indexOf(“.”,1);
var valid_short_name = valid_domains[i].substring(0, dot_pos+1);

tldPos = domain.indexOf(valid_short_name);
if ((tldPos > -1) && ((domainLen – tldPos) == valid_domain_len))
hostMatch = true;
}
if (hostMatch)
{
// replace beginning of domain with http://www.google since links will refer back to it
if ((i > 0) && (tldPos > -1))
{
var last_dot = domain.indexOf(“.”,tldPos+1)
if (last_dot > -1)
domain = “www.google” + domain.substring(last_dot);
}
break;
}
}

if (hostMatch)
{
// using ajax engine
if ((path.indexOf(“search?”) == 0) ||
(path.indexOf(“sponsoredlinks?”) == 0) ||
(path.indexOf(“webhp?”) == 0) ||
(path.indexOf(“webhp#”) == 0) ||
(path.indexOf(“#q=”) == 0) ||
(path.indexOf(“#hl=”) == 0) ||
(path.indexOf(“#sclient=”) == 0))
{
return true;
}
}

return false;
};
searchshield.GoogleSearchEngine.prototype.includeLink = function(tag)
{
var href = “”;
var outHref = false;
var findStr = “”;

// check for interstitials
if (searchshield.DoesURLContain(tag.href, this.search.uri.host))
{
findStr = this.search.uri.host + “/interstitial?”;
if (tag.className == “l” && tag.href)
{
if (tag.href.indexOf(findStr) != -1)
{
findStr = “?url=”;
var pos = tag.href.indexOf(findStr);
if (pos !== -1)
{
pos += 5;
outHref = tag.href.substring(pos);
if (searchshield.FilterUrl(outHref, this.filter_urls))
return false;

return outHref;
}
}
}

if (tag.className == “sla”)
{
findStr = “/url?q=”;
urlPos = tag.href.indexOf(findStr);
if (urlPos != -1)
{
urlPos += 7;
outHref = tag.href.substring(urlPos);
return outHref;
}
}

// if an ad id
if ((tag.id.indexOf(“pa”) == 0) || (tag.id.indexOf(“an”) == 0) ||
(tag.className == “resultLink”))
{
var urlPos = -1;

// ads now need unescaping
href = unescape(tag.href);

findStr= “/url?sa=”;
if (href.indexOf(findStr) != -1)
{ // first kind, locate real url
findStr= “&q=http”;
urlPos = href.indexOf(findStr);
if (urlPos != -1)
urlPos += 3; // puts it on the http
}
if (urlPos == -1)
{
findStr = “/pagead/iclk?sa=”;
if (href.indexOf(findStr) != -1)
{ // second kind, locate real url
findStr = “&adurl=http”;
urlPos = href.indexOf(findStr);
if (urlPos != -1)
urlPos += 7; // puts it on the http
}
}
if (urlPos == -1)
{
if (href.indexOf(“/aclk?sa=”) != -1)
{ // third kind
urlPos = href.indexOf(“&q=http”);
if (urlPos != -1)
urlPos += 3; // puts it on the http
else
{
urlPos = href.indexOf(“&lp=http”);
if (urlPos != -1)
urlPos += 4;
else
{
findStr = “&adurl=http”;
urlPos = href.indexOf(findStr);
if (urlPos != -1)
urlPos += 7; // puts it on the http
}

}
}
}
if (urlPos == -1)
{
if (href.indexOf(“/url?cad=”) != -1)
{ // fourth kind
urlPos = href.indexOf(“&q=http”);
if (urlPos != -1)
urlPos += 3; // puts it on the http
}
}
if (urlPos != -1)
{
outHref = href.substring(urlPos);

// extract any fragment text, shouldn’t be unescaped
var pound = outHref.indexOf(“#”);
if (pound != -1)
{
var fragment = outHref.substring(pound);
outHref = outHref.substring(0, pound);
outHref = unescape(outHref);
outHref += fragment;
if (searchshield.FilterUrl(outHref, this.filter_urls))
return false;

return outHref;
}

outHref = unescape(outHref);
if (outHref.indexOf(“?”) == -1)
{
var ampPos = outHref.indexOf(“&”);
if (ampPos != -1)
outHref = outHref.substring(0, ampPos);
}

if (searchshield.FilterUrl(outHref, this.filter_urls))
return false;

return outHref;
}
}

// recommended link – use following to see one
// http://www.google.cz/search?hl=cs&q=warey&btnG=Hledat&lr=lang_cs
// elem parent class = r
// href must contain – url? and q=http
var parentNode = tag.parentNode;
if (parentNode && (parentNode.className.toLowerCase() == “r”))
{
href = tag.href;
if (href && (href.indexOf(“/url?”) != -1))
{
// locate the real url
var urlPos = href.indexOf(“q=http”);
if (urlPos != -1)
{
urlPos += 2;
outHref = href.substring(urlPos);

// include entire param up to ‘&’
var ampPos = outHref.indexOf(“&”);
if (ampPos != -1)
outHref = outHref.substring(0, ampPos);

return outHref;
}
}
}
}
// no link to self
else if (tag.className && (tag.className.charAt(0) == “l” || tag.className == “sla”))
{
// check for any images on the link
if (0 === tag.getElementsByTagName(“IMG”).length)
return tag.href;
}

// else nothing
return false;
};
/////////////// GOOGLE ///////////////

/////////////// AVG GOOGLE SEARCH ENGINE ///////////////
searchshield.AVGGoogleSearchEngine = function(search)
{
searchshield.SearchEngine.call(this, search);
this.onlyPrimaries = false;
};
searchshield.AVGGoogleSearchEngine.prototype = new searchshield.SearchEngine();
searchshield.AVGGoogleSearchEngine.prototype.constructor = searchshield.AVGGoogleSearchEngine;
searchshield.AVGGoogleSearchEngine.prototype.name = “avggoogle”; // the name by which the search engine is known (always lowercase)
searchshield.AVGGoogleSearchEngine.prototype.validSearch = function(href) {

var uri;
if (typeof(this.search) === ‘undefined’ || null === this.search)
uri = searchshield.parseLink(href);
else
uri = this.search.uri;

if(!uri || !uri.host)
return false;

var domain = uri.host;

// re stitch the uri path and query elements to
// use existing logic
var path = uri.path + uri.delimiter + uri.query;

if (domain.indexOf(“search.avg.com”) > -1)
{ // ads link back to google
return true;
}

return false;
};
searchshield.AVGGoogleSearchEngine.prototype.includeLink = function(tag)
{
var outHref = false;
var findStr = “”;

// check for interstitials
if (searchshield.DoesURLContain(tag.href, “google.com”))
{
// link back to self – DIV elem GrandParent class of res1 or res3 is Sponsored Link
var parentNode = tag.parentNode;
if (parentNode)
{
var grandParentNode = tag.parentNode.parentNode;
if (grandParentNode)
{
if ((grandParentNode.tagName == “DIV”) &&
((grandParentNode.className.toLowerCase() == “res1”) ||
(grandParentNode.className.toLowerCase() == “res3”)))
{
var urlPos = -1;

// ads now need unescaping
href = unescape(tag.href);

if (urlPos == -1)
{
if (href.indexOf(“/aclk?sa=”) != -1)
{
findStr = “&adurl=http”;
urlPos = href.indexOf(findStr);
if (urlPos != -1)
urlPos += 7; // puts it on the http

}
}
if (urlPos != -1)
{
outHref = href.substring(urlPos)
// extract any fragment text, shouldn’t be unescaped
var pound = outHref.indexOf(“#”);
if (pound != -1)
{
var fragment = outHref.substring(pound);
outHref = outHref.substring(0, pound);
outHref = unescape(outHref);
outHref += fragment;
if (searchshield.FilterUrl(outHref, this.filter_urls))
return false;

return outHref;
}

outHref = unescape(outHref);
if (outHref.indexOf(“?”) == -1)
{
var ampPos = outHref.indexOf(“&”);
if (ampPos != -1)
outHref = outHref.substring(0, ampPos);
}

if (searchshield.FilterUrl(outHref, this.filter_urls))
return false;

return outHref;
}
}
}
}
}

// no link to self
else
{
var parentNode = tag.parentNode;
if (parentNode)
{
var grandParentNode = tag.parentNode.parentNode;
if (grandParentNode)
{
if ((grandParentNode.tagName == “DIV”) &&
(grandParentNode.className.toLowerCase() == “res2”))
{
// check for any images on the link
if (0 === tag.getElementsByTagName(“IMG”).length)
return tag.href;
}
}
}
}

// else nothing
return false;
}
/////////////// AVG GOOGLE ///////////////

/////////////// YAHOO SEARCH ENGINE ///////////////
searchshield.YahooSearchEngine = function(search)
{
searchshield.SearchEngine.call(this, search);
this.showCleanVerdicts = false;
};
searchshield.YahooSearchEngine.prototype = new searchshield.SearchEngine();
searchshield.YahooSearchEngine.prototype.constructor = searchshield.YahooSearchEngine;
searchshield.YahooSearchEngine.prototype.name = “yahoo”;
searchshield.YahooSearchEngine.prototype.validSearch = function(href)
{
var uri;
if (typeof(this.search) === ‘undefined’ || null === this.search)
uri = searchshield.parseLink(href);
else
uri = this.search.uri;

if(!uri || !uri.host)
return false;

var domain = uri.host;

// re stitch the uri path and query elements to
// use existing logic
var path = uri.path + uri.delimiter + uri.query;

// For Yahoo the host must match:
// search.yahoo.com OR
// xx.search.yahoo.com where xx is the country code OR
// search.yahoo.co.jp OR
// for Yahoo China: one.cn.yahoo.com, search.cn.yahoo.com or http://www.yahoo.cn
if ((domain.match(/search\.yahoo\.co(?:m|\.jp)/i) ||
domain.match(/(?:search|one)\.cn\.yahoo\.com/i) ||
domain.match(/www\.yahoo\.cn/i)) &&
path.match(/^(?:search[;?]|s\?)/i))
{
return true;
}

return false;
};
searchshield.YahooSearchEngine.prototype.includeLink = function(tag)
{
var href = “”;
var outHref = “”;
var findStr = “”;

// yahoo likes to encode the url
href = unescape(tag.href);

if ((tag.className.indexOf(“yschttl”) != -1) ||
(tag.className.indexOf(“spt”) != -1))
{
var da = href.indexOf(“**”);
var ad = href.indexOf(“*-“);
if (da != -1)
outHref = href.substring(da+2);
else if (ad != -1)
outHref = href.substring(ad+2);
else
outHref = href ;

if (outHref.toLowerCase().indexOf(“overture.”) !== -1)
return false;
}
else if ((tag.tagName) &&
(tag.tagName === “A”) &&
(!tag.className))
{
var tagParent = tag.parentNode;

// if anchor without className then search parentNodes
if ((tagParent) &&
(tagParent.tagName !== “EM”) &&
(searchshield.getParentNodeByClassName(“yst-web”, tag, 4)))
{
// China Yahoo support
outHref = href;
}

else if ((tagParent) &&
(tagParent.tagName === “H3”) &&
(!!searchshield.getParentNodeById(“WS2m”,tag, 5)))
{
// Japan Yahoo support
var da = href.indexOf(“**”);
if (da == -1)
outHref = href;
else
outHref = href.substring(da+2);
}

else if ((tagParent) &&
(tagParent.className !== “c”) &&
(tagParent.parentNode.id !== “fpn”) &&
(!!searchshield.getParentNodeByClassName(“ymc”, tag, 7)))
{
// Korea Yahoo support – when not caught by yschttl
var da = href.indexOf(“**”);
if (da !== -1)
outHref = href.substring(da+2);
}
}
else if (!this.onlyPrimaries)
{
findStr = “&yargs=”;
var yargs = href.indexOf(findStr);
if (yargs != -1)
{
outHref = href.substring(yargs+findStr.length);
// check for prefix
if (outHref.indexOf(“://”) == -1)
outHref = “http://&#8221; + outHref;

// if inside an , probably a paypal link, don’t include
if (tag.parentNode && (tag.parentNode.tagName == “I”))
return false;
}
}

// filter domains
// split the url based on ‘/’
var parts = !!outHref ? outHref.split(‘/’) : null;

// Filter out domains that match any of the search engine’s names
if (!parts || !parts[2])
return false;

var domain = parts[2];
if ((domain.indexOf(“rdrjp.yahoo.com”) != -1) ||
(domain.indexOf(“rdrkrs.yahoo.com”) != -1) ||
(domain.indexOf(“rdrtpe.yahoo.com”) != -1) ||
(domain.indexOf(“rdrird.yahoo.com”) != -1) ||
(domain.indexOf(“rdrhk2.yahoo.com”) != -1) ||
(domain.indexOf(“rdrsg1.yahoo.com”) != -1) ||
(domain.indexOf(“rdrin2.yahoo.com”) != -1) ||
(domain.indexOf(“rdre1.yahoo.com”) != -1) ||
(domain.indexOf(“rdrw1.yahoo.com”) != -1) )
{
return false;
}

// set for yahoo to get parent node for image insertion
var hash = searchshield.avgCallFunc(this.doc, ‘GetHash’, outHref);
tag.setAttribute(“id”, “xplid_” + hash);
return outHref;
};
/////////////// YAHOO SEARCH ENGINE ///////////////

/////////////// AVG YAHOO SEARCH ENGINE ///////////////
searchshield.AVGYahooSearchEngine = function(search)
{
searchshield.SearchEngine.call(this, search);
this.showCleanVerdicts = false;
};
searchshield.AVGYahooSearchEngine.prototype = new searchshield.SearchEngine();
searchshield.AVGYahooSearchEngine.prototype.constructor = searchshield.AVGYahooSearchEngine;
searchshield.AVGYahooSearchEngine.prototype.name = “avgyahoo”;
searchshield.AVGYahooSearchEngine.prototype.validSearch = function(href)
{
var uri;
if (typeof(this.search) === ‘undefined’ || null === this.search)
uri = searchshield.parseLink(href);
else
uri = this.search.uri;

if(!uri || !uri.host)
return false;

var domain= uri.host;
//path may be ‘avg/search’ or ‘search’
var pathArray = uri.path.split(“/”);
var avg = pathArray[0];
// re stitch the uri path and query elements
// to use existing logic
var path = (undefined == pathArray[1]) ? pathArray[0] : pathArray[1];
path += uri.delimiter + uri.query;

// For AVG Yahoo classic the host must match:
// yhs.search.yahoo.com OR
// .yhs.search.yahoo.com
if (domain.indexOf(“yhs.search.yahoo.co”) != -1)
{
if ((avg == “avg”) &&
((path.indexOf(“search?”) == 0) ||
(path.indexOf(“search;”) == 0)))
{
return true;
}
}

// also support new metro version which DOESN’T
// contain /avg so avg split part is path
// valid domains are:
// search.yahoo.com,
// xx.search.yahoo.com and
// search.yahoo.co.xx
if (domain.indexOf(“search.yahoo.co”) != -1)
{
// path (split avg) must start with search and
// contain the avg toolbar parameter
if (((path.indexOf(“search?”) == 0) ||
(path.indexOf(“search;”) == 0)) &&
(path.indexOf(“fr=yhs-avg”) != -1))
{
return true;
}
}

return false;
};
searchshield.AVGYahooSearchEngine.prototype.includeLink = function(tag)
{
var href = “”;
var outHref = “”;
var findStr = “”;

if (this.search.doc.body.className.toLowerCase() != “standard”)
{ // handle as std Yahoo results page
return searchshield.YahooSearchEngine.prototype.includeLink(tag);
}

// yahoo likes to encode the url
href = unescape(tag.href);

if (tag.target == “_top”)
{
var da = href.indexOf(“**”);
if (da != -1)
outHref = href.substring(da+2);
else
outHref = href ;

if (outHref.toLowerCase().indexOf(“overture.”) !== -1)
return false;
}
else if (!this.onlyPrimaries)
{
findStr = “&yargs=”;
var yargs = href.indexOf(findStr);
if (yargs != -1)
{
outHref = href.substring(yargs+findStr.length);
// check for prefix
if (outHref.indexOf(“://”) == -1)
outHref = “http://&#8221; + outHref;

// if inside an , probably a paypal link, don’t include
if (tag.parentNode && (tag.parentNode.tagName == “I”))
return false;
}
}

// filter domains
// split the url based on ‘/’
var parts = outHref.split(‘/’);

// Filter out domains that match any of the search engine’s names
if (!parts[2])
return false;

var domain = parts[2];
if ((domain.indexOf(“rdrjp.yahoo.com”) != -1) ||
(domain.indexOf(“rdrkrs.yahoo.com”) != -1) ||
(domain.indexOf(“rdrtpe.yahoo.com”) != -1) ||
(domain.indexOf(“rdrird.yahoo.com”) != -1) ||
(domain.indexOf(“rdrhk2.yahoo.com”) != -1) ||
(domain.indexOf(“rdrsg1.yahoo.com”) != -1) ||
(domain.indexOf(“rdrin2.yahoo.com”) != -1) ||
(domain.indexOf(“rdre1.yahoo.com”) != -1) ||
(domain.indexOf(“rdrw1.yahoo.com”) != -1) )
{
return false;
}

return outHref;
};
searchshield.AVGYahooSearchEngine.prototype.updateImage = function (hash, search, score, image, alt_image, flyover, click_thru, altClick_thru)
{
// remove style that is set when alt image is applied
this.updateImageStyle = {
verticalAlign: null
};

// don’t show verisign icon
if (alt_image && (alt_image.length > 0))
this.omitAltImage = true;

var parent = searchshield.SearchEngine.prototype.updateImage;
return parent.call(this, hash, search, score, image, alt_image, flyover, click_thru, altClick_thru);
};
/////////////// AVG YAHOO SEARCH ENGINE ///////////////

/////////////// MSN SEARCH ENGINE ///////////////
searchshield.MSNSearchEngine = function(search)
{
searchshield.SearchEngine.call(this, search);
this.onlyPrimaries = false;
};
searchshield.MSNSearchEngine.prototype = new searchshield.SearchEngine();
searchshield.MSNSearchEngine.prototype.constructor = searchshield.MSNSearchEngine;
searchshield.MSNSearchEngine.prototype.name = “msn”;
searchshield.MSNSearchEngine.prototype.validSearch = function(href)
{
var uri;
if (typeof(this.search) === ‘undefined’ || null === this.search)
uri = searchshield.parseLink(href);
else
uri = this.search.uri;

if(!uri || !uri.host)
return false;

var hostMatch = false;
var domain = uri.host;

// re stitch the uri path and query elements to
// use existing logic
var path = uri.path + uri.delimiter + uri.query;

// For MSN the host must match:
// search.msn.com OR
// search.live.com
if (domain.indexOf(“search.msn.co”) > -1)
{
if (domain.charAt(13) == ‘m’)
hostMatch = true;
else if ((domain.charAt(13) == ‘.’) && (domain.length == 16))
hostMatch = true;
}
else if (domain.indexOf(“search.live.co”) > -1)
{
if (domain.charAt(14) == ‘m’)
hostMatch = true;
else if ((domain.charAt(14) == ‘.’) && (domain.length == 17))
hostMatch = true;
}

if (hostMatch)
{
if (path.indexOf(“results.aspx”) == 0)
return true;
}

return false;
};
searchshield.MSNSearchEngine.prototype.includeLink = function(tag)
{
var outHref = false;

// these don’t seem common from Firefox, but they are in IE
if (searchshield.DoesURLContain(tag.href, “g.msn.co”))
{
var qPos = tag.href.indexOf(“?”);
if (qPos != -1)
{
var postPart = tag.href.substring(qPos+1);
var dblAmp = postPart.indexOf(“&&”);
if (dblAmp != -1)
{
outHref = postPart.substring(0, dblAmp);
return outHref;
}
}
}
else if (searchshield.DoesURLContain(tag.href, “r.msn.co”))
{
var element = tag;
var parentNode = tag.parentNode;

// top links – check for a CITE
var spanElements = element.getElementsByTagName(“CITE”);
if ((spanElements != null) &&
(spanElements.length > 0))
{
outHref = spanElements[0].innerHTML;
// replace any nbsp’s
outHref = outHref.replace(” “, ” “);

// url is after the last space in the html, after the ‘-‘
var space_pos = outHref.lastIndexOf(” “);
if (space_pos != -1)
outHref = outHref.slice(space_pos + 1);

outHref = searchshield.checkUrl(outHref);
return outHref;
}

// side links
if (element.lastChild != null)
{
outHref = element.lastChild.innerHTML;
if ( outHref != null)
{
outHref = searchshield.checkUrl(outHref);
return outHref;
}
}
}
else if (searchshield.DoesURLContain(tag.href, this.search.uri.host) ||
searchshield.DoesURLContain(tag.href, “.live.com”) ||
searchshield.DoesURLContain(tag.href, “msn.”) ||
searchshield.DoesURLContain(tag.href, “msnscache.com”) ||
searchshield.DoesURLContain(tag.href, “advertising.microsoft.co”) ||
searchshield.DoesURLContain(tag.href, “javascript:”) ||
searchshield.DoesURLContain(tag.href, “go.microsoft.co”) ||
searchshield.DoesURLContain(tag.href, “hotmail.co”))
{
// not a link
return false;
}
else if (tag.id.toLowerCase() == “trademarks”)
{
// don’t link the trademark at the bottom of the page
return false;
}
else
{
// include it
return tag.href;
}
};
/////////////// MSN SEARCH ENGINE ///////////////

/////////////// BING SEARCH ENGINE ///////////////
searchshield.BingSearchEngine = function(search)
{
searchshield.SearchEngine.call(this, search);
};
searchshield.BingSearchEngine.prototype = new searchshield.SearchEngine();
searchshield.BingSearchEngine.prototype.constructor = searchshield.BingSearchEngine;
searchshield.BingSearchEngine.prototype.name = “bing”;
searchshield.BingSearchEngine.prototype.validSearch = function(href)
{
var uri;
if (typeof(this.search) === ‘undefined’ || null === this.search)
uri = searchshield.parseLink(href);
else
uri = this.search.uri;

if(!uri || !uri.host)
return false;

var hostMatch = false;
var domain = uri.host;

// re stitch the uri path and query elements to
// use existing logic
var path = uri.path + uri.delimiter + uri.query;

// For bing the host must match:
// http://www.bing.com or http://www.bing.net
// xx.bing.com or xx.bing.net where xx is a country code
// bing.com.xx where xx is a country code
// bing.search.xxxx.net where xxxx may be something like daum
if ((domain.indexOf(“www.bing.com”) !== -1) ||
(domain.indexOf(“www.bing.net”) !== -1) ||
(domain.indexOf(“bing.net”) !== -1))
{
hostMatch = true;
}
else if ((domain.indexOf(“bing.search.”) !== -1) &&
(domain.indexOf(“.net”) === (domain.length-4)))
{ //bing.search.xxxx.net
hostMatch = true;
}
else
{ // xx.bing.com or bing.com.xx
var domainLen = domain.length;
var tldPos = domain.indexOf(“.bing.com”);
if (tldPos > -1)
{
if ((domainLen – tldPos) == 9)
hostMatch = true;
}
}

if (hostMatch)
{
if (path.indexOf(“search?”) == 0)
return true;
}

return false;

};
searchshield.BingSearchEngine.prototype.includeLink = function(tag)
{
var outHref = false;

if (tag.tagName == ‘IMG’)
{ //no images
return false;
}

if (tag.href.charAt(0) == ‘/’)
{ //no relative links
return false;
}

if (tag.id.toLowerCase() == “trademarks”)
{
// don’t link the trademark at the bottom of the page
return false;
}

if ((tag.parentNode) &&
(tag.parentNode.id.toLowerCase() == “sc_stc”))
{ // don’t verdict the social sites – our verdict doesn’t fit
return false;
}
else if (!!searchshield.getParentNodeByClassName(“sw_t”,tag,3))
{ // no links in page header
return false;
}
else if (searchshield.DoesURLContain(tag.href, “r.msn.co”) ||
searchshield.DoesURLContain(tag.href, “overture.com”))
{ // france has r.msn.co and italy has overture.com sponsored links
// with the link in CITE element

var spanElements = null;

// top links – check for a CITE
spanElements = tag.getElementsByTagName(“CITE”);
if ((spanElements == null) || (spanElements.length 0))
{
outHref = spanElements[0].innerHTML;
if (outHref != null)
{
// replace any nbsp’s
outHref = outHref.replace(” “, ” “);

// url is after the last space in the html, after the ‘-‘
var space_pos = outHref.lastIndexOf(” “);
if (space_pos != -1)
outHref = outHref.slice(space_pos + 1);

outHref = searchshield.checkUrl(outHref);

// save the link
return outHref;
}
}

// side links
if (tag.lastChild != null)
{
outHref = tag.lastChild.innerHTML;
if (outHref != null)
{
outHref = searchshield.checkUrl(outHref);
// save the link
return outHref;
}
}
}
// no sponsored links for now
else if (searchshield.DoesURLContain(tag.href, this.search.uri.host) ||
searchshield.DoesURLContain(tag.href, “.live.com”) ||
searchshield.DoesURLContain(tag.href, “.bing.com”) ||
searchshield.DoesURLContain(tag.href, “.bing.net”) ||
searchshield.DoesURLContain(tag.href, “.daum.net”) ||
searchshield.DoesURLContain(tag.href, “.gmarket.co”) ||
searchshield.DoesURLContain(tag.href, “.multimap.com”) ||
searchshield.DoesURLContain(tag.href, “msn.”) ||
searchshield.DoesURLContain(tag.href, “ms.ciao.”) ||
searchshield.DoesURLContain(tag.href, “ms.ciao-“) ||
searchshield.DoesURLContain(tag.href, “advertising.microsoft.co”) ||
searchshield.DoesURLContain(tag.href, “javascript:”) ||
searchshield.DoesURLContain(tag.href, “go.microsoft.co”) ||
searchshield.DoesURLContain(tag.href, “hotmail.co”) ||
searchshield.DoesURLContain(tag.href, “cc.bingj.com”) ||
searchshield.DoesURLContain(tag.href, “microsofttranslator.com”) ||
searchshield.DoesURLContain(tag.href, “.engkoo.com”) ||
searchshield.DoesURLContain(tag.href, “sealinfo.verisign.com”) ||
searchshield.DoesURLContain(tag.href, “explabs.com”) ||
searchshield.DoesURLContain(tag.href, “onlinehelp.microsoft.com”))
{
// not a link
return false;
}
else
return tag.href;
};
searchshield.BingSearchEngine.prototype.addImage = function(node, image, hidden)
{
var element = node.element;
var parentNode = node.element.parentNode;
var grandParentNode = !!parentNode ? parentNode.parentNode : null;

// if there are redundant links in the same grandparent then skip them
if (!!grandParentNode)
{
gpChildren = grandParentNode.childNodes;
for (var i=0; i < gpChildren.length; i++)
{
if (!!element.href && gpChildren[i].tagName == "A" && gpChildren[i].href == element.href)
return;
}
}

var parent = searchshield.SearchEngine.prototype.addImage;
return parent.call(this, node, image, hidden);
};
/////////////// BING SEARCH ENGINE ///////////////

/////////////// BAIDU SEARCH ENGINE ///////////////
searchshield.BaiduSearchEngine = function(search)
{
searchshield.SearchEngine.call(this, search);
};
searchshield.BaiduSearchEngine.prototype = new searchshield.SearchEngine();
searchshield.BaiduSearchEngine.prototype.constructor = searchshield.BaiduSearchEngine;
searchshield.BaiduSearchEngine.prototype.name = "baidu";
searchshield.BaiduSearchEngine.prototype.validSearch = function(href)
{
var uri;
if (typeof(this.search) === 'undefined' || null === this.search)
uri = searchshield.parseLink(href);
else
uri = this.search.uri;

if(!uri || !uri.host)
return false;

var hostMatch = false;
var domain = uri.host;

// re stitch the uri path and query elements to
// use existing logic
var path = uri.path + uri.delimiter + uri.query;

if (domain == "www.baidu.com" || path.indexOf("testBaidu") !== -1)
hostMatch = true;

if (hostMatch)
{
if (path.indexOf("s?") == 0)
return true;
}

return false;
};
searchshield.BaiduSearchEngine.prototype.includeLink = function(tag)
{
if (tag.className && tag.className == "m")
return false;

if (searchshield.DoesURLContain(tag.href, this.search.uri.host))
return false;
else
{
// no link to self
var traverseElement = tag.parentNode;
while ( traverseElement && traverseElement.className != "tbody")
{
if (traverseElement.className == "f")
return tag.href;

traverseElement = traverseElement.parentNode;
}

return false;
}

};
searchshield.BaiduSearchEngine.prototype.addImage = function(node, image, hidden)
{
this.addImageStyle = {
position: "relative",
top: "0.05em"
};

var parent = searchshield.SearchEngine.prototype.addImage;
return parent.call(this, node, image, hidden);
};
searchshield.BaiduSearchEngine.prototype.updateImage = function (hash, search, score, image, alt_image, flyover, click_thru, altClick_thru)
{
// remove style that is set when alt image is applied
this.updateImageStyle = {
verticalAlign: null
};

var parent = searchshield.SearchEngine.prototype.updateImage;
return parent.call(this, hash, search, score, image, alt_image, flyover, click_thru, altClick_thru);
};
/////////////// BAIDU SEARCH ENGINE ///////////////

/////////////// EARTHLINK SEARCH ENGINE ///////////////
searchshield.EarthlinkSearchEngine = function(search)
{
searchshield.SearchEngine.call(this, search);
this.onlyPrimaries = false;

this.addAnchorStyle = {
position: "static"
};
};
searchshield.EarthlinkSearchEngine.prototype = new searchshield.SearchEngine();
searchshield.EarthlinkSearchEngine.prototype.constructor = searchshield.EarthlinkSearchEngine;
searchshield.EarthlinkSearchEngine.prototype.name = "earthlink";
searchshield.EarthlinkSearchEngine.prototype.validSearch = function(href)
{
var uri;
if (typeof(this.search) === 'undefined' || null === this.search)
uri = searchshield.parseLink(href);
else
uri = this.search.uri;

if(!uri || !uri.host)
return false;

var hostMatch = false;
var domain = uri.host;

// re stitch the uri path and query elements to
// use existing logic
var path = uri.path + uri.delimiter + uri.query;

// For EarthLink the host must match:
// search.earthlink.net
if (("search.earthlink.net" == domain) &&
(path.indexOf("search?") == 0))
{
return true;
}

return false;
};
searchshield.EarthlinkSearchEngine.prototype.includeLink = function(tag)
{
var outHref = "";
var findStr = "";

// check for an anchor
if (tag.tagName == "A")
{
// check for sponsored
if (tag.id.indexOf("a") == 0)
{
var q = tag.href.indexOf("&q=");
var qlen = 3;
if (q == -1)
{
q = tag.href.indexOf("&adurl=");
qlen = 7;
if (q == -1)
return false;
}

// find end of url
var end = tag.href.indexOf("&", q+qlen);
if (end < 0)
end = tag.href.length;

// add the link
outHref = tag.href.substring(q+qlen, end);

if (searchshield.FilterUrl(outHref, this.filter_urls))
return false;

return outHref;
}

// don't search url's to self
if ((tag.href.indexOf("://") == -1) || searchshield.DoesURLContain(tag.href, this.search.uri.host))
return false;

// if a normal web result add it
if (tag.parentNode && (tag.parentNode.tagName == "H3") &&
tag.parentNode.parentNode && (tag.parentNode.parentNode.tagName == "LI") &&
tag.parentNode.parentNode.parentNode && (tag.parentNode.parentNode.parentNode.tagName == "UL"))
{
if (searchshield.FilterUrl(tag.href, this.filter_urls))
return false;

return tag.href;
}
}

return false;
};
/////////////// EARTHLINK SEARCH ENGINE ///////////////

/////////////// AOL SEARCH ENGINE ///////////////
searchshield.AOLSearchEngine = function(search)
{
searchshield.SearchEngine.call(this, search);

this.addImageStyle = {
display: "inline"
};
this.addAnchorStyle = {
display: null
};
this.updateImageStyle = {
verticalAlign: null,
display: "inline"
};
};
searchshield.AOLSearchEngine.prototype = new searchshield.SearchEngine();
searchshield.AOLSearchEngine.prototype.constructor = searchshield.AOLSearchEngine;
searchshield.AOLSearchEngine.prototype.name = "aol";
searchshield.AOLSearchEngine.prototype.validSearch = function(href)
{
var uri;
if (typeof(this.search) === 'undefined' || null === this.search)
uri = searchshield.parseLink(href);
else
uri = this.search.uri;

if(!uri || !uri.host)
return false;

var domain = uri.host;
//path may be 'aol/search' or 'search'
var pathArray = uri.path.split("/");
var aol = pathArray[0];
// re stitch the uri path and query elements
// to use existing logic
var path = (undefined == pathArray[1]) ? pathArray[0] : pathArray[1];
path += uri.delimiter + uri.query;

if ("search.aol.com" == domain)
{
if ((aol == "aol") &&
(path.indexOf("search?") == 0))
{
return true;
}
}

return false;
};
searchshield.AOLSearchEngine.prototype.includeLink = function(tag)
{
if (searchshield.DoesURLContain(tag.href, this.search.uri.host))
return false;

// sponsored links – google
if ((tag.className) && (tag.className.indexOf("slLink") != -1))
{ //parse for embedded href

if (tag.href.indexOf("/aclk?sa=") == -1)
return false;

var adurl = tag.href.indexOf("&adurl=http");
if (adurl != -1)
{
var urlPos = adurl+7; // puts it on the http
var outHref = tag.href.substring(urlPos);

// extract any fragment text, do not unescape
var pound = outHref.indexOf("#");
if (pound != -1)
{
var fragment = outHref.substring(pound);
outHref = outHref.substring(0, pound);
outHref = unescape(outHref);
outHref += fragment;
if (searchshield.FilterUrl(outHref, this.filter_urls))
return false;

return outHref;
}

outHref = unescape(outHref);
if (outHref.indexOf("?") == -1)
{
var ampPos = outHref.indexOf("&");
if (ampPos != -1)
outHref = outHref.substring(0, ampPos);
}

if (searchshield.FilterUrl(outHref, this.filter_urls))
return false;

return outHref;
}

return false;
}

if (tag.className == "find")
return tag.href;

return false;
};
searchshield.AOLSearchEngine.prototype.insertNodes = function(node, doc)
{
var element = node.element;
var score = node.score;

if (element && element.className && element.className.indexOf("slLink") != -1)
{ //sponsored links only

// for alt image
if (score == searchshield.SCORE_SS_VERISIGN)
return [element.nextSibling, element.parentNode];

// for verdict image
var cN = element.childNodes;
var cnLen = cN.length;
for (var i=0; i now http://us.yhs4.search.yahoo.com/yhs/search?fr=altavista&fr=altavista&itag=ody&q=warez&kgs=1&kls=0
// xx.altavista.com where xx is a country code
var hostMatch = false;
if (“www.altavista.com” == domain)
{
hostMatch = true;
}
else
{
// xx.altavista.com
var pDest = domain.indexOf(“.altavista.com”);
if ((pDest != -1 ) && ((domain.length – pDest) == 14))
{
hostMatch = true;
}
else
{
// a reference to altavista must be present in yahoo search url
var pRef = (uri.qsArray.fr && uri.qsArray.fr == ‘altavista’);
pDest = domain.indexOf(“search.yahoo.com”);
if (pDest != -1 && pRef)
hostMatch = true;
}
}

if (hostMatch)
{
//path must start with web/results?
if ((path.indexOf(“yhs/search?”) == 0) ||
(path.indexOf(“search;”) == 0) ||
(path.indexOf(“yhs/search;”) == 0) ||
(path.indexOf(“web/results?”) == 0)||
(path.indexOf(“fr=altavista”) != -1))
{
return true;
}
}

return false;
};
searchshield.AltaVistaSearchEngine.prototype.includeLink = function(tag)
{
var outHref = “”;
var findStr = “”;

// initial checks
if ((!tag.href) ||
(tag.href.charAt(0) == ‘#’) ||
(tag.href.indexOf(“javascript:”) == 0))
{
return false;
}

if (searchshield.DoesURLContain(tag.href, this.search.uri.host))
return false;

if ((tag.className == “spt”) ||
(tag.className == “res”) ||
(tag.className == “yschttl spt”))
{
findStr = “/**”;
var pos = tag.href.indexOf(findStr);
if (pos != -1)
{
pos += 3;
outHref = tag.href.substring(pos);
outHref = unescape(outHref);

// no results for overture.com & no yahoo domains
chkHref = outHref.toLowerCase();
if (chkHref.indexOf(“overture.”) != -1)
return false;

// split the url based on ‘/’
var parts = outHref.split(‘/’);

// only need a domain
if ((parts != null) && (parts[2] != null))
{
var domain = parts[2];
if ((domain.indexOf(“rdrjp.yahoo.com”) != -1) ||
(domain.indexOf(“rdrkrs.yahoo.com”) != -1) ||
(domain.indexOf(“rdrtpe.yahoo.com”) != -1) ||
(domain.indexOf(“rdrird.yahoo.com”) != -1) ||
(domain.indexOf(“rdrhk2.yahoo.com”) != -1) ||
(domain.indexOf(“rdrsg1.yahoo.com”) != -1) ||
(domain.indexOf(“rdrin2.yahoo.com”) != -1) ||
(domain.indexOf(“rdre1.yahoo.com”) != -1) ||
(domain.indexOf(“rdrw1.yahoo.com”) != -1) )
{
return false
}
}

return outHref;
}
else
{
return tag.href;
}
}

return false;
};
searchshield.AltaVistaSearchEngine.prototype.getImgElement = function (element)
{
while (element != null)
{
element = element.nextSibling;
if (element != null)
{
if ((element.id == null) || (element.id.indexOf(“LXPLSS_”) == -1))
{ // not our id but hit another anchor no verdict
if (element.tagName == “A”)
{
element = null;
break;
}
}
else if (element.tagName == “A”)
break;
}
}

var rtnElem = !!element ? element.firstChild : element;
return rtnElem;
};
/////////////// ALTAVISTA SEARCH ENGINE ///////////////

/////////////// YANDEX SEARCH ENGINE ///////////////
searchshield.YandexSearchEngine = function(search)
{
searchshield.SearchEngine.call(this, search);
};
searchshield.YandexSearchEngine.prototype = new searchshield.SearchEngine();
searchshield.YandexSearchEngine.prototype.constructor = searchshield.YandexSearchEngine;
searchshield.YandexSearchEngine.prototype.name = “yandex”;
searchshield.YandexSearchEngine.prototype.validSearch = function(href)
{
var uri;
if (typeof(this.search) === ‘undefined’ || null === this.search)
uri = searchshield.parseLink(href);
else
uri = this.search.uri;

if(!uri || !uri.host)
return false;

var domain= uri.host;
// re stitch the uri path and query elements
// to use existing logic
var path = uri.path + uri.delimiter + uri.query;

if (((domain.indexOf(“yandex.ru”) > -1) ||
(domain.indexOf(“yandex.com”) > -1)) &&
(path.indexOf(“yandsearch?”) == 0))
{
return true;
}

return false;
};
searchshield.YandexSearchEngine.prototype.includeLink = function(tag)
{
if (tag.href.indexOf(“/search”) != -1)
{
return false;
}

if (searchshield.DoesURLContain(tag.href, this.search.uri.host) ||
searchshield.DoesURLContain(tag.href, “.yandex.net”) ||
searchshield.DoesURLContain(tag.href, “.yandex.ru”) ||
searchshield.DoesURLContain(tag.href, “moikrug.ru”) ||
searchshield.DoesURLContain(tag.href, “ya.ru”) ||
searchshield.DoesURLContain(tag.href, “.yandex.com”) ||
searchshield.DoesURLContain(tag.href, “yandex.st”))
{
return false;
}

parentNode = tag.parentNode;
if ((tag.parentNode) &&
(tag.parentNode.parentNode) &&
(tag.parentNode.parentNode.className.toLowerCase() == “moreinfo”))
{
return false;
}

return tag.href;
};
searchshield.YandexSearchEngine.prototype.getImgElement = function (element)
{
while (element != null)
{
element = element.nextSibling;
if (element != null)
{
if ((element.id == null) || (element.id.indexOf(“LXPLSS_”) == -1))
{ // not our id but hit another anchor no verdict
if (element.tagName == “A”)
{
element = null;
break;
}
}
else if (element.tagName == “A”)
break;
}
}

var rtnElem = !!element ? element.firstChild : element;
return rtnElem;
};
/////////////// YANDEX SEARCH ENGINE ///////////////

/////////////// SEZNAM SEARCH ENGINE ///////////////
searchshield.SeznamSearchEngine = function(search)
{
searchshield.SearchEngine.call(this, search);
};
searchshield.SeznamSearchEngine.prototype = new searchshield.SearchEngine();
searchshield.SeznamSearchEngine.prototype.constructor = searchshield.SeznamSearchEngine;
searchshield.SeznamSearchEngine.prototype.name = “seznam”;
searchshield.SeznamSearchEngine.prototype.validSearch = function(href)
{
var uri;
if (typeof(this.search) === ‘undefined’ || null === this.search)
uri = searchshield.parseLink(href);
else
uri = this.search.uri;

if(!uri || !uri.host)
return false;

var domain= uri.host;
// re stitch the uri path and query elements
// to use existing logic
var path = uri.path + uri.delimiter + uri.query;

if ((domain.indexOf(“search.seznam.cz”) > -1) &&
((path.indexOf(“?”) == 0) || (path.indexOf(“svet”) == 0)))
{
return true;
}

return false;
};
searchshield.SeznamSearchEngine.prototype.includeLink = function(tag)
{
if (searchshield.DoesURLContain(tag.href, this.search.uri.host))
return false;

var parentNode = tag.parentNode;
if (parentNode)
{
var grandParentNode = tag.parentNode.parentNode;
if ((parentNode.tagName == “SPAN”) &&
((parentNode.className.toLowerCase() == “sklik-url”) ||
(parentNode.className.toLowerCase() == “sklik-title”)))
{ // locate the real url and unencode it
var urlPos = tag.href.indexOf(“&url=http”);

if (urlPos != -1)
{
urlPos += 5;
outHref = tag.href.substring(urlPos);
outHref = unescape(outHref);

return outHref;
}
}
else if (grandParentNode)
{
var greatGrandParentNode = tag.parentNode.parentNode.parentNode;
if ((grandParentNode.tagName == “DIV”) &&
((grandParentNode.className.toLowerCase() == “text”) || (grandParentNode.className.toLowerCase() == “hlasky otz”)))
{ // standard link
return tag.href;
}
else if (greatGrandParentNode && greatGrandParentNode.tagName == “DIV” &&
(greatGrandParentNode.className.toLowerCase() == “hotlinks”))
{ // hint link
return tag.href;
}

}
}

return false;
};
searchshield.SeznamSearchEngine.prototype.updateImage = function (hash, search, score, image, alt_image, flyover, click_thru, altClick_thru)
{
this.elementAttribute = {
width: “18”,
height: “18”
};

this.updateImageStyle = {
width: “18px”,
height: “18px”
};

var parent = searchshield.SearchEngine.prototype.updateImage;
return parent.call(this, hash, search, score, image, alt_image, flyover, click_thru, altClick_thru);
};
/////////////// SEZNAM SEARCH ENGINE ///////////////

/////////////// WEBHLEDANI SEARCH ENGINE ///////////////
searchshield.WebhledaniSearchEngine = function(search)
{
searchshield.SearchEngine.call(this, search);
};
searchshield.WebhledaniSearchEngine.prototype = new searchshield.SearchEngine();
searchshield.WebhledaniSearchEngine.prototype.constructor = searchshield.WebhledaniSearchEngine;
searchshield.WebhledaniSearchEngine.prototype.name = “webhledani”;
searchshield.WebhledaniSearchEngine.prototype.validSearch = function(href)
{
var uri;
if (typeof(this.search) === ‘undefined’ || null === this.search)
uri = searchshield.parseLink(href);
else
uri = this.search.uri;

if(!uri || !uri.host)
return false;

var domain= uri.host;
// re stitch the uri path and query elements
// to use existing logic
var path = uri.path + uri.delimiter + uri.query;

if ((domain.indexOf(“webhledani.cz”) > -1) &&
(path.indexOf(“results.aspx?”) == 0))
{
return true;
}

return false;
};
searchshield.WebhledaniSearchEngine.prototype.includeLink = function(tag)
{
var parentNode = tag.parentNode;

if (searchshield.DoesURLContain(tag.href, this.search.uri.host))
{
if ( tag.href.indexOf(“/redir.aspx?”) != -1)
{
attrNode = tag.attributes;
if ( attrNode == null )
return false;

var outHref = attrNode.getNamedItem(“onmouseover”).nodeValue;
if ( outHref == null )
return false;

var findStr = “window.status=”;
if (outHref.indexOf(findStr)!= -1)
{
// get text before first semicolon
var semicolon = outHref.indexOf(“;”);
if (semicolon > -1)
outHref = outHref.substring(findStr.length, semicolon);

// strip quotation marks
outHref = outHref.replace(/[‘”]/g, “”);

var space = outHref.indexOf(” “);
var firstDot = outHref.indexOf(“.”);

if ((space > -1) && (space < firstDot))
outHref = outHref.substring(space+1);

outHref = searchshield.checkUrl(outHref);
return outHref;
}
}
}

return false;
};
searchshield.WebhledaniSearchEngine.prototype.insertNodes = function(node, doc)
{
var element = node.element;
var score = node.score;

// for alt image
if (score == searchshield.SCORE_SS_VERISIGN)
return [element.nextSibling, element.parentNode];

// for verdict image
var cN = element.childNodes;
var cnLen = cN.length;
for (var i=0; i -1) ||
(domain.indexOf(“shop.benl.ebay”) > -1))
{
if ((path.indexOf(“?_from=”) == 0) ||
(path.indexOf(“i.html”) > -1))
{
return true;
}
}

// ebay.se
if ((domain.indexOf(“search.eim.ebay”) > -1) &&
((path.indexOf(“?kw=”) > -1) || (path.indexOf(“?ev=”) > -1)))
{
return true;
}

if ((domain.indexOf(“search.auction.co.kr”) > -1 ) &&
((path.indexOf(“?keyword=”) > -1)))
{
// would normally set these properties in the constructor or in an
// overriding function but they’re only required for this domain

// links are in iframes
this.processFrames = true;

// must downsize verdicts for proper display
this.elementAttribute = {
width: “16”,
height: “16”
};
this.updateImageStyle = {
width: “16px”,
height: “16px”
};

return true;
}

// latin america ebay
// listado.mercadolibre.com.xx or listado.mercadolibre.co.xx
// or listado.mercadolibre.xx or
// category.mercadolibre.com.xx or listado.mercadolibre.xx/category
// lista.mercadolivre.com.xx or lista.mercadolivre.com.xx/category
if ((domain.indexOf(“www.”) == -1) &&
((domain.indexOf(“.mercadolibre.”) > -1 ) ||
(domain.indexOf(“.mercadolivre.”) > -1 )))
{
return true;
}
return false;
};
searchshield.eBaySearchEngine.prototype.includeLink = function(tag)
{
var parentNode = null;
var outHref = false;

if (searchshield.DoesURLContain(tag.href, this.search.uri.host))
return false;

if ( tag.href.indexOf(“.ebayrtm.com/clk?”) > -1 )
{
if ( tag.title == null || tag.title.length -1)
{ // at least one dot
if (outHref.indexOf(this.search.uri.host) == -1)
{ // no host
if (outHref.toLowerCase().indexOf(“ebay.com”) == -1)
{
return outHref;
}
}
}
}
}
// ebay.se – Google ads
parentNode = tag.parentNode;
if (parentNode && (parentNode.className.toLowerCase() == “google-ad-link”))
{
if (tag.href.indexOf(“/aclk?sa=”) != -1)
{
findStr = “&adurl=http”;
var urlPos = tag.href.indexOf(findStr);
if (urlPos != -1)
{
urlPos += 7; // puts it on the http
outHref = tag.href.substring(urlPos);

// extract any fragment text, shouldn’t be unescaped
var pound = outHref.indexOf(“#”);
if (pound != -1)
{
var fragment = outHref.substring(pound);
outHref = outHref.substring(0, pound);
outHref = unescape(outHref);
outHref += fragment;
if (searchshield.FilterUrl(outHref, this.filter_urls))
return false;

return outHref;
}

outHref = unescape(outHref);
if (outHref.indexOf(“?”) == -1)
{
var ampPos = outHref.indexOf(“&”);
if (ampPos != -1)
outHref = outHref.substring(0, ampPos);
}

if (searchshield.FilterUrl(outHref, this.filter_urls))
return false;
return outHref;
}
}
}

// auction.co.kr
parentNode = tag.parentNode;
if (parentNode && (parentNode.className.toLowerCase() == “link”))
{
if (tag.href.indexOf(“adcr.naver.com”) > -1)
{
outHref = tag.innerText;
if ((outHref == null) || (outHref.length -1 )
{
var spanElements = tag.getElementsByTagName(“span”);
if ((spanElements != null) &&
(spanElements.length > 0))
{
if ( spanElements[0].className.toLowerCase() == “mclics-url” )
{
outHref = spanElements[0].innerHTML;
if ( outHref == null || outHref.length -1)
{ // at least one dot
if ((outHref.toLowerCase().indexOf(“mercadolibre”) == -1) &&
(outHref.toLowerCase().indexOf(“mercadolivre”) == -1))
{
return outHref;
}
}
}
}
}
}

return false;
};
/////////////// EBAY SEARCH ENGINE ///////////////

/////////////// DIGG SEARCH ENGINE ///////////////
searchshield.DiggSearchEngine = function(search)
{
searchshield.SearchEngine.call(this, search);
this.new_links = false;
};
searchshield.DiggSearchEngine.prototype = new searchshield.SearchEngine();
searchshield.DiggSearchEngine.prototype.constructor = searchshield.DiggSearchEngine;
searchshield.DiggSearchEngine.prototype.name = “digg”;
searchshield.DiggSearchEngine.prototype.validSearch = function(href)
{
var uri;
if (typeof(this.search) === ‘undefined’ || null === this.search)
uri = searchshield.parseLink(href);
else
uri = this.search.uri;

if(!uri || !uri.host)
return false;

var domain= uri.host;
// re stitch the uri path and query elements
// to use existing logic
var path = uri.path + uri.delimiter + uri.query;

if ((domain.indexOf(“digg.com”) > -1) &&
(path.indexOf(“/ad”) == -1))
{
return true;
}

return false;
};
searchshield.DiggSearchEngine.prototype.includeLink = function(tag)
{
var outHref = false;
var findStr = “”;

if ((tag.parentNode) &&
(tag.parentNode.className.toLowerCase() == “digg-count”))
{
return false;
}

if (searchshield.DoesURLContain(tag.href, this.search.uri.host))
{
if (tag.className && tag.className.indexOf(‘source’) != -1)
{
findStr = “/search?q=site:”;
var urlPos = tag.href.indexOf(findStr);
if (urlPos != -1)
{
urlPos += 15;
outHref = tag.href.substring(urlPos);
return outHref;
}
}
}

return false;
};
searchshield.DiggSearchEngine.prototype.addImage = function(node, image, hidden)
{
// remove style that is set when alt image is applied
this.addAnchorStyle = {
background: “none”
};

var parent = searchshield.SearchEngine.prototype.addImage;
return parent.call(this, node, image, hidden);
};
/////////////// DIGG SEARCH ENGINE ///////////////

/////////////// SLASHDOT SEARCH ENGINE ///////////////
searchshield.SlashdotSearchEngine = function(search)
{
searchshield.SearchEngine.call(this, search);
this.showCleanVerdicts = false;
this.new_links = false;
this.type = ‘inline’;
};
searchshield.SlashdotSearchEngine.prototype = new searchshield.SearchEngine();
searchshield.SlashdotSearchEngine.prototype.constructor = searchshield.SlashdotSearchEngine;
searchshield.SlashdotSearchEngine.prototype.name = “slashdot”;
searchshield.SlashdotSearchEngine.prototype.validSearch = function(href)
{
var uri;
if (typeof(this.search) === ‘undefined’ || null === this.search)
uri = searchshield.parseLink(href);
else
uri = this.search.uri;

if(!uri || !uri.host)
return false;

var domain= uri.host;
// re stitch the uri path and query elements
// to use existing logic
var path = uri.path + uri.delimiter + uri.query;

if (domain.indexOf(“slashdot.org”) != -1)
{
return true;
}

return false;
};
searchshield.SlashdotSearchEngine.prototype.includeLink = function(tag)
{
if (searchshield.DoesURLContain(tag.href, this.search.uri.host))
return false;

if ( tag.href.indexOf(“mailto:”) != -1 )
return false;

if ( tag.href.indexOf(“slashdot.org”) != -1 )
return false;

if (tag.parentNode && (tag.parentNode.tagName == “DIV”))
{
if (tag.parentNode.id.indexOf(“text-“) != -1)
{
return tag.href;
}
}
else if ( tag.parentNode && tag.parentNode.parentNode && tag.parentNode.parentNode.tagName == “DIV” )
{
if ( tag.parentNode.parentNode.id.indexOf(“text-“) != -1 )
{
return tag.href;
}
}

return false;
};
searchshield.SlashdotSearchEngine.prototype.addImage = function(node, image, hidden)
{
var doc = this.search.doc;

this.init_inline_ratings(doc);
this.show_inline_ratings(doc, node, image);
};
/////////////// SLASHDOT SEARCH ENGINE ///////////////

/////////////// TWITTER SEARCH ENGINE ///////////////
searchshield.TwitterSearchEngine = function(search)
{
searchshield.SearchEngine.call(this, search);
this.showCleanVerdicts = false;
this.new_links = false;
this.type = ‘inline’;
};
searchshield.TwitterSearchEngine.prototype = new searchshield.SearchEngine();
searchshield.TwitterSearchEngine.prototype.constructor = searchshield.TwitterSearchEngine;
searchshield.TwitterSearchEngine.prototype.name = “twitter”;
searchshield.TwitterSearchEngine.prototype.twitter_filter_urls = [“twitpic.com”, “twitterfeed.com”, “twitter.peoplebrowsr.com”];
searchshield.TwitterSearchEngine.prototype.validSearch = function(href)
{
var uri;
if (typeof(this.search) === ‘undefined’ || null === this.search)
uri = searchshield.parseLink(href);
else
uri = this.search.uri;

if(!uri || !uri.host)
return false;

var domain= uri.host;

if (domain.indexOf(“twitter.com”) != -1)
{
return true;
}

return false;
};
searchshield.TwitterSearchEngine.prototype.includeLink = function(tag)
{
if (searchshield.DoesURLContain(tag.href, this.search.uri.host))
return false;

if (tag.className.length = 4))
{
// else we want the fourth value
var match = matches[3];
if (match && (match.length > 0))
return match
}

return href;
};
/////////////// GMAIL SEARCH ENGINE ///////////////

/////////////// FACEBOOK SEARCH ENGINE ///////////////
searchshield.FacebookSearchEngine = function(search)
{
searchshield.SearchEngine.call(this, search);
this.showCleanVerdicts = false;
this.type = ‘inline’
};
searchshield.FacebookSearchEngine.prototype = new searchshield.SearchEngine();
searchshield.FacebookSearchEngine.prototype.constructor = searchshield.FacebookSearchEngine;
searchshield.FacebookSearchEngine.prototype.name = “facebook”; // the name by which the search engine is known (always lowercase)
searchshield.FacebookSearchEngine.prototype.validSearch = function(href)
{
var uri;
if (typeof(this.search) === ‘undefined’ || null === this.search)
uri = searchshield.parseLink(href);
else
uri = this.search.uri;

if(!uri || !uri.host)
return false;

if (uri.host.indexOf(“www.facebook.com”) != -1)
return true;

return false;
};
searchshield.FacebookSearchEngine.prototype.includeLink = function(tag)
{
if (searchshield.DoesURLContain(tag.href, this.search.uri.host) ||
(searchshield.DoesURLContain(tag.href, ‘static.ak.fbcdn.net’)))
{
return false;
}

// don’t put verdicts in areas where typing is going on
if (tag.parentNode)
{
var parentDiv = searchshield.getParentNodeByTagName(“DIV”, tag, “className”);
if (parentDiv &&
(parentDiv.className == “Mentions_Input”) ||
(parentDiv.className.indexOf(‘UIThumbPager_’) != -1))
{
return false;
}
}

return tag.href
};
searchshield.FacebookSearchEngine.prototype.addImage = function(node, image, hidden)
{
var doc = this.search.doc;

this.init_inline_ratings(doc);
this.show_inline_ratings(doc, node, image);
};
/////////////// FACEBOOK SEARCH ENGINE ///////////////

/////////////// AVG TOOLBAR REPORTING ///////////////
var avgreport = {
BLOCK_SEVERITY: 3,
scanResult: function (doc, url, foundUrl, ip) {
// report scan end only if surf enabled
if (‘1’ != searchshield.avgCallFunc(doc, ‘GetSurfEnabled’))
return;

// for now native is handling the interstitial
var results = searchshield.avgCallFunc(doc, ‘MalsiteCheck’, url);
if ( results == null )
return;

var parts = results.split(‘::’);

// need at least severity
if (parts == null)
return;

if (!ip)
ip = “”;

// use a block severity if foundUrl is given
var severity = !!foundUrl ? avgreport.BLOCK_SEVERITY : parseInt(parts[0], 10);
var category = “”;
var threat = “”;

// fill in the category and threat if something was found
if (severity > 0)
{
category = parts[2];
threat = parts[4];
}
// else
// return;

var scan_result = searchshield.avgCallFunc(doc, ‘ReportScanResult’, url, url, threat, category, ip, severity);
var scan_end = avgreport.scanEnd(doc, url);

return (scan_result && scan_end);
},
scanEnd: function (doc, url) {
return searchshield.avgCallFunc(doc, ‘ReportScanEnd’, url);
},
GetInterstitialIP: function (interstitial) {
// simple regex to pull the IP address
var regex = /(([1-9][0-9]{0,2})|0)\.(([1-9][0-9]{0,2})|0)\.(([1-9][0-9]{0,2})|0)\.(([1-9][0-9]{0,2})|0)/;
var match = regex.exec(interstitial);
if (!match)
return ”;

return match[0];
}
}
/////////////// AVG TOOLBAR REPORTING ///////////////

/////////////// FLYOVERS ///////////////
var avglsflyover = {
count: 0,
poppedUp: false,
poppedElement: null,
orig_onmousemove: null,
reset: function () {
avglsflyover.count = 0;
avglsflyover.poppedUp = false;
avglsflyover.poppedElement = null;
avglsflyover.orig_onmousemove = null;
},
popup: function (event, hash, search, flyover) {
if (!event)
event = window.event;

var div = document.getElementById(“XPLSS_Flyover”);
if (div == null)
return;

// establish target element and get its containing document object
// in case verdict is inside a frame
var eventTarget = event.srcElement || event.currentTarget;
var frameDoc = eventTarget.ownerDocument;

// if the element is the clock, don’t pop over it
if ((eventTarget.src != null) && (eventTarget.src.indexOf(“clock.gif”) != -1))
return;

// save the element we popped over
avglsflyover.poppedElement = eventTarget;

// if no flyover get it
if ((flyover == null) || (flyover == “”))
{
flyover = searchshield.avgCallFunc(frameDoc, ‘BuildFlyover’, hash);

if (!flyover)
return;

// cleanup flyover, replace any new lines
flyover = flyover.replace(/\r/g, “”);
flyover = flyover.replace(/\n/g, “”);
// escape any single quotes
flyover = flyover.replace(/’/g, “'”);
}

// set the html in the layer
div.innerHTML = flyover;

// there is an unwanted text node that causes vertical misalignment of flyover
if (div.firstChild.nodeType == 3)
div.removeChild(div.firstChild);

avglsflyover.poppedUp = true;

// reset display count
avglsflyover.count = 0;

div.onmouseout = avglsflyover.hide;

// if an onmousemove is already set and it isn’t us, save it and restore later
if ((frameDoc.onmousemove != null) && (frameDoc.onmousemove != avglsflyover.position))
avglsflyover.orig_onmousemove = frameDoc.onmousemove;
frameDoc.onmousemove = avglsflyover.position;
},
hide: function (event, force) {
var div = document.getElementById(“XPLSS_Flyover”);
if ((div == null) || (div.style == null) || (div.style.visibility == “hidden”))
return;

var trans_div = document.getElementById(“XPLSS_Trans”);
if ((trans_div == null) || (trans_div.style == null) || (trans_div.style.visibility == “hidden”))
return;

if (!!force)
return setFlyoverStyle(div, trans_div);

if (!event)
event = window.event;

// establish target element and get its containing document object
// in case verdict is inside a frame
var eventTarget = event.srcElement || event.currentTarget;
var frameDoc = eventTarget.ownerDocument;

// restore onmousemove
if (avglsflyover.orig_onmousemove != null)
frameDoc.onmousemove = avglsflyover.orig_onmousemove;

if (avglsflyover.poppedElement)
avglsflyover.poppedElement.style.border = “”;

var relatedElement = event.toElement;
if (!relatedElement)
{ //this happens on mouseout when verdict and flyover are on different frames/docs
window.top.document.detachEvent(‘onmouseout’, avglsflyover.hide);
window.top.document.attachEvent(‘onmouseout’, avglsflyover.hide);
return;
}

// make sure we aren’t still over the popped image or our layer
if (searchshield.containedIn(avglsflyover.poppedElement, relatedElement) ||
searchshield.containedIn(div, relatedElement) ||
searchshield.containedIn(trans_div, relatedElement))
{
return;
}

setFlyoverStyle();

// hide and move somewhere off screen (negative offsets)
function setFlyoverStyle()
{
div.style.visibility = “hidden”;
div.style.left = “-2100px”;
div.style.top = “-2100px”;
trans_div.style.visibility = “hidden”;
trans_div.style.left = “-2100px”;
trans_div.style.top = “-2100px”;

return true;
}
},
position: function () {
if (!avglsflyover.poppedUp || (avglsflyover.poppedElement == null))
return;

var flyover = document.getElementById(“XPLSS_Flyover”);
if (flyover == null)
return;

// relative position of flyover in relation to icon
var locateX = 0; // 0=left, 1=right
var locateY = 0; // 0=above, 1=below, 2=beside icon

// get window sizes
var winSize = searchshield.viewPortSize();
var windowX = winSize[0];
var windowY = winSize[1];

// get the exact size of the flyover
var flyoverSize = searchshield.elementSize(flyover);
var flyoverX = flyoverSize[0];
var flyoverY = flyoverSize[1];

var verdictWidth = 0;
if (avglsflyover.poppedElement && avglsflyover.poppedElement.width)
verdictWidth = avglsflyover.poppedElement.width;

// get the bounding rect for image(s)
var imgRect = searchshield.GetFullBoundingRect(avglsflyover.poppedElement);

// half width/height of element bounding rect
var halfX = (imgRect.right – imgRect.left) / 2;
var halfY = (imgRect.bottom- imgRect.top) / 2;

// element the mouse is over, get the center position
var posX = searchshield.offsetLeft(avglsflyover.poppedElement) + halfX;
var posY = searchshield.offsetTop(avglsflyover.poppedElement) + halfY;

// if a verdict is inside a frame must get offsets for the frame element
var docFrames = document.frames;
if (docFrames)
{
for (var i=0; i posX)
{
// right
offsetX += halfX;
locateX = 1;
}
else
{
//left
offsetX -= (flyoverX + halfX);
}
if ((windowY – posY) > posY)
{
// below
if (posY < (windowY/4))
{
offsetY -= halfY;
locateY = 1;
}
else
{
offsetY -= (flyoverY / 2);
locateY = 2;
}
}
else
{
// above
if ((windowY – posY) < (windowY/4))
{
offsetY -= (flyoverY – halfY);
}
else
{
offsetY -= (flyoverY / 2);
locateY = 2;
}
}
// make sure we aren't off the screen
if (offsetY windowY)
offsetY = windowY – flyoverY;

// add page offsets back
offsetX += pageOffsetX;
offsetY += pageOffsetY;
posX += pageOffsetX;
posY += pageOffsetY;

var paddedOffsetX = 0; //provide space between icon and flyover
var padX = 3;
if (locateX == 0)
paddedOffsetX = offsetX – padX;
else
paddedOffsetX = offsetX + padX;

// set where to put the flyover
flyover.style.top = offsetY + “px”;
flyover.style.left = paddedOffsetX + “px”;

// set where to put the transparent layer
var trans = document.getElementById(“XPLSS_Trans”);
if (trans != null)
{
var trans_left = 0;
var trans_top = 0;
var trans_width= 0;
var trans_height = 0;

// transparent layer should overlap verdict image
if (locateX == 0)
trans_left = posX – flyoverX – halfX; // left
else
trans_left = posX – transXOffset – verdictWidth; // right

trans.style.left = trans_left + “px”;
trans.style.top = offsetY + “px”;

trans.style.width = flyoverX + “px”;
trans.style.height = flyoverY + “px”;
}

avglsflyover.display();
},
display: function () {
avglsflyover.count++;
if (avglsflyover.count == 1)
{
var flyover = document.getElementById(“XPLSS_Flyover”);
if (flyover == null)
return;

// show the flyover, must use a little count to tell, crazy stuff
flyover.style.visibility = “visible”;

// show the transparent layer
var trans_div = document.getElementById(“XPLSS_Trans”);
if (trans_div == null)
return;

trans_div.style.visibility = “visible”;

avglsflyover.poppedUp = false;
}
},
show: function () {
var div = document.getElementById(“XPLSS_Flyover”);
if (div == null)
return;

div.style.visibility = “visible”;

var trans_div = document.getElementById(“XPLSS_Trans”);
if (trans_div == null)
return;
trans_div.style.visible = “visible”;
}
};

var avglsinlineflyover = {
build: function (riskCategory, riskName, bgColor, borderColor) {
var html = ”;
html += ”

“;
html += ”
“;
html += riskCategory + ”
“;
html += riskName + ”

“;

return html;
},
popup: function (event, flyover, blUrl) {
//set verdict info
var div = document.getElementById(‘XPLSS_InlineFlyover’);
if (div == null)
return;

// blUrl is an object for a blacklisted short url
// when it is passed get the final url
if (blUrl != undefined)
{
var finalUrl = searchshield.avgCallFunc(document, ‘GetFinalUrl’, blUrl.sUrl);
var uri = searchshield.parseLink(unescape(finalUrl));
if (uri.source != null)
{ // regexp failed so used split to parse url
var qsUrl = uri.source.indexOf(“?url=”);
if (qsUrl != -1)
riskName = blUrl.riskNameLabel + uri.source.substring(qsUrl + 5);
else
riskName = blUrl.riskNameLabel + uri.source;
}
else if ((uri.qsArray.url != null) && (uri.qsArray.url.length > 0))
{
riskName = blUrl.riskNameLabel + uri.qsArray.url;
}
else
riskName = blUrl.riskNameLabel + blUrl.sUrl

flyover = avglsinlineflyover.build(blUrl.riskCategory, riskName, blUrl.bgColor, blUrl.borderColor);
}

div.innerHTML = flyover;
div.style.width = “auto”; //reset width
div.style.position = “absolute”;

if (!event)
event = window.event;

var eventTarget = event.srcElement;
avglsinlineflyover.position(eventTarget);
},
hide: function (event) {
if (!event)
event = window.event;

var div = document.getElementById(“XPLSS_InlineFlyover”);
if (div == null)
return;

div.visibility = “hidden”; //invisible
div.style.left = “-5000px”;
},
position: function (imageElem) {
var flyover = document.getElementById(‘XPLSS_InlineFlyover’);
if (flyover == null)
return;

// relative position of flyover in relation to icon
var locateX = 0; // 0=left, 1=right
var locateY = 0; // 0=above, 1=below, 2=beside icon

// get window sizes
var winSize = searchshield.viewPortSize();
var windowX = winSize[0];
var windowY = winSize[1];

// Must know if there is a horizontal scroll bar for Firefox
// for proper flyover positioning near bottom edge
var scrollYWidth = winSize[2];
var scrollBarX = winSize[2] > 0 ? true : false;

// get the exact size of the flyover
var flyoverSize = searchshield.elementSize(flyover);
var flyoverX = flyoverSize[0];
var flyoverY = flyoverSize[1];

flyover.style.width = flyoverX + “px”;

// get the bounding rect for image(s)
var imgRect = imageElem.getBoundingClientRect();

// half width/height (center) of element bounding rect
var halfX = (imgRect.right – imgRect.left) / 2;
var halfY = (imgRect.bottom- imgRect.top) / 2;

// element the mouse is over, get the center position
var posX = searchshield.offsetLeft(imageElem) + halfX;
var posY = searchshield.offsetTop(imageElem) + halfY;

var pageOffsetX = 0;
var pageOffsetY = 0;

// normalize pos to 0 — get amount of scrolling in browser window
var scroll = searchshield.scrollSize(imageElem);
var pageOffsetX = scroll[0];
var pageOffsetY = scroll[1];
var hasParentFrame = scroll[2];

posX -= pageOffsetX;
posY -= pageOffsetY;

//compensate for Firefox 3
if (posX posX)
{
// right
offsetX += halfX;
locateX = 1;
}
else
{
//left
offsetX -= (flyoverX + halfX);
}
if ((windowY – posY) > posY)
{
// below
if (posY < (windowY/4))
{
offsetY -= halfY;
locateY = 1;
}
else
{
offsetY -= (flyoverY / 2) – halfY;
locateY = 2;
}
}
else
{
// above
if ((windowY – posY) < (windowY/4))
{
offsetY -= (flyoverY – halfY);
}
else
{
offsetY -= (flyoverY / 2) + halfY;
locateY = 2;
}
}
// make sure we aren't off the screen
if (offsetY windowY)
{
offsetY = windowY – flyoverY;
}
else if (scrollBarX && ((windowY – (posY + halfY)) < scrollYWidth))
{ //verdict overlaps the horizontal scrollbar
offsetY = windowY – (flyoverY + scrollYWidth);
}

// add page offsets back – if not in frame
if (!hasParentFrame)
{
offsetX += pageOffsetX;
offsetY += pageOffsetY;
}
posX += pageOffsetX;
posY += pageOffsetY;

var paddedOffsetX = 0; //provide space between icon and flyover
var padX = 3;
if (locateX == 0)
paddedOffsetX = offsetX – padX;
else
paddedOffsetX = offsetX + padX;

// set where to put the flyover
flyover.style.top = offsetY + "px";
flyover.style.left = paddedOffsetX + "px";

avglsinlineflyover.display();
},
display: function () {
var div = document.getElementById('XPLSS_InlineFlyover');
if (div == null)
return;

// show the flyover
div.style.visibility = "visible";
},
imageExists: function(element) {
if (element)
{
// check next siblings children
var sibling = element.nextSibling;

if ((sibling == null) || (sibling.getElementsByTagName == null))
return false;

var images = sibling.getElementsByTagName("IMG");
if (images == null)
return false;

for (var i = 0; i < images.length; i++)
{
if (images[i].id == "avg_ls_image")
return true;
}
}

return false;
},
getImage: function (anchor) {
if (anchor)
{
var imageElem = null;
var images = anchor.getElementsByTagName("img");
if (images == null)
return imageElem;

for (var i = 0; i

Katalina Leon

Today I’m excited because my dear friend has a new release. I’ve learned to expect the unexpected in her books, but the end results are always the same: a fascinating amazing journey. Kat’s on my auto-buy list and today is no different. Here’s a taste of what you’ll find in her newest release Sugar Roux Voodoo:

Blurb:

New Orleans, 1834. Lark
La Beau is a green-eyed beauty and respected beneficent voodoo priestess with the sometimes uncooperative gift of clairvoyance. Captain Valcour Curry is a
debonair, larger-than-life buccaneer with ambition to burn and a taste for fine things. Following a whirlwind romance with Lark, he disappears at sea, leaving Lark with a riverboat and a child to rear—alone.

A guilty act of piracy causes Valcour to fall victim to a shapeshifting magician who practices the dark art of soul-swapping. For five years Valcour has been enslaved as an emotionless zombie with no memory of his loved ones or past. From dusk to dawn he is cursed to toil in the cane fields while the evil magician uses his soul to lure women and have his brutal way with them.

Lark will risk hell and journey to the oppressive Broken Oak Plantation to break the curse. It’s a terrifying place. Her only tools to call Valcour’s lost soul back to life are
voodoo and the sensual power of love.

An Excerpt From: SUGAR ROUX
VOODOO

Copyright © KATALINA
LEON, 2011

All Rights Reserved, Ellora’s Cave
Publishing, Inc.

Chapter One

Mississippi River, New Orleans,
October 1834

Lark reluctantly picked up the sad, little bundle of tattered fabric, human hair and tiny animal skulls and handed it back to her disappointed client. “I won’t do this and you’d regret it if I did.” She paused. “I know your heart’s broken, chere, but
that sort of revenge is always wrong. I don’t do that kind of magic, so don’t ask.”

A bitter frown creased the woman’s face as she accepted the rejected juju bundle into her hand.

Lark allowed the disappointed woman a moment of silence to reflect.

The riverboat’s massive paddlewheel thunked loudly against the murky water of the Mississippi as it slowly steamed upriver.

The woman parted her lips to protest the returned bundle at the exact moment the shrill, double blast of the Sugar Roux Voodoo
Queen
’s steam whistle blew and drowned out her words before she could even release them into the riverboat’s elegant parlor.

Lark’s palm rose in the air, silently signaling the woman to hold her words until the whistle finished blasting. She reclined against the wingback chair, adorned with cypress armrests carved into the likeness of snarling lions’ heads. Her fingertips absently stroked against the lions’ polished heads as the whistles blew. She knew it was senseless to attempt to speak over them, so she waited.

Lark’s head casually tilted against the nappy, red velvet upholstery as she silently studied the offensive little bundle in the woman’s hands. She drew a tense breath, knowing once again she had been misunderstood and placed in an uncomfortable situation.

The whistle grew silent, but the lingering echo continued to ring in her ears. She leaned forward and gently confronted the woman. “Who told you I would do such a thing?”

“N-no one.” The distraught woman stuttered. “Everyone knows your name. You’re the queen of the river. Your reputation is legend. I know you could do what I’ve asked. You’ve helped many others. Why won’t you help me?” Fresh tears trickled down the woman’s cheeks. “I’ve been wronged!”

Lark rose slowly from the throne-like chair. Her aubergine satin dress and layers of crisp, horsehair crinoline crinkled softly as she stood. “I would never deliberately harm an innocent woman.”

The woman scoffed. “She’s not innocent. I can assure you of that. She’s a rouge- cheeked-help-yourself hussy!”

“I’m going to pour you a bourbon.” Lark spoke gently. “You’re going to drink it, and you and I are going to talk.”

She walked to an elegant, glass cabinet and removed a slender, cut-crystal decanter of amber liquid and poured a generous slosh into a crystal goblet that caught the flickering candlelight. A splintered burst of tiny rainbows cast against the lacquered walls of the parlor. She ceremoniously handed the bourbon to the anxious woman.

The woman eagerly accepted the goblet with narrowed eyes. “Did you cast a roux on this?” she asked hopefully. “Is the potion enchanted? Will this bring my man back?”

Lark sadly shook her head. “No roux. It’s not enchanted potion, it’s just good bourbon.”

The woman looked painfully disappointed but took a sip anyway. Her lips tensed against the bourbon, as if it burned. “I can find a way to pay you more if that’s the problem?”

“It’s not the problem,” Lark spoke firmly. “I never charge anyone. The most I ask of others is that they do a kind service for someone else in need.”

A dismissive frown darkened the woman’s face. “I’m the one in need.” She gulped the bourbon in a single swallow.

A moment of embattled silence settled between the women. The riverboat’s massive paddlewheel churned slowly beyond the partially opened window, carrying a stream of cool, moist air into the overheated parlor suite.

Lark’s fingers fussed with an errant hairpin and carefully tucked a falling curl back in place. Her glossy, chestnut-brown ringlets spilled over the crown of her head and spiraled past her shoulders.

The woman slumped in the chair, sobbing quietly and slowly rocking back and forth.

“Listen to me carefully.” Lark gazed at the teary-eyed woman fidgeting nervously before her. The woman had puffy, crimson rings surrounding her eyes from days of crying. Lark spoke calmly. “I don’t do the sort of magic you want with good reason—it ends up being bad for everyone—especially you.”

Defiance and disappointment burned in the woman’s eyes. “How so? Who’s going to know?”

“You must understand.” Lark delicately folded her hands across her heart. “I’m a sworn beneficent. I don’t hurt no one—ever. It is against my code of duty.” She paused. “I must warn you, seeking revenge against the woman who stole your man will most likely harm you. I strongly advise you abandon such plans.”

The woman bit down on her fist in anguish. “I don’t want her to suffer—much. I just want her dead! I want my man back. He’s my man. I had him first. Why won’t you help me?”

Lark moved closer to the woman and placed her hand on her shoulder. “Chere, she didn’t make your man leave you, he left on his own for his own reasons.”

The woman glanced up at Lark in utter desperation. “It’s unjust. I gave that man my youth, my heart and my trust. There must be something you can do?”

Lark slowly shook her head. “I wish there was, but love doesn’t work that way. It’s often unfair and others are always free to do as they like. It’s not right, but that’s the way it is.”

Lark leaned closer. “Can I tell you a secret? If you can forgive him and allow your heart to heal, you can be happy again, and everyone loves a happy person who knows how to forgive. It wouldn’t surprise me at all if a better man with a loyal heart came into your life and filled the empty space.”

The woman looked appalled. “I don’t want another man. I want my man. I gave him everything—he owes me!”

“I agree, he does owe you, but most likely it’s a debt you’ll never have the satisfaction of being repaid. You have to be brave and walk on without him.”

The woman collapsed in tears. “I’m afraid of being without him. Even when it wasn’t good, at least I knew I belonged to him and I had some idea of what the future held. Now I’ve got nothing!”

Lark gently patted the woman’s wild head of unkempt hair. Obviously, the woman had done nothing to care for herself in recent days. “I understand. I really do. I’ve had a man I loved more than my life leave me.”

Just Another Rainy Day

YAY! Today is release day for me. It’s my first for 2011 and I’m excited. I had a lot of fun writing this story and hope you will have fun reading it!
Here’s a little taste of what you’ll find between the covers. You can buy it here:  Just Another Rainy Day
Blurb:
Tired of their ho-hum sex life, Jack decides to spice things up by planning a surprise for his wife. After sending the children off for an overnight with their aunt, Jack handcuffs Beth to their bed.

Beth awakes naked, blindfolded and at the mercy of her husband. The day starts off with being fed by Jack and quickly turns into hot and heavy sex. She soon learns that a slip of the tongue can lead to stinging ass cheeks.

This rainy day will be spent pushing their sexual limits. Whether in bed or out, Jack will leave Beth begging for more—until she says something unforgiveable.

By reading any further, you are stating that you are at least 18 years of age. If you are under the age of 18, it is necessary to exit this site.
An Excerpt From: JUST ANOTHER RAINY DAY
Copyright © AMBER SKYZE, 2011
All Rights Reserved, Ellora’s Cave Publishing, Inc.
Chapter One

“Rise and shine, sleepyhead.”
Beth opened her eyes to total darkness. She attempted to move, but found her arms were pulled above her head. Around her wrists was soft fur. She tugged and the rattling sound of chains filled her ears. She was restrained. Fear spread throughout her body and into her throat.
“Why am I handcuffed?” As she tried to sit up she realized she was also blindfolded. Never in their fifteen years of marriage had she woken to find herself trussed like a slave or prisoner.
The smell of bacon wafted closer, assaulting her nostrils.
“I’m going to fuck that pussy all day long.”
Beth moved her head to the left where Jack’s voice echoed through the room. She shivered. The thought of him fucking her all day sent chills down her spine, until reality came crashing back.
“What about the kids? Surely they’ll want Mom to cook them breakfast and drive them all over God’s creation.”
“All taken care of. I just sent them packing with Auntie. They’ll be home tomorrow bright and early.”
How long had she’d slept? She knew she was exhausted when she fell into bed the night before, but to sleep through the kids waking and Jack shackling her to the bed wasn’t like her.
“Did you spike my drink last night, Jack?”
A full belly laugh filled the room. “I’d hardly do something so sinister.”
He had a point. In all their marriage he’d never even spoken an ill word against her. Why should she accuse him of something so hideous?
“How did you manage to handcuff me to the bed?”
“You were snoring peacefully. I moved your arms without getting a peep out of you. You barely stirred.”
Beth racked her brains trying to remember any feeling of being moved around, but nothing came to mind.
“Clever, Jack, now uncuff me please.”
“No can do.”
“Huh? Please, Jack. My arms can only take so much of being stretched like this. I’d like you to release me, now.”
“Remember your prisoner fantasy?”
How could she forget? She’d told him about the fantasy eons ago. They’d been enjoying a glass of white wine on a cold winter’s night. They’d nestled all cozy in front of the fireplace. As they gazed into the glowing embers, she had shared her deepest darkest desires. Beth had told him how she wanted to feel as if she’d been kidnapped, taken away and tortured in every delicious way imaginable. Jack had listened quietly and nodded at the appropriate times. She’d explained that she pictured herself in the shower after a long day. A stranger would appear and pull her soaking wet from the streaming water. He’d carry her to her bedroom where he’d take what he wanted. He’d ignore her pleas for him to stop. He’d fuck her until they were both sated.
She’d thought he’d forgotten by now. Obviously he had been biding his time.
“Is this what is happening today? You’re living out my fantasy?” A slight shiver passed through her body. Jack had listened. He’d taken her seriously and decided to give her what she needed.
“We are and I’m in control. You will do as I say or suffer the consequences.”
Beth shook as a chill of delight filled her. Jack’s voice was deep and demanding. He was using his dominant tone.
“Got it.” A secret smile filled her soul.

Day 9 – 12 Days of Christmas

Over at my other blog.  Amber Skyze

Day 8 – 12 Days of Christmas

Over on my other blog.  Amber Skyze

Day 4 of the 12 Days of Christmas Contest

Today is Day 4 of my Christmas contest over on my other blog. If you like to win free books, then drop in and comment.

Amber Skyze

Naughty St. Nick

Today I’m celebrating my new release, a Christmas themed story. I’m also hosting a 12 days of Christmas contest over on my other blog – Amber Skyze

For those who aren’t interested here’s a little taste of my newest release, available today from Aspen Mountain Press

Blurb:

Nick has fought his attraction to Emily since the summer. Work and other commitments have kept him from pursuing a relationship. Christmas is upon them and Nick finds he has free time on his hands. He devices a little plan to get her sexy body prepared for what he hopes will be a night of passion she’ll never forget.

Someone is sending Emily erotic toys. The naughty notes attached are charging her dormant body to life with promises of red hot sex. She’s not sure who her secret Santa is, but if he’s truly following the Twelve Days of Christmas she’s about to find out.

Will Emily succumb to this Naughty St. Nick?

Excerpt:

Emily pattered over to the front door. She peered through the peephole.

“Hmmm, I swear I heard the doorbell.” She threw opened the door against the bitter cold of the winter storm brewing outside. Shivering, she bent over the threshold and glanced in both directions. Her skin pebbled from the snowflakes landing on her bare arms.

“Strange, I know the doorbell rang.” She was about to close the door when she noticed a small brown box, sitting off to the right.

Intrigued, she placed a sock covered foot into the icy snow and retrieved the box. She quickly slammed the door and hurried back to her blanket on the couch. She nestled under the red fuzzy blanket. Turning the box in her hands she looked for an addressee.

“Nothing.” She couldn’t help but wonder if it were meant for her or if someone left it on her doorstep mistakenly. She shook the box. Something bounced around inside.
Unable to fight her curiosity any longer she tore open the package. There inside was a mistletoe-colored finger butt plug, with little white snowmen on it. Tingling sensations warmed her body straight down to her core. Thoughts of teasing the rim of her ass with the humming vibrator tantalized her.

She needed to know who sent it. Digging deeper into the box she searched for a card or anything cluing her in to who the sender was. She found a tiny note card that read:

On the first day of Christmas my true love gave me to, one butt plug a hummin’.

Emily thought she’d explode into orgasm right then and there. The idea of someone wanting to charge her ass to life enthralled her. Filled with an arousal that ran deep, Emily knew she had to pleasure herself.

Heat from the flames crackling in the fireplace warmed her chilled body, smoothing her skin. The television blared in the background, but Emily tuned it out. She’d been watching a movie about a money heist on a train or something crazy. It hadn’t held her attention. Turning the plug over in her hands, she found something that gripped her total attention. She couldn’t imagine who would send her something so erotic.

Settling into the pillow she closed her eyes and pictured the guy from Six A, as the bearer of her gift. His wavy blond hair and those piercing green eyes charged her body. She’d fantasized about him a few times. Oh who was she kidding she masturbated to the image of his shit eating grin too many times to count.

Emily longed to run her hand over his taunt abs. She wanted to trace a finger along the vee that disappeared below the trim of his pants to see if it went down to his cock, which she knew would be large and bulging. It seemed hard to believe she’d been drooling over him since summer.

After she witnessed his body in scant clothing she wanted a piece of him.

Previous Older Entries