﻿ //Redimensiona a div "conteudo"
function ResizeDivConteudo()
{
	//Altura da viewport sem o topo
	var alt_viewport = $(window).height() - $("#topo").height();
	
	//Define a altura do conteudo de acordo com a viewport
	$("#conteudo").css("height", alt_viewport);

}

//Define a altura da div "conteudo" quando a página é carregada ou redimensionada
window.onload = window.onresize = function()
{
	//ResizeDivConteudo();
}

function ValidarPagina(validationGroup)
{
    for (i=0; i<Page_Validators.length; i++) 
    {
        if (Page_Validators[i].validationGroup == validationGroup) 
        {
            ValidatorValidate(Page_Validators[i]);
        }
    }
}


/**** MANIPULATE ELEMENTS FUNCTIONS ****/

function getEvent(event) {
    /// <summary>
    /// Retorna o evento disparador. X-browser compliance.
    /// DEPRICATED -> Usuar funções do namespace de cada app.
    /// </summary>
	var e = (!event) ? window.event : event;
	return e;
}

function getEventKey(event) {
    /// <summary>
    /// Retorna o keycode/charcode da tecla digitada no evento. X-browser compliance.
    /// DEPRICATED -> Usuar funções do namespace de cada app.
    /// </summary>
	var e = getEvent(event);
	var keycode = (e.keyCode) ? e.keyCode : e.which;
	return keycode;
}

function getEventTarget(event) {
    /// <summary>
    /// Retorna o elemento que iniciou o evento. X-browser compliance.
    /// DEPRICATED -> Usuar funções do namespace de cada app.
    /// </summary>
    var e = getEvent(event);
    var t = (e.target) ? e.target : e.srcElement;
	if (t.nodeType == 3) {
	    // Safari bug
		t = t.parentNode;
    }
    return t;
}

function searchInvalidValidator(element, validationGroup) {
    /// <summary>
    /// Método que procura o primeiro validador inválido da página e set o focus para o controle validado.
    /// DEPRICATED -> Usuar funções do namespace de cada app.
    /// </summary>
    if (!element.isDisabled) {  
        ValidarPagina(validationGroup);
        for (i=0; i<Page_Validators.length; i++) {
            if (!Page_Validators[i].isvalid) {
                document.getElementById(Page_Validators[i].controltovalidate).focus(); 
                return false;
            }
        }
        return true;
    } else {
        return false;
    }
}


/**** MANIPULATE DOM ELEMENTS FUNCTIONS ****/

function setElementText(element, text) {
    /// <summary>
    /// atualiza o texto de um element DOM (ex: label)
    /// DEPRICATED -> Usuar funções do namespace de cada app.
    /// </summary>
    var olabel;
    if (typeof element == "string") { 
        olabel = $get(element);    
    } else { olabel = element; }
    if (!olabel) { alert("[ "+element+" ] NÃO ENCONTRADO!!"); }
    // remove o texto antigo
    if (olabel) {
        if (olabel.childNodes[0]) {
            olabel.removeChild(olabel.childNodes[0]);
        }
        var newtext = document.createTextNode(text);
        olabel.appendChild(newtext);
    } 
}

function getElementText(element) {
    /// <summary>
    /// retorna o texto de um element DOM (ex: label)
    /// TODO: criar recursividade com filhos (nodetype == 1)
    /// DEPRICATED -> Usuar funções do namespace de cada app.
    /// </summary>
    var olabel;
    var text;
    if (typeof element == "string") { 
        olabel = $get(element);    
    } else { olabel = element; }
    if (!olabel) { 
        alert("FUNCTION setElementText() PARAM element[ "+element+" ] não encontrado!");
        return;
    } else {
        for (var i = 0; i < olabel.childNodes.length; i++) {
            if (olabel.childNodes[i].nodeType == 3) {
                text = olabel.childNodes[i].nodeValue;
                break;
            }
        }
        return text;
    }
}

function setMensagemAviso(msg, type){
    /// <summary>
    /// atualiza o texto de um element DOM (ex: label)
    /// type: warning = darkblue | error = red
    /// DEPRICATED -> Usuar funções do namespace de cada app.
    /// </summary>
    var label = $get('ctl00_lblAviso');
    var color = 'black';
    if (type == 'warning') {
        color = 'darkblue';        
    } else if (type == 'error') {
        color = 'red';
    }
    if (label) {
        // remove outras msgs
        if (label && label.childNodes[0]) { label.removeChild(label.childNodes[0]); }
        
        if (msg.length > 0) {
            var style = label.getAttribute("style");
            if (!style) {
                label.setAttribute("style", "color: "+color);
            } else {
                style.color = color;
            }
            var newbold = document.createElement("b");
            var newtext = document.createTextNode(msg);
            
            newbold.appendChild(newtext);
            label.appendChild(newbold);
        }
    } else {
        alert("element[ ctl00_lblAviso ] não encontrado!");
    }
}

function stringToNumber(string) {
    /// <summary>
    /// Remove letras e caracteres, remove '.', troca ',' por '.' para casas decimais.
    /// DEPRICATED -> Usuar funções do namespace de cada app.
    /// </summary>
    var i = 0;
    var negativo = false;
    while (string.charAt(i) == ' ') {
        i++;
    }
    if (string.charAt(i) == '-') {
        negativo = true;
    }
    var temp = string.replace(/\./g, '');
    temp = temp.replace(/,/g, '.');
    temp = temp.replace(/[^0-9.]/g, '');
    if (negativo) {
        return -(+temp);    
    } else {
        return (+temp);
    }
}


function maskNumber(val, mask) {
    /// <summary>
    /// R$ ###.###.###.##0,00
    /// #-##.#-##.#-##.##000
    /// 12
    /// 12.3
    /// 12.33
    /// 12.33555678
    /// DEPRICATED -> Usuar funções do namespace de cada app.
    /// </summary>
    var prefix;
    var rad;
    var sufix;
    var negative = false;
    if (val < 0) {
        negative = true;
    }
    if (typeof val == 'number') {
        val = String(val);
        val = val.replace(/\./g, ',');
        prefix = mask.substring(0, mask.indexOf('#'));
        sufix = mask.substring(mask.lastIndexOf('#')+1, mask.length);
        mask = mask.substring(mask.indexOf('#'), mask.length);
        //mask = mask.substring(mask.indexOf('#'), mask.lastIndexOf('#')+1);
        // normaliza o value caso haja 
        if (sufix) {
            if (sufix.indexOf(',') > -1) {
                ts = sufix.split(',');
                tv = val.split(',');
                // ambos possuem decimal
                if (ts.length == tv.length) {
                    // decimal do sufixo maior q decimal do valor
                    if (tv[1].length < ts[1].length) {
                        for (var i = 0; i < ts[1].length; i++) {
                            if (tv[1].charAt(i) == '') {
                                tv[1] += ts[i].charAt(i);
                            }
                        }
                    // remove caracteres qndo o decimal do valor é maior q o decimal do sufixo
                    } else if (tv[1].length > ts[1].length) { 
                        val = val.substring(0, val.length-(tv[1].length-ts[1].length));
                    }
                // adiciona o decima do sufixo ao valor
                } else if (tv.length < ts.length) {
                    val += ","+ts[1];
                }
            }
        } 
        var im = 0;
        if (val.length - sufix.length > 0) {
            for (var j = val.length - sufix.length - 1; j > -1; j--) {
                if (val.charAt(j) != '') {
                    if (mask.charAt(mask.length - sufix.length - 1 - im) != '#') {
                        val = val.substring(0, j + 1) + mask.charAt(mask.length - sufix.length - 1 - im) + val.substring(j + 1, val.length);
                    }
                }
                im++;
            }
        }
    }
    if (typeof val == 'string') {
        if (negative) {
            return "( " + prefix + val + " )";
        } else {
            return prefix + val;
        }
    } else {
        return null;
    }
}


function pageLoad(sender, args){
    /// <summary>
    /// DOTNET infra
    /// executa apos carregar a tela (DOM READY)
    /// </summary>

    // checa versao do flash player para definicao do conteudo
    // do progress template
    if (typeof swfobject != 'undefined')
    {
        swfobject.embedSWF( "swf/progress_template.swf" , "progress_img_container", "210", "230", "5.0.0", false, false, {wmode:"transparent"});
    }
    
    // seta classe css FOCUS no event focus dos elementos
    //$(":input:not(:hidden):not(:image)").bind("focus", function () {
    //    Sys.UI.DomElement.addCssClass(this, 'focus');
    //});
    // remove classe css FOCUS no event blur dos elementos
    //$(":input:not(:hidden):not(:image)").bind("blur", function () {
    //    Sys.UI.DomElement.removeCssClass(this, 'focus');
    //});
    
    // guarda o ultimo campo que obteve foco
    //$(":input:not(:hidden):not(:image)").bind("blur", wfp.form.setLastFocus);

    // caso haja o plugin SCROLLTO do JQUERY traz campo em foco para o topo da pagina
    //$(":input:not(:hidden):not(:image)").bind("focus", function () {
    //    if ($.scrollTo) { $("#conteudo").scrollTo(this, 250, { offset:-50, axis:'y', easing:'linear' }); }   
    //});

    // tratamento ENTER BACKSPACE
    //document.onkeydown = wfp.keyboard.disableKeys; // IE, Firefox, Safari
    //document.onkeypress = wfp.keyboard.disableKeys; // only Opera needs the backspace nullifying in onkeypress
       
    // atalhos de teclado
    //$("#conteudo").bind("keydown", wfp.keyboard.shortcuts);
   
    // vincula a navegação de teclado ao keydown
    //$(":input:not(:hidden):not(:image)").bind("keydown", wfp.form.nav);
}


/**** SINDEMPREGOS SINGLETON OBJ ****/

var se = {};

se.enter = {
    isExcessao : function (e) {
        var is = false;
        var list = se.enter._excessoes;
        for(var property in list) {
            if (list[property] == e.id) { is = true; }
        }
        return is;
    }
};

se.enter._excessoes = {
    // pesquisa bne
    salarioInicial : 'ctl00_conteudo_txtSalarioInicial_txtValor',  
    salarioFinal : 'ctl00_conteudo_txtSalarioFinal_txtValor', 
    experiencia : 'ctl00_conteudo_txtExperiencia_txtValor',
    idadeMinima : 'ctl00_conteudo_txtIdadeMinima_txtValor',
    idadeMaxima : 'ctl00_conteudo_txtIdadeMaxima_txtValor',
    bairro : 'ctl00_conteudo_txtBairro',
    empresa : 'ctl00_conteudo_txtEmpresa',
    ramo : 'ctl00_conteudo_txtRamo',
    nome : 'ctl00_conteudo_txtNome',
    // outras telas
    pretensaoSalarial : 'ctl00_conteudo_txtPretensaoSalarial_txtValor',
    ultimosDias : 'ctl00_conteudo_txtUltimosDias_txtValor'
};


/**** WEBFOPAG SINGLETON OBJ ****/
// var cultureObject = Sys.CultureInfo.CurrentCulture;
// Sys.CultureInfo.CurrentCulture.numberFormat.NumberNegativePattern


var wfp = {
    // {vars}
    // constants
    VERSION : function () {
        return 1.1;
    },
    // MMDDYYYY
    VERSION_DATE : function () {
        return new Date("10-28-2008");
    }
    // private vars
    // public vars
    // {methods}
    // private methods
    // public methods
};

wfp.browser = {
    /// <summary>
    /// Informações sobre o navegador do usuário.
    /// </summary>
    isIE : function () {
        return Sys.Browser.agent == Sys.Browser.InternetExplorer ? true : false;
    },
    isFirefox : function () {
        return Sys.Browser.agent == Sys.Browser.Firefox ? true : false;
    },
    isOpera : function () {
        return Sys.Browser.agent == Sys.Browser.Opera ? true : false;
    },
    isSafari : function () {
        return Sys.Browser.agent == Sys.Browser.Safari ? true : false;
    }
};

wfp.util = {
    isArray : function (e) {
        /// <summary>
        /// Verifica se o elemento é um array.
        /// </summary>
        return (typeof(e.length) == "undefined") ? false : true;
    },
    isTextFullySelected : function (e) {
        /// <summary>
        /// Verifica se usuário selecionou do texto em um DOM element. X-browser compliance.
        /// </summary>
        var value = false;
        var str = "";
        var maxlength = e.getAttribute("MaxLength");
        if (document.selection) {
            //IE support
            e.focus();
            sel = document.selection.createRange();
            if (sel.text != "") {
                str = sel.text;
                if (str.length >= maxlength) { value = true; }
            }
        } else if (typeof e.selectionStart == 'number') {
            //MOZILLA/NETSCAPE support
            var startPos = e.selectionStart;
            var endPos = e.selectionEnd;
            if (startPos == '0' && endPos == maxlength) { value = true; }
        }
        return value;
    },
    isTextNotSelected : function (e) {
        /// <summary>
        /// Verifica se usuário não selecionou parte do texto em um DOM element. X-browser compliance.
        /// </summary>
        var value = false;
        if (document.selection) {
            //IE support
            e.focus();
            sel = document.selection.createRange();
            if (sel.text == "") { value = true; }
        } else if (typeof e.selectionStart == 'number') {
            //MOZILLA/NETSCAPE support
            var startPos = e.selectionStart;
            var endPos = e.selectionEnd;
            if (startPos == endPos) { value = true; }
        }
        return value;
    },
    getSelectionStart : function (e) {
        /// <summary>
        /// Retorna a posição inicial de seleção do texto em um DOM element.
        /// </summary>
       if (document.selection) {
            var textRange = document.selection.createRange();
            var isCollapsed = textRange.compareEndPoints("StartToEnd", textRange) == 0;
	        if (!isCollapsed) { textRange.collapse(true); }
            var bookmark = textRange.getBookmark();
            return bookmark.charCodeAt(2) - 2;
        } else if (typeof e.selectionStart == 'number') {
            return e.selectionStart;    
        }  
    },
    getSelectionEnd : function (e) {
        /// <summary>
        /// Retorna a posição final de seleção do texto em um DOM element.
        /// </summary>
        if (document.selection) {
            var textRange = document.selection.createRange();
            var isCollapsed = textRange.compareEndPoints("StartToEnd", textRange) == 0;
            if (!isCollapsed) { textRange.collapse(false); }
            var bookmark = textRange.getBookmark();
            return bookmark.charCodeAt(2) - 2;
        } else if (typeof e.selectionEnd == 'number') {
            return e.selectionEnd;
        }
    },
    getSelectionSize : function (e) {
        /// <summary>
        /// Retorna o tamanho da seleção do texto em um DOM element.
        /// </summary>
        if (document.selection) {
            var textRange = document.selection.createRange();
            return textRange.text.length;        
        } else if (typeof e.selectionStart == 'number') {
            return e.selectionEnd - e.selectionStart;
        }
    }
};

wfp.util.string = {
    toNumber : function (string) {
        /// <summary>
        /// Remove letras e caracteres, remove '.', troca ',' por '.' para casas decimais.
        /// </summary>
        var i = 0;
        var negativo = false;
        while (string.charAt(i) == ' ') {
            i++;
        }
        if (string.charAt(i) == '-') {
            negativo = true;
        }
        var temp = string.replace(/\./g, '');
        temp = temp.replace(/,/g, '.');
        temp = temp.replace(/[^0-9.]/g, '');
        if (negativo) {
            return -(+temp);    
        } else {
            return (+temp);
        }
    }
};

wfp.util.number = {
    mask : function (val, mask) {
        /// <summary>
        /// Insere uma mascara em um nro.
        /// 'R$ ###.###.###.##0,00'
        /// '#-###-###-##.##000'
        /// 12
        /// 12.3
        /// 12.33
        /// 12.33555678
        /// </summary>
        var prefix;
        var rad;
        var sufix;
        var negative = false;
        if (val < 0) {
            negative = true;
        }
        if (typeof val == 'number') {
            val = String(val);
            val = val.replace(/\./g, ',');
            prefix = mask.substring(0, mask.indexOf('#'));
            sufix = mask.substring(mask.lastIndexOf('#')+1, mask.length);
            mask = mask.substring(mask.indexOf('#'), mask.length);
            //mask = mask.substring(mask.indexOf('#'), mask.lastIndexOf('#')+1);
            // normaliza o value caso haja 
            if (sufix) {
                if (sufix.indexOf(',') > -1) {
                    ts = sufix.split(',');
                    tv = val.split(',');
                    // ambos possuem decimal
                    if (ts.length == tv.length) {
                        // decimal do sufixo maior q decimal do valor
                        if (tv[1].length < ts[1].length) {
                            for (var i = 0; i < ts[1].length; i++) {
                                if (tv[1].charAt(i) == '') {
                                    tv[1] += ts[i].charAt(i);
                                }
                            }
                        // remove caracteres qndo o decimal do valor é maior q o decimal do sufixo
                        } else if (tv[1].length > ts[1].length) { 
                            val = val.substring(0, val.length-(tv[1].length-ts[1].length));
                        }
                    // adiciona o decima do sufixo ao valor
                    } else if (tv.length < ts.length) {
                        val += ","+ts[1];
                    }
                }
            } 
            var im = 0;
            if (val.length - sufix.length > 0) {
                for (var j = val.length - sufix.length - 1; j > -1; j--) {
                    if (val.charAt(j) != '') {
                        if (mask.charAt(mask.length - sufix.length - 1 - im) != '#') {
                            val = val.substring(0, j + 1) + mask.charAt(mask.length - sufix.length - 1 - im) + val.substring(j + 1, val.length);
                        }
                    }
                    im++;
                }
            }
            if (typeof val == 'string') {
                if (negative) {
                    return "( " + prefix + val + " )";
                } else {
                    return prefix + val;
                }
            } else {
                return null;
            }            
        } else {
            return null;
        }
    }
};

/**** EVENTS ****/

wfp.event = {
    stopEvent : function (event) {
    /// <summary>
    /// Cancela o evento.
    /// </summary>
        if (event.originalEvent != null) { event = event.originalEvent; }
        if (event.preventDefault) {
            event.preventDefault();
        }
        event.returnValue = false;
        if (event.stopPropagation) {
            event.stopPropagation();
        }
        event.cancelBubble = true;
    },
    getTargetFromEvent : function (event) {
    /// <summary>
    /// Retorna o elemento que iniciou o evento.
    /// </summary>
        var t = (event.target) ? event.target : event.srcElement;
	    if (t.nodeType == 3) {
	        // Safari bug
		    t = t.parentNode;
        }
        return t;
    },
    getEvent : function (event) {
    /// <summary>
    /// Retorna o evento disparador. X-browser compliance.
    /// </summary>
	    var e = (!event) ? window.event : event;
	    return e;
    }
};

/**** FORM NAVEGATION ****/

wfp.form = {
    nav : function (event) {
    /// <summary>
    /// Inicializa a captura das teclas de navegação do formulario.
    /// </summary>
        var k = wfp.keyboard.getKeyFromEvent(event)[0];
        var t = wfp.event.getTargetFromEvent(event);
        var ac = wfp.form.util.hasBehaviorAutoComplete(t);
        var n;
        var selectok = true;
        var tag = String(t.nodeName).toLowerCase();
        var type = String(t.type).toLowerCase();                
        var id = t.id;
        var mod = wfp.keyboard.hasModifierKeyPressed(event); 
        if (wfp.keyboard.isArrowKey(k) && k == wfp.keyboard._arrows.UP_ARROW) {
            wfp.event.stopEvent(event);
            if (t.tagName.toLowerCase() == 'select') {
                if (!wfp.form.util.isSelectedIndexAtMinMaxRange(t, 'min')) {
                    selectok = false;
                    t.selectedIndex--;
                }
            }
            // só deve mudar de campo se não estiver navegando dentro da lista de um autocomplete
            // caso select (combobox) so muda para próximo campo se estiver no indice min
            if (ac[0] && !ac[1] && selectok){
                t.blur();
                window.setTimeout(function () {
                    wfp.form.previous(t);
                }, 300);
            } else if (!ac[0] && selectok) {
                t.blur();
                window.setTimeout(function () {
                    wfp.form.previous(t);
                }, 200);
            }
        } else if (wfp.keyboard.isArrowKey(k) && k == wfp.keyboard._arrows.DOWN_ARROW) {
           wfp.event.stopEvent(event);
            if (t.tagName.toLowerCase() == 'select') {
                if (!wfp.form.util.isSelectedIndexAtMinMaxRange(t, 'max')) {
                    selectok = false;
                    t.selectedIndex++;
                }
            }
           // só deve mudar de campo se não estiver navegando dentro da lista de um autocomplete
           // caso select-one (combobox) so muda para próximo campo se estiver no indice max
           // campos com autocomplete estão com um delay de meio segundo
           if (ac[0] && !ac[1] && selectok){
                t.blur();
                window.setTimeout(function () {
                    wfp.form.next(t);
                }, 300);
           } else if (!ac[0] && selectok){
                t.blur();
                window.setTimeout(function () {
                    wfp.form.next(t);
                }, 200);
            }
        } else if (k == wfp.keyboard._commands.TAB) {
            wfp.event.stopEvent(event);
            if (!event.shiftKey && !event.shiftLeft) {
                if (t.tagName.toLowerCase() == 'select') {
                    if (!wfp.form.util.isSelectedIndexAtMinMaxRange(t, 'max')) {
                        selectok = false;
                        t.selectedIndex++;
                    }
                }
                if (ac[0] && !ac[1] && selectok){
                    t.blur();
                    window.setTimeout(function () {
                        wfp.form.next(t);
                    }, 300);
                } else if (!ac[0] && selectok){
                    t.blur();
                    window.setTimeout(function () {
                        wfp.form.next(t);
                  }, 200);
                }
            } else if (event.shiftKey || event.shiftLeft) {
                if (t.tagName.toLowerCase() == 'select') {
                    if (!wfp.form.util.isSelectedIndexAtMinMaxRange(t, 'min')) {
                        selectok = false;
                        t.selectedIndex--;
                    }
                }
                if (ac[0] && !ac[1] && selectok){
                    t.blur();
                    window.setTimeout(function () {
                        wfp.form.previous(t);
                    }, 300);
                } else if (!ac[0] && selectok){
                    t.blur();
                    window.setTimeout(function () {
                        wfp.form.previous(t);
                    }, 200);
                }
            }
        }
    },
    getNavigationListFromElement : function (e) {
    /// <summary>
    /// Retorna a lista de campos do formulário ativos para navegação por teclado.
    /// </summary>
//        var parent = e.parentNode;
//        // navega em até o pai máximo
//        while (parent != null && parent.id != "conteudo" && parent.id != "topo") {
//            var pClass = parent.className;
//            // verifica se é uma modal     
//            if (pClass.match("painel_resultado_padrao") || pClass == "uc_cep") { 
//                break;
//            }
//            parent = parent.parentNode;
//        }
//        // seta form para navegação 
//        var container;
//        if (parent == null) {
//            container = "#conteudo";
//        } else if (typeof parent.id == 'string' && parent.id) {
//            container = "#"+parent.id;
//        } else {
//            container = "."+parent.className;
//        }
//        // busca todos os campos (input, textarea, select and button elements) menos (input image)
//        return $(container).find(":input:visible:not(:image)");
    },
    getNavigationList : function () {
    /// <summary>
    /// Retorna a lista de campos do formulário ativos para navegação por teclado.
    /// </summary>
        // busca todos os campos (input, textarea, select and button elements) menos (input image)
        return $("#conteudo").find(":input:visible:not(:image)");
    },    
    getFirstElement : function () {
    /// <summary>
    /// Retorna o primeiro campo possivel de foco do formulário.
    /// </summary>
        var list = wfp.form.getNavigationList();
        for (var i = 0; i < list.length; i++) {
            if (wfp.form.util.canHaveFocus(list[i])) {
                return list[i];
                break;
            }
        }
    },
    getLastElement : function () {
    /// <summary>
    /// Retorna o ultimo campo possivel de foco do formulário.
    /// </summary>
        var list = wfp.form.getNavigationList();
        for (var i = list.length-1; i >= 0; i--) {
            if (wfp.form.util.canHaveFocus(list[i])) {
                return list[i];
                break;
            }
        }
    },
    getLastFocus : function () {
    /// <summary>
    /// Retorna o ultimo campo com foco guardado no campo HIDDEN do form (caso exista).
    /// </summary>
        var temp = $get('ctl00_hfUltimoFoco');
        if (temp != null) {
            if (temp.value != "") {
                var lastFocus = $get(temp.value);
                if (lastFocus != null) {
                    return lastFocus;
                }                
            }
        }
        return null;
    },
    setLastFocus : function (e) {
    /// <summary>
    /// Atualiza campo HIDDEN do form (caso exista) com o id do ultimo campo com foco.
    /// </summary>
        var t = wfp.event.getTargetFromEvent(e);
        if (t != null) {
            var lastFocus = $get('ctl00_hfUltimoFoco');    
            if (lastFocus != null) {
                lastFocus.value = t.id;
            }
        }
    },
    next : function (e) {
    /// <summary>
    /// Retorna o proximo campo possivel de foco, ou ele mesmo caso não haja próximo campo ou algum validator obrigue o foco.
    /// </summary>
//        if (e == $get(e.id)) {
//            var eform = wfp.form.getNavigationListFromElement(e);
//            var foundElement = false;
//            var nextElement;
//            var n;
//            if (!wfp.form.util.validateFocusOnError(e)) { 
//                for (var i = 0; i < eform.length; i++) {
//                    if (eform[i].id == e.id) {
//                        foundElement = true;
//                    }
//                    // prox element pos target ativo que não seja ignorado
//                    if (foundElement && eform[i].id != e.id &&  wfp.form.util.canHaveFocus(eform[i])){
//                        nextElement = eform[i];
//                        break;
//                    }
//                }        
//            }
//            if (typeof nextElement == "object") { 
//                 n = nextElement;
//            } else { 
//                n = e;
//            }
//            n.focus();
//            if (n.select) {
//                n.select();
//            }        
//        }
    },
    previous : function (e) {
    /// <summary>
    /// Retorna o campo anterior possivel de foco, ou ele mesmo caso não haja campo anterior ou algum validator obrigue o foco.
    /// ELEMENT OBJECT
    /// </summary>
        if (e == $get(e.id)) {
            var eform = wfp.form.getNavigationListFromElement(e);
            var foundElement = false;
            var previousElement;
            var p;
            if (!wfp.form.util.validateFocusOnError(e)) { 
                for (var i = eform.length-1; i >= 0; i--) {
                    if (eform[i].id == e.id) {
                        foundElement = true;
                    }
                    // prox element pos target ativo que não seja ignorado
                    // alterado comparações para ID para evitar erros de comparação quando
                    // há postback ne tela durante
                    if (foundElement && eform[i].id != e.id && wfp.form.util.canHaveFocus(eform[i])) { 
                        previousElement = eform[i];
                        break;
                    }
                }
            }
            if (typeof previousElement == "object") { 
                p = previousElement;
            } else { 
                p = e;
            }
            p.focus();
            if (p.select) {
                p.select();
            }        
        }
    }
};

wfp.form.util = {
    isBtnPesquisa : function (e) {
        var idPesquisa = 'ctl00_txtFiltroPesquisa_txtValor';
        if (typeof e == 'string') {
            if (e == idPesquisa) {
                return true;
            }
        } else {
            if (e.id == idPesquisa) {
                return true;
            }
        }
        return false;
    },
    getBtnPesquisa : function () {
        return $get("ctl00_btiPesquisar");
    },
    isValidFormElement : function (e) {
        if (String(e.nodeName).toLowerCase() == 'input' && String(e.type).toLowerCase() == 'text') { // caixa texto
            return true;
        } else if (String(e.nodeName).toLowerCase() == 'input' && String(e.type).toLowerCase() == 'submit') { // botoes
           return true;
        } else if (String(e.nodeName).toLowerCase() == 'textarea') { // caixa texto multi linha
           return true;
        } else if (String(e.nodeName).toLowerCase() == 'select') { // dropdown list
            return true;
        } else {
            return false;
        }
    },
    isSelectedIndexAtMinMaxRange : function (e, axis) {
    /// <summary>
    /// Verifica se o componente SELECT está com a menor opção ou maior opção selecionado
    /// axis = min / max
    /// </summary>
        var node = e.nodeName.toLowerCase();
        var type = String(e.type).toLowerCase();
        if (e && node == 'select' && type == 'select-one') {
            if (e.selectedIndex == '0' && axis.toLowerCase() == 'min') {
                return true;
            } else if (e.selectedIndex == e.length-1 && axis.toLowerCase() == 'max') {
                return true;
            } else {
                return false;
            }
        } else {
            // caso não seja um SELECT retorna TRUE
            return true;
        }
    },
    hasBehaviorAutoComplete : function (e) {
    /// <summary>
    /// Verifica se é um componente AJAX autocomplete e se está navegando nas opções.
    /// hasBehavior = se é um componente autocomplete.
    /// hasFlyout = é um componetne autocomplete e a lista de opções está sendo exibida.
    /// </summary>
        var listBehavior = Sys.UI.Behavior.getBehaviors(e);
        var hasAutoComplete = false;
        var hasFlyout = false;
        if (listBehavior.length > 0) {
            for (var i = 0; i < listBehavior.length; i++) {
                if (listBehavior[i].get_name() == "AutoCompleteBehavior") { 
                    hasAutoComplete = true;
                    if (listBehavior[i]._completionListElement.childNodes.length > 0) {
                        hasFlyout = true;
                    }
                    break;
                }
            }
        }
        return [hasAutoComplete, hasFlyout];
    },
    hasVisibleParent : function (e) {
    /// <summary>
    /// Verifica se os pais do elemento estão escondidos
    /// </summary>
        if (!e.disabled && // form element
           (e.type && (e.type != "hidden")) && // form element
           (e.style && e.style.display != "none")) { // other elements
            var eparent = e.parentNode;
            while (eparent.id != "conteudo" && eparent.id != "topo" && 
             (eparent.style && eparent.style.display != "none")) {
                eparent = eparent.parentNode;
            }
            if (eparent.style.display != "none") { return true; } 
            else { return false; }
        } else {
            return false;
        }
    },
    canHaveFocus : function (e) {
    /// <summary>
    /// Verifica se o campo é passivel de foco. Está visível, com os pais visíveis e 
    /// não está na lista de elementos ignorados e não está desabilitado.
    /// </summary>
         if (wfp.form.util.hasVisibleParent(e) && !wfp.form.util.ignoreElement(e) && !e.disabled) {
            return true;
        } else {
            return false
        }
    },
    autoCompleteClientSelected : function (source, eventArgs) {
    /// <summary>
    /// Seleciona o próximo campo possível de foco.
    /// *** Essa func é utilizada somente dentro do AjaxTookit:AutoCompleteExtender ***
    /// *** OnClientItemSelected="wfp.form.util.autoCompleteClientSelected" ***
    /// </summary>
        var t = source.get_element();
        wfp.form.next(t);
    },
    ignoreElement : function (e) {
    /// <summary>
    /// Verifica padrões de nomenclatura de elementos da navegação que deverão ser ignorados
    /// </summary>
        if (typeof e == "object" && e.id && e.id.match(".*_ign.*")) { //tela "lançamento folha lote"
            return true;
        } else if (typeof e == "string" && e.match(".*_ign.*")) {
            return true;
        } else {
            return false;
        }
    },
    validateFocusOnError : function (e) {
    /// <summary>
    /// Verifica se os validadores do componente permitem a ida para o proximo campo
    /// TRUE : campo com erro e o validador obriga o foco.
    /// FALSE : campo com erro e o validator não obriga o foco ou campo sem erro de validação.
    /// </summary>
        var validator = e.getAttribute("Validators");
        var pattern = /(\d|[a-z]|[A-Z]|[_])+(([_][r][e])|([_][c][v])|([_][r][v]))(\d|[A-Z]|[a-z])+$/; 
        if (typeof(validator) == 'object' && validator) {
            for (var i = 0; i < validator.length; i++) {
                // valida os 3 tipos de validadores _re (req field) _rv (req validator) _cv (custom validator)
                if (pattern.exec(validator[i].id)) {
                    var focusOnError = validator[i].getAttribute("focusOnError");
                    var isValid = validator[i].getAttribute("isValid");
                    if ((typeof(isValid) == "boolean" && isValid == false) && 
                        (typeof(focusOnError) == "string" && focusOnError === "t")) {
                        return true;
                    }
                } 
            } 
        } 
        return false;
    },
    searchInvalidValidator : function (e, vg) {
    /// <summary>
    /// Procura o primeiro validador inválido da página e traz o focus para o controle.
    /// </summary>
        if (!e.isDisabled) {  
            wfp.form.util.validarPagina(vg);
            for (var i = 0; i < Page_Validators.length; i++) {
                if (!Page_Validators[i].isvalid) {
                    document.getElementById(Page_Validators[i].controltovalidate).focus(); 
                    return false;
                }
            }
            return true;
        } else {
            return false;
        }
    },
    validarPagina : function (vg) {
    /// <summary>
    /// Valida pagina.
    /// </summary>
       for (var i = 0; i < Page_Validators.length; i++) {
            if (Page_Validators[i].validationGroup == vg) {
                ValidatorValidate(Page_Validators[i]);
            }
        }
    }
};


/**** KEYS ****/

// IE reflete charcode somente no keypress

// MOZILLA Firefox

// KeyEvent = http://developer.mozilla.org/en/DOM/Event/UIEvent/KeyEvent
// event.keyCode = http://developer.mozilla.org/en/DOM/event.keyCode
// event.charCode = http://developer.mozilla.org/en/DOM/event.charCode

// event.charCode = Returns the Unicode value of a non-character key in a keypress event (tab esc bkspc del ins hom end F*)
// event.keyCode = Returns the Unicode value of a character key pressed during a keypress event

// KEYPRESS NÃO DEMONSTRA = capslok shift ctrl alt printscreen scrolllok numlok

wfp.keyboard = {
    getKeyFromEvent : function (event) {
        var k = (event.keyCode) ? event.keyCode : null; // RETORNA NON CHAR
        var c = (event.charCode) ? event.charCode : null; // RETORNA CHAR
        if (wfp.browser.isIE) {
            if (event.type == 'keypress') {
                c = k;
                k = 0;
            }
        }
	    return [k, c];    
    },
    isDomNonCharacter : function (event) {
        var eType = event.type;
        if (wfp.browser.isFirefox && eType == 'keyppress') {
            // TODO e validar com IE
            // TODO e validar com IE
            // TODO e validar com IE
            // TODO e validar com IE
            // TODO e validar com IE
        }
    },
    isEnter : function (code) {
        if (code == wfp.keyboard._command.ENTER) {
            return true;
        } else {
            return false;
        }
    },
    isArrowKey : function (code) {
        var is = false;
        var list = wfp.keyboard._arrows;
        for(var property in list) {
            if (list[property] == code) { is = true; }
        }
        return is;
    },
    isNumberKey : function (code) {
        var is = false;
        var list = wfp.keyboard._numbers;
        for(var property in list) {
            if (list[property] == code) { is = true; }
        }
        return is;
    },
    isLetterKey : function (code) {
        var is = false;
        var list = wfp.keyboard._letters;
        for(var property in list) {
            if (list[property] == code) { is = true; }
        }
        return is;
    },
    isCommandKey : function (code) {
        var is = false;
        var list = wfp.keyboard._command;
        for(var property in list) {
            if (list[property] == code) { is = true; }
        }
        return is;
    },
    isModifierKey : function (code) {
        var is = false;
        var list = wfp.keyboard._modifier;
        for(var property in list) {
            if (list[property] == code) { is = true; }
        }
        return is;
    },
    isCharacterKey : function (code) {
        // numbers
        if (code >= wfp.keyboard._numbers.ZERO && code <= wfp.keyboard._numbers.NINE) { return true; }
        // numpad
        if (code >= wfp.keyboard._numpad.NUM_ZERO && code <= wfp.keyboard._numpad.NUM_MULTIPLY) { return true; }
        // letters
        if (keyCode >= wfp.keyboard._letters.A && keyCode <= wfp.keyboard._letters.Z) { return true; }
        
        // TODO
    },
    hasModifierKeyPressed : function (e) {
    /// <summary>
    /// Verifica se alguma tecla modificadora está sendo pressionada.
    /// </summary>        
        // verifica se é um evento do jqery
        if (e.originalEvent != null) { e = e.originalEvent; }
        var modifier = null;
        if (e.altKey == true) {
            modifier = 'ALT';
        } else if (e.altLeft == true) {
            modifier = 'ALT';
        } else if (e.ctrlKey == true) {
            modifier = 'CTRL';
        } else if (e.ctrlLeft == true) {
            modifier = 'CTRL';
        } else if (e.shiftKey == true) {
            modifier = 'SHIFT';
        } else if (e.shiftLeft == true) {
            modifier = 'SHIFT';
        }
        return modifier;
    },
    shortcuts : function (event) {
    /// <summary>
    /// Atalhos da applicação.
    /// </summary>        
        var type = event.type;
        var k = wfp.keyboard.getKeyFromEvent(event)[0];
        var mod = wfp.keyboard.hasModifierKeyPressed(event);
        // IE não possui charcode e só diferencia Maisculo de Minúsculo no keypress
        if (type == 'keydown' || type == 'keyup') { 
            if (k == 113) {
                // 113 = F2
                var btnF2 = $get('ctl00_btnAtalhoF2');
                if (btnF2 != null) {
                    wfp.event.stopEvent(event);
                    btnF2.click();
                }
            } else if (k == 119) {
                // 119 = F8
                var btnF8 = $get('ctl00_btnAtalhoF8');
                if (btnF8 != null) {
                    wfp.event.stopEvent(event);
                    btnF8.click();
                }
            } else if (k == 120) {
                // 120 = F9
                var tempF9 = $get('ctl00_btnAtalhoF9');
                if (tempF9 != null) {
                    if (tempF9.value != '') {
                        var btnF9 = $get(tempF9.value);
                        if (btnF9 != null) {
                            wfp.event.stopEvent(event);
                            btnF9.click();
                        }
                    }
                }
            } else if (k == 123) {
                // 123 = F12
                var tempF12 = $get('ctl00_hfIDBtnF12');
                if (tempF12 != null) {
                    if (tempF12.value != '') {
                        var btnF12 = $get(tempF12.value);
                        if (btnF12 != null) {
                            wfp.event.stopEvent(event);
                            btnF12.click();
                        }
                    }
                }
            } 
            if (mod === 'ALT') {
                if (k == 68) {
                // ALT + D (68)
                    var tempAltD = $get('ctl00_hfIDBtnAltD');
                    if (tempAltD != null) {
                        if (tempAltD.value != '') {
                            var btnAltD = $get(tempAltD.value);
                             if (btnAltD != null) {
                                var confirm = window.confirm("Tem certeza que deseja excluir?");
                                if (confirm) {
                                    btnAltD.click();
                                    wfp.event.stopEvent(event);
                                }
                            }
                        }
                    }
                } else if (k == 83) {
                // ALT + S (83)
                    if (wfp.form.util.searchInvalidValidator('Salvar')) {
                        var tempAltS = $get('ctl00_hfIDBtnAltS');
                        if (typeof tempAltS == 'object') {
                            if (tempAltS.value != '') {
                                var btnAltS = $get(tempAltS.value);
                                if (typeof btnAltS == 'object') {
                                    btnAltS.click();
                                    wfp.event.stopEvent(event);
                                }
                            }
                        }
                    }
                }
            }
        }
    },
    disableKeys : function (event) {
        var k, t, ty, ro;
        if (window.event) { // eg. IE
            k = window.event.keyCode;
            t = window.event.srcElement.nodeName;
            ty = window.event.srcElement.type;
            ro = window.event.srcElement.getAttribute("readonly");
        } else if (event.which) { // eg. Firefox
            k = event.which;
            t = event.target.nodeName;
            ty = event.target.type;
            ro = event.target.getAttribute("readonly");
        }
        if (k == 8 && (t !== 'INPUT' && t !== 'TEXTAREA') || ro == true) {
            return false;
        } else if (k == 13 && (t !== 'TEXTAREA' && ty !== 'submit')) {
            return false;
        }
    }   
};

wfp.keyboard._numbers = {
    ZERO: 48,
    ONE: 49,
    TWO: 50,
    THREE: 51,
    FOUR: 52,
    FIVE: 53,
    SIX: 54,
    SEVEN: 55,
    EIGHT: 56,
    NINE: 57
};

wfp.keyboard._letters = {
    A: 65,
    B: 66,
    C: 67,
    D: 68,
    E: 69,
    F: 70,
    G: 71,
    H: 72,
    I: 73,
    J: 74,
    K: 75,
    L: 76,
    M: 77,
    N: 78,
    O: 79,
    P: 80,
    Q: 81,
    R: 82,
    S: 83,
    T: 84,
    U: 85,
    V: 86,
    W: 87,
    X: 88,
    Y: 89,
    Z: 90
};

wfp.keyboard._space = {
    SPACE : 23
};

wfp.keyboard._modifiers = {
    SHIFT: 16,
    CTRL: 17,
    ALT: 18
};

wfp.keyboard._commands = {
    BACKSPACE: 8,
    TAB: 9,
    ENTER: 13,
    PAUSE_BREAK : 19,
    CAPS_LOCK : 20,
    ESCAPE : 27,
    PAGE_UP : 33,
    PAGE_DOWN : 34, 
    END : 35, 
    HOME : 36, 
    INSERT_KEY : 45,
    DELETE_KEY : 46,
    LEFT_WINDOW_KEY : 91, 
    RIGHT_WINDOW_KEY : 92, 
    SELECT_KEY : 93
};

wfp.keyboard._arrows = {
    LEFT_ARROW : 37, 
    UP_ARROW : 38, 
    RIGHT_ARROW : 39, 
    DOWN_ARROW : 40
};

wfp.keyboard.table = {

};

wfp.keyboard.table.dom = {
    DOM_CANCEL :        3,
    DOM_HELP :          6,
    DOM_BACK_SPACE :    8,
    DOM_TAB :           9,
    DOM_CLEAR :         12,
    DOM_RETURN :        13,
    DOM_ENTER :         14,
    DOM_SHIFT :         16,
    DOM_CONTROL :       17,
    DOM_ALT :           18,
    DOM_PAUSE :         19,
    DOM_CAPS_LOCK :     20,
    DOM_ESCAPE :        27,
    DOM_SPACE :         32,
    DOM_PAGE_UP :       33,
    DOM_PAGE_DOWN :     34,
    DOM_END :           35,
    DOM_HOME :          36,
    DOM_LEFT :          37,
    DOM_UP :            38,
    DOM_RIGHT :         39,
    DOM_DOWN :          40,
    DOM_PRINTSCREEN :   44,
    DOM_INSERT :        45,
    DOM_DELETE :        46,
    DOM_0 :             48,
    DOM_1 :             49,
    DOM_2 :             50,
    DOM_3 :             51,
    DOM_4 :             52,
    DOM_5 :             53,
    DOM_6 :             54,
    DOM_7 :             55,
    DOM_8 :             56,
    DOM_9 :             57,
    DOM_SEMICOLON :     59,
    DOM_EQUALS :        61,
    DOM_A :             65,
    DOM_B :             66,
    DOM_C :             67,
    DOM_D :             68,
    DOM_E :             69,
    DOM_F :             70,
    DOM_G :             71,
    DOM_H :             72,
    DOM_I :             73,
    DOM_J :             74,
    DOM_K :             75,
    DOM_L :             76,
    DOM_M :             77,
    DOM_N :             78,
    DOM_O :             79,
    DOM_P :             80,
    DOM_Q :             81,
    DOM_R :             82,
    DOM_S :             83,
    DOM_T :             84,
    DOM_U :             85,
    DOM_V :             86,
    DOM_W :             87,
    DOM_X :             88,
    DOM_Y :             89,
    DOM_ :              90,
    DOM_CONTEXT_MENU :  93,
    DOM_NUMPAD0 :       96,
    DOM_NUMPAD1 :       97,
    DOM_NUMPAD2 :       98,
    DOM_NUMPAD3 :       99,
    DOM_NUMPAD4 :       100,
    DOM_NUMPAD5 :       101,
    DOM_NUMPAD6 :       102,
    DOM_NUMPAD7 :       103,
    DOM_NUMPAD8 :       104,
    DOM_NUMPAD9 :       105,
    DOM_MULTIPLY :      106,
    DOM_ADD :           107,
    DOM_SEPARATOR :     108,
    DOM_SUBTRACT :      109,
    DOM_DECIMAL :       110,
    DOM_DIVIDE :        111,
    DOM_F1 :            112,
    DOM_F2 :            113,
    DOM_F3 :            114,
    DOM_F4 :            115,
    DOM_F5 :            116,
    DOM_F6 :            117,
    DOM_F7 :            118,
    DOM_F8 :            119,
    DOM_F9 :            120,
    DOM_F10 :           121,
    DOM_F11 :           122,
    DOM_F12 :           123,
    DOM_F13 :           124,
    DOM_F14 :           125,
    DOM_F15 :           126,
    DOM_F16 :           127,
    DOM_F17 :           128,
    DOM_F18 :           129,
    DOM_F19 :           130,
    DOM_F20 :           131,
    DOM_F21 :           132,
    DOM_F22 :           133,
    DOM_F23 :           134,
    DOM_F24 :           135,
    DOM_NUM_LOCK :      144,
    DOM_SCROLL_LOCK :   145,
    DOM_COMMA :         188,
    DOM_PERIOD :        190,
    DOM_SLASH :         191,
    DOM_BACK_QUOTE :    192,
    DOM_OPEN_BRACKET :  219,
    DOM_BACK_SLASH :    220,
    DOM_CLOSE_BRACKET : 221,
    DOM_QUOTE :         222,
    DOM_META :          224
};

wfp.keyboard.table.keycode = {
    BACKSPACE : 8, 
    TAB : 9, 
    ENTER : 13, 
    SHIFT : 16, 
    CTRL : 17, 
    ALT : 18, 
    PAUSE_BREAK : 19, 
    CAPS_LOCK : 20, 
    ESCAPE : 27, 
    SPACE : 32,
    PAGE_UP : 33,
    PAGE_DOWN : 34, 
    END : 35, 
    HOME : 36, 
    LEFT_ARROW : 37, 
    UP_ARROW : 38, 
    RIGHT_ARROW : 39, 
    DOWN_ARROW : 40, 
    INSERT_KEY : 45, 
    DELETE_KEY : 46, 
    ZERO : 48, 
    ONE : 49, 
    TWO : 50, 
    THREE : 51, 
    FOUR : 52, 
    FIVE : 53, 
    SIX : 54, 
    SEVEN : 55, 
    EIGHT : 56, 
    NINE : 57, 
    A : 65, 
    B : 66, 
    C : 67, 
    D : 68, 
    E : 69, 
    F : 70, 
    G : 71, 
    H : 72, 
    I : 73, 
    J : 74, 
    K : 75, 
    L : 76, 
    M : 77, 
    N : 78, 
    O : 79, 
    P : 80, 
    Q : 81, 
    R : 82, 
    S : 83, 
    T : 84, 
    U : 85, 
    V : 86, 
    W : 87, 
    X : 88, 
    Y : 89, 
    Z : 90, 
    LEFT_WINDOW_KEY : 91, 
    RIGHT_WINDOW_KEY : 92, 
    SELECT_KEY : 93, 
    NUMPAD_ZERO : 96, 
    NUMPAD_ONE : 97, 
    NUMPAD_TWO : 98, 
    NUMPAD_THREE : 99, 
    NUMPAD_FOUR : 100, 
    NUMPAD_FIVE : 101, 
    NUMPAD_SIX : 102, 
    NUMPAD_SEVEN : 103, 
    NUMPAD_EIGHT : 104, 
    NUMPAD_NINE : 105, 
    MULTIPLY : 106, 
    ADD : 107, 
    SUBTRACT : 109, 
    DECIMAL_POINT : 110, 
    DIVIDE : 111, 
    F1 : 112, 
    F2 : 113, 
    F3 : 114, 
    F4 : 115, 
    F5 : 116, 
    F6 : 117, 
    F7 : 118, 
    F8 : 119, 
    F9 : 120, 
    F10 : 121, 
    F11 : 122, 
    F12 : 123, 
    NUM_LOCK : 144, 
    SCROLL_LOCK : 145, 
    SEMI_COLON : 186,       // ;
    EQUAL_SIGN : 187, 
    COMMA : 188, 
    DASH : 189,             // -
    PERIOD : 190, 
    FORWARD_SLASH : 191, 
    GRAVE_ACCENT : 192, 
    OPEN_BRACKET : 219, 
    BACK_SLASH : 220, 
    CLOSE_BRAKET : 221, 
    SINGLE_QUOTE : 222
};

wfp.keyboard.table.charcode = {
    NULL : 0,
    START_HEADING : 1,
    START_TEXT : 2,
    END_TEXT : 3,
    END_TRANSMISSION : 4,
    ENQUIRY : 5,
    ACKNOWLEDGE : 6,
    BELL : 7,
    BACKSPACE : 8, 
    TAB : 9, 
    NEW_LINE_FEED : 10,
    VERTICAL_TAB : 11,
    NEW_FORM_FEED : 12, 
    ENTER : 13, 
    SHIFT_OUT : 14,
    SHIFT_IN : 15,
    DATA_LINK_ESCAPE : 16,          //  SHIFT
    DEVICE_CONTROL_1 : 17,          //  CTRL
    DEVICE_CONTROL_2 : 18,          //  ALT
    DEVICE_CONTROL_3 : 19,          //  PAUSE_BREAK
    DEVICE_CONTROL_4 : 20,          //  CAPS_LOCK
    NEGATIVE_ACKNOWLEDGE : 27,      //  ESCAPE
    FILE_SEPARATOR : 28,
    GROUP_SEPARATOR : 29,
    RECORD_SEPARATOR : 30,
    UNIT_SEPARATOR : 31,
    SPACE : 32,                     // SPACE
    EXCLAMATION_MARK : 33,          // ! PAGE_UP
    DOUBLE_QUOTE : 34,              // " PAGE_DOWN
    HASH : 35,                      // # END
    DOLAR : 36,                     // $ HOME
    PERCENT : 37,                   // % LEFT_ARROW
    AMPERSAND : 38,                 // & UP_ARROW
    SINGLE_QUOTE : 39,              // ' RIGHT_ARROW
    LEFT_ROUND_BRACKET : 40,        // ( DOWN_ARROW
    RIGHT_ROUND_BRACKET : 41,       // ) 
    MULTIPLY : 42,                  // * 
    ADD : 43,                       // + 
    COMMA : 44,                     // , 
    INSERT_KEY : 45,                // - INSERT_KEY
    DELETE_KEY : 46,                // . DELETE_KEY
    FOWARD_SLASH : 47,              // /
    ZERO : 48, 
    ONE : 49, 
    TWO : 50, 
    THREE : 51, 
    FOUR : 52, 
    FIVE : 53, 
    SIX : 54, 
    SEVEN : 55, 
    EIGHT : 56, 
    NINE : 57,
    COLON : 58,                       // :
    SEMI_COLON : 59,                  // ;
    LEFT_ANGLE_BRAKET : 60,           // <
    EQUAL : 61,                       // =
    RIGHT_ANGLE_BRAKET : 62,          // >
    QUESTION_MARK : 63,               // ?
    AT_SIGN : 64,                     // @
    A : 65, 
    B : 66, 
    C : 67, 
    D : 68, 
    E : 69, 
    F : 70, 
    G : 71, 
    H : 72, 
    I : 73, 
    J : 74, 
    K : 75, 
    L : 76, 
    M : 77, 
    N : 78, 
    O : 79, 
    P : 80, 
    Q : 81, 
    R : 82, 
    S : 83, 
    T : 84, 
    U : 85, 
    V : 86, 
    W : 87, 
    X : 88, 
    Y : 89, 
    Z : 90, 
    LEFT_SQUARE_BRAKET : 91,        // LEFT_WINDOW_KEY
    BACK_SLASH : 92,                // RIGHT_WINDOW_KEY
    RIGHT_SQUARE_BRAKET : 93,       // SELECT_KEY
    CARET : 94,                     // ^        
    UNDERSCORE : 95,                // _
    APOSTROPHE : 96,                // ` NUMPAD_ZERO
    a : 97,                         // NUMPAD_ONE
    b : 98,                         // NUMPAD_TWO
    c : 99,                         // NUMPAD_THREE
    d : 100,                        // NUMPAD_FOUR
    e : 101,                        // NUMPAD_FIVE
    f : 102,                        // NUMPAD_SIX
    g : 103,                        // NUMPAD_SEVEN
    h : 104,                        // NUMPAD_EIGHT
    i : 105,                        // NUMPAD_NINE
    j : 106,                        // MULTIPLY
    k : 107,                        // ADD
    l : 108,                        // SUBTRACT
    m : 109,                        // DECIMAL_POINT
    n : 110,                        // DECIMAL_POINT
    o : 111,                        // DIVIDE
    p : 112,                        // F1
    q : 113,                        // F2
    r : 114,                        // F3
    s : 115,                        // F4
    t : 116,                        // F5
    u : 117,                        // F6
    v : 118,                        // F7
    w : 119,                        // F8
    x : 120,                        // F9
    y : 121,                        // F10
    z : 122,                        // F11
    LEFT_CURLY_BRAKET : 123,        // { F12
    PIPE : 124,                     // | 
    RIGHT_CURLY_BRAKET : 125,       // }
    TILE : 126,                     // ~
    DEL : 127                       // DEL
}; 