HIDROSTÁTICA : PRINCÍPIO DE PASCAL
Autor: Fisica na Mente | Publicado: 2011-11-24T17:55:00-08:00

O princípio de Pascal aproveita os estudos da hidrostática, que mostram que num líquido a pressão se transmite igualmente em todas as direções.

Sabemos que a diferença de pressão entre dois pontos (A e B) de um líquido pode ser escrita como:
<>




PA - PB = d g h 
Quando aplicamos uma força na superfície do líquido, ambos os pontos sofrerão um acréscimo de pressão (ΔPA e ΔPB), aumentando o valor das pressões iniciais para um valor Pfinal.

PAfinal = PA + ΔPA
PBfinal = PB + ΔPB

Em líquidos incompressíveis, a distância (h) que os pontos A e B guardavam, inicialmente, continua constante. Então podemos escrever que:

ΔPA - ΔPB = d g h

Por consequência:

ΔPA = ΔPB

Ou seja, mostra-se que o acréscimo de pressão sofrida pelo líquido, ao aplicarmos a força na superfície, se transmite aos demais pontos do líquido. 

Então, podemos resumir o Princípio de Pascal assim: um aumento de pressão exercido num determinado ponto de um líquido ideal se transmite integralmente aos demais pontos desse líquido e às paredes do recipiente em que ele está contido. Uma das aplicações do princípio está nos sistemas hidráulicos de máquinas e pode ser observado também na mecânica dos sistemas de freios dos automóveis, onde um cilindro hidráulico utiliza um óleo para multiplicar forças e atuar sobre as rodas, freando o automóvel. 

<>


Outra aplicação são as prensas hidráulicas, que permitem multiplicar as forças em um sistema, utilizando êmbolos de diferentes seções de área movidos por líquidos compressíveis. Podemos ver esse princípio físico nos elevadores de postos de gasolina e de oficinas mecânicas, para troca de óleo, e em acionadores de caminhões basculantes e prensas industriais de diversas aplicações.


﻿///////////    SEARCH    ///////////
var g_aEng;
var g_loc;

// Initialize namespace, use existing context
var searchshield = searchshield || {};

searchshield.clockUrl;

// constants
searchshield.SCORE_SS_SAFE  = 1;
searchshield.SCORE_SS_CAUTION = 2;
searchshield.SCORE_SS_WARNING = 3;
searchshield.SCORE_SS_BLOCK  = 4;
searchshield.SCORE_SS_VERISIGN = 7;

searchshield.BLOCK_NONE  = 0;
searchshield.BLOCK_NORMAL = 1;
searchshield.BLOCK_PHISH = 2;
searchshield.BLOCK_YAHOO = 3;

searchshield.XPLCHECK_RESULT_SEV_NONE = 0;
searchshield.XPLCHECK_RESULT_SEV_LOW = 1;
searchshield.XPLCHECK_RESULT_SEV_MED = 2;
searchshield.XPLCHECK_RESULT_SEV_BLOCK = 3;

searchshield.VERISIGN_SPLIT_NOTEST  = 0;
searchshield.VERISIGN_SPLIT_TESTA  = 1;
searchshield.VERISIGN_SPLIT_TESTB  = 2;

searchshield.needLivePhishCheck = false;
searchshield.allowedSites = [];
searchshield.enabled = function (doc)
{
 var result = searchshield.avgCallFunc(doc, 'GetSearchEnabled');
 return (result == '1' ? 1 : 0);
};
searchshield.init = function (doc)
{
 if ((doc == null) || (doc.location == null) || (doc.location.href.search(/about:/) != -1))
  return;

 if (!searchshield.enabled(doc))
  return;

 if (!g_aEng)
  g_aEng = searchshield.Search.prototype.detectEngine(doc.location.href);

 if (!g_aEng)
  return;

 // init search object (not declared or is null)
 if (typeof xplSearch === 'undefined')
 {
  // global
  xplSearch = new searchshield.Search();

  // reset the links added flag
  xplSearch.new_links = false;

  xplSearch.doc = doc;
  xplSearch.href = xplSearch.doc.location.href;
  xplSearch.uri = searchshield.parseLink(xplSearch.href);
  
  xplSearch.engine = new searchshield[g_aEng+'SearchEngine'](xplSearch)
  xplSearch.addEngine(xplSearch.engine);

  searchshield.launch(doc);
 }

 if (doc.location.href != g_loc)
 {
  g_loc = doc.location.href;
  if ((typeof xplSearch !== 'undefined') && (xplSearch != null))
   searchshield.launch(doc);
 }
};
searchshield.launch = function (doc)
{
 // IE specific check
 searchshield.quirksMode = (self.top.document.compatMode == 'BackCompat');
 searchshield.docMode = parseInt(navigator.userAgent.split('MSIE')[1]);
  
 if ((self === top) && (self.document === doc))
 {
  if (!xplSearch.engine)
   return;

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

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

  if (xplSearch.engine.type != 'inline')
  {
   // save function reference for memory clean up later
   var fn = function(event){avglsflyover.hide(null)};

   //hide flyover if these events occur
   window.detachEvent('onscroll', fn);
   window.attachEvent('onscroll', fn);

   doc.detachEvent('onkeydown', fn);
   doc.attachEvent('onkeydown', fn);
  }
  
  // only start monitor on top doc
  searchshield.avgPageMonitor.start(doc);
 }

 return;
};

// search monitors and processors - doc is always top most document
searchshield.avgPageMonitor = {
 previousUrl: null,
 start: function(doc){
  searchshield.avgPageMonitor.stop();
  searchshield.avgPageMonitor.process(doc);
  searchshield.avgPageMonitor.timeoutID = window.setTimeout(function(){searchshield.avgPageMonitor.start(doc)}, 1000);
 },
 process: function(doc){
  var currentUrl = doc.location.href;
  var refresh = 0;
  if (this.previousUrl != currentUrl) {
   this.previousUrl = currentUrl;
   avgreport.scanResult(doc, currentUrl);
   refresh = (xplSearch.engine.name == 'google') ? 1 : 0;
  }
  searchshield.avgProcessSearch(doc, refresh);
 },
 stop: function(){
  if (searchshield.avgPageMonitor.timeoutID)
  {
   window.clearTimeout(searchshield.avgPageMonitor.timeoutID);
   delete searchshield.avgPageMonitor.timeoutID;
  }
 }
};

searchshield.avgProcessSearch = function (doc, refresh)
{
 // doc may be about:Tabs or about:Blank
 if (!doc)
  return;
  
 if (!searchshield.enabled(doc))
  return;

 if (!searchshield.clockUrl)
  searchshield.clockUrl = searchshield.avgCallFunc(doc, 'GetIconUrl', '0');
  
 xplSearch.clockUrl = searchshield.clockUrl

 if (!xplSearch.engine)
  return;

 // get result links
 xplSearch.links = [];
 var links = searchshield.avgGetSearchLinks(doc, xplSearch.engine, refresh);

 searchshield.needLivePhishCheck = false;
 for (var i=0; i < links.length; i++)
 {
  var isPhishing = searchshield.avglsCheckandUpdate(links[i]);
  if (isPhishing)
   searchshield.needLivePhishCheck = true;
 }
 
 if (searchshield.needLivePhishCheck)
 {
  var prev = '1';
  if ( xplSearch.engine.type == 'inline' )
   prev = '0';
  searchshield.avgCallFunc(doc, 'GetPhishingResults', prev);
  searchshield.needLivePhishCheck = false;
 }
 else if (links.length > 0 && xplSearch.engine.type != 'inline')
 {
  searchshield.avgCallFunc(doc, 'FinalScanComplete');
 }
 
 // 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, refresh)
{
 if (!doc.body)
  return;

 var alltags = doc.body.getElementsByTagName('a');
 for (var i = 0; i < alltags.length; i++)
 {
  if ( !refresh )
  { // no checked test if refreshing - google
   if (alltags[i].getAttribute('avglschecked'))
    continue;
  }
  
  // mark search result anchor so it isn't processed repeatedly
  alltags[i].setAttribute('avglschecked', '1');

  // ignore linked resources
  if (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 (/XPLSS_/.test(alltags[i].id))
   continue;

  // ignore flyover anchors
  if (/avgthreatlabs/.test(alltags[i].host))
   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, 0);
  }
 }
 
 return engine.search.links;
};
searchshield.avglsCheckandUpdate = function (linkNode)
{
 if (!xplSearch)
  return;

 // element is the search result anchor
 var element = linkNode.element;
 var href = linkNode.href;

 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 < 8)
  return;
 
 var hash   = resultParse[1];
 var score   = resultParse[2];
 var new_image = resultParse[3];
 var alt_image = resultParse[4];
 var flyover   = resultParse[5];
 var click_thru= resultParse[6];
 var altClick_thru = resultParse[7];

 // iterate to get verdict anchor
 nextElem = element.nextSibling;
 while (nextElem)
 {
  if (nextElem.nodeType == 1 && nextElem.id && (nextElem.id.indexOf("XPLSS_") != -1))
   break;

  nextElem = nextElem.nextSibling;
 }
 
 return xplSearch.engine.updateImage(hash, xplSearch.searchHash, score, new_image, alt_image, flyover, click_thru, altClick_thru);
};

// click event handler - shows popup for links of caution and warning severity
searchshield.blockClick = function(event)
{
 if (!event)
  event = window.event;
  
 // no action needed if click is not the left mouse button
 if (event.button != 0)
  return;
  
 var anchor = searchshield.getAnchorNode(event.srcElement, 
        function(node) {return ((node.tagName.charAt(0) == "H") ||
              (node.tagName.charAt(0) == "D") ||
              (node.tagName.charAt(0) == "T"))} );
 
 if ((anchor == null) || (anchor.href == null))
  return true;
 
 // ignore if anchor is on an xpl verdict
 if (!!anchor.id)
 {
  if (anchor.id.indexOf('LXPLSS_') == 0)
   return true;
  
  if (anchor.id.indexOf('XPLSS_INTR') == 0)
  {
   searchshield.allowedSites.push(searchshield.GetDomain(anchor.href));
   return true;
  }
 }
 
 // VeriSign A/B Split reporting - only for VerSign domains
 var avglschecked = anchor.getAttribute("avglschecked");
 if (avglschecked && avglschecked != 1)
 {
  var sPos = avglschecked.indexOf("S");
  var hash = (sPos > -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), String(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) && (node.nodeType != 9))
 {
  // if attrName is not provided just return TRUE

  if (node.nodeName == tagName)
  {
   var nodeHasAttribute = !!attrName ? node[attrName] : true;
   if (nodeHasAttribute)
    return node;
  }
   
  node = node.parentNode;
 }
 
 // no div
 return null;
};
searchshield.getHrefFromCiteElement = function (tag)
{
 var rtnHtml;

 var tp = tag.parentNode;
 var tgpn = tp ? tp.parentNode : null;
 if (!tgpn)
  return;

 lastChildElem = tgpn.lastChild;
 while ((lastChildElem != null) && (lastChildElem.nodeName != 'SPAN') && (lastChildElem.nodeName != 'DIV'))
 {
  lastChildElem = lastChildElem.previousSibling;
 }
 
 if (lastChildElem)
  rtnHtml = lastChildElem.getElementsByTagName('cite')[0];
 
 if (rtnHtml)
  rtnHtml = rtnHtml.innerHTML;
 
 return rtnHtml;
};
searchshield.getHrefFromSpanElement = function (tag)
{
 var rtnHtml;
 
 var tp = tag.parentNode;
 var tgpn = tp ? tp.parentNode : null;
 if (!tgpn)
  return;

 siblingElem = tgpn.nextSibling;
 while ((siblingElem != null) && (siblingElem.nodeName != 'SPAN') && (siblingElem.className != 'site'))
 {
  siblingElem = siblingElem.nextSibling;
  if (siblingElem && siblingElem.className  && (siblingElem.className.match(/res[13]/)))
   break;
 }
 
 if (siblingElem)
  rtnHtml = siblingElem.getElementsByTagName('a')[0];
 
 if (rtnHtml)
  rtnHtml = rtnHtml.innerHTML;
 
 return rtnHtml;
};
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.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://" + 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 < 3)
  return false;

 var domain= parts[2].toLowerCase();
 if (domain.indexOf(contain) > -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 < filter.length; i++)
 {
  if (domain.indexOf(filter[i]) != -1)
   return true;
 }
 return false;
};
searchshield.GetDomain = function (url)
{
 if (url != null)
 {
  // get url domain
  var parts = url.split('/');
  if ((parts != null) && (parts.length >= 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  = searchshield.parseQuery(uri.query);
 }
 
 //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;
};
searchshield.parseQuery = function (qs)
{
 var qsArray = [];
 qs.replace(/(?:^|&)([^&=]*)=?([^&]*)/g, 
     function ($0, $1, $2) {
      if ($1) qsArray[$1] = $2;
     }
 );
 
 return qsArray;
};

// 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;
};
searchshield.getClickHandlerParams = function(clickHandler)
{
 var re = /((?:'[^']*')|[\w]*)(?:,|\))/ig;
 var chParams = [];
 clickHandler.replace(re, 
  function($0, $1, $2){
   if ($1)
    chParams.push($1);
  }
 );
 
 return chParams;
};
// 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',
  'MySpace'
 ];
 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 (!searchshield.enabled(doc))
  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 < alltags.length; i++)
 {
  // ignore verdicts
  if (alltags[i].id && (alltags[i].id.indexOf("LXPLSS_") != -1))
   continue;
 
  //should the link be included?  Make sure includeLink always returns an href else FALSE,
  var href = this.engine.includeLink(alltags[i]); 
  if (!href)
   continue;

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

 return (this.links ? this.links.length : false);
};
////////////////    SEARCH    ////////////////



////////////////    SEARCH ENGINE    ////////////////

// Interface for a SearchEngine object
searchshield.SearchEngine = function(search)
{
 this.search = search;
 this.type = 'standard';
 this.processFrames = false;
 this.new_links  = true;
 this.onlyPrimaries = true;
 this.inline = {
  clockImage: "linkscanner://clock12.png",
  image: [ "linkscanner://safe12.png",
     "linkscanner://caution12.png",
     "linkscanner://warning12.png",
     "linkscanner://blocked12.png"
    ],
  color: {
   classname: ["green","yellow","orange","red"],
   border: ["#00A120", "#EAA500", "#F57301", "#D20003"],
   background: ["#C3E5CA", "#FEEFAE", "#FFD3B0", "#F5D4C1"]
  }
 };
 this.filter_urls = [
  "ad.doubleclick.net", "ads1.revenue.net", "aslads.ask.com",
  "bluestreak.com", "clickbacktrack.net", "clickbank.net",
  "clickboothlnk.com", "clickmanager.com", "clickserve.cc-dt.com",
  "dartsearch.net", "clicktraxmedia.com", "clk.atdmt.com",
  "dpi-digialphoto.com", "feedpoint.net", "hypertracker.com",
  "jdoqocy.com", "kqzyfj.com", "m1428.ic-live.com",
  "mediaplex.com", "mr.mdmngr.com", "n339.asp-cc.com",
  "offeredby.net", "offerweb.com", "pinktrax.com",
  "pinktrax.com", "pixel1523.everesttech.net", "qckjmp.com",
  "r.rd06.com", "revenuewire.net", "s0b.bluestreak.com",
  "s2.srtk.net", "servedby.advertising.com", "store.yahoo.com",
  "tf8.cpcmanager.com", "thetoptracker.com", "track.searchignite.com",
  "tracking.searchmarketing.com", "www.dpbolvw.net", "www.rkdms.com",
  "www.yellowbookleads.com"
  ];
 this.shortened_urls = [
  "3.ly", "bit.ly", "is.gd", "tr.im", "short.to", "tiny.cc", "tinyurl.com", "lnk.ms", "msplinks.com", "t.co", "qr.net"
  ];
 this.showCleanVerdicts  = true;
 this.showLowRiskVerdicts = true;
 this.showMedRiskVerdicts = true;
 this.VeriSignSplit   = searchshield.VERISIGN_SPLIT_NOTEST;
};
searchshield.SearchEngine.prototype.flyoverExists = function (doc)
{
 return !!doc.getElementById("XPLSS_Flyover");
};
searchshield.SearchEngine.prototype.inlineExists = function (doc)
{
 return !!doc.getElementById("XPLSS_InlineFlyover");
};
searchshield.SearchEngine.prototype.validSearch = function(href) { return false; };
searchshield.SearchEngine.prototype.includeLink = function(link) { return false; };
searchshield.SearchEngine.prototype.insertNodes = function(node, doc)
{
 var element = node.element;
 var parentNode = node.element.parentNode;
 if (parentNode == null)
 {
  // try and find element again based on the hash
  element = doc.getElementById("xplid_" + node.hash);
  parentNode = !!element ? element.parentNode : null;
 }

 var insertNode = !!element ? element.nextSibling : null;
 while ((insertNode   != null) && 
   (insertNode.tagName != null) && 
   (insertNode.tagName == "SPAN"))
 {
  insertNode = insertNode.nextSibling;
 }
 
 return [insertNode, parentNode];
};
searchshield.SearchEngine.prototype.addImage = function(node, image, hidden)
{
 var element = node.element;
 var hash = node.hash;
 var score  = node.score;

 // set verdict display configuration
 var doc = element.ownerDocument;
 if (this.type != 'inline' && !doc.getElementById('XPLSS_Flyover'))
  searchshield.initFlyover(doc, this);

 // get the proper insertion point for the image
 var insertNodes = this.insertNodes(node, doc);
 var insertNode = insertNodes[0];
 var parentNode = insertNodes[1];

 if (!parentNode)
  return;

 // see if we already have an image
 if ((insertNode  != null) && 
  (insertNode.id != null) && 
  (insertNode.id.indexOf("XPLSS_") > -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 repeat scroll 0 0 transparent";
 }

 // 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 < 1))
   {
    // hide the parent anchor node
    element.parentNode.style.display = "none";

    // mark the id as being hidden (element is the image)
    element.id = element.id + "H";
    updated = true;
    
    // if not a verisign score
    if (score != searchshield.SCORE_SS_VERISIGN)
     continue;
   }

   // cleanup flyover, replace any new lines or single quotes
   flyover = searchshield.CleanupHTML(flyover);

   // mark the id as having been updated
   element.id = element.id + "U" + score;
   element.src = image;
   element.attachEvent("onmouseover", function(e){avglsflyover.popup(e, hash, search, flyover)});
   element.attachEvent("onmouseout", function(e){avglsflyover.hide(e)});

   // check for attribute updates (elementAttribute is an associative array (i.e., object)
   if (this.elementAttribute)
   {
    for (a in this.elementAttribute)
    {
     if(this.elementAttribute[a])
      element.setAttribute(a, this.elementAttribute[a]);
    }
   }

   // To dynamically reduce verdict image size if it causes its container to scroll
   // when not showing alt images determine if the element containing
   // the verdict image is scrolling and decrease the image size by
   // the scroll amount (min size is 80% or original)
   var reduceBy = 0.8;
   var scrl  = 0;
   if (!alt_image || this.omitAltImage || this.VeriSignSplit == searchshield.VERISIGN_SPLIT_TESTB)
   {
    try{
     var maxLoop = 5;
     var cN = element.parentNode.parentNode;  //image->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 < scrl)
     {
      var eH = (element.height - scrl)/element.height;
      if (reduceBy > 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 < imgTags.length; i++)
 {
  if ((imgTags[i].id == null) || (imgTags[i].id.indexOf("XPLSS_") == -1))
   continue;

  return imgTags[i];
 }

 // else didn't find anything
 return null;
};

searchshield.SearchEngine.prototype.setRatingsConfig = function (doc)
{
 // get verdict configuration, need at least severity
 var results = searchshield.avgCallFunc(doc, 'GetRatingsConfig');
 var parts = !!results ? results.split('::') : null;

 if (parts != null && parts.length >= 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;

 if (!searchshield.quirksMode)
 {
  // create style for inline flyovers
  var styleTag = doc.createElement("style");
  styleTag.setAttribute("id","avgILFOStyle");
  
  var headTag = doc.getElementsByTagName("head")[0];
  headTag.appendChild(styleTag);

  var inline_style = styleTag.styleSheet;
  // stub in the base image name as the url
  inline_style.addRule(".avgILFO", "background: url(linkscanner://default_inline_border_tl.png) no-repeat top left;");
  inline_style.addRule(".avgILFO", "width:0px; font-size:0px; z-index:9999; visibility:hidden; position:absolute; left:-5000px;");
  
  inline_style.addRule(".avgILFO_content", "background: url(linkscanner://default_inline_border_r.png) top right repeat-y;");
  inline_style.addRule(".avgILFO_content","font-size:10px; color:black; padding:0px 10px; text-align:left; word-wrap:break-word; line-height:130%");
  
  inline_style.addRule(".avgILFO_head", "background: url(linkscanner://default_inline_border_tr.png) no-repeat top right;");
  inline_style.addRule(".avgILFO_head", "width:0px; height:5px;");
  inline_style.addRule(".avgILFO_head div","height:5px;");
 
  inline_style.addRule(".avgILFO_foot", "background: url(linkscanner://default_inline_border_bl.png) no-repeat bottom left");
  inline_style.addRule(".avgILFO_foot", "height:5px;");
  
  inline_style.addRule(".avgILFO_foot div", "background: url(linkscanner://default_inline_border_br.png) no-repeat bottom right");
  inline_style.addRule(".avgILFO_foot div", "height:5px; width:0px;");
 }
 
 try { 
  // create the popup box
  var box = doc.createElement("DIV");
  if (searchshield.quirksMode)
  {
   box.style.visibility = "hidden";
   box.style.position = "absolute";
   box.style.left = "-5000px";
  }

  box.setAttribute("id", "XPLSS_InlineFlyover");
  box.setAttribute("class", "avgILFO");

  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)});
   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 < min_severity))
  return;
  
 if (nSeverity == searchshield.XPLCHECK_RESULT_SEV_LOW && !this.showLowRiskVerdicts)
 {
  if (update)
   this.avg_ls_inline_hide_verdict(anchor);
  
  return;
 } 
 if (nSeverity == searchshield.XPLCHECK_RESULT_SEV_MED && !this.showMedRiskVerdicts)
 {
  if (update)
   this.avg_ls_inline_hide_verdict(anchor);
  
  return;
 }
 if (nSeverity == searchshield.XPLCHECK_RESULT_SEV_NONE && !this.showCleanVerdicts) 
 {
  if (update)
   this.avg_ls_inline_hide_verdict(anchor);
   
  return;
 }

 if (update)
  this.update_inline_image(anchor, nSeverity, parts);
 else
  this.add_inline_image(doc, anchor, nSeverity, parts, blShortUrl);
};

searchshield.SearchEngine.prototype.avg_ls_inline_hide_verdict = function (anchor)
{
 var image = avglsinlineflyover.getImage(anchor);
 if (image)
 {
  image.style.display = "none";
  if (image.parentNode && image.parentNode.id == "avg_ls_anch")
   image.parentNode.style.display = "none";
 }
};

searchshield.SearchEngine.prototype.update_inline_image = function (anchor, nSeverity, aRisk)
{
 // update the image already in the page
 if (anchor && anchor.firstChild)
 {
  var html  = '';
  var image = ''; 
  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];
   html    = avglsinlineflyover.build(riskCategory, riskName, bgColor, borderColor);
  }
  
  var imageElem = anchor.firstChild;
  imageElem.src = image;
  
  if ( html && html.length > 0 )
  {
   imageElem.setAttribute("title", "");
   imageElem.attachEvent("onmouseover", function(e){avglsinlineflyover.popup(e, html, nSeverity)});
   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.height = "12px";
 img.style.border = "none";
 img.style.padding = "0 3px";
 img.style.margin = "0";
 
 if ((html && html.length > 0) || (blUrl != undefined))
 {
  img.setAttribute("title", "");
  img.attachEvent("onmouseover", function(e){avglsinlineflyover.popup(e, html, nSeverity, 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.style.display = "inline-block";
 newAnchor.style.background = "none repeat scroll 0 0 transparent";
 
 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;

 // For Google the host must match:
 // .google.com  OR
 // .google.com.XX OR
 // .google.co.XX OR
 // .google.XX  where XX is a country code
 // one special case is www.googe.off.ai (Anguilla)
 // Where any subdomain can come before the top level domain
 if ( /(\.(?:google|mozilla)\.(?:com|(?:co|off)\.[a-z]{2}|[a-z]{2}))/i.test(domain) )
 {
  //check the path
  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);

    // the destination url is in the href string of this redirector
    if (outHref.indexOf('xg4ken.com') > -1)
    {
     urlPos = (unescape(outHref)).indexOf('url[]=') + 6;
     var destUrl = (unescape(outHref)).substring(urlPos);
     if (searchshield.FilterUrl(destUrl, this.filter_urls))
     {
      var destUrl = searchshield.getHrefFromCiteElement(tag);
      if (destUrl)
       return searchshield.checkUrl(searchshield.removeHtmlTags(destUrl));

      return false;
     }

     return destUrl;
    }

    // filtered url but can get destination from href string
    if (outHref.indexOf('altfarm.mediaplex.com') > -1)
    {
     var tmpoh = unescape(outHref);
     var destUrl = tmpoh.substring(tmpoh.indexOf('DURL=')+5);
     if (destUrl != null)
     {
      var destUrl = unescape(destUrl);
      return destUrl;
     }
    }

    // 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))
    {
     var destUrl = searchshield.getHrefFromCiteElement(tag);
     if (destUrl)
      return searchshield.checkUrl(searchshield.removeHtmlTags(destUrl));

     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;
 }
 // special case for ie6 results
 else if (searchshield.docMode == 6 || searchshield.docMode == 7)
 {
  var parentNodeClass = tag.parentNode ? tag.parentNode.className : '';
  if ((tag.className == '') && (parentNodeClass == 'r'))
  {
   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);

      // the destination url is in the href string of this redirector
      if (outHref.indexOf('xg4ken.com') > -1)
      {
       urlPos = (unescape(outHref)).indexOf('url[]=') + 6;
       var destUrl = (unescape(outHref)).substring(urlPos);
       if (searchshield.FilterUrl(destUrl, this.filter_urls))
       {
        var destUrl = searchshield.getHrefFromCiteElement(tag);
        if (destUrl)
         return searchshield.checkUrl(searchshield.removeHtmlTags(destUrl));

        return false;
       }

       return destUrl;
      }

      // filtered url but can get destination from href string
      if (outHref.indexOf('altfarm.mediaplex.com') > -1)
      {
       var tmpoh = unescape(outHref);
       var destUrl = tmpoh.substring(tmpoh.indexOf('DURL=')+5);
       if (destUrl != null)
       {
        var destUrl = unescape(destUrl);
        return destUrl;
       }
      }
    
      // 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))
      {
       var destUrl = searchshield.getHrefFromCiteElement(tag);
       if (destUrl)
        return searchshield.checkUrl(searchshield.removeHtmlTags(destUrl));

       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 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://" + 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;
 this.omitAltImage = true;

 this.updateImageStyle = {
  verticalAlign: null
 };
};
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://" + 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;
};
///////////////    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("&nbsp;", " ");

   // 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:
 // www.bing.com or 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)
 {
  var displayStyle = (domain == 'bing.search.daum.net') ? 'inline-block' : 'inline';
  this.addAnchorStyle = {
   display: displayStyle
  };
  
  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 (/trademarks/i.test(tag.id))
 {
  // don't link the trademark at the bottom of the page
  return false;
 }
 
 if ((tag.parentNode) && (/sc_stc/i.test(tag.parentNode.id)))
 { // 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))
  {
   if (tag.parentNode && tag.parentNode.parentNode)
    spanElements = tag.parentNode.parentNode.getElementsByTagName("CITE");
  }
  
  if ((spanElements != null) && (spanElements.length > 0))
  {
   outHref = spanElements[0].innerHTML;
   if (outHref != null)
   {
    // replace any nbsp's
    outHref = outHref.replace("&nbsp;", " ");

    // 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") ||
   searchshield.DoesURLContain(tag.href, ".myoverture"))
 {
  // 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);

 this.updateImageStyle = {
  verticalAlign: null
 };
};
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;
  }

};
///////////////    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/.test(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 topAnchor") != -1))
 { //parse for embedded href

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

  var adurl = tag.href.indexOf("&adurl=http");
  // if an adurl the destination href can be acquired from the onclick handler
  if (adurl != -1)
  {
   var destUrl;
   var clickHandler = tag.getAttribute('onclick');
   if (clickHandler != null)
   {
    // the destination href is the 2nd parameter (zero-based array)
    destUrl = searchshield.getClickHandlerParams(clickHandler)[1];
    if (destUrl != null)
    {
     destUrl = searchshield.removeHtmlTags(destUrl.replace(/'/g,''));
     return searchshield.checkUrl(destUrl);
    }
   }
  }

  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 < cnLen; i++)
  {
   if ((cN[i].nodeType == 1) && 
    (cN[i].nodeName == 'SPAN') && 
    ((cN[i].className == 'title') || (cN[i].className == 'durl')))
    return [cN[i].nextSibling, cN[i].parentNode];
  }
 }

 var parent = searchshield.SearchEngine.prototype.insertNodes;
 return parent.call(this, node, doc);
};
///////////////    AOL SEARCH ENGINE    ///////////////




///////////////    ASK SEARCH ENGINE    ///////////////
searchshield.AskSearchEngine = function(search)
{
 searchshield.SearchEngine.call(this, search);
};
searchshield.AskSearchEngine.prototype = new searchshield.SearchEngine();
searchshield.AskSearchEngine.prototype.constructor = searchshield.AskSearchEngine;
searchshield.AskSearchEngine.prototype.name = "ask";
searchshield.AskSearchEngine.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 ("www.ask.com" == domain)
 {
  if (path.indexOf("web?") == 0)
   return true;
 }

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

 if (searchshield.DoesURLContain(tag.href, this.search.uri.host))
  return false;
 
 if ((tag.className) && (tag.className.indexOf("nu") != -1) && (tag.className.indexOf("info") == -1)) 
 {
  // exclude green links
  if ((tag.firstChild) &&
   (tag.firstChild.className) &&
   (tag.firstChild.className.indexOf('attrib') == 0))
  {
   return false;
  }

  // ads link to google with class nu
  findStr = "www.google.com";
  if (tag.href.indexOf(findStr) != 0)
  {
   if (tag.href.indexOf(findStr + "/aclk?sa=") != -1)
   { 
    findStr = "&adurl=http";
    var pos = tag.href.indexOf(findStr);
    if (pos != -1)
    {
     pos += 7;
     outHref = tag.href.substring(pos);
     outHref = unescape(outHref);
     if (searchshield.FilterUrl(outHref, this.filter_urls))
       return false;
     return outHref;
    }
   }
  }
  else
  { // ad not to google just use href
   outHref = tag.href;
   if (searchshield.FilterUrl(outHref, this.filter_urls))
    return false;
   return outHref;
  }
 }
 // primary results have class containing title or L2 ( Wikipedia links )
 else if ((tag.className) && ((tag.className.indexOf("title") != -1) || (tag.className.toLowerCase() == "l2")))
 {
  outHref = tag.href;
  if (searchshield.FilterUrl(outHref, this.filter_urls))
   return false;
  return outHref;
 }
 
 return false;
};
///////////////    ASK SEARCH ENGINE    ///////////////




///////////////    ALTAVISTA SEARCH ENGINE    ///////////////
searchshield.AltaVistaSearchEngine = function(search)
{
 searchshield.SearchEngine.call(this, search);
};
searchshield.AltaVistaSearchEngine.prototype = new searchshield.SearchEngine();
searchshield.AltaVistaSearchEngine.prototype.constructor = searchshield.AltaVistaSearchEngine;
searchshield.AltaVistaSearchEngine.prototype.name = "altavista";
searchshield.AltaVistaSearchEngine.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;

 // www.atlavista.com ---> 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;
 
 var spnsdLinks = searchshield.getParentNodeByTagName("DIV", tag, "className");
 if ((spnsdLinks) &&
  (spnsdLinks.className.indexOf('ads') > -1)) // sponsored links
 {
  if (!tag.parentNode)
   return false;

  // parse ads for em tag
  var baseNode;
  if (spnsdLinks.className.indexOf('ads horiz') > -1) // horizontal ads sections
   baseNode = tag.parentNode.parentNode;
  else
   baseNode = tag.parentNode;
  
  if (!baseNode || !baseNode.lastChild || baseNode.lastChild.tagName != 'EM')
   return false;

  var outHref = searchshield.removeHtmlTags(baseNode.lastChild.innerHTML);
  return outHref;
 }
 
 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.match(/yandex\.com|by|kz|ru|ua/i)) &&
  (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);

 this.elementAttribute = {
  width: "18",
  height: "18"
 };

 this.updateImageStyle = {
  width: "18px",
  height: "18px"
 };
};
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;
};
///////////////    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)
{
 if (tag.href.indexOf("/redir.aspx?") != -1)
 {
  var ancestorNode;

  // sponsored link
  if ((ancestorNode = searchshield.getParentNodeByClassName("results sponsored", tag, 3)) != null)
  {
   if ((ancestorNode = searchshield.getParentNodeByClassName("res1", tag, 2)) != null)
   {
    
    var spanSibling = ancestorNode.nextSibling;
    while (spanSibling.nodeName != 'SPAN')
    {
     spanSibling = spanSibling.nextSibling;
     if (spanSibling.nodeName == 'DIV' || spanSibling.className == 'res1')
     {
      spanSibling = null;
      break;
     }
    }

    if (spanSibling)
      outHref = spanSibling.innerHTML;
   }

   if (outHref)
    return searchshield.checkUrl(searchshield.removeHtmlTags(outHref)); 
  }
 
  if ((ancestorNode = searchshield.getParentNodeByClassName("right-sponsored", tag, 3)) != null)
  {
   var outHref;

   if ((ancestorNode = searchshield.getParentNodeByClassName("res3", tag, 2)) != null)
   {
    
    var spanSibling = ancestorNode.nextSibling;
    while (spanSibling.nodeName != 'SPAN')
    {
     spanSibling = spanSibling.nextSibling;
     if (spanSibling.nodeName == 'DIV' || spanSibling.className == 'res3')
     {
      spanSibling = null;
      break;
     }
    }

    if (spanSibling)
      outHref = spanSibling.innerHTML;
   }

   if (outHref)
    return searchshield.checkUrl(searchshield.removeHtmlTags(outHref)); 
  }

  // result link
  if (searchshield.getParentNodeByClassName("results", tag, 3) != null)
  {
   if ((ancestorNode = searchshield.getParentNodeByClassName("res2", tag, 2)) != null)
   {
    if (tag.parentNode && (tag.parentNode.nodeName != 'P'))
     return getLinkHref(ancestorNode);
   }
  }
 }

 return false;

 function getLinkHref(aNode)
 {
  var spanElems = aNode.getElementsByTagName('span');
  for (var i=0; i < spanElems.length; i++)
  {
   if (spanElems[i].className != 'site')
    continue;

   var outAnchor = spanElems[i].getElementsByTagName('a')[0];
   if (outAnchor == null)
    outAnchor = spanElems[i];

   return searchshield.checkUrl(searchshield.removeHtmlTags(outAnchor.innerHTML));
  }

  return false;
 }
};
///////////////    WEBHLEDANI SEARCH ENGINE    ///////////////




///////////////    EBAY SEARCH ENGINE    ///////////////
searchshield.eBaySearchEngine = function(search)
{
 searchshield.SearchEngine.call(this, search);
};
searchshield.eBaySearchEngine.prototype = new searchshield.SearchEngine();
searchshield.eBaySearchEngine.prototype.constructor = searchshield.eBaySearchEngine;
searchshield.eBaySearchEngine.prototype.name = "ebay";
searchshield.eBaySearchEngine.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;
 // shop.ebay.xx
 // shop.xxxx.ebay.xx like shop.benl.ebay.be
 // search.auction.co.kr 
 var path = uri.path + uri.delimiter + uri.query;
 
 if ((domain.indexOf("shop.ebay") > -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 < 0 )
   return false;
     
  outHref = searchshield.removeHtmlTags(tag.title);
  if (outHref.indexOf(" ") == -1)
  { // no spaces
   if (outHref.indexOf(".") > -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 < 0))
    return false;
    
   return outHref;
  }
 }
 
 // latin america ebay
 if ( tag.href.toLowerCase().indexOf("clickcounter?") > -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 < 0 )
     return false;
    outHref = searchshield.removeHtmlTags(outHref);
    if (outHref.indexOf(" ") == -1)
    { // no spaces
     if (outHref.indexOf(".") > -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 (tag.className == 'twitter-timeline-link')
 {
  // can't pass the tag's href if domain is t.co cause then new posts
  // will not get an immediate verdict even if it has a dangerous link
  if (tag.href.indexOf('/t.co/') != -1)
  {
   // the tag's inner text may be truncated and end in the 
   // unicode suspension character (i.e., ...) and it cannot 
   // be used.
   if (tag.innerText.charCodeAt(tag.innerText.length-1) == 8230)
   {
    // older posts may not always have data-expanded-url
    var destUrl = tag.getAttribute('data-expanded-url');
    if (!!destUrl)
     return destUrl;

    var finalUrl = searchshield.avgCallFunc(document, 'GetFinalUrl', tag.href);
    return finalUrl;
   }

   return searchshield.checkUrl(tag.innerText);
  }

  return tag.href;
 }

 return false;
};
searchshield.TwitterSearchEngine.prototype.addImage = function(node, image, hidden)
{
 var doc   = this.search.doc;
  
 this.init_inline_ratings(doc);
 this.show_inline_ratings(doc, node, image);
};
///////////////    TWITTER SEARCH ENGINE    ///////////////




///////////////    GMAIL SEARCH ENGINE    ///////////////
searchshield.GMailSearchEngine = function(search)
{
 searchshield.SearchEngine.call(this, search);
 this.processFrames = true;
 this.showCleanVerdicts  = false;
 this.type = 'inline';
};
searchshield.GMailSearchEngine.prototype = new searchshield.SearchEngine();
searchshield.GMailSearchEngine.prototype.constructor = searchshield.GMailSearchEngine;
searchshield.GMailSearchEngine.prototype.name = "gmail"; // the name by which the search engine is known (always lowercase)
searchshield.GMailSearchEngine.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("mail.google.") != -1) || 
  (domain.indexOf("gmail.") != -1))
 {
  return true;
 }

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

 // don't mark anything but http://
 if (tag.href.indexOf("mailto") == 0)
  return false;

 var parentDiv = searchshield.getParentNodeByTagName("DIV", tag, "className");
 if ((parentDiv) &&
  ((parentDiv.className == "ii gt") || // mail message body
   (parentDiv.className == "mv") || // top sponsored links
   (parentDiv.className == "vb") || // right sponsored links
   (parentDiv.className == "im") || // inside quotes
   (parentDiv.className == "gmail_quote") || // quote
   (parentDiv.className == "msg") // basic html mode
   )) // right ads
 {
  // parse for any ads
  var newHref = this.parseAdUrl(tag.href);
  return newHref;
 }
 
 return false;
};
searchshield.GMailSearchEngine.prototype.addImage = function(node, image, hidden)
{
 var doc   = this.search.doc;
  
 this.init_inline_ratings(doc);
 this.show_inline_ratings(doc, node, image);
};
searchshield.GMailSearchEngine.prototype.parseAdUrl = function(href)
{
 if (!href)
  return href;

 // check for google ad
 var regex = "^http(s)?\:\/\/([a-zA-Z0-9]+)\.googlesyndication\.com.+\&adurl\=(.+)";
 var re = new RegExp(regex);
 var matches = href.match(re);
 if (matches && (matches.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 (!tag.href || (tag.href.indexOf('facebook.com') > -1) || (tag.href.indexOf('ak.fbcdn.net') > -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    ///////////////


///////////////    MYSPACE SEARCH ENGINE    ///////////////
searchshield.MySpaceSearchEngine = function(search)
{
 searchshield.SearchEngine.call(this, search);
 this.showCleanVerdicts = false;
 this.type = 'inline';
};
searchshield.MySpaceSearchEngine.prototype = new searchshield.SearchEngine();
searchshield.MySpaceSearchEngine.prototype.constructor = searchshield.MySpaceSearchEngine;
searchshield.MySpaceSearchEngine.prototype.name = "myspace"; // the name by which the search engine is known (always lowercase)
searchshield.MySpaceSearchEngine.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.myspace.com") != -1) 
  return true;

 return false;
};
searchshield.MySpaceSearchEngine.prototype.includeLink = function(tag)
{
 // related domains do not get verdicts
 if (/myspace/.test(tag.hostname) || /myspace/.test(tag.href))
  return false;

 if (/msplinks\.com/i.test(tag.href))
  return searchshield.checkUrl(tag.innerText);
 
 return tag.href;
};
searchshield.MySpaceSearchEngine.prototype.addImage = function(node, image, hidden)
{
 var doc   = this.search.doc;
  
 this.init_inline_ratings(doc);
 this.show_inline_ratings(doc, node, image);
};
///////////////    MYSPACE 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,
 reset: function () {
  avglsflyover.count = 0;
  avglsflyover.poppedUp = false;
  avglsflyover.poppedElement = 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;
  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, "&#39;");
  }

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

  // needed to prevent the flyover from hiding inadvertantly in IE7
  if (searchshield.docMode == 7) {
   div.style.backgroundColor = "#fff";
  }

  // 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;

  avglsflyover.position();
 },
 hide: function (event) {
  var frameDoc = document || top.document;
  var div = frameDoc.getElementById("XPLSS_Flyover");
  if ((div == null) || (div.style == null) || (div.style.visibility == "hidden"))
   return;

  var trans_div = frameDoc.getElementById("XPLSS_Trans");
  if ((trans_div == null) || (trans_div.style == null) || (trans_div.style.visibility == "hidden"))
   return;

  // scroll and keydown events will pass a null event by design
  // toElement will be null when mousing out of frameelement containing a verdict
  if (event == null || event.toElement == null)
  {
   return;
  }

  if (trans_div.contains(event.toElement) || div.contains(event.toElement))
   return;

  // if the toElement is a cooresponding alt image then don't hide
  // use try/catch because toElement will be null when mousing out of frame
  try {
   if (!!event.toElement.id && !!event.srcElement.id)
   {
    if (event.toElement.id.indexOf(event.srcElement.id.substring(0,event.srcElement.id.length-2)) == 0)
     return;
  
    if (event.srcElement.id == 'XPLSS_Trans' && /XPLSS_\d+VU\d/.test(event.toElement.id))
     return;
   }
  }
  catch(err){}


  // hide and move somewhere off screen (negative offsets)
  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 < docFrames.length; i++)
   {
    try {
     var frameElem = docFrames[i].frameElement;
     if (frameElem.contentWindow.document.getElementById(avglsflyover.poppedElement.id))
     {
      posX += searchshield.offsetLeft(frameElem);
      posY += searchshield.offsetTop(frameElem);
      break;
     }
    }
    catch(frmErr){}
   }
  }

  var transXOffset = 0;
  if (imgRect.mid == undefined)
   transXOffset = -1 * halfX;
  else
   transXOffset = ((imgRect.right + imgRect.left) / 2) - imgRect.mid;
  
  // normalize pos to 0  -- get amount of scrolling in browser window
  var scroll   = searchshield.scrollSize();
  var pageOffsetX  = scroll[0];
  var pageOffsetY  = scroll[1];

  posX -= pageOffsetX;
  posY -= pageOffsetY;

  // setup the offsets
  var offsetX = posX;
  var offsetY = posY;

  // calc where to display on page
  if ((windowX - 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);
    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 < 0)
   offsetY = 0;

  if ((offsetY + flyoverY) > 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 + verdictWidth + "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";
   flyover.onmouseout = function(){
    avglsflyover.hide(event);
   };

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

   trans_div.style.visibility = "visible";
   trans_div.onmouseout = function(){
    avglsflyover.hide(event);
   };

   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 + '
';
  html += '



';

  return html;
 },
 popup: function (event, flyover, nSeverity, 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 riskUrl = blUrl.sUrl;
   if ((finalUrl) && (searchshield.FilterUrl(finalUrl, xplSearch.engine.shortened_urls)))
    finalUrl = avglsinlineflyover.getUrlFromQueryString(finalUrl);

   var riskName = blUrl.riskNameLabel + finalUrl;
   flyover = avglsinlineflyover.build(blUrl.riskCategory, riskName, blUrl.bgColor, blUrl.borderColor);
  }

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

  if (searchshield.quirksMode || searchshield.docMode <= 7)
  {
   var className = xplSearch.engine.inline.color.classname[nSeverity];
   var imgBase = "linkscanner://" + className + "_inline_border_";
   var divWidth = searchshield.elementSize(div)[0];
   //round up to nearest 10 to avoid intentional wrapping in div
   var flyoverWidth = divWidth + (10 - Math.ceil(10*((divWidth/10) - Math.floor(divWidth/10))));

   var ilfoDivs = div.getElementsByTagName("div");
   if (ilfoDivs && ilfoDivs.length == 5)
   {
    //div.style.fontSize = "10px";
    div.style.backgroundImage = "url(" + imgBase + "tl.png)";
    div.style.backgroundPosition = "0 0";
    div.style.backgroundRepeat = "no-repeat";
    div.style.width = flyoverWidth + "px";
    div.style.zIndex = "9999";
   
    // avgILFO_head
    ilfoDivs[0].style.backgroundImage = "url(" + imgBase + "tr.png)";
    ilfoDivs[0].style.backgroundPosition = "top right";
    ilfoDivs[0].style.backgroundRepeat = "no-repeat";
    ilfoDivs[0].style.width = flyoverWidth + "px";
    ilfoDivs[0].style.height = "5px";

    // avgILFO_head div
    ilfoDivs[1].style.height = "5px";
   
    // avgILFO_content
    ilfoDivs[2].style.backgroundImage = "url(" + imgBase + "r.png)";
    ilfoDivs[2].style.backgroundPosition = "top right";
    ilfoDivs[2].style.backgroundRepeat = "repeat-y";
    ilfoDivs[2].style.fontSize = "10px";
    ilfoDivs[2].style.color = "black";
    ilfoDivs[2].style.padding = "0px 10px";
    ilfoDivs[2].style.textAlign = "left";
    ilfoDivs[2].style.wordWrap = "break-word";
    ilfoDivs[2].style.lineHeight = "130%";

    // avgILFO_foot
    ilfoDivs[3].style.backgroundImage = "url(" + imgBase + "bl.png)";
    ilfoDivs[3].style.backgroundPosition = "bottom left";
    ilfoDivs[3].style.backgroundRepeat = "no-repeat";
    ilfoDivs[3].style.height = "5px";
   
    // avgILFO_foot div
    ilfoDivs[4].style.backgroundImage = "url(" + imgBase + "br.png)";
    ilfoDivs[4].style.backgroundPosition = "bottom right";
    ilfoDivs[4].style.backgroundRepeat = "no-repeat";
    ilfoDivs[4].style.width = flyoverWidth + "px";
    ilfoDivs[4].style.height = "5px";
   }
   else
   {
    div.style.fontSize = "10px";
    div.style.backgroundColor = xplSearch.engine.inline.color.background[nSeverity];
    div.style.border = xplSearch.engine.inline.color.border[nSeverity] + " solid 3px";
    div.style.padding = "3px 8px";
   }
  }
  else
  {
   // apply updated styles for new flyover content
   var sheets = document.styleSheets;
   for (var i=0; i < sheets.length; i++)
   {
    if (sheets[i].id && sheets[i].id == "avgILFOStyle")
    {
     var avgILFOStyle = sheets[i];
     break;
    }
   }
   if (typeof(avgILFOStyle) !== "undefined")
   {
    var className = xplSearch.engine.inline.color.classname[nSeverity];
    var divWidth = searchshield.elementSize(div)[0];
    //round up to nearest 10 to avoid intentional wrapping in div
    var flyoverWidth = divWidth + (10 - Math.ceil(10*((divWidth/10) - Math.floor(divWidth/10))));

    var rules = avgILFOStyle.rules;
    for (var i=0; i < rules.length; i++)
    {
     var bgImg = rules[i].style.backgroundImage;
     var selText = rules[i].selectorText.toLowerCase();

     if (bgImg)
     {
      var bgImgStyle = bgImg.replace(/default/, className);
      rules[i].style.backgroundImage = bgImgStyle;
     }

     if (((selText == ".avgilfo") ||
      (selText == ".avgilfo_head") ||
      (selText == ".avgilfo_foot div")) &&
      (rules[i].style.width) && (rules[i].style.width == "0px"))
     {
      rules[i].style.width = (flyoverWidth) + "px";
     }
    }
   }
  }

  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.style.visibility = "hidden"; //invisible
  div.style.left = "-5000px";

  if (!searchshield.quirksMode)
  {
   // reset flyover styles
   var sheets = document.styleSheets;
   for (var i=0; i < sheets.length; i++)
   {
    if (sheets[i].id && sheets[i].id == "avgILFOStyle")
    {
     var avgILFOStyle = sheets[i];
     break;
    }
   }
   if (typeof(avgILFOStyle) !== "undefined")
   {
    var rules = avgILFOStyle.rules;
    for (var i=0; i < rules.length; i++)
    {
     var bgImg = rules[i].style.backgroundImage;
     var selText = rules[i].selectorText.toLowerCase();
     if (bgImg)
     { 
      var bgImgStyle = bgImg.replace(/:\/\/([a-z]+)_/i, '://default_');
      rules[i].style.backgroundImage = bgImgStyle;
     }

     if (((selText == ".avgilfo") ||
      (selText == ".avgilfo_head") ||
      (selText == ".avgilfo_foot div")) &&
      (rules[i].style.width))
     {
      rules[i].style.width = "0px";
     }
    }
   }
  }
 },
 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;
  var hasParentFrame = false;

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

  //compensate for Firefox 3
  if (posX < imgRect.left)
   posX = imgRect.left+halfX;

  // setup the offsets
  var offsetX = posX;
  var offsetY = posY;

  // calc where to display on page
  if ((windowX - posX) > posX)
  {
   // right
   //offsetX += halfX;
   offsetX = imgRect.right + 3;
   locateX = 1;
  }
  else
  {
   //left
   //offsetX -= (flyoverX + halfX);
   offsetX = imgRect.left - flyoverX - 3;
  }
  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 < 0)
   offsetY = 0;

  if ((offsetY + flyoverY) > 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 = offsetX + "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 < images.length; i++)
   {
    if (images[i].id == "avg_ls_image")
    {
     imageElem = images[i];
     break;  
    }    
   }
   return imageElem;
  }  
 },
 getUrlFromQueryString: function (inUrl) {
  var url = inUrl;
  var uri = searchshield.parseLink(unescape(inUrl));

  if (uri.source != null)
  { // regexp failed so used split to parse url
   var qsUrl = uri.source.indexOf("?url=");
   if (qsUrl != -1)
    url = uri.source.substring(qsUrl + 5);
   else
    url = uri.source;
  }
  else if ((uri.qsArray.url != null) && (uri.qsArray.url.length > 0))
  {
   url = uri.qsArray.url;
  }

  return url;
 },
 mouseOverHandler: function (e, doc, engine) {
  if (e && e.srcElement && e.srcElement.href)
  {
   // need to keep a reference to the function registered 
   // by the listener to be able to remove it.
   var handlerFunc = arguments.callee;
   var element = e.srcElement;
   var href = e.srcElement.href;

   // need an engine   
   if (!engine)
    return;

   // check if it has an image already
   if (avglsinlineflyover.imageExists(element))
    return;

   // add the image, returns the anchor not the image
   var new_element = engine.add_inline_image(doc, element, null, null);

   // do the check and update in the background
   setTimeout(function() {avglsinlineflyover.checkAndUpdate(doc, element, new_element, engine, handlerFunc)}, 1);
  }
 },
 checkAndUpdate: function (doc, element, new_element, engine, handlerFunc) {
  if (!engine)
   return;

  try {
   // remove the listener and get final url
   element.detachEvent("onmouseover", handlerFunc, false);
   var finalUrl = searchshield.avgCallFunc(doc, 'GetFinalUrl', element.href);
  }
  catch(e) {}

  if ((typeof(finalUrl) != 'undefined') && finalUrl)
  {
   // if still a tiny url check for final url embedded in querystring
   if (searchshield.FilterUrl(finalUrl, engine.shortened_urls) && 
    (finalUrl.indexOf("?url=") != -1))
   {
    finalUrl = avglsinlineflyover.getUrlFromQueryString(finalUrl);
   }
   // update the verdict
   engine.display_inline(doc, new_element, finalUrl, null, true);
  }
  else
  {
   engine.avg_ls_inline_hide_verdict(new_element);
  }
 }
};
///////////////    FLYOVERS    ///////////////


(function(){
 setTimeout( function() {
  try {
   if ((self == top) && top.document) {
    searchshield.init(top.document, 1);
   }
  }
  catch(e){return;}
 }, 1 );
 return;
})();
 



REFERÊNCIA BIBLIOGRÁFICAS : 
CARVALHO NETO, C. Z. OMOTE, N. &amp; PUCCI, L. F. S. Física vivencial. São Paulo: Laborciência Editora, 1998. 
WEB SITE : http://educacao.uol.com.br/fisica/principio-de-pascal.jhtm&nbsp;&nbsp;&amp; (&nbsp;Imagens Google )