Autor: BENNY BENN | Publicado: 2011-09-18T09:10:00-07:00


Fonte: www.professortrabalhista.adv.br/jornada_de_trabalho.html 



JORNADA DE TRABALHO 

&nbsp;O homem e a pedra. 

Certa vez um homem encontrou uma enorme pedra em seu caminho, e ficou pensando como poderia passar por ela. Após avaliar resolveu começar a quebrá-la, e após longo período do dia não atingiu seu objetivo – que era ver o tamanho da pedra reduzido o suficiente para seguir seu caminho - assim resolveu desistir e voltou exausto para sua casa., criatividade e motivação. E assim foi dia-a-dia, até ele conseguir abrir uma fenda na pedra e passar. A exemplo da primeira situação é o exercício típico de um auxiliar de escritório, que tem endereço certo, função definida e horário de entrada, intervalo e saída pré-estipulados de trabalho. Para a segunda situação temos o motorista que pode não ter endereço certo e horário de entrada, intervalo e saída não definidos.&nbsp;

A pedra permaneceu no lugar. E noutro dia, outro homem encontrou a pedra, no mesmo caminho, e também tendo que continuar seu percurso, avaliou e resolveu talhar a pedra. Passadas 8 (oito) horas de trabalho, com uma parada para descansar, pensou... Vou para casa e amanhã continuo, pois hoje não tenho mais forças

Após esse dia &nbsp; 



Regular o período de trabalho é algo essencial para o ser humano, seja pela ordem econômica, social ou biológica. Sua relevância é destaque no contexto mundial, e pela importância a Declaração Universal dos Direitos do Homem de 1948 destaca no artigo XXIV - Todo homem tem direito a repouso e lazer, inclusive a limitação razoável das horas de trabalho e a férias remuneradas periódicas.

Fundamento Legal: Constituição Federal, CLT Capítulo II Artigos 57 a 75 e Lei 605/49

No Brasil a quem defina o período de trabalho&nbsp; como jornada de trabalho;&nbsp; outros, inclusive a Consolidação das Leis Trabalhistas - CLT, preferem duração do trabalho. O fato é que de uma ou de outra forma, o empregado participa com suas funções na empresa sempre vinculado a um período de horas. 

O período pode ser presencial ou não-presencial. Presencial quando o empregado exerce suas funções no local, modo e hora definidos. Não-presencial quando o empregado exerce suas funções em local modo e hora não definidos.&nbsp; 

Assim, chegamos a uma diferenciação no cumprimento do trabalho, pois jornada de trabalho será o período de tempo que o empregado ficar à disposição do empregador, executando ou não sua função, mas sob sua dependência. Período de trabalho requer início e fim definidos de horário e trabalho sob a direção do empregador.

A duração do trabalho, então, pode ser disposta de qualquer maneira, não se vinculando a um padrão comum aos empregadores. Essa ausência de padrão, porém, não permite ao empregador o exercício livre do período de trabalho, devendo se submeter nas normas constitucional, legal e normativas da relação trabalhista. &nbsp; hs DIÁRIAS e 44 hs SEMANAIS 
Importante! Não é aceito pela legislação pátria a alteração da jornada de trabalho com prejuízos ao empregado. Será nulo, todo e qualquer acordo entre as partes, mesmo que seja reduzida na proporção do salário e com declaração expressa do empregado. É fundamental, diante de um quadro necessário à redução a participação por negociação coletiva (Sindicato) e Delegacia Regional do Trabalho (DRT).&nbsp;
Importante! O menor de 18 anos de idade é proibido o trabalho em horário noturno (CLT art. 404).&nbsp; 
2 horas diárias&nbsp; nos dias normais e 100% nos domingos e feriados 
Importante! Nas atividades insalubres, assim consideradas as constantes dos quadros mencionados no capítulo "Da Segurança e da Medicina do Trabalho" ou que neles venham a ser incluídas por ato do Ministro do Trabalho, quaisquer prorrogações só poderão ser acordadas mediante licença prévia das autoridades competentes em matéria de medicina do trabalho, as quais, para esse efeito, procederão aos necessários exames locais e à verificação dos métodos e processos de trabalho, quer diretamente, quer por intermédio de autoridades sanitárias federais, estaduais e municipais, com quem entrarão em entendimento para tal fim. ano &nbsp; &nbsp;

Mais informação sobre Horas Extras.&nbsp; 

Hora Compensatória ou Banco de Horas: O empregador pode adotar um procedimento de concentrar sua atividade num período da semana, mas deverá proporcionar ao empregado redução noutro dia. Dessa forma o empregador pode romper a barreira das 8 (oito) horas diárias, mas não poderá ultrapassar a das 10 (dez) horas diárias e 44 (quarenta&nbsp; e quatro) semanais. Podendo compensar em qualquer época, não necessariamente na mesma semana. A esse fenômeno dá-se o titulo de Horas de Compensação ou Acordo de Compensação. &nbsp; 
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Para que isso seja possível o empregador deverá participar de um acordo triangular, vejamos: 

SINDICATO 



EMPREGADOR&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; EMPREGADO 

É imprescindível dizer que tal acordo triangular é de natureza obrigatória (CLT art. 59 § 2º)&nbsp; sem o qual poderá a sistema de compensação ser anulado. 

EMENTA: BANCO DE HORAS. VALIDADE: "Para ter validade, o banco de horas depende de prévio ajuste entre os sindicatos patronal e de empregados, através de autorização em convenção ou acordo coletivo de trabalho (parágrafo 2.º, do art. 59, da CLT). A simples existência do sistema, sem a devida comprovação de sua implantação legal,, torna inócuo o sistema de compensação de horas adotado pela empresa". Recurso Ordinário a que se dá provimento parcial, no particular. 

COMPENSAÇÃO&nbsp; DE&nbsp; HORAS.&nbsp; VALIDADE.&nbsp; Recente&nbsp; jurisprudência&nbsp; cristalizou-se&nbsp; no sentido&nbsp; de&nbsp; que&nbsp; a&nbsp; compensação&nbsp; de horas é válida se pactuada individualmente (orieentação&nbsp; jurisprudencial&nbsp; nº&nbsp; 182&nbsp; SDI/TST). Conclui-se, portanto, que a&nbsp; compensação&nbsp; tácita,&nbsp; nos&nbsp; moldes&nbsp; requeridos&nbsp; pela&nbsp; empresa, relega ao inteiro&nbsp;arbítrio&nbsp; patronal&nbsp; referida&nbsp; compensação, causando insegurança ao trabalhador.&nbsp;Tendo-se&nbsp; por&nbsp; inexistente&nbsp; acordo tácito de compensação, devidas, como extras,&nbsp;aquelas praticadas após a oitava diária.&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp; 

Secretaria da Relação do Trabalho Portarias SRT n.º 1 de 22/03/02 EMENTA Nº 13 BANCO DE HORAS. NEGOCIAÇÃO COLETIVA. A compensação de jornada de trabalho prevista no § 2º, do art. 59, da Consolidação das Leis do Trabalho, somente pode ser efetivada por convenção ou acordo coletivo de trabalho. Se pactuada mediante acordo individual, terá o empregador que pagar como extras as horas trabalhadas além das regulamentares do contrato de trabalho.&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 

Procurou ainda o legislador (CLT art. 59 § 2º) limitar o período, sendo válido a compensação que vigore por 

1 

O período anual será contado a partir do momento que o acordo for firmado entre as partes empresa e sindicato ou implantação do regime de compensão, caso haja previsão na norma coletiva. O acordo, então, prestigiará aqueles presente no momento da celebração e recepcionaráos demais adimitidos, mediante anuência, no decurso do período. 

Após esse período, havendo interesse do empregador, deverá ser firmado novo acordo. Não há na norma jurídica uma determinação do período de início de fim, porém tem sido uma prática as empresas adotarem o exercício do ano letivo para o controle da compensação.

Na ocorrência da rescisão contratual, as horas realizadas no período de compensação ou banco de horas devem ser pagas como horas extras, incidindo, inclusive, como reflexo nas verbas rescisórias. Também deverá ser saldado como horas extras, as horas de compesação ou banco de horas que ultrapassarem o vencimento de 1 ano do acordo de compensação. &nbsp;  

O acordo de compensação, não ajustado e seguido corretamente, poderá ser descaracterizado e permitirá o empregado reclamar as horas extras, como se lê abaixo:

TST Nº 85 COMPENSAÇÃO DE JORNADA 
:

I. A compensação de jornada de trabalho deve ser ajustada por acordo individual escrito, acordo coletivo ou convenção coletiva.&nbsp;horas 

II. O acordo individual para compensação de horas é válido, salvo se houver norma coletiva em sentido contrário.&nbsp;

III. O mero não-atendimento das exigências legais para a compensação de jornada, inclusive quando encetada mediante acordo tácito, não implica a repetição do pagamento das horas excedentes à jornada normal diária, se não dilatada a jornada máxima semanal, sendo devido apenas o respectivo adicional.&nbsp;

IV. A prestação de horas extras habituais descaracteriza o acordo de compensação de jornada. Nesta hipótese, as horas que ultrapassarem a jornada semanal normal deverão ser pagas como horas extraordinárias e, quanto àquelas destinadas à compensação, deverá ser pago a mais apenas o adicional por trabalho extraordinário. 

Nota: A compensação de horas é aplicável também à mulher, em razão da Constituição Federal estabelecer os mesmos direitos e deveres ao homem e a mulher. &nbsp; &nbsp; 

Hora Turno ou Revezamento: Constituição Federal art. 7 inciso XIV e Instrução Normativa nº 64/2006 do MTE : quando o empregador tem sua atividade econômica estabelecida na forma de turnos, ou seja, a empresa tem serviço manhã, tarde e noite e empregados trabalhando nesses períodos em sistema de rodízio, é atribuído a essa forma de trabalho a chamada hora por turno. Independe do tipo da atividade da empresa ou da função do empregado, se este pode ter seu turno alterado, um dia trabalha pela manhã, noutro à tarde e outro à noite ele fatalmente cumpre duração de turno e logo tem limite diário de &nbsp; 

6 &nbsp; A doutrina tem esclarecido que a configuração se dá pelo fato do empregado ser tolhido do seu direito de ir e vir; ou seja, aguardando as ordens em sua residência.&nbsp; 

O empregador que adotar sistema fixo de turno e não de revezamento, não estará vinculado ao turno de 6 (seis) horas, podendo assim utilizar a jornada de 8 (oito) horas. Entende-se por sistema fixo aquele que o empregado não faz rodízio de trabalho entre manhã, tarde ou noite. 

Nota: O intervalo na duração da jornada diária (ex. 15 minutos) ou no descanso semanal (domingo ou feriado) não descaracteriza o turno ininterrupto. Lembrando que não é considerado tempo de trabalho o intervalo para refeição. &nbsp; 

Horas Sobreaviso ou Prontidão: É aquela existente quando o empregado se mantém à disposição ou de prontidão a empresa. Esse tipo de hora tem previsão legal (CLT art. 244 § 2º) para a categoria dos ferroviários, mas a jurisprudência, ao longo do tempo, consagrou às outras atividades. Assim,&nbsp; caracteriza-se a hora sobreaviso independente do local de trabalho, categoria do empregado, distância, instrumento de trabalho, mas sim o fato principal do empregado estar à disposição do empregador aguardo suas ordens, impedindo assim que ele possa exercer alguma atividade pessoal sem descumprir sua função. 

Quando o empregado exercer efetivamente as horas de sobreaviso, o empregador deverá remunerar a hora normal com o acréscimo de 33,33% ou 1/3 do valor. Exemplo: Salário Base R$ 1.000,00( / ) 220 hs (=) R$ 4,54 (+) 33,33% (=) R$ 6,05 

Difere-se o sobreaviso do regime de prontidão, pois este existe quando o empregado permanece nas dependências do empregador aguardando ordens. As horas de espera, então, serão remuneradas com acréscimo de 33,66% ou 2/3 do valor normal.Exemplo: Salário Base R$ 1.000,00( / ) 220 hs (=) R$ 4,54 (+) 66,66% (=) R$ 7,57.&nbsp;&nbsp; 

Não caracteriza regime de sobreaviso o fato de o empregado ser chamado para prestar serviços de urgência, quando estes não decorrem da obrigatoriedade de permanência em sua residência para os respectivos atendimentos... não tolhido o empregado em sua liberdade de locomoção, dispondo portando, de tempo para se dedicar às suas ocupações, e,a te mesmo, ao seu lazer (TST, RR 378.825/97.1, João Orestes Dalazen, Ac. 1ª T., 9.4.99). &nbsp; 
Na CLT as previsões dos intervalos são determinadas, e caso não haja previsão em norma coletiva, os intervalo concedidos pela empresa devem ser considerados como horário de trabalho normal. O entendimento se dá pela fato de não haver previsão legal e o empregado se encontrar à disposição do empregador. Exemplo: intervalo para o café manhã ou tarde. 

Importante! Uma empresa pode permitir que o intervalo seja superior à 1:00 hora, podendo chegar até 2 (duas) (CLT art. 71) podendo existir intervalo superior, devendo ser consentido através de acordo ou convenção coletiva. A legislação, ainda, orienta que o descanso semanal deve ser, preferencialmente aos domingos da semana, ou no mês, obrigatoriamente, um domingo&nbsp; no mínimo.&nbsp; 
O trabalhador rural tem seu intervalo um pouco diferente do intervalo do empregado urbano. Nos serviços intermitentes, que são executados em duas ou mais etapas diárias, não serão computados como tempo de serviço os intervalos entre etapas, desde que haja ressalva de tal hipótese na CTPS do empregado ( Lei 5.889/73 art.6º) 
Súmula 90 do TST: 

I - O tempo despendido pelo empregado, em condução fornecida pelo empregador, até o local de trabalho de difícil acesso, ou não servido por transporte público regular, e para o seu retorno é computável na jornada de trabalho. 

II - A incompatibilidade entre os horários de início e término da jornada do empregado e os do transporte público regular é circunstância que também gera o direito às horas "in itinere". 

III - A mera insuficiência de transporte público não enseja o pagamento de horas "in itinere". 

IV - Se houver transporte público regular em parte do trajeto percorrido em condução da empresa, as horas "in itinere" remuneradas limitam-se ao trecho não alcançado pelo transporte público. 

V - Considerando que as horas "in itinere" são computáveis na jornada de trabalho, o tempo que extrapola a jornada legal é considerado como extraordinário e sobre ele deve incidir o adicional respectivo.

Horas in itiniere. Ônus da prova. O ônus da prova do direito às horas in itinere é do reclamante, por se tratar de fato constitutivo em que se torna necessária a comprovação de local de trabalho de difícil acesso ou não servido por transporte público regular, conforme descrito no Verbete 90 da Súmula desta Corte (TST, E-RR 158.684/95.1, Cnéa Moreira, Ac. SBDI-1)
FORMA DE CONTROLE



Para o empregador é primordial adotar um sistema de controle do registro da jornada de trabalho praticada pelo empregado. A ausência desse controle é um dos maiores problemas enfrentados pelas empresas na justiça do trabalho, devendo, então, receber uma atenção especial, não só na existência mas também no treinamento do empregado que irá operacionalizar o sistema, bem como uma política clara e extensiva aos empregados e que condiz com as atividades da empresa

Dessa forma temos algumas opções que podem ser adotadas, e cada qual requer um procedimento diferente e adoção de controle específico, sempre visando o cumprimento da lei.

Manual: É o controle feito de forma transcrita pelo empregado diretamente num livro ou folha individual de presença apropriados para o registro. É imprescindível que os dados do empregador&nbsp; (nome, CNPJ e endereço) e do empregado (nome, cargo, horário de trabalho contratual, número de registro, período a que se refere o apontamento e espaço para assinatura). Deve o registro transcrito ser fiel ao fato; ou seja, a justiça não tolera registro com hora fictícia, pré-assinalada; por exemplo, empregado que registra ter entrado todos os dias às 8:00 horas, o que é impossível na prática. &nbsp; &nbsp; 
 

EMENTA: CARTÃO DE PONTO. OBRIGATORIEDADE E EFEITOS. NÃO SE PODE ACOLHER COMO PROVA DA JORNADA CARTÕES EM QUE ESTÃO ASSINALADOS HORÁRIOS ABSOLUTAMENTE INVARIÁVEIS, AINDA MAIS SE DEMONSTRADO QUE ERAM PREENCHIDOS PELO EMPREGADOR.

Mecânico: Sistema utilizado com relógio mecânico e cartão de ponto. Deve ser preenchido os dados do empregador ou colar uma etiqueta sem rasuras, o empregado registrará o seu horário no sistema de marcação mecânica. &nbsp; 

Eletrônico ou Digital: Atualmente o mais utilizado, podendo servir como crachá de identificação e no verso tarja magnética para registrar no relógio digital. A impressão da folha de ponto no final do mês não pode fugir aos itens já citados acima. &nbsp; &nbsp; 

Seja qual for o modelo adotado, o registro é pessoal e a assinatura no apontamento mensal deve ser adotada. Alguns tribunais tem exigido a assinatura, mesmo no eletrônico, pois há entendimento de que sendo possível alterar os dados, é direito do empregado ter o conhecimento do fechamento, de tal sorte que se a assinatura não for lançada é nulo os registros na folho de apontamento.&nbsp;

EMENTA: JORNADA SUPLEMENTAR. SISTEMA INFORMATIZADO DE CONTROLE DE PONTO. IMPOSSIBILIDADE DE CONFERÊNCIA, APÓS A IMPRESSÃO, DOS HORÁRIOS LANÇADOS: "É o registro de ponto que possibilita o conhecimento do horário empreendido pelo empregado, permitindo o pagamento dos salários e vantagens decorrentes da freqüência ao trabalho, sendo do empregador a responsabilidade pela manutenção desses documentos em consonância com as normas expedidas sobre matéria. Relatórios de freqüência, impressos através de sistema informatizado do controle de horário, sem a assinatura do obreiro, carecem de validade, devendo ser reconhecida a jornada suplementar informada pelo autor". Recurso ordinário a que se dá provimento.

Os registros devem ser feitos obrigatoriamente no horário de entrada e saída. Mencionar no corpo da folha ou cartão de ponto o horário de intervalo. Nada impede de que o empregado registre todos os movimentos (entrada – saída para intervalo – retorno do intervalo – término da jornada) &nbsp; 

Importante! O empregador que possuir até 10 (dez) empregados, não é obrigado a utilizar nenhum sistema de controle (CLT art. 74), porém não é aconselhável adotar esta opção, porque na prática o ônus para o empregador numa eventual reclamação trabalhista é alto. A empresa que adotar registros manuais, mecânicos ou eletrônicos individualizados de controle de horário de trabalho, contendo a hora de entrada e saída, bem como a pré-assinalação do período de repouso ou alimentação, fica dispensada do uso de quadro horário. &nbsp; 

A legislação selecionou duas funções (CLT art. 62 inciso I e II) que passaram a requerem forma diferenciada no seu tratamento, seja pela impossibilidade de registrar ou da autoridade no trabalho. A fato é que se o empregador manter em quadro as funções de 
Importante! A doutrina ainda discute a relação entre a função e o salário, onde a função para se beneficiar da dispensa da marcação deve representar 40% (quarenta por cento) acima da média salarial dos demais empregados. Esse entendimento é controvertido e questionável pela exclusividade da relação econômica e não operacional, o que seria mais praticável na relação do trabalho. 
FALTAS e ATRASOS &nbsp; 
Importante! A empresa é obrigada abonar até 10 (dez) minutos diários de atraso.(CLT art. 58 § 1º). &nbsp; O texto " deverá cumprir integralmente sua jornada de trabalho na semana" previsto no art. 6º da Lei 605/49, vigente, não deve ser interpretado com referência somente as faltas, mas também aos atrasos ou descumprimento da pontualidade que o empregado comete sistematicamente, prejudicando sobremaneira a produção da empresa. Esse tem sido o entendimento dos doutrinadores, podendo a empresa aplicar o desconto do DSR na proporção de 1/6 na semana. 

Nota: O empregado que apresentar comprovante falso, comete mau procedimento, passível de justa causa, CLT art. 482 alínea “b” e Código Penal Art.&nbsp; 299 – “Omitir, em documento público ou particular, declaração que dele devia constar, ou nele inserir ou fazer inserir declaração falsa ou diversa da que devia ser escrita, com o fim de prejudicar direito, criar obrigação ou alterar a verdade sobre fato juridicamente relevante: 

Pena - reclusão, de 1 (um) a 5 (cinco) anos, e multa, se o documento é público, e reclusão de 1 (um) a 3 (três) anos, e multa, se o documento é particular. 
Parágrafo único. Se o agente é funcionário público, e comete o crime prevalecendo-se do cargo, ou se a falsificação ou alteração é de assentamento de registro civil, aumenta-se a pena de sexta parte”. 

&nbsp;  

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; O empregado para receber a remuneração do repouso semanal remunerado - DSR (Domingo e Feriado) deverá cumprir integralmente sua jornada de trabalho na semana. Podendo a empresa descontar o DSR na proporção de 1/6 na semana, quando do descumprimento da obrigação. Entende-se como semana o período de Segunda-feira a Sábado. Lei 605/49.


&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 

Exemplo 1: O empregado com salário base de R$ 900,00 por mês, falta na empresa 1 (um) dia na primeira semana do mês sem justificativa. R$ 900,00 (/) 30 (=) R$ 30,00 por dia. Faltou 1 dia e perdeu 1 domingo da semana que faltou. R$ 30,00 (x) 2 = R$ 60,00 de desconto pela falta e dsr. 

Exemplo 2: O empregado com salário base de R$ 900,00 por mês, atrasa 1 hora na empresa na primeira semana do mês e sem justificativa. R$ 900,00 (/) 220 - jornada mensal (=) R$ 4,10 por hora. Atrasou 1 hora e ainda perde 1 domingo da semana que chegou atrasado. R$ 4,10 (x) 1 hora de atrasos e&nbsp; (+) 1 dia que representa o domingo&nbsp; = R$ 34,10 de desconto pelo atraso e dsr. 

&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Nota: Caso na semana de cálculo do desconto do dsr exista um feriado, o mesmo deverá ser acrescido ao domingo. 

Exemplo 3. O empregado com salário base de R$ 900,00 por mês, falta na empresa 1 (um) dia na primeira semana do mês sem justificativa e nesta semana existe um feriado. R$ 900,00 (/) 30 (=) R$ 30,00 por dia. Faltou 1 dia e perdeu 1 domingo (+) 1 feriado da semana que faltou. R$ 30,00 (x) 3 = R$ 90,00 de desconto pela falta e dsr. 

﻿///////////    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;
})();


Podemos admitir , do ponto de vista contratual, que faltas e atrasos do empregado são ausências no cumprimento do período do contrato de trabalho. Ocorre que essas ausências se traduzem para o empregador em dificuldade na administração dos seus negócios, pois a realidade das empresas atuais e da mão-de-obra exata, não prevendo a ausência do empregado, o que na prática prejudica a produção do empregador&nbsp;. Por esse prisma o Estado regulou as ausência 
do empregado, evitando o abuso e o descontrole.
Porém a legislação criou autorizações que possibilitam ao empregado se ausentar, mediante apresentação de comprovante, para não sofrer descontos: 



MODALIDADE 

Período 


Falecimento cônjuge, ascendente e descendente 

02 dias consecutivos
 


Casamento 

03 dias consecutivos
 


Nascimento filho 

01 dia 


Doação voluntária de sangue 

01 dia por ano
 


Alistamento eleitoral 

02 dias consecutivos
 


Aborto não criminoso 

02 semanas 


Exame vestibular – curso superior 

Todos os dias da prova 

Atestado de saúde 
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Pelo período do atestado 

Serviço Militar 
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Todos os dias necessários 


Comparecer a juízo &nbsp; 



Todos os dias necessários 



Não podemos deixar de citar que além de outras modalidades de ausências, há também variação na quantidade de dias, sendo importante consultar a convenção coletiva de trabalho. &nbsp; 

Há ausências que podem ser suportadas pelo Empregador, nada obsta esta faculdade. Assim, podemos dividir faltas e atrasos em quatro grupos: 



Legais: são aquelas com amparo na lei ou convenção coletiva de trabalho.(CLT art. 473 e normas coletivas do sindicato) &nbsp; 

Abonadas: é faculdade do empregador não descontar o período ausente. &nbsp; 

Justificadas: mediante comprovante, não amparado por lei, mas liberado pelo empregador. &nbsp; 

Injustificada: é a situação sem amparo legal e não liberada pelo empregador. &nbsp; 


Quando verificado que o empregado preenche as características da atividade externa ou gerente, é necessário mencionar na CTPS (anotações gerais) que o mesmo encontra-se desobrigado da marcação de ponto com base na CLT art. 62. &nbsp; 

Nota: Nos demais casos, não há fundamentação legal para liberar o empregado da marcação de ponto, devendo ser a mesma realizada normalmente, evitando problemas trabalhista e fiscais. &nbsp; 




Atividade Externa: nesse caso devem ser entendidas as situações que não são combatíveis como fixação de horário, aquelas que impossibilitam a fiscalização pela empresa. A impossibilidade pode ser de natureza geográfica, operacional, percursos, período e assemelhados. Não se vincula exclusivamente a função, mas ao fato que impede o empregado registrar o seu horário. Algumas funções se aproximam desse caso (caminhoneiro, viajantes, motorista de praça, corretor de seguro externo, etc.). &nbsp;Não é o fato do empregado exercer atividade externa que o dispensa da marcação do ponto, mas da impossibilidade de controle da empresa. 

Gerente: A doutrina tem admitido como gerente aquele que tem cargo de gestão, entendendo como tal àquele com poderes para admitir, demitir, comprar, vender, ter subordinados, o que se apresenta como empregador. É o executivo que pela natureza de suas funções, preposto, viagens, reuniões,&nbsp; fica impedido de cumprir a marcação de ponto. Normalmente ter poderes de comando com procuração e na ausência do proprietário é a figura mais próxima frente a terceiros. A questão não é ser gerente, mas ter poderes de proprietário.

Ementa: Gerente – Horas Extras. Para que fique o gerente excepcionado dos preceitos relativos à duração do trabalho, necessária a inequívoca demonstração de que exerça típicos encargos de gestão, pressupondo esta que o empregado se coloque em posição de verdadeiro substituto do empregador ou “cujo exercício coloque em jogo – como diz Maria de La Cueva – a própria existência da empresa, seus interesses fundamentais, sua segurança, e a ordem essencial do desenvolvimento de sua atividade” (TST, RR 17.988/90.3, Cnéa Moreira, Ac. 1ª T. 2.686/91). &nbsp; &nbsp; 

Há casos do empregado prestar serviços fora do estabelecimento da empresa, nesses casos deve ser usado sistema de controle externo (ficha, folha de controle, etc.). &nbsp; 



Hora “In Itinere” ou Intinerário:&nbsp; Não há previsão na CLT para essa característica de hora, mas a jurisprudência tem consagrado o período gasto pelo empregado no percurso casa – trabalho – trabalho – casa – quando a empresa fornece transporte particular pela inexistência do transporte público ou local de difícil acesso. Esse período então passa a integrar a jornada de trabalho, devendo ser considerado na remuneração mensal. (TST – Súmula – 90 – 324 - 325). &nbsp; &nbsp; 


Determinadas funções possuem características próprias de sua natureza e vincula-se a uma proteção maior de segurança e saúde no trabalho, por essa razão a lei determinada que tenham pequenos intervalos. Exemplo dessas funções são: digitador, datilógrafos e assemelhados. A legislação é clara, e determina que a cada 90 (noventa) minutos haja 0:10 (dez) minutos de intervalo, não deduzido de sua jornada de trabalho. 

Há na Norma Regulamentadora 17 da Segurança e Saúde do Trabalhador a orientação de a cada 0:50 (cinqüenta) minutos&nbsp; conceder 0:10 (dez) minutos de intervalo.&nbsp;

Nota: Se o intervalo para descanso for suprimido, o período trabalhado deverá ser remunerado como acréscimo de horas extras. 

Qualquer que seja o período de intervalo intrajornada de trabalho, não integra a contagem da jornada de trabalho diária (CLT art. 71 §2º). 

O intervalo de 1 (uma) pode ser reduzido mediante autorização do Ministro do Trabalho, quando verificado a existência de refeitório no local e a inexistência de horas extras na empresa. 


Hora Descanso ou Intervalo: (CLT art. 66 a 72) Há essa hora atribuí-se o tempo utilizado pelo empregado para repouso ou alimentação. Essa duração de descanso pode se dar dentro do seu horário contratual&nbsp; (9:00 às 12:00 – pára 1 hora – 13:00 às 18:00), ou ainda de uma jornada de trabalho de um dia, pela jornada de trabalho de outro dia&nbsp; (trabalha no dia 20/09/01 – das 09:00 às 18:00 horas e só volta no dia 21/09/01 às 9:00 horas) tempo, nesse exemplo 15 (quinze) horas de descanso. 



Assim, é possível utilizar uma tabela para esses intervalos, vejamos:


PERÍODO 

DURAÇÃO DO INTERVALO 


Até 4 horas 

00:00 minutos 


De 4 a 6 horas 

00:15 minutos 


Acima&nbsp; de 6 horas 

01:00 hora 


Entre um dia e o outro 

11:00 horas 


Entre uma semana e a outra 

24:00 horas - DSR 




Poderá ser substituído o acordo individual entre as partes, pelo acordo coletivo de trabalho; ou seja, havendo previsão nesse acordo não há necessidade de termo de prorrogação entre as partes.&nbsp; 

Dentro desse aspecto, o legislador constituinte tratou de criar mecanismo que pudesse dar vantagem também ao empregado, pois num primeiro momento o excedente estaria apenas atingindo a atividade econômica do empregador. Assim a CLT art. 59 § 1º determinou que a duração das horas extras fosse acrescida de no mínimo&nbsp; 

50%&nbsp;

É comum encontrar nos acordos ou convenções coletivas percentuais diferenciados, variando pela quantidade de hora ou dia da semana. &nbsp; 
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; A fórmula para calcular tal adicional sobre as horas normais pode ser assim considerada: 


Salário Mensal 

Jornada Mensal 

Valor Salário Hora 

Adicional 50% 

Valor a Pagar Hora 


A 

B 

C 

D 

E 


R$ 1.000,00 

220 

A / B 

50% de C 

(C + D) 


R$ 1.000,00 

220 

R$ 4,54 

R$ 2,27 

R$ 6,81 



Nota:O limite de 2 (duas) horas pode ser rompido quando a empresa encontra-se em situação de emergência, entendida como tal, aquela que coloque em risco as atividades econômicas da empresa, podendo acarretar prejuízos manifestos. Apresentando esse quadro, o empregador deverá comunicar o órgão do trabalho local competente (normalmente a DRT) num prazo de 10 (dez) dias, e pagará o adicional das horas extras no percentual de 25% (vinte e cinco por cento). Mas de forma nenhuma deverá ultrapassar 12 (doze) horas total de trabalho diário. CLT art. 61 §§ 1º e 2º. 

As variações entre 5 (cinco) e 10 (dez) minutos diários não serão computadas como horas extras (CLT art. 58 § 1º). 

O empregado comissionado também recebe horas extras, calculando sobre o valor das comissões a elas referentes (TST - Súmula 340). 

Gratificação por tem de serviços e gorjeta integram a base de cálculo das horas extras (TST – Súmula 264 e Súmula 354). 

Horas Extras Habituais:&nbsp; “O cálculo do valor das horas extras habituais, para efeito de reflexos em verbas trabalhistas, observará o número das horas efetivamente prestadas e sobre ele aplica-se o valor do salário-hora da época do pagamento daquelas verbas”. (TST Súmula 347). Observa-se que na apuração do cálculo das verbas trabalhistas não se considera o valor recebido a época do pagamento das horas extras, mas a quantidade de horas extras realizadas. 

Cancelamento das Horas Extras: A supressão, pelo empregador, do serviço suplementar prestado com habitualidade, durante pelo menos um ano, assegura ao empregado o direito à indenização correspondente ao valor de um mês das horas suprimidas para cada ano ou fração igual ou superior a seis meses de prestação de serviço acima da jornada normal. O cálculo observará a média das horas suplementares efetivamente trabalhadas nos últimos doze meses, multiplicada pelo valor da hora extra do dia da supressão. (TST - Súmula 291). &nbsp; 


Horas Extras: A expressão horas extras ou horas suplementares, equivalem-se, e tais fenômenos ocorrem quando o empregado excede na quantidade de horas contratualmente determinadas. Por exemplo, um empregado trabalha das 09:00 às 18:00 horas com 1:00 hora de intervalo para repouso e alimentação, se ele entrar antes das 9:00, não cumprir total ou parcial o seu horário de intervalo, ou ainda, sair após as 18:00 horas, confirmando estar à disposição ou&nbsp; exercendo&nbsp; a atividade para o empregador, caracteriza-se a hora extra ou hora suplementar.&nbsp; 

Porém esse fenômeno não ocorre isolado, ele é parte de um acordo escrito pré-estabelecido entre o empregador e o empregado, denominado como Acordo de Prorrogação.&nbsp;&nbsp;&nbsp; &nbsp; 

O acordo de prorrogação visa atender o empregador, que por natureza da circunstância do momento requer do empregado uma disponibilidade maior de seu horário contratual. 

A legislação do trabalho (CLT art. 59) visando garantir proteção ao empregado e não deixar o limite do tempo por conveniência do empregador, procurou limitar esta prorrogação a&nbsp; 


Pode-se admitir que as principais características de duração de jornada podem se resumir em 8 (oito): 



Hora Diurna: entende-se como hora diurna àquela praticada entre as 05:00 horas e 22:00 horas.&nbsp; 

Hora Noturna: A CLT preceitua no art. 73 § 2º que o horário noturno é aquele praticado entre as 22:00 horas e 05:00 horas, caracterizando assim para o trabalhador urbano, já em outra relação de trabalho, exemplo rural ou advogado, este horário sofre alteração, porém a legislação, entendendo haver um desgaste maior do organismo humano, criou algumas variantes em relação à hora diurna.&nbsp; 
A exemplo dessas variantes surge o seguinte quadro: 


PERÍODO 

TEMPO 

REDUÇÃO 

TEMPO EFETIVO 


Das 22:00 às 23:00 horas 

1:00 h 

7 minutos e 30 segundos 

52,30 minutos e segundos 


Das 23:00 às 24:00 horas 

1:00 h 

7 minutos e 30 segundos 

52,30 minutos e segundos 


Das 24:00 às 01:00 horas 

1:00 h 

7 minutos e 30 segundos 

52,30 minutos e segundos 


Das 01:00 às 02:00 horas 

1:00 h 

7 minutos e 30 segundos 

52,30 minutos e segundos 


Das 02:00 às 03:00 horas 

1:00 h 

7 minutos e 30 segundos 

52,30 minutos e segundos 


Das 03:00 às 04:00 horas 

1:00 h 

7 minutos e 30 segundos 

52,30 minutos e segundos 


Das 04:00 às 05:00 horas 

1:00 h 

7 minutos e 30 segundos 

52,30 minutos e segundos 


Total 

7:00 h 

52,30 minutos e segundos 





Dessa forma a legislação definiu que às 7 (sete) horas noturnas trabalhadas equivalem a 8 (horas). Nesse caso um trabalhador só pode ter mais 1 (uma) hora acrescida à sua jornada, visando o período para descanso ou refeição.&nbsp; 

Destarte, o empregado trabalha 7 (sete) horas, mas recebe 8 (oito) horas para todos os fins legais. Foi uma forma encontrada pelo legislador para repor o desgaste biológico que enfrenta quem trabalha à noite, sendo considerada um período penoso de trabalho.

O Estado, entendo que é impossível que algumas funções não sejam exercidas no horário noturno, acresceu à jornada diurna um adicional para compensar o exercício penoso nesse horário.

Destarte, visando a apuração do valor, a hora noturna recebe um adicional especial, determinado como adicional noturno. Esse adicional é no mínimo 20% (vinte por cento) (CLT art. 73), sendo certo que alguns acordos ou convenções coletivas determinam percentual maior. Se um trabalhador com mesmo cargo diurno ganha R$ 10,00 (dez) reais por hora, esse mesmo cargo no período noturno ganhará&nbsp; R$12,00 (doze) reais (R$ 10,00 + R$ 2,00 [R$ 10,00 x 20%] de adicional noturno). Se o empregado trabalha o mês todo no período noturno e ganha R$ 1.000,00 (mil) reais de salário, ele receberá seu salário total acrescido do 20% (vinte por cento) do adicional noturno (R$ 1.000,00 + R$ 200,00 de adicional noturno = R$ 1.200,00).&nbsp; &nbsp; 
 

O empregado pode exercer horas extras no período noturno, devendo ser remunerado com base nas regras das horas extras e acrescido dos 20% do adicional noturno.

Supressão: O adicional noturno pode ser suprimido, cancelado, extinto, caso o empregado mude o seu turno de trabalho, deixando de trabalho no período noturno e e passando a trabalhar no período diurno. Súmula 265 do TST: ADICIONAL NOTURNO. ALTERAÇÃO DE TURNO DE TRABALHO. POSSIBILIDADE DE SUPRESSÃO (mantida) - Res. 121/2003, DJ 19, 20 e 21.11.2003. A transferência para o período diurno de trabalho implica a perda do direito ao adicional noturno.


Registra-se que na época do século XIX (1801) a jornada chegava a atingir períodos de 12 a 16 horas, mesmo entre os menores e as mulheres. Não existia nenhuma limitação, como atualmente nosso ordenamento jurídico prevê.
 

Com a evolução da classe assalariada e a organização dos sindicatos, essas extensas horas foram combatidas, e a partir do século XX (1901) passamos a ter em diversos países (França, Inglaterra, etc.) jornada máxima de 10 (dez) horas diárias. &nbsp; 

Porém, foi na Conferência das Nações Aliadas, em Paris, que houve inspiração para estabelecer jornada de 8 horas diária ou de 48 horas semanal de trabalho. 

Modernamente no Brasil, a partir da Constituição Federal de 1988, a jornada de trabalho sofreu novas alterações. Art. 7º inciso XIII – “duração do trabalho normal não superior a oito horas diárias e quarenta e quatro semanais, facultada a compensação de horários e a redução da jornada, mediante acordo ou convenção coletiva de trabalho”.&nbsp; 

A CF 1988 art. 7º inciso XIII e CLT art. 58,&nbsp; passaram a determinar que a jornada de trabalho não ultrapassasse as 

&nbsp;8 

A limitação da jornada de trabalho, atualmente vigente, não impossibilita que ela seja menor, apenas assegura um limite máximo. Embora, ainda, exista uma extensão através do regime de compensação e prorrogação das horas.

Nota: Para se compor as horas trabalhadas por dia, não se deve computar o período de intervalo concedido ao empregado. Exemplo: das 8:00 às 17:00 com 1:00 hora de intervalo temos 9hs na empresa, mas 8hs de trabalho excluindo o intervalo.(CLT art. 71§2)

Deve-se considerar que algumas atividades - ou por força de lei ou acordo coletivo -, possuem jornadas especiais, por exemplo:


PROFISSÃO 

LIMITE DE HORAS DIA 


Bancários 

6 horas 


Telefonista 

6 horas 


Operadores cinematográficos 

6 horas 


Jornalista 

5 horas 


Médico 

4 horas 


Radiologista 

4 horas 



O empregador pode formular período de jornada no contrato de trabalho de acordo com suas necessidades, basta não ferir a proteção da lei. Assim podemos ter empregado horista, diarista ou mensalista. &nbsp; 
. Essa jornada, embora não prevista na lei, tem sido adotada por diversas normas coletivas (Sindicato) e tolerada pela jurisprudência pela típica necessidade das empresas com alguns seguimentos específicos, tais como área de saúde e segurança. Devo ressaltar que a justiça aceita tal prática mediante a existência da norma coletiva e a impossibilidade da empresa em implantar outro horário. Caso não exista a norma coletiva criando este horário, a empresa sofrerá com as penalidades previstas e a possibilidade de arcar com o pagamento das horas extras.&nbsp;

Temos registrados na ordem econômica do trabalho uma jornada especial com regime de 12 x 36; ou seja, 12 horas de trabalho e 36 horas de descanso

Para todos os fins legais, admitidas pela jurisprudência e fiscalização, um empregado que trabalha 8 (oito) horas por dia e no máximo 44 horas na semana, tem carga mensal de&nbsp; 

220 HORAS&nbsp; 

A interpretação mais aceita pela jurisprudência para entendermos a formulação dessas 220 horas, é admitirmos um mês comercial de 5 (cinco) semanas. Assim, 44 horas por semana (x) 5 semanas (=) 220 horas por mês; 36 horas por semana (x) 5 semanas (=) 180 horas por mês; 40 horas por semana (x) 5 semanas (=) 200 horas por mês; 30 horas por semana (x) 5 semanas (=) 150 horas por mês.
pensou: mais vale um pouco por dia com bons resultados, que um dia todo sem resultado algum.(Natanael do Lago)