/*********************************************************************
multi-language validation script
	version 2.21
	by matthew frank

There are no warranties expressed or implied.  I will not be held
responsible for any loss of data or sanity through the use or
implementation of this script.  This script may be re-used and
distrubted freely provided this header remains intact and all
supporting files are included (unaltered) in the distribution:

	FormVal.js   - this file
	validation.htm  - example form
	readme.htm      - directions on using this script
	(validation.zip contains all files)

If you are interested in keeping up with the latest releases of this
script or asking questions about its implementation, think about joining
the eGroups discussion forum dedicated to data validation:

	http://www.egroups.com/group/validation

*********************************************************************/
/*
VALIDAÇÕES POSSÍVEIS:
	1  - REQUIRED	- Exige que o seja preenchido (Campo obrigatório)
	2  - INTEGER	- Exige que o campo seja um valor inteiro
	3  - FLOAT		- Exige que o campo seja um valor real 
	4  - DATE		- Exige que o campo seja uma data válida, é necessário colocar as "/" de separação, por default o ano deve possuir 4 dígitos e o formato
	                  padrão é "MM/DD/YYYY" o que pode ser alterado passando o novo formato - DATE="DD/MM/YYYY"
	5  - AMOUNT		- Exige que o campo seja um valor monetário sem/com duas casas decimais e ponto de separação de milhar
	                  Alterado por Fabiano em 26/05/2006 (Exigir marcador de separação de milhar) 
	6  - MASK		- 
	7  - REGEXP		-
	8  - AND		- Conector lógico "e" que permite a combinção entre validações
	9  - OR			- Conector lógico "ou" que permite a combinação entre validações
	10 - NOSPACE	- Retira espaços em branco do início e final do campo
	11 - UPPERCASE 
	12 - LOWERCASE
	13 - NUMPROCESSO  - Permite validar os números de processo conforme padrão para a Justiça Federal em Alagoas. Aceita como parâmetro:
	                    numprocesso='jfc' - indica que o numero será validado como sendo um número da Justiça Federal Comum - AAAA.80.00.NNNNNN-N (Maceió)
						                                                                                                 ou - AAAA.80.01.NNNNNN-N (Arapiraca)
						numprocesso='jef' - indica que o numero será validado como sendo um número do Juizado Especial Federal - AAAA.80.13.NNNNNN-N
						                                                                                                 ou - AAAA.80.15.50NNNN-N (Arapiraca)						
						numprocesso='tur' - indica que o numero será validado como sendo um número da Turma Recursal - AAAA.80.14.NNNNNN-N
	                    
	                    Adicionado por Fabiano em 25/05/2006
	14 - CPF        - 	Permite validar se é um número de CPF válido. 
						Os CPF's 000.000.000-00 ... 999.999.999-99 são retornados como inválidos
						Aceita números formatados e sem formatação
						Aceita como parâmetro: cpf="formatar" - indica que o número de CPF, se válido, deverá ser formatado na saída: NNN.NNN.NNN-NN
						Adicionado por Fabiano em 09/06/2006
	15 - CNPJ       - 	Permite validar se é um número de CNPJ válido. 
						Os CNPJ's com números base 11.111.111 ... 99.999.999 são retornados como inválidos
						Aceita números formatados e sem formatação
						Aceita como parâmetro: cnpj="formatar" - indica que o número de CNPJ, se válido, deverá ser formatado na saída: NN.NNN.NNN/NNNN-NN
						Adicionado por Fabiano em 09/06/2006
	16 - CAPCHA		-	Permite validar se o valor digitado pelo usuário é igual a sequência gerada aleatoriamente (capcha)
						Deve ser passado como parâmetro o valor gerado aleatoriamente: capcha="sequencia"
						Adicionado por Fabiano em 26/07/2006

Para se utilizar este script três inserções deverão ser feitas na página que contém os campos a serem validos:
1 - logo abaixo da tag <body> colocar as 5 linhas abaixo atentando para o path correto do gif FormVal.gif:
 <STYLE>
 <!--
     .required {background-image:url(../img/FormVal.gif); background-position:top right; background-repeat:no-repeat;}
  -->
 </STYLE>
2 - imediatamente antes da tag </body> atentando para o path correto do arquivo FormVal.js
   <SCRIPT LANGUAGE="JScript" SRC="../funcoes/FormVal.js"></SCRIPT>
3 - Em cada tag <input> do formulário em que se deseja validação colocar os parâmetros necessários:
   Ex.: <input ... required ... > <input ... amount="," ... > etc
   
*********************************************************************/
<!--
/*********************************************************************
 *********************************************************************/
// Funções auxiliares para validação e formatação de números de processo na Justiça Federal
// por Fabiano A. Costa 
// Em: 24/05/2006
// 
//--------------------------------------------------------------------------------
// //Formatação dos números com 15 digitos e 10 digitos da página inicial
function formata_numero(num){
	if(num.charAt(0) == '2'){
		numero = num.substr(0,4)+ '.' + num.charAt(4) + num.charAt(5) + '.'+ num.charAt(6) + num.charAt(7) +'.'+ num.charAt(8)+num.charAt(9)+num.charAt(10) + num.charAt(11) + num.charAt(12) + num.charAt(13)+ '-' + num.charAt(14);			
	}else{
		numero = num.substr(0,2)+'.'+ num.charAt(2)+ num.charAt(3)+num.charAt(4)+num.charAt(5)+num.charAt(6)+ num.charAt(7)+ num.charAt(8)+'-'+ num.charAt(9);
	}
	return numero;
}
//--------------------------------------------------------------------------------
// Função que completa o numero do processo com zeros para que fique correto
function completa_zeros(numero){
	var num, i, zeros = '';	

	if(numero.charAt(0) == '2'){	
		for(i=1; i <= 15 - numero.length;i++){
			zeros = zeros + '0';
		}		
		numero = numero.substr(0,8) + zeros + numero.substr(8,numero.length );		
	} else {
		for(i=1; i <= 10 - numero.length;i++){
			zeros = zeros + '0';
		}		
		numero = numero.substr(0,2) + zeros + numero.substr(2,numero.length );					
	}
	
	return numero;
}

//--------------------------------------------------------------------------------
// Função que extrai todos os digitos de uma string
function extrai_digitos(str){
	var str_numeros = "";
	var i;
	for(i=0; i < str.length; i++){
		if((str.charAt(i) >= '0') && (str.charAt(i) <= '9'))
			str_numeros = str_numeros + str.charAt(i);
	}
	str_numeros = completa_zeros(str_numeros);
	return str_numeros;
}

//--------------------------------------------------------------------------------
// Função que calcula o digito verificador do numero dado (com 10 digitos)
function calcula_digito1(numero){
	var digito = 0;
	var i;
	
	for(i=0; i< 9; i++){
		digito += parseInt(numero.charAt(i))*(i+1); 
	}
	digito = digito%11;
	if(digito > 9)
		digito = 0;
	return digito;
}
//--------------------------------------------------------------------------------
// Função que calcula o digito verificador do numero dado (com 15 digitos)
function calcula_digito2(numero){
	var digito = 0;
	var i;
	for(i=13; i > -1; i--){
		if(i >= 6) {
				digito += parseInt(numero.charAt(i))*(15-i); 
		}else {
			digito += parseInt(numero.charAt(i))*(7-i); 		
		}

	}
	digito = digito%11;
	if(digito > 9)
		digito = 0;
		
	return digito;
}
//---------------------------------------------------------------------------------
// Função que verifica o digito verificador do número de um processo dado no formato (99999999999)
function verifica_digito_processo(numero){
	var valido = true;
	var digito = -1;
	
	// Verifica o digito para um processo com 10 algarismos
	if(numero.length == 10){				
		digito = calcula_digito1(numero);						
		if(digito != parseInt(numero.charAt(9))){
			valido = false;
		}
	} 
	// Verifica o digito para um processo com 15algarismos	
	else if(numero.length == 15){
		digito = calcula_digito2(numero);										
		if(digito != parseInt(numero.charAt(14))){
			valido = false;
		}		
	} 
	// O número do processo não possui 10 nem 15 algarismos
	else {
		valido = false;
	}
	
	return valido;
}
//--------------------------------------------------------------------------------//
//Essa função só é utilizada se a opção for justiça comum
function retira_caracteres(str){
	var campo_final = "";
	var i;
	for(i=0; i < str.length; i++){
		if((str.charAt(i) != '/') && (str.charAt(i) != '%')&& (str.charAt(i) != '#')&& (str.charAt(i) != '$')&& (str.charAt(i) != '@'))
			campo_final = campo_final + str.charAt(i);
	}
	
	return campo_final;	
}
//--------------------------------------------------------------------------------------
function ZerosAEsquerda(str, quantidade){
	var i, zeros = '';
	for (i=0; i <= (quantidade - str.length-1); i++){
		zeros = '0'+zeros;
	}
	str = zeros+str;
	return str;
}
//--------------------------------------------------------------------------------
//Função que completa o ano com os 4 digitos
function CompletaAno(Ano){

	var anoTotal, tamanho = Ano.length;
	
	if(tamanho == 2)
		if (Ano.substr(0,1) > 5)
			anoTotal = "19"+Ano;
		else
			anoTotal = "20"+Ano;
	else if(tamanho == 1)	
		anoTotal = "200"+Ano;
	else if(tamanho == 0)
		anoTotal = (new Date()).getYear();
	else
		anoTotal = Ano;
	
	return anoTotal;
}
//--------------------------------------------------------------------------------//
function ENumero(caractere){
	if((caractere >= '0') && (caractere <= '9')){
		return true;
	}else 
		return false;
}
//----------------------------------------------------------------------------------//
//Função que verifica se o ultimo caractere é '%' e o substitui pelo digito verificador
function CompletaDigito(Processo){
	var i, novoProcesso = '',digito = '';
	
	if(Processo.charAt(Processo.length-1) == '%'){
		if(Processo.length == 10){				
			digito = calcula_digito1(Processo);	
		}
		if(Processo.length == 15){
			digito = calcula_digito2(Processo);	
		}

		for(i=0;i<Processo.length-1;i++){
			novoProcesso = novoProcesso + Processo.charAt(i);
		}		
		novoProcesso = novoProcesso + digito;
	}else
		novoProcesso = Processo;
	return novoProcesso;
}
//--------------------------------------------------------------------------------//
//Função que monta o processo. Traduzido da função em ASP de consulta processual
function montar_processo(NumProc, opcao){

	var nParteAtual = 1
	var nParteAsterisco = 0
	var Parte1 = '';
	var Parte2 = ''; 
	var Parte3 = '';
	var Parte4 = '';
	var SecaoDef = '80';
	var LocalidadeDef;
	var Pos, caractere, Processo, Secao, Localidade;
	
	if(opcao == 'jfc')
		LocalidadeDef = '00';
	else if(opcao == 'jef')
		LocalidadeDef = '13';
		else if (opcao == 'tur')
		     LocalidadeDef = '14';
		
	var Tam = NumProc.length;
	for (Pos = 0; Pos <= Tam-1; Pos++){	
		caractere =  NumProc.substr(Tam-Pos-1,1);
		if ((ENumero(caractere)) || (caractere == '-')){
			if (ENumero(caractere)){
				if (nParteAtual == 1){
					Parte1 = caractere+Parte1;
				} else if(nParteAtual == 2){
					Parte2 = caractere+Parte2;
				} else if(nParteAtual == 3){
					Parte3 = caractere+Parte3;
				}else if(nParteAtual == 4){
					Parte4 = caractere+Parte4;
				}
			}
		} else if ((caractere == '.') || (caractere == '*')){
			if (caractere == '*'){
				if(Pos == 0){
					Parte1 = '%';
					nParteAtual = nParteAtual - 1;
				} else{
					nParteAtual = nParteAtual + 1;			
					nParteAsterisco = nParteAtual;
				}
			}
			nParteAtual = nParteAtual + 1;
		}
	}

	//NUMERO ANTIGO: no caso 95.987 é formato antigo.
	if ((nParteAsterisco == 0) && (nParteAtual == 2) && (Parte2.length == 2)){
		Processo = Parte2+ZerosAEsquerda(Parte1,8);
	//NUMERO NOVO
	} else {
		//Excessao: no caso 03*987 o asterisco devia pular mais um, e 03 é o ano.
		if((nParteAsterisco == 2) && (nParteAtual == 3)){
			Parte4 = Parte3;
			Parte3 = '';
		}

		NumProcesso = Parte1;
		Localidade = Parte2;
		Secao = Parte3;
		Ano = Parte4;

		if ((NumProcesso.length > 0) && (nParteAsterisco == 0) && (nParteAtual == 1) && ((Secao.length + Localidade.length + Ano.length) == 0))
			Processo = NumProcesso;
		else {
			if (Secao.length == 0)
				Secao = SecaoDef;

			if (Localidade.length == 0)
				Localidade = LocalidadeDef;

		   	Processo =  CompletaAno(Ano) + ZerosAEsquerda(Secao,2) + ZerosAEsquerda(Localidade,2) + ZerosAEsquerda(NumProcesso,7);
		}
	}

	Processo = CompletaDigito(Processo);
	return Processo;
}
/*
************************************************************************************************************************************************
                                             FINAL DAS FUNÇÕES PARA VALIDAÇÃO DE NÚMERO DE PROCESSO
************************************************************************************************************************************************
*/
/*
************************************************************************************************************************************************
// Funções auxiliares para validação e formatação de números de CPF e CNPJ
// por Fabiano A. Costa 
// Em: 09/06/2006
************************************************************************************************************************************************
*/
/**
 * PROTÓTIPOS:
 * método String.lpad(int pSize, char pCharPad)
 * método String.trim()
 *
 * String unformatNumber(String pNum)
 * String formatCpfCnpj(String pCpfCnpj, boolean pUseSepar, boolean pIsCnpj)
 * String dvCpfCnpj(String pEfetivo, boolean pIsCnpj)
 * boolean isCpf(String pCpf)
 * boolean isCnpj(String pCnpj)
 * boolean isCpfCnpj(String pCpfCnpj)
 */


var NUM_DIGITOS_CPF  = 11;
var NUM_DIGITOS_CNPJ = 14;
var NUM_DGT_CNPJ_BASE = 8;


/**
 * Adiciona método lpad() à classe String.
 * Preenche a String à esquerda com o caractere fornecido,
 * até que ela atinja o tamanho especificado.
 */
String.prototype.lpad = function(pSize, pCharPad)
{
	var str = this;
	var dif = pSize - str.length;
	var ch = String(pCharPad).charAt(0);
	for (; dif>0; dif--) str = ch + str;
	return (str);
} //String.lpad


/**
 * Adiciona método trim() à classe String.
 * Elimina brancos no início e fim da String.
 */
String.prototype.trim = function()
{
	return this.replace(/^\s*/, "").replace(/\s*$/, "");
} //String.trim


/**
 * Elimina caracteres de formatação e zeros à esquerda da string
 * de número fornecida.
 * @param String pNum
 *      String de número fornecida para ser desformatada.
 * @return String de número desformatada.
 */
function unformatNumber(pNum)
{
	return String(pNum).replace(/\D/g, "").replace(/^0+/, "");
} //unformatNumber


/**
 * Formata a string fornecida como CNPJ ou CPF, adicionando zeros
 * à esquerda se necessário e caracteres separadores, conforme solicitado.
 * @param String pCpfCnpj
 *      String fornecida para ser formatada.
 * @param boolean pUseSepar
 *      Indica se devem ser usados caracteres separadores (. - /).
 * @param boolean pIsCnpj
 *      Indica se a string fornecida é um CNPJ.
 *      Caso contrário, é CPF. Default = false (CPF).
 * @return String de CPF ou CNPJ devidamente formatada.
 */
function formatCpfCnpj(pCpfCnpj, pUseSepar, pIsCnpj)
{
	if (pIsCnpj==null) pIsCnpj = false;
	if (pUseSepar==null) pUseSepar = true;
	var maxDigitos = pIsCnpj? NUM_DIGITOS_CNPJ: NUM_DIGITOS_CPF;
	var numero = unformatNumber(pCpfCnpj);

	numero = numero.lpad(maxDigitos, '0');
	if (!pUseSepar) return numero;

	if (pIsCnpj)
	{
		reCnpj = /(\d{2})(\d{3})(\d{3})(\d{4})(\d{2})$/;
		numero = numero.replace(reCnpj, "$1.$2.$3/$4-$5");
	}
	else
	{
		reCpf  = /(\d{3})(\d{3})(\d{3})(\d{2})$/;
		numero = numero.replace(reCpf, "$1.$2.$3-$4");
	}
	return numero;
} //formatCpfCnpj


/**
 * Calcula os 2 dígitos verificadores para o número-efetivo pEfetivo de
 * CNPJ (12 dígitos) ou CPF (9 dígitos) fornecido. pIsCnpj é booleano e
 * informa se o número-efetivo fornecido é CNPJ (default = false).
 * @param String pEfetivo
 *      String do número-efetivo (SEM dígitos verificadores) de CNPJ ou CPF.
 * @param boolean pIsCnpj
 *      Indica se a string fornecida é de um CNPJ.
 *      Caso contrário, é CPF. Default = false (CPF).
 * @return String com os dois dígitos verificadores.
 */
function dvCpfCnpj(pEfetivo, pIsCnpj)
{
	if (pIsCnpj==null) pIsCnpj = false;
	var i, j, k, soma, dv;
	var cicloPeso = pIsCnpj? NUM_DGT_CNPJ_BASE: NUM_DIGITOS_CPF;
	var maxDigitos = pIsCnpj? NUM_DIGITOS_CNPJ: NUM_DIGITOS_CPF;
	var calculado = formatCpfCnpj(pEfetivo, false, pIsCnpj);
	calculado = calculado.substring(2, maxDigitos);
	var result = "";

	for (j = 1; j <= 2; j++)
	{
		k = 2;
		soma = 0;
		for (i = calculado.length-1; i >= 0; i--)
		{
			soma += (calculado.charAt(i) - '0') * k;
			k = (k-1) % cicloPeso + 2;
		}
		dv = 11 - soma % 11;
		if (dv > 9) dv = 0;
		calculado += dv;
		result += dv
	}

	return result;
} //dvCpfCnpj


/**
 * Testa se a String pCpf fornecida é um CPF válido.
 * Qualquer formatação que não seja algarismos é desconsiderada.
 * @param String pCpf
 *      String fornecida para ser testada.
 * @return <code>true</code> se a String fornecida for um CPF válido.
 */
function isCpf(pCpf)
{
	var numero = formatCpfCnpj(pCpf, false, false);
	var base = numero.substring(0, numero.length - 2);
	var digitos = dvCpfCnpj(base, false);
	var algUnico, i;

	// Valida dígitos verificadores
	if (numero != base + digitos) return false;

	/* Não serão considerados válidos os seguintes CPF:
	 * 000.000.000-00, 111.111.111-11, 222.222.222-22, 333.333.333-33, 444.444.444-44,
	 * 555.555.555-55, 666.666.666-66, 777.777.777-77, 888.888.888-88, 999.999.999-99.
	 */
	algUnico = true;
	for (i=1; i<NUM_DIGITOS_CPF; i++)
	{
		algUnico = algUnico && (numero.charAt(i-1) == numero.charAt(i));
	}
	if (algUnico)
	{
	  return false; 
	}
	else
	{
		return true;
	}
} //isCpf


/**
 * Testa se a String pCnpj fornecida é um CNPJ válido.
 * Qualquer formatação que não seja algarismos é desconsiderada.
 * @param String pCnpj
 *      String fornecida para ser testada.
 * @return <code>true</code> se a String fornecida for um CNPJ válido.
 */
function isCnpj(pCnpj)
{
	var numero = formatCpfCnpj(pCnpj, false, true);
	var base = numero.substring(0, NUM_DGT_CNPJ_BASE);
	var ordem = numero.substring(NUM_DGT_CNPJ_BASE, 12);
	var digitos = dvCpfCnpj(base + ordem, true);
	var algUnico;

	// Valida dígitos verificadores
	if (numero != base + ordem + digitos) return false;

	/* Não serão considerados válidos os CNPJ com os seguintes números BÁSICOS:
	 * 11.111.111, 22.222.222, 33.333.333, 44.444.444, 55.555.555,
	 * 66.666.666, 77.777.777, 88.888.888, 99.999.999.
	 */
	algUnico = numero.charAt(0) != '0';
	for (i=1; i<NUM_DGT_CNPJ_BASE; i++)
	{
		algUnico = algUnico && (numero.charAt(i-1) == numero.charAt(i));
	}
	if (algUnico) return false;

	/* Não será considerado válido CNPJ com número de ORDEM igual a 0000.
	 * Não será considerado válido CNPJ com número de ORDEM maior do que 0300
	 * e com as três primeiras posições do número BÁSICO com 000 (zeros).
	 * Esta crítica não será feita quando o no BÁSICO do CNPJ for igual a 00.000.000.
	 */
	if (ordem == "0000") return false;
	return (base == "00000000"
		|| parseInt(ordem, 10) <= 300 || base.substring(0, 3) != "000");
} //isCnpj


/**
 * Testa se a String pCpfCnpj fornecida é um CPF ou CNPJ válido.
 * Se a String tiver uma quantidade de dígitos igual ou inferior
 * a 11, valida como CPF. Se for maior que 11, valida como CNPJ.
 * Qualquer formatação que não seja algarismos é desconsiderada.
 * @param String pCpfCnpj
 *      String fornecida para ser testada.
 * @return <code>true</code> se a String fornecida for um CPF ou CNPJ válido.
 */
function isCpfCnpj(pCpfCnpj)
{
	var numero = pCpfCnpj.replace(/\D/g, "");
	if (numero.length > NUM_DIGITOS_CPF)
		return isCnpj(pCpfCnpj)
	else
		return isCpf(pCpfCnpj);
} //isCpfCnpj
/*
************************************************************************************************************************************************
                                             FINAL DAS FUNÇÕES PARA VALIDAÇÃO CPF E CNPJ
************************************************************************************************************************************************
*/

/*====================================================================
Function: Err
Purpose:  Custom object constructor
Inputs:   None
Returns:  undefined
====================================================================*/
function Err(){
	/*********************************************************************
	Method:   Err.clear
	Purpose:  Clear values from Error object
	Inputs:   none
	Returns:  undefined
	*********************************************************************/
	this.clear=function (){
		this.source=new Object;
		this.type=new Object;
		this.format=new String;
	}
	/*********************************************************************
	Method:   Err.add
	Purpose:  Adds error to Error object
	Inputs:   oSource - source element object
	          vType   - integer value of error type (or custom string)
	          sFormat - optional date format
	Returns:  undefined
	*********************************************************************/
	this.add=function (oSource,vType,sFormat){
		this.source=oSource;
		this.type=vType;
		this.format=sFormat;
	}
	/*********************************************************************
	Method:   Err.raise
	Purpose:  Gives visual warning to user about all errors contained in
	          the Error object
	Inputs:   none
	Returns:  undefined
	*********************************************************************/
	this.raise=function (){
		var oElement=this.source;
		var sLang;
		var sNym=oElement.getAttribute("nym");
		// if type is not a number, it must be a custom error message
		var sMsg=(typeof this.type=="string")?this.type:oElement.getAttribute("msg");

		oElement.paint();
		if(oElement.select)
			oElement.select();
		if(sMsg)
			alert(sMsg);
		else{
			// Walk through object hierarchy to find applicable language
			var oParent=oElement;
			sLang=oParent.getAttribute("lang").substring(0,2).toLowerCase();
			while(!sLang || !_validation.messages[sLang]){
				oParent=oParent.parentElement;
				if(oParent)
					sLang=oParent.getAttribute("lang").substring(0,2).toLowerCase();
				else
					// Default language is English
					sLang="en";
			}
			sMsg=_validation.messages[sLang][this.type];
			alert(((sNym)?sNym+": ":"")+sMsg+((this.format)
				?" "+this.format.reformat(sLang,this.type):""));
		}

		// Perform onvalidatefocus event handler for invalid field
		if(oElement.onvalidatefocus)
			oElement.onvalidatefocus();

		// Give invalid field focus
		oElement.focus();
		// Clear the Err object
		this.clear();
	}

	// Define the working object model
	this.clear();
}

/*====================================================================
Function: Validation
Purpose:  Custom object constructor.
Inputs:   None
Returns:  undefined
====================================================================*/
function Validation(){
	// Define global constants for calls to error message arrays
	this.REQUIRED = 0;
	this.INTEGER  = 1;
	this.FLOAT    = 2;
	this.DATE     = 3;
	this.AMOUNT   = 4;
	this.MASK     = 5;
	this.NUMPROCESSO = 6;   // Adicionado por Fabiano em 25/05/2006
	this.CPF      	= 7; // Adicionado por Fabiano em 09/06/2006
	this.CNPJ     	= 8; // Adicionado por Fabiano em 09/06/2006
	this.CAPCHA		= 9; // Adicionado por Fabiano em 26/07/2006

	// Create error message dictionary
	this.messages = new Array;

	// Prototype the date tokens for each language
	Array.prototype.MM = new String;
	Array.prototype.DD = new String;
	Array.prototype.YYYY = new String;

	//English
	this.messages["en"]=new Array(
		"Please enter a value",
		"Please enter a valid integer",
		"Please enter a valid floating point",
		"Please enter a valid date",
		"Please enter a valid monetary amount",
		"Please enter a value in the form of ",
	    "Please enter a valid process number",  // Adicionado por Fabiano em 25/05/2006
	    "Please enter a valid cpf number",  // Adicionado por Fabiano em 09/06/2006
		"Please enter a valid cnpj number",  // Adicionado por Fabiano em 09/06/2006
		"Please enter the correct sequence"); // Adicionado por Fabiano em 26/07/2006

		with(this.messages["en"]){
			MM="MM";
			DD="DD";
			YYYY="YYYY";
		}

	//Portuguese
	this.messages["pt"]=new Array(
		"Campo de preenchimento obrigatório",
		"Por favor digite um valor numérico inteiro",
		"Por favor digite o valor ponto flutuante",
		"Por favor digite uma data válida",
		"Por favor digite o valor monetário",
		"Por favor digite um valor no formulario ",
		"Por favor digite um número de processo válido",   // Adicionado por Fabiano em 25/05/2006
	    "Por favor digite um número de CPF válido",  // Adicionado por Fabiano em 09/06/2006
		"Por favor digite um número de CNPJ válido",  // Adicionado por Fabiano em 09/06/2006	
		"Por favor digite o valor correto da sequência"); // Adicionado por Fabiano em 26/07/2006
		with(this.messages["pt"]){
			MM="MM";
			DD="DD";
			YYYY="AAAA";
		}

	//French
	this.messages["fr"]=new Array(
		"Entrer une valeur, SVP",
		"Entrer un entier correct, SVP",
		"Entrer un point flottant correct, SVP",
		"Entrer une date correcte, SVP",
		"Entrer une valeur monetaire correcte, SVP",
		"Entrer, SVP, une valeur suivant le format suivant: ",
	    "Entrer, un process number correct, SVP",   // Adicionado por Fabiano em 25/05/2006
	    "Please enter a valid cpf number",  // Adicionado por Fabiano em 09/06/2006
		"Please enter a valid cnpj number",  // Adicionado por Fabiano em 09/06/2006
		"Please enter the correct sequence"); // Adicionado por Fabiano em 26/07/2006
		with(this.messages["fr"]){
			MM="MM";
			DD="JJ";
			YYYY="AAAA";
		}

	//German
	this.messages["de"]=new Array(
		"Tragen Sie bitte einen Wert ein",
		"Tragen Sie bitte eine gültige Ganze Zahl ein",
		"Tragen Sie bitte ein Fließkomma ein",
		"Tragen Sie bitte ein gültiges Datum ein",
		"Tragen Sie bitte eine gültigen Geldbetrag ein",
		"Tragen Sie bitte einen Wert ein in Form von ",
	    "Please enter a valid process number",  // Adicionado por Fabiano em 25/05/2006
	    "Please enter a valid cpf number",  // Adicionado por Fabiano em 09/06/2006
		"Please enter a valid cnpj number",  // Adicionado por Fabiano em 09/06/2006
		"Please enter the correct sequence"); // Adicionado por Fabiano em 26/07/2006
		with(this.messages["de"]){
			MM="MM";
			DD="TT";
			YYYY="JJJJ";
		}

	//Italian
	this.messages["it"]=new Array(
		"Si prega di inserire un valore",
		"Si prega di inserire un valido numero intero",
		"Si prega di inserire un valido numero in virgola mobile",
		"Si prega di inserire una data valida",
		"Si prega di inserire una quantitá di valuta valida",
		"Si prega di inserire un valore nel formato ",
        "Please enter a valid process number",  // Adicionado por Fabiano em 25/05/2006
	    "Please enter a valid cpf number",  // Adicionado por Fabiano em 09/06/2006
		"Please enter a valid cnpj number",  // Adicionado por Fabiano em 09/06/2006
		"Please enter the correct sequence"); // Adicionado por Fabiano em 26/07/2006
		with(this.messages["it"]){
			MM="MM";
			DD="GG";
			YYYY="AAAA";
		}

	//Spanish
	this.messages["es"]=new Array(
		"Por favor introduzca un valor",
		"Por favor introduzca un numero entero válido",
		"Por favor introduzca un punto flotante válido",
		"Por favor introduzca una fecha válida",
		"Por favor introduzca una cantidad monetaria válida",
		"Por favor introduzca un valor con el siguiente formato ",
	    "Please enter a valid process number",  // Adicionado por Fabiano em 25/05/2006
	    "Please enter a valid cpf number",  // Adicionado por Fabiano em 09/06/2006
		"Please enter a valid cnpj number",  // Adicionado por Fabiano em 09/06/2006
		"Please enter the correct sequence"); // Adicionado por Fabiano em 26/07/2006
		with(this.messages["es"]){
			MM="MM";
			DD="DD";
			YYYY="AAAA";
		}

	//Dutch
	this.messages["nl"]=new Array(
		"Vul s.v.p. een waarde in",
		"Vul s.v.p. een geldig geheel getal in",
		"Vul s.v.p. een geldig zwevend decimaal teken in",
		"Vul s.v.p. een geldige datum in",
		"Vul s.v.p. een geldig geldbedrag in",
		"Vul s.v.p. een waarde in, in de vorm van ",
	    "Please enter a valid process number",  // Adicionado por Fabiano em 25/05/2006
	    "Please enter a valid cpf number",  // Adicionado por Fabiano em 09/06/2006
		"Please enter a valid cnpj number",  // Adicionado por Fabiano em 09/06/2006
		"Please enter the correct sequence"); // Adicionado por Fabiano em 26/07/2006
		with(this.messages["nl"]){
			MM="MM";
			DD="DD";
			YYYY="JJJJ";
		}

	//Swedish
	this.messages["sv"]=new Array(
		"Var vänlig fyll i ett värde",
		"Var vänlig fyll i ett giltigt heltal",
		"Var vänlig fyll i ett giltigt tal",
		"Var vänlig fyll i ett giltigt datum",
		"Var vänlig fyll i ett giltigt belopp",
		"Var vänlig fyll i ett värde på formen ",
		"Please enter a valid process number",  // Adicionado por Fabiano em 25/05/2006
	    "Please enter a valid cpf number",  // Adicionado por Fabiano em 09/06/2006
		"Please enter a valid cnpj number",  // Adicionado por Fabiano em 09/06/2006
		"Please enter the correct sequence"); // Adicionado por Fabiano em 26/07/2006
		with(this.messages["sv"]){
			MM="MM";
			DD="DD";
			YYYY="ÅÅÅÅ";
		}

	/*********************************************************************
	Method:   Validation.setDefault
	Purpose:  Set value for variable v if v is zero, empty string or
	          undefined
	Inputs:   v - variable (passed by value)
	          d - default value
	Returns:  v or d
	*********************************************************************/
	this.setDefault=function (v, d){
		return (v)?v:d;
	}
	/*********************************************************************
	Method:   Validation.isDate
	Purpose:  Check that value is a date of the correct format
	Inputs:   oElement - form element
	          sFormat  - string format
	Returns:  boolean
	*********************************************************************/
	this.isDate=function (oElement,sFormat){
		var sDate=oElement.value;
		var aDaysInMonth=new Array(31,28,31,30,31,30,31,31,30,31,30,31);

		// Fetch the date separator from the user's input
		var sSepDate=sDate.charAt(sDate.search(/\D/));
		// Fetch the date separator from the format
		var sSepFormat=sFormat.charAt(sFormat.search(/[^MDY]/i));
		// Compare separators
		if (sSepDate!=sSepFormat)
			return false;

		// Fetch the three pieces of the date from the user's input and the format
		var aValueMDY=sDate.split(sSepDate);
		var aFormatMDY=sFormat.split(sSepFormat);
		var iMonth,iDay,iYear;

		// Validate that all pieces of the date are numbers
		if (  !_validation.isNum(aValueMDY[0])
			||!_validation.isNum(aValueMDY[1])
			||!_validation.isNum(aValueMDY[2]))
			return false;

		// Assign day, month, year based on format
		switch (aFormatMDY[0].toUpperCase()){
			case "YYYY" :
				iYear=aValueMDY[0];
				break;
			case "DD" :
				iDay=aValueMDY[0];
				break;
			case "MM" :
				iMonth=aValueMDY[0];
				break;
			default :
				return false;
		}
		switch (aFormatMDY[1].toUpperCase()){
			case "YYYY" :
				iYear=aValueMDY[1];
				break;
			case "MM" :
				iMonth=aValueMDY[1];
				break;
			case "DD" :
				iDay=aValueMDY[1];
				break;
			default :
				return false;
		}
		switch(aFormatMDY[2].toUpperCase()){
			case "MM" :
				iMonth=aValueMDY[2];
				break;
			case "DD" :
				iDay=aValueMDY[2];
				break;
			case "YYYY" :
				iYear=aValueMDY[2];
				break;
			default :
				return false;
		}

		// Require 4 digit year
		if(oElement.form.getAttribute("year4")!=null && iYear.length!=4)
			return false;
		// Process pivot date and update field
		var iPivot=_validation.setDefault(oElement.getAttribute("pivot"),
			oElement.form.getAttribute("pivot"));
		if(iPivot && iPivot.length==2 && iYear.length==2){
			iYear=((iYear>iPivot)?19:20).toString()+iYear;
			var sValue=aFormatMDY.join(sSepFormat).replace(/MM/i,iMonth);
			sValue=sValue.replace(/DD/i,iDay).replace(/YYYY/i,iYear);
			oElement.value=sValue;
		}

		// Check for leap year
		var iDaysInMonth=(iMonth!=2)?aDaysInMonth[iMonth-1]:
			((iYear%4==0 && iYear%100!=0 || iYear % 400==0)?29:28);

		return (iDay!=null && iMonth!=null && iYear!=null
				&& iMonth<13 && iMonth>0 && iDay>0 && iDay<=iDaysInMonth);
	}
	/********************************************
	Method:   Validation.isNum
	Purpose:  Check that parameter is a number
	Inputs:   v - string value
	Returns:  boolean
	********************************************/
	this.isNum=function (v){
		return (typeof v!="undefined" && v.toString() && !/\D/.test(v));
	}
	/*********************************************************************
	Method:   Validation.setup
	Purpose:  Set up methods and event handlers for all forms and elements
	Inputs:   none
	Returns:  undefined
	*********************************************************************/
	this.setup=function (){
		// Fan through forms on page to perform initializations
		var i,iForms=document.forms.length;
		for(i=0; i<iForms; i++){
			var oForm=document.forms[i];
			if(!oForm.bProcessed){
				/*********************************************
				Method:   Form.markRequired
				Purpose:  Mark all required fields for a form
				Inputs:   none
				Returns:  undefined
				*********************************************/
				oForm.markRequired=function (){
					var i, iElements=this.elements.length;
					var sMarkHTML, sMarkWhere;
					for(i=0; i<iElements; i++){
						var oElement=this.elements[i];
						// Perform onmark event handler
						if(oElement.onmark && oElement.onmark()==false)
							continue;
						if(oElement.getAttribute("required")!=null){
							sMarkHTML=this.getAttribute("insert");
							sMarkWhere=this.getAttribute("mark");
							if(sMarkHTML){
								switch(sMarkWhere.toLowerCase()){
									case "before" :
										sMarkWhere="beforeBegin";
										break;
									default :
										sMarkWhere="afterEnd";
								}
								oElement.insertAdjacentHTML(sMarkWhere,sMarkHTML);
							}else{
								var sClassName=oElement.className;
								if(sClassName!="required"){
									oElement.setAttribute("nonreqClass",oElement.className);
									oElement.className="required";
								}else{
									oElement.className=_validation.setDefault(oElement.getAttribute("nonreqClass"),oElement.className);
									oElement.removeAttribute("nonreqClass");
								}
							}
						}
					}
				}
				var sValidateWhen=oForm.getAttribute("validate");
				if (sValidateWhen!=null){
					//
					// Capture and replace onreset and onsubmit event handlers
					//
					oForm.fSubmit=oForm.onsubmit;
					oForm.fReset=oForm.onreset;

					// Create new event handlers
					oForm.onsubmit=function (){
						var i, oElement, iElements=this.elements.length;
						// Restore all elements to original style
						for (i=0; i<iElements; i++)
							this.elements[i].restore();
						// Validate individual elements
						for(i=0;i<iElements;i++){
							oElement=this.elements[i];
							// Perform default validation for element
							if (!oElement.valid()){
								_err.raise();
								event.returnValue=false;
								return;
							}
						}

						// Perform original onsubmit event handler
						if (this.fSubmit && this.fSubmit()==false){
							event.returnValue=false;
							return;
						}

						// Insert default values just before submit
						var vDefault;
						for(i=0;i<iElements;i++){
							oElement=this.elements[i];
							vDefault=oElement.getAttribute("default");
							if(vDefault && !oElement.value)
								oElement.value=vDefault;
						}
					}
					oForm.onreset=function (){
						var i, iElements=this.elements.length;
						for (i=0; i<iElements; i++)
							this.elements[i].restore();
						// Perform original event handler if present
						if (this.fReset && this.fReset()==false)
								event.returnValue=false;
					}
				}
				oForm.bProcessed=true;
			}
			// Create Input methods
			var j, iElements=oForm.elements.length;
			for(j=0; j<iElements; j++){
				var oElement=oForm.elements[j];
				if(!oElement.bProcessed) {

					// All event handlers are presumed to be strings/functions
					// at parse-time and assigned only as functions at run-time.

					// Create custom onvalidate event handlers
					var vOnValidate=oElement.getAttribute("onvalidate");
					if(vOnValidate){
						if(typeof vOnValidate!="function")
							oElement.onvalidate=new Function(vOnValidate);
						else
							oElement.onvalidate=vOnValidate;
					}
					// Create custom handler for onvalidatefocus event
					var vOnValidateFocus=oElement.getAttribute("onvalidatefocus");
					if(vOnValidateFocus){
						if(typeof vOnValidateFocus!="function")
							oElement.onvalidatefocus=new Function(vOnValidateFocus);
						else
							oElement.onvalidatefocus=vOnValidateFocus;
					}
					// Custom onmark event handler
					var vOnMark=oElement.getAttribute("onmark");
					if(vOnMark){
						if(typeof vOnMark!="function")
							oElement.onmark=new Function(vOnMark);
						else
							oElement.onmark=vOnMark;
					}
					// Custom onkeypress filtering for text fields
					if(oElement.onkeypress)
						oElement.fKeypress=oElement.onkeypress;
					oElement.onkeypress=function (){
						if(this.fKeypress && this.fKeypress()==false)
							event.returnValue=false;
						var sFilter=this.getAttribute("filter");
						if(sFilter){
							var sKey=String.fromCharCode(event.keyCode);
							var re=new RegExp(sFilter);
							// Do not filter out ENTER!
							if(sKey!="\r" && !re.test(sKey))
								event.returnValue=false;
							event.keyCode=sKey.charCodeAt(0);
						}
					}
					// Custom onchange validation
					if(sValidateWhen=="onchange") {
						// Capture and replace onchange event handlers
						if(oElement.onchange)
							oElement.fChange=oElement.onchange;
						oElement.onchange=function (){
							this.restore();
							if(!this.valid()){
								_err.raise();
								event.returnValue=false;
							}
							if(this.fChange && this.fChange()==false){
								event.returnValue=false;
							}
						}
					}
					/***********************************
					Method:   Input.paint
					Purpose:  Change style of element
					Inputs:   none
					Returns:  undefined
					***********************************/
					oElement.paint=function(){
						var sColor = _validation.setDefault(
							this.getAttribute("invalidColor"),
							this.form.getAttribute("invalidColor") );
						if (!sColor){
							// Paint element by changing class
							this.setAttribute("oldClass", this.className);
							this.className = "invalid";
						}else{
							// Paint element by changing color directly
							this.setAttribute("bg", this.style.backgroundColor);
							this.style.backgroundColor = sColor;
						}
					}
					/********************************************
					Method:   Input.restore
					Purpose:  Restore element to original style
					Inputs:   none
					Returns:  undefined
					********************************************/
					oElement.restore=function () {
						var sBG=this.getAttribute("bg");
						if (sBG!=null) {
							// Revert to previous background color
							this.style.backgroundColor = sBG;
							this.removeAttribute("bg");
						}else{
							var sOldClass=this.getAttribute("oldClass");
							if (sOldClass!=null){
								// Revert to previous class
								this.className=sOldClass;
								this.removeAttribute("oldClass");
							}
						}
					}
					/**********************************************
					Method:   Input.valid
					Purpose:  Validate an element based on the
					          attributes provided in the HTML text
					Inputs:   none
					Returns:  boolean
					**********************************************/
					oElement.valid=function (){
						var sType=this.type;
						if(sType=="text" || sType=="textarea" || sType=="file"){
							// Trim leading and trailing spaces
							if(this.form.getAttribute("notrim")==null)
								this.value = this.value.trim();
							// Remove any Server Side Include text
							if(this.form.getAttribute("ssi")==null){
								while (this.value.search("<!-"+"-#") > -1)
									this.value = this.value.replace("<"+"!--#", "<"+"!--");
							}
						}
						// REQUIRED
						if(this.getAttribute("required")!=null && !this.value){
							_err.add(this, _validation.REQUIRED, null);
					 		return false;
						}
												// NUMPROCESSO - **************************************** ADICIONADO POR FABIANO EM 25/05/2006
						var sNumProcessoType=this.getAttribute("numprocesso");
						if(this.getAttribute("numprocesso")!=null && this.value){
							var num = montar_processo(retira_caracteres(this.value),sNumProcessoType);
							//Verifica se o número do processo é válido de acordo com o dígito verificador	
	                        var valido = verifica_digito_processo(num);
	                        //Se o número do processo for válido, formata o número
	                        if (valido) 
							{
		    		          this.value = formata_numero(num);
							} else
							{
		                      _err.add(this, _validation.NUMPROCESSO, null);
							  return false;
	                        }	
						}
						// CPF - *********************************************** ADICIONADO POR FABIANO EM 09/06/2006
						var bCPFformat=this.getAttribute("cpf"); 
						// Atribui um valor default para formataCPF
						bCPFformat=(bCPFformat=="formatar")?true:false;
						if(this.getAttribute("cpf")!=null && this.value){
							if (isCpf(this.value))
							{
								this.value = formatCpfCnpj(this.value, bCPFformat, false);
							}
							else
							{
								_err.add(this,_validation.CPF, null);
								return false;
							}
						}
						// CNPJ - ********************************************** ADICIONADO POR FABIANO EM 09/06/2006
					    var bCNPJformat=this.getAttribute("cnpj"); 
						// Atribui um valor default para formataCNPJ
						bCNPJformat=(bCNPJformat=="formatar")?true:false;
						if(this.getAttribute("cnpj")!=null && this.value){
							if (isCnpj(this.value))
							{
								this.value = formatCpfCnpj(this.value, bCNPJformat, true);
							}
							else
							{
								_err.add(this,_validation.CNPJ, null);
								return false;
							}
						}
						// CAPCHA - ******************************************* ADICIONADO POR FABIANO EM 26/07/2006
						var sCAPCHAsequencia=this.getAttribute("capcha"); 
						if(this.getAttribute("capcha")!=null && this.value){
							if ((this.value)!=sCAPCHAsequencia)
							{
								_err.add(this,_validation.CAPCHA, null);
								return false;
							}
						}
						// FLOAT
						var sFloatDelimiter=this.getAttribute("float");
						var bSigned=this.getAttribute("signed")!=null;
						if (sFloatDelimiter!=null && this.value){
							// Assign default value to delimiter
							sFloatDelimiter=(sFloatDelimiter==",")?",":"\\.";
							var re=new RegExp("^("+((bSigned)?"[\\-\\+]?":"")+"(\\d*"+sFloatDelimiter+"?\\d+)|(\\d+"+sFloatDelimiter+"?\\d*))$");
							if (!re.test(this.value)){
								_err.add(this, _validation.FLOAT, null);
								return false;
							}
						}
						// AMOUNT
						var sAmtDelimiter = this.getAttribute("amount");
						
						if (sAmtDelimiter!=null && this.value){
							// Assign default value to delimiter
							sAmtDelimiter=(sAmtDelimiter==",")?",":"\\.";
//							var re = new RegExp("^"+((bSigned)?"[\\-\\+]?":"")+"\\d+("+sAmtDelimiter+"\\d{2})?$");
//                          Modificado por Fabiano em 25/05/2006 para atender aos separadores de milhar
                            var re = new RegExp("^"+((bSigned)?"[\\-\\+]?":"")+"\\d{1,3}(\\.\\d{3})*("+sAmtDelimiter+"\\d{2}){1}$");
							if(!re.test(this.value)){
								_err.add(this, _validation.AMOUNT, null);
								return false;
							}
						}
						// INTEGER
						if (this.getAttribute("integer")!=null && this.value){
							var re=new RegExp("^"+((bSigned)?"[\\-\\+]?":"")+"\\d+$");
							if (!re.test(this.value)){
								_err.add(this, _validation.INTEGER, null);
								return false;
							}
						}
						// DATE
						var sFormat=this.getAttribute("date");
						if (sFormat!=null && this.value) {
							// Set default date format
							sFormat = _validation.setDefault(sFormat, "MM/DD/YYYY");
							if (!_validation.isDate(this,sFormat)){
								_err.add(this, _validation.DATE, sFormat.toUpperCase());
								return false;
							}
						}
						// MASK
						var sMask=this.getAttribute("mask");
						if(sMask && this.value){
							var sPattern=sMask.replace(
								/(\$|\^|\*|\(|\)|\+|\.|\?|\\|\{|\}|\||\[|\])/g,"\\$1");
							sPattern=sPattern.replace(/9/g ,"\\d");
							sPattern=sPattern.replace(/x/ig,".");
							sPattern=sPattern.replace(/z/ig,"\\d?");
							sPattern=sPattern.replace(/a/ig,"[A-Za-z]");
							var re=new RegExp("^"+sPattern+"$");
							if(!re.test(this.value)){
								_err.add(this, _validation.MASK, sMask);
								return false;
							}
						}
						// REGEXP
						var sRegexp=this.getAttribute("regexp");
						if(sRegexp && this.value){
							var re=new RegExp(sRegexp);
							if(!re.test(this.value)){
								_err.add(this, _validation.MASK, sRegexp);
								return false;
							}
						}
						// AND
						var sAnd=this.getAttribute("and");
						if(sAnd && this.value){
							var aAnd = sAnd.split(/,/);
							var i, iFields=aAnd.length;
							// Require each element in the list if this element is valued
							for(i=0; i<iFields; i++){
								var oNewElement=this.form.elements[aAnd[i]];
								if(oNewElement && oNewElement.value.trim()==""){
									_err.add(oNewElement, _validation.REQUIRED, null);
									return false;
								}
							}
						}
						// OR
						var sOr=this.getAttribute("or");
						if(sOr && this.value==""){
							var aOr=sOr.split(/,/);
							var i, iFields=aOr.length;
							var oNewElement, bAccum=false;
							for(i=0; i<iFields; i++){
								oNewElement=this.form.elements[aOr[i]];
								if(oNewElement)
									bAccum |= !!oNewElement.value.trim();
							}
							if(!bAccum){
								_err.add(this, _validation.REQUIRED, null);
								return false;
							}
						}
						// NOSPACE
						if (this.getAttribute("nospace")!=null)
							this.value=this.value.replace(/\s/g,"");
						// UPPERCASE
						if (this.getAttribute("uppercase")!=null)
							this.value=this.value.toUpperCase();
						// LOWERCASE
						if (this.getAttribute("lowercase")!=null)
							this.value=this.value.toLowerCase();
						// Perform onvalidate event handler
						if(this.onvalidate && this.onvalidate()==false)
							return false;

						return true;
					}
					oElement.bProcessed=true;
				}
			}
		}
	}
	// Limit use of script to valid environments
	if("".replace && document.body && document.body.getAttribute){
		/*********************************************************************
		Method:   String.trim
		Purpose:  Removing leading and trailing spaces
		Inputs:   none
		Returns:  string
		*********************************************************************/
		String.prototype.trim=function (){
			return this.replace(/^\s+|\s+$/g,"");
		}
		/*********************************************************************
		Method:   String.reformat
		Purpose:  Translate the date format into the correct language
		Inputs:   sLang - language of error message to display
		          iType - type of failed validation
		Returns:  string
		*********************************************************************/
		String.prototype.reformat=function (sLang,iType){
			var sString=this.valueOf();
			if (iType==_validation.DATE && _validation.messages[sLang]) {
				sString=sString.replace(/MM/,_validation.messages[sLang].MM);
				sString=sString.replace(/DD/,_validation.messages[sLang].DD);
				sString=sString.replace(/YYYY/,_validation.messages[sLang].YYYY);
			}
			return sString;
		}
		// Form setup
		if(document.forms){
			// Process forms and elements
			this.setup();

			var i, iForms=document.forms.length;
			for(i=0; i<iForms; i++){
				var oForm=document.forms[i];
				if(oForm.getAttribute("mark")!=null)
					oForm.markRequired();
			}
		}
	}
}
_validation=new Validation;
_err=new Err;

