// ###### <select> element utilities ######
{
    // --- SORTING OPTIONS ---
    {
        function compareOptionText(a, b) {
            var aText = a.text; 
            var bText = b.text;
            
            if(!compareOptionText.isCaseSensitive) {
                aText = a.text.toLowerCase();
                bText = b.text.toLowerCase();
            }
            
            /*
             * return >0 if a>b
             * 0 if a=b
             * <0 if a<b
             */
            // textual comparison
            return aText != bText ? aText < bText ? -1 : 1 : 0;
            //return a.text!=b.text ? a.text<b.text ? -1 : 1 : 0;
            // numerical comparison
            // return a.text - b.text;
        }
        compareOptionText.isCaseSensitive = false;
        
        function sortOptions(list, isCaseSensitive) {
            var items    = list.options.length;
            var tmpArray = new Array(items);
            
            for(i = 0; i < items; i++) {
                tmpArray[i] = new Option(list.options[i].text, list.options[i].value);
            }
            
            compareOptionText.isCaseSensitive = isCaseSensitive;
            tmpArray.sort(compareOptionText);
            
            // make copies of sorted options back to list
            for(i = 0; i < items; i++) {
                list.options[i] = new Option(tmpArray[i].text, tmpArray[i].value);
            }
        }
    }
    
    // --- INDEX AND SEARCHING OPTIONS ---
    {
        /** Returns the index of the option that corresponds to the given option value.
         * If no such option exists in the given <select> element, the function will
         * return -1.
         * @param idSelect the ID of the <select> element whose options we want to look in.
         * @param optionValue the value of the option we're looking for.
         * @return the index of the requested option if it could be found ; -1 otherwise. */
        function findIndexOfOption(idSelect, optionValue) {
            var functionResult = -1;
            var oSelect;
            
            if(typeof(idSelect) == 'object') {
                oSelect = idSelect;   
            }
            else {
                oSelect = document.getElementById(idSelect);
            }
            
            if(oSelect.options.length > 0) {
                for(var i = 0; i < oSelect.options.length; i++) {
                    var oOption = oSelect.options[i];
                    if(oOption.value === optionValue) {
                        // keep the index in memory (to return it) and exit the loop
                        functionResult = i;
                        i              = oSelect.options.length;
                    }
                }
            }
            
            return functionResult;
        }
    }
    
    // --- OPTIONS MANAGEMENT ---
    {
        function select_clearOptions(idSelect) {
            var oSelect;
            
            if(typeof(idSelect) == 'object') {
                oSelect = idSelect;   
            }
            else {
                oSelect = document.getElementById(idSelect);
            }
            if(oSelect) {
                var iIndex;
                var oChild;
                
                for(iIndex = 0; iIndex < oSelect.childNodes.length;) {
                    oChild = oSelect.childNodes[iIndex];
                    if(oChild.value) {
                        oSelect.removeChild(oChild);
                    }
                    else {
                        ++iIndex;
                    }
                }
            }
        }
    }
    
    // --- TABLE MANAGEMENT ---
    {
        function table_clearRows(idTable) {
            var oSelect;
            
            if(typeof(idTable) == 'object') {
                oTable = idTable;   
            }
            else {
                oTable = document.getElementById(idTable);
            }
            if(oTable) {
                var oRows = oTable.rows;
                while(oRows.length) {
                    oTable.deleteRow(oRows.length-1);
                }
            }
        }
    }
    
    // --- SWITCH LIST MANAGEMENT ---
    function switchList(from,removeFrom,to,appendTo)
    {
        var oFrom = document.getElementById(from);
        var oTo = document.getElementById(to);
        
        var arrFrom = new Array();
        var arrTo = new Array();
        
        for(iOption=0; iOption < oFrom.options.length; iOption++)
        {
            if(oFrom.options[iOption].selected)
            {
                arrFrom[arrFrom.length] = oFrom.options[iOption];
                arrTo[arrTo.length] = new Option(oFrom.options[iOption].text, oFrom.options[iOption].value);
            }
        }
        
        for(iOption=0; iOption < arrFrom.length; iOption++)
        {
            var oOption = arrFrom[iOption];
            
            if(removeFrom == 1)
            {
                if(oFrom == oOption.parentNode) {
                    oFrom.removeChild(oOption);
                }
                else {
                    var oParent = oOption.parentNode;
                    oParent.removeChild(oOption);
                }
            }
            if(appendTo == 1)
            {
                if(to == "fieldChoice" && oOption.value.match(/^cfField\.\d+$/)) {
                    var oOptGroups = oTo.getElementsByTagName("optgroup");
                    if(oOptGroups.length > 0) {
                        var oOptGroup = oOptGroups[0];
                        oOptGroup.appendChild(oOption);
                    }
                }
                else {
                    //oTo.appendChild(arrTo[iOption]);
                    oTo.options[oTo.options.length] = arrTo[iOption];
                }
            }
        }
    }
    
    // --- MOVE LIST MANAGEMENT ---
    function moveList(p_field, p_way)
    {
        var oIndexes = new Array();
        
        var oSelect = document.getElementById(p_field);
        for(iOption=0; iOption < oSelect.options.length; iOption ++)
        {
            if(oSelect.options[iOption].selected)
            {
                oIndexes[oIndexes.length] = iOption;    
            }
        }
        
        if(p_way == 'up')
        {
            for(iOption=0; iOption < oIndexes.length; iOption ++)
            {
                iIndex = oIndexes[iOption];
                if(iIndex > 0)
                {
                    pIndex = iIndex - 1;
                    sValue = oSelect.options[pIndex].value;
                    sText = oSelect.options[pIndex].text;
                    
                    oSelect.options[pIndex].value = oSelect.options[iIndex].value;
                    oSelect.options[pIndex].text = oSelect.options[iIndex].text;
                    
                    oSelect.options[pIndex].selected = true;
                    
                    oSelect.options[iIndex].value = sValue;
                    oSelect.options[iIndex].text = sText;
                    
                    oSelect.options[iIndex].selected = false;
                }
            }
        }
        else if(p_way == 'down')
        {
            for(iOption = (oIndexes.length-1); iOption >= 0; iOption --)
            {
                iIndex = oIndexes[iOption];
                pIndex = iIndex + 1;
                if(pIndex < oSelect.options.length)
                {
                    sValue = oSelect.options[pIndex].value;
                    sText = oSelect.options[pIndex].text;
                    
                    oSelect.options[pIndex].value = oSelect.options[iIndex].value;
                    oSelect.options[pIndex].text = oSelect.options[iIndex].text;
                    
                    oSelect.options[pIndex].selected = true;
                    
                    oSelect.options[iIndex].value = sValue;
                    oSelect.options[iIndex].text = sText;
                    
                    oSelect.options[iIndex].selected = false;
                }
            }        
        }
    }
}

// ##### Radio button utilities ######
{
    function radio_getCurrentValue(inputName) {
        var functionResult;
        
        var oInputs = document.getElementsByName(inputName);
        if(oInputs && oInputs.length > 0) {
            for(var iInput = 0; iInput < oInputs.length; iInput += 1) { 
                var oInput = oInputs[iInput];
                if(oInput.type == "radio") {
                    if(oInput.checked) {
                        functionResult = oInput.value;
                        iInput = oInputs.length; // exit for loop
                    }
                }
            }
        }
        
        return functionResult;
    }
}

// ###### Dynamic create element ######
{
    function createElement(p_element, p_type, p_name, p_id, p_value, p_class)
    {
        var oElement = document.createElement(p_element);
        if(p_id != '')
        {
            oElement.id = p_id;
        }
        
        if(p_name != '')
        {
            oElement.name = p_name;
        }
        
        if(p_class != '')
        {
            oElement.className = p_class;
        }
        
        if(p_element == 'img')
        {
            oElement.alt = p_type;
            oElement.src = p_value;
            oElement.border = 0;
        }
        else if(p_element == 'input')
        {
            oElement.type = p_type;
            oElement.value = p_value;
        }
        else if(p_element == 'a')
        {
            oElement.href = p_value;
            oElement.title = p_type;
        }
        return oElement;
    }
    
    function createNamedElement(type, name) {
        var element = null;
        
        // Try the IE way; this fails on standards-compliant browsers
        try {
            element = document.createElement('<'+type+' name="'+name+'">');
        }
        catch (e) {
        }
        
        if (!element || element.nodeName.toUpperCase() != type.toUpperCase()) {
            // Non-IE browser; use canonical method to create named element
            element      = document.createElement(type);
            element.name = name;
        }
        
        return element;
    }
}

// ##### Event management #####
{
    function stopReturnKey(evt) {
        var evt  = (evt) ? evt : ((event) ? event : null);
        var node = (evt.target) ? evt.target : ((evt.srcElement) ? evt.srcElement : null);
        if ((evt.keyCode == 13) && (node.type=="text"||node.type=="password"))  {return false;}
        return true;
    }
}

// ###### Output HTML from an XML source (page description) #####
{
    function HtmlEntities(texte) {
        texte = texte.replace(/&/g,'&amp;'); // 38 26
        texte = texte.replace(/"/g,'&quot;'); // 34 22
        texte = texte.replace(/\'/g,'&#39;'); // 39 27
        texte = texte.replace(/</g,'&lt;'); // 60 3C
        texte = texte.replace(/>/g,'&gt;'); // 62 3E
        
        texte = getHtmlEntities(texte);
        
        return texte;
    }
    
    function getHtmlEntities(texte) {
        texte = texte.replace(/[\u2018|\u2019|\u201A]/g, "&#39;"); // Microsoft "Smart" Single Quotes
        texte = texte.replace(/[\u201C|\u201D|\u201E]/g, "&quot;"); // Microsoft "Smart" Double Quotes
        texte = texte.replace(/\u2026/g, "...");
        texte = texte.replace(/[\u2013|\u2014]/g, "-");
        texte = texte.replace(/\u02C6/g, "^");
        texte = texte.replace(/\u2039/g, "&lt;");
        texte = texte.replace(/\u203A/g, "&gt;");
        texte = texte.replace(/[\u02DC|\u00A0]/g, " ");
        
        texte = texte.replace(/\^/g,'&circ;'); // 94 5E
        texte = texte.replace(//g,'&lsquo;'); // 145 91
        //texte = texte.replace(//g,'&rsquo;'); // 146 92
        texte = texte.replace(//g,'&ldquo;'); // 147 93
        texte = texte.replace(//g,'&rdquo;'); // 148 94
        texte = texte.replace(//g,'&bull;'); // 149 95
        texte = texte.replace(//g,'&ndash;'); // 150 96
        texte = texte.replace(//g,'&mdash;'); // 151 97
        texte = texte.replace(//g,'&tilde;'); // 152 98
        texte = texte.replace(//g,'&trade;'); // 153 99
        texte = texte.replace(//g,'&scaron;'); // 154 9A
        texte = texte.replace(//g,'&rsaquo;'); // 155 9B
        texte = texte.replace(//g,'&oelig;'); // 156 9C
        texte = texte.replace(//g,'&#357;'); // 157 9D
        texte = texte.replace(//g,'&#382;'); // 158 9E
        texte = texte.replace(//g,'&Yuml;'); // 159 9F
        // texte = texte.replace(/ /g,'&nbsp;'); // 160 A0
        texte = texte.replace(//g,'&iexcl;'); // 161 A1
        texte = texte.replace(//g,'&cent;'); // 162 A2
        texte = texte.replace(//g,'&pound;'); // 163 A3
        //texte = texte.replace(/ /g,'&curren;'); // 164 A4
        texte = texte.replace(//g,'&yen;'); // 165 A5
        texte = texte.replace(//g,'&brvbar;'); // 166 A6
        texte = texte.replace(//g,'&sect;'); // 167 A7
        texte = texte.replace(//g,'&uml;'); // 168 A8
        texte = texte.replace(//g,'&copy;'); // 169 A9
        texte = texte.replace(//g,'&ordf;'); // 170 AA
        texte = texte.replace(//g,'&laquo;'); // 171 AB
        texte = texte.replace(//g,'&not;'); // 172 AC
        texte = texte.replace(//g,'&shy;'); // 173 AD
        texte = texte.replace(//g,'&reg;'); // 174 AE
        texte = texte.replace(//g,'&macr;'); // 175 AF
        texte = texte.replace(//g,'&deg;'); // 176 B0
        texte = texte.replace(//g,'&plusmn;'); // 177 B1
        texte = texte.replace(//g,'&sup2;'); // 178 B2
        texte = texte.replace(//g,'&sup3;'); // 179 B3
        texte = texte.replace(//g,'&acute;'); // 180 B4
        texte = texte.replace(//g,'&micro;'); // 181 B5
        texte = texte.replace(//g,'&para'); // 182 B6
        texte = texte.replace(//g,'&middot;'); // 183 B7
        texte = texte.replace(//g,'&cedil;'); // 184 B8
        texte = texte.replace(//g,'&sup1;'); // 185 B9
        texte = texte.replace(//g,'&ordm;'); // 186 BA
        texte = texte.replace(//g,'&raquo;'); // 187 BB
        texte = texte.replace(//g,'&frac14;'); // 188 BC
        texte = texte.replace(//g,'&frac12;'); // 189 BD
        texte = texte.replace(//g,'&frac34;'); // 190 BE
        texte = texte.replace(//g,'&iquest;'); // 191 BF
        texte = texte.replace(//g,'&Agrave;'); // 192 C0
        texte = texte.replace(//g,'&Aacute;'); // 193 C1
        texte = texte.replace(//g,'&Acirc;'); // 194 C2
        texte = texte.replace(//g,'&Atilde;'); // 195 C3
        texte = texte.replace(//g,'&Auml;'); // 196 C4
        texte = texte.replace(//g,'&Aring;'); // 197 C5
        texte = texte.replace(//g,'&AElig;'); // 198 C6
        texte = texte.replace(//g,'&Ccedil;'); // 199 C7
        texte = texte.replace(//g,'&Egrave;'); // 200 C8
        texte = texte.replace(//g,'&Eacute;'); // 201 C9
        texte = texte.replace(//g,'&Ecirc;'); // 202 CA
        texte = texte.replace(//g,'&Euml;'); // 203 CB
        texte = texte.replace(//g,'&Igrave;'); // 204 CC
        texte = texte.replace(//g,'&Iacute;'); // 205 CD
        texte = texte.replace(//g,'&Icirc;'); // 206 CE
        texte = texte.replace(//g,'&Iuml;'); // 207 CF
        texte = texte.replace(//g,'&ETH;'); // 208 D0
        texte = texte.replace(//g,'&Ntilde;'); // 209 D1
        texte = texte.replace(//g,'&Ograve;'); // 210 D2
        texte = texte.replace(//g,'&Oacute;'); // 211 D3
        texte = texte.replace(//g,'&Ocirc;'); // 212 D4
        texte = texte.replace(//g,'&Otilde;'); // 213 D5
        texte = texte.replace(//g,'&Ouml;'); // 214 D6
        texte = texte.replace(//g,'&times;'); // 215 D7
        texte = texte.replace(//g,'&Oslash;'); // 216 D8
        texte = texte.replace(//g,'&Ugrave;'); // 217 D9
        texte = texte.replace(//g,'&Uacute;'); // 218 DA
        texte = texte.replace(//g,'&Ucirc;'); // 219 DB
        texte = texte.replace(//g,'&Uuml;'); // 220 DC
        texte = texte.replace(//g,'&Yacute;'); // 221 DD
        texte = texte.replace(//g,'&THORN;'); // 222 DE
        texte = texte.replace(//g,'&szlig;'); // 223 DF
        texte = texte.replace(//g,'&agrave;'); // 224 E0
        texte = texte.replace(//g,'&aacute;'); // 225 E1
        texte = texte.replace(//g,'&acirc;'); // 226 E2
        texte = texte.replace(//g,'&atilde;'); // 227 E3
        texte = texte.replace(//g,'&auml;'); // 228 E4
        texte = texte.replace(//g,'&aring;'); // 229 E5
        texte = texte.replace(//g,'&aelig;'); // 230 E6
        texte = texte.replace(//g,'&ccedil;'); // 231 E7
        texte = texte.replace(//g,'&egrave;'); // 232 E8
        texte = texte.replace(//g,'&eacute;'); // 233 E9
        texte = texte.replace(//g,'&ecirc;'); // 234 EA
        texte = texte.replace(//g,'&euml;'); // 235 EB
        texte = texte.replace(//g,'&igrave;'); // 236 EC
        texte = texte.replace(//g,'&iacute;'); // 237 ED
        texte = texte.replace(//g,'&icirc;'); // 238 EE
        texte = texte.replace(//g,'&iuml;'); // 239 EF
        texte = texte.replace(//g,'&eth;'); // 240 F0
        texte = texte.replace(//g,'&ntilde;'); // 241 F1
        texte = texte.replace(//g,'&ograve;'); // 242 F2
        texte = texte.replace(//g,'&oacute;'); // 243 F3
        texte = texte.replace(//g,'&ocirc;'); // 244 F4
        texte = texte.replace(//g,'&otilde;'); // 245 F5
        texte = texte.replace(//g,'&ouml;'); // 246 F6
        texte = texte.replace(//g,'&divide;'); // 247 F7
        texte = texte.replace(//g,'&oslash;'); // 248 F8
        texte = texte.replace(//g,'&ugrave;'); // 249 F9
        texte = texte.replace(//g,'&uacute;'); // 250 FA
        texte = texte.replace(//g,'&ucirc;'); // 251 FB
        texte = texte.replace(//g,'&uuml;'); // 252 FC
        texte = texte.replace(//g,'&yacute;'); // 253 FD
        texte = texte.replace(//g,'&thorn;'); // 254 FE
        texte = texte.replace(//g,'&yuml;'); // 255 FF
        
        return texte;
    }
    
    function get_html_translation_table (table, quote_style) {
        // Returns the internal translation table used by htmlspecialchars and htmlentities  
        // 
        // version: 1008.1718
        // discuss at: http://phpjs.org/functions/get_html_translation_table
        // +   original by: Philip Peterson
        // +    revised by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
        // +   bugfixed by: noname
        // +   bugfixed by: Alex
        // +   bugfixed by: Marco
        // +   bugfixed by: madipta
        // +   improved by: KELAN
        // +   improved by: Brett Zamir (http://brett-zamir.me)
        // +   bugfixed by: Brett Zamir (http://brett-zamir.me)
        // +      input by: Frank Forte
        // +   bugfixed by: T.Wild
        // +      input by: Ratheous
        // %          note: It has been decided that we're not going to add global
        // %          note: dependencies to php.js, meaning the constants are not
        // %          note: real constants, but strings instead. Integers are also supported if someone
        // %          note: chooses to create the constants themselves.
        // *     example 1: get_html_translation_table('HTML_SPECIALCHARS');
        // *     returns 1: {'"': '&quot;', '&': '&amp;', '<': '&lt;', '>': '&gt;'}
        
        var entities = {}, hash_map = {}, decimal = 0, symbol = '';
        var constMappingTable = {}, constMappingQuoteStyle = {};
        var useTable = {}, useQuoteStyle = {};
        
        // Translate arguments
        constMappingTable[0]      = 'HTML_SPECIALCHARS';
        constMappingTable[1]      = 'HTML_ENTITIES';
        constMappingQuoteStyle[0] = 'ENT_NOQUOTES';
        constMappingQuoteStyle[2] = 'ENT_COMPAT';
        constMappingQuoteStyle[3] = 'ENT_QUOTES';
     
        useTable       = !isNaN(table) ? constMappingTable[table] : table ? table.toUpperCase() : 'HTML_SPECIALCHARS';
        useQuoteStyle = !isNaN(quote_style) ? constMappingQuoteStyle[quote_style] : quote_style ? quote_style.toUpperCase() : 'ENT_COMPAT';
     
        if (useTable !== 'HTML_SPECIALCHARS' && useTable !== 'HTML_ENTITIES') {
            throw new Error("Table: "+useTable+' not supported');
            // return false;
        }
     
        entities['38'] = '&amp;';
        if (useTable === 'HTML_ENTITIES') {
            entities['160'] = '&nbsp;';
            entities['161'] = '&iexcl;';
            entities['162'] = '&cent;';
            entities['163'] = '&pound;';
            entities['164'] = '&curren;';
            entities['165'] = '&yen;';
            entities['166'] = '&brvbar;';
            entities['167'] = '&sect;';
            entities['168'] = '&uml;';
            entities['169'] = '&copy;';
            entities['170'] = '&ordf;';
            entities['171'] = '&laquo;';
            entities['172'] = '&not;';
            entities['173'] = '&shy;';
            entities['174'] = '&reg;';
            entities['175'] = '&macr;';
            entities['176'] = '&deg;';
            entities['177'] = '&plusmn;';
            entities['178'] = '&sup2;';
            entities['179'] = '&sup3;';
            entities['180'] = '&acute;';
            entities['181'] = '&micro;';
            entities['182'] = '&para;';
            entities['183'] = '&middot;';
            entities['184'] = '&cedil;';
            entities['185'] = '&sup1;';
            entities['186'] = '&ordm;';
            entities['187'] = '&raquo;';
            entities['188'] = '&frac14;';
            entities['189'] = '&frac12;';
            entities['190'] = '&frac34;';
            entities['191'] = '&iquest;';
            entities['192'] = '&Agrave;';
            entities['193'] = '&Aacute;';
            entities['194'] = '&Acirc;';
            entities['195'] = '&Atilde;';
            entities['196'] = '&Auml;';
            entities['197'] = '&Aring;';
            entities['198'] = '&AElig;';
            entities['199'] = '&Ccedil;';
            entities['200'] = '&Egrave;';
            entities['201'] = '&Eacute;';
            entities['202'] = '&Ecirc;';
            entities['203'] = '&Euml;';
            entities['204'] = '&Igrave;';
            entities['205'] = '&Iacute;';
            entities['206'] = '&Icirc;';
            entities['207'] = '&Iuml;';
            entities['208'] = '&ETH;';
            entities['209'] = '&Ntilde;';
            entities['210'] = '&Ograve;';
            entities['211'] = '&Oacute;';
            entities['212'] = '&Ocirc;';
            entities['213'] = '&Otilde;';
            entities['214'] = '&Ouml;';
            entities['215'] = '&times;';
            entities['216'] = '&Oslash;';
            entities['217'] = '&Ugrave;';
            entities['218'] = '&Uacute;';
            entities['219'] = '&Ucirc;';
            entities['220'] = '&Uuml;';
            entities['221'] = '&Yacute;';
            entities['222'] = '&THORN;';
            entities['223'] = '&szlig;';
            entities['224'] = '&agrave;';
            entities['225'] = '&aacute;';
            entities['226'] = '&acirc;';
            entities['227'] = '&atilde;';
            entities['228'] = '&auml;';
            entities['229'] = '&aring;';
            entities['230'] = '&aelig;';
            entities['231'] = '&ccedil;';
            entities['232'] = '&egrave;';
            entities['233'] = '&eacute;';
            entities['234'] = '&ecirc;';
            entities['235'] = '&euml;';
            entities['236'] = '&igrave;';
            entities['237'] = '&iacute;';
            entities['238'] = '&icirc;';
            entities['239'] = '&iuml;';
            entities['240'] = '&eth;';
            entities['241'] = '&ntilde;';
            entities['242'] = '&ograve;';
            entities['243'] = '&oacute;';
            entities['244'] = '&ocirc;';
            entities['245'] = '&otilde;';
            entities['246'] = '&ouml;';
            entities['247'] = '&divide;';
            entities['248'] = '&oslash;';
            entities['249'] = '&ugrave;';
            entities['250'] = '&uacute;';
            entities['251'] = '&ucirc;';
            entities['252'] = '&uuml;';
            entities['253'] = '&yacute;';
            entities['254'] = '&thorn;';
            entities['255'] = '&yuml;';
        }
     
        if (useQuoteStyle !== 'ENT_NOQUOTES') {
            entities['34'] = '&quot;';
        }
        if (useQuoteStyle === 'ENT_QUOTES') {
            entities['39'] = '&#39;';
        }
        entities['60'] = '&lt;';
        entities['62'] = '&gt;';
     
     
        // ascii decimals to real symbols
        for (decimal in entities) {
            symbol = String.fromCharCode(decimal);
            hash_map[symbol] = entities[decimal];
        }
        
        return hash_map;
    }
    
    function html_entities_decode (string, quote_style) {
        // Convert all HTML entities to their applicable characters  
        // 
        // version: 1008.1718
        // discuss at: http://phpjs.org/functions/html_entity_decode
        // +   original by: john (http://www.jd-tech.net)
        // +      input by: ger
        // +   improved by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
        // +    revised by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
        // +   bugfixed by: Onno Marsman
        // +   improved by: marc andreu
        // +    revised by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
        // +      input by: Ratheous
        // +   bugfixed by: Brett Zamir (http://brett-zamir.me)
        // +      input by: Nick Kolosov (http://sammy.ru)
        // +   bugfixed by: Fox
        // -    depends on: get_html_translation_table
        // *     example 1: html_entity_decode('Kevin &amp; van Zonneveld');
        // *     returns 1: 'Kevin & van Zonneveld'
        // *     example 2: html_entity_decode('&amp;lt;');
        // *     returns 2: '&lt;'
        var hash_map = {}, symbol = '', tmp_str = '', entity = '';
        tmp_str = string.toString();
        
        if (false === (hash_map = this.get_html_translation_table('HTML_ENTITIES', quote_style))) {
            return false;
        }
     
        // fix &amp; problem
        // http://phpjs.org/functions/get_html_translation_table:416#comment_97660
        delete(hash_map['&']);
        hash_map['&'] = '&amp;';
     
        for (symbol in hash_map) {
            entity = hash_map[symbol];
            tmp_str = tmp_str.split(entity).join(symbol);
        }
        tmp_str = tmp_str.split('&#039;').join("'");
        
        return tmp_str;
    }
    
    function html_entity_decode(text, receiverId) {
        var result = "";
        
        // get the receiver and put only a textarea inside of it
        var oReceiver       = document.getElementById(receiverId);
        oReceiver.innerHTML = "<textarea id='html_entity_decoder'>" + text + "</textarea>";
        
        // get the textarea we just created
        var oTextArea = document.getElementById("html_entity_decoder");
        
        // get the decoded string
        result = oTextArea.value;
        
        // reset the receiver's contents
        oReceiver.innerHTML = "";
        
        return result;
    }
    
    String.prototype.htmlEntities = function () {
       return this.replace(/&/g,'&amp;').replace(/</g,'&lt;').replace(/>/g,'&gt;');
    };
    
    String.prototype.stripTags = function () {
       return this.replace(/<([^>]+)>/g,'');
    }
    
    function removeAccents(text) {
        var accentuation = "";
        var conversion   = "AAAAAAaaaaaaOOOOOOooooooEEEEeeeeIIIIiiiiUUUUuuuuyNnCc";
        
        var result = "";
        for(var index = 0; index < text.length; index += 1) {
            var character = text.charAt(index);
            
            var charIndex = accentuation.indexOf(character);
            if(charIndex != -1) {
                var convertedChar = conversion.charAt(charIndex);
                
                if(convertedChar) {
                    result += convertedChar + '';
                }
            }
            else {
                result += character+'';
            }
        }
        
        return result;
    }
    
    function escape4JS(texte) {
        if(typeof(texte) == "string") {
            texte = texte.replace(/"/g,"''");
            texte = texte.replace(/</g,'');
            texte = texte.replace(/>/g,'');
        }
        
        return texte;
    }
    
    function escape4JSON(texte) {
        if(typeof(texte) == "string") {
            texte = texte.replace(/"/g,"''");
            texte = texte.replace(/</g,'');
            texte = texte.replace(/>/g,'');
            texte = replace2TextArea(texte);
        }
        
        return texte;
    }
    
    function escape4db(texte, character) {
        if(typeof(texte) == "string") {
            texte = texte.replace(/\\\\/gi, "");
            if(character && character != null) {
                texte = texte.replace(new RegExp(character, 'gi'), '\\'+character);
            }
        }
        return texte;
    }
    
    function replace2TextArea(texte) {
        texte = texte.replace(/\r\n|\n\r|[\r\n]/g, '[br]');
        
        return texte;
    }
    
    function replace4TextArea(texte) {
        texte = texte.replace(/\[br\]/g, "\r\n");
        
        return texte;
    }
    
    function decode(str) {
         return unescape(str.replace(/\+/g, " "));
    }
    
    
    function str_shave(str) {
        str          = str.replace(String.fromCharCode(160), ' ');
        str          = str.replace(/(&#160;)|(&nbsp;)/g, " ").replace(/(^\s+)|(\s\s+)|(\s+$)/g, "");
        var charCode = str.charCodeAt(0);
        if(str == ' ' || (str.length == 1 && charCode == 160) || str == '&nbsp;' || str == '&#160;') str = '';
        return str;
    }
}

function collapseCellularFormat(cellular) {
    cellular = cellular.replace(/\(/g, "");
    cellular = cellular.replace(/\)/g, "");
    cellular = cellular.replace(/-/g, "");
    cellular = cellular.replace(/\./g, "");
    cellular = cellular.strim();
    
    return cellular;
}

// ###### Converse file size to string ######
{
    function convertFileSize(sSize)
    {
        iSize = sSize;
        if(iSize > 1000000)
        {
            strSize = (iSize / 1000 / 1000).toFixed(2) + " Mo";    
        }
        else
        {
            strSize = (iSize / 1000).toFixed(2) + " Ko";    
        }
        return strSize;
    }
}

// ###### String prototype ######
{
    String.prototype.cleanup = function() {
        sTexte = this;
        sTexte = sTexte.replace(/\s/g, "_" );
        sTexte = sTexte.replace(/"/g,''); // 34 22
        sTexte = sTexte.replace(/&/g,''); // 38 26
        sTexte = sTexte.replace(/\'/g,''); // 39 27
        sTexte = sTexte.replace(/</g,''); // 60 3C
        sTexte = sTexte.replace(/>/g,''); // 62 3E
        sTexte = sTexte.replace(/\^/g,''); // 94 5E
        sTexte = sTexte.replace(//g,''); // 145 91
        sTexte = sTexte.replace(//g,''); // 146 92
        sTexte = sTexte.replace(//g,''); // 147 93
        sTexte = sTexte.replace(//g,''); // 148 94
        sTexte = sTexte.replace(//g,''); // 149 95
        sTexte = sTexte.replace(//g,''); // 150 96
        sTexte = sTexte.replace(//g,''); // 151 97
        sTexte = sTexte.replace(//g,''); // 152 98
        sTexte = sTexte.replace(//g,''); // 153 99
        sTexte = sTexte.replace(//g,'s'); // 154 9A
        sTexte = sTexte.replace(//g,''); // 155 9B
        sTexte = sTexte.replace(//g,'oe'); // 156 9C
        sTexte = sTexte.replace(//g,''); // 157 9D
        sTexte = sTexte.replace(//g,'z'); // 158 9E
        sTexte = sTexte.replace(//g,'Y'); // 159 9F
        sTexte = sTexte.replace(//g,''); // 161 A1
        sTexte = sTexte.replace(//g,''); // 162 A2
        sTexte = sTexte.replace(//g,''); // 163 A3
        sTexte = sTexte.replace(//g,''); // 165 A5
        sTexte = sTexte.replace(//g,''); // 166 A6
        sTexte = sTexte.replace(//g,''); // 167 A7
        sTexte = sTexte.replace(//g,''); // 168 A8
        sTexte = sTexte.replace(//g,''); // 169 A9
        sTexte = sTexte.replace(//g,''); // 170 AA
        sTexte = sTexte.replace(//g,''); // 171 AB
        sTexte = sTexte.replace(//g,''); // 172 AC
        sTexte = sTexte.replace(//g,''); // 173 AD
        sTexte = sTexte.replace(//g,''); // 174 AE
        sTexte = sTexte.replace(//g,''); // 175 AF
        sTexte = sTexte.replace(//g,''); // 176 B0
        sTexte = sTexte.replace(//g,''); // 177 B1
        sTexte = sTexte.replace(//g,''); // 178 B2
        sTexte = sTexte.replace(//g,''); // 179 B3
        sTexte = sTexte.replace(//g,''); // 180 B4
        sTexte = sTexte.replace(//g,'u'); // 181 B5
        sTexte = sTexte.replace(//g,''); // 182 B6
        sTexte = sTexte.replace(//g,''); // 183 B7
        sTexte = sTexte.replace(//g,''); // 184 B8
        sTexte = sTexte.replace(//g,''); // 185 B9
        sTexte = sTexte.replace(//g,''); // 186 BA
        sTexte = sTexte.replace(//g,''); // 187 BB
        sTexte = sTexte.replace(//g,''); // 188 BC
        sTexte = sTexte.replace(//g,''); // 189 BD
        sTexte = sTexte.replace(//g,''); // 190 BE
        sTexte = sTexte.replace(//g,''); // 191 BF
        sTexte = sTexte.replace(//g,'A'); // 192 C0
        sTexte = sTexte.replace(//g,'A'); // 193 C1
        sTexte = sTexte.replace(//g,'A'); // 194 C2
        sTexte = sTexte.replace(//g,'A'); // 195 C3
        sTexte = sTexte.replace(//g,'A'); // 196 C4
        sTexte = sTexte.replace(//g,'A'); // 197 C5
        sTexte = sTexte.replace(//g,'AE'); // 198 C6
        sTexte = sTexte.replace(//g,'C'); // 199 C7
        sTexte = sTexte.replace(//g,'E'); // 200 C8
        sTexte = sTexte.replace(//g,'E'); // 201 C9
        sTexte = sTexte.replace(//g,'E'); // 202 CA
        sTexte = sTexte.replace(//g,'E'); // 203 CB
        sTexte = sTexte.replace(//g,'I'); // 204 CC
        sTexte = sTexte.replace(//g,'I'); // 205 CD
        sTexte = sTexte.replace(//g,'I'); // 206 CE
        sTexte = sTexte.replace(//g,'I'); // 207 CF
        sTexte = sTexte.replace(//g,'D'); // 208 D0
        sTexte = sTexte.replace(//g,'N'); // 209 D1
        sTexte = sTexte.replace(//g,'O'); // 210 D2
        sTexte = sTexte.replace(//g,'O'); // 211 D3
        sTexte = sTexte.replace(//g,'O'); // 212 D4
        sTexte = sTexte.replace(//g,'O'); // 213 D5
        sTexte = sTexte.replace(//g,'O'); // 214 D6
        sTexte = sTexte.replace(//g,'x'); // 215 D7
        sTexte = sTexte.replace(//g,'O'); // 216 D8
        sTexte = sTexte.replace(//g,'U'); // 217 D9
        sTexte = sTexte.replace(//g,'U'); // 218 DA
        sTexte = sTexte.replace(//g,'U'); // 219 DB
        sTexte = sTexte.replace(//g,'U'); // 220 DC
        sTexte = sTexte.replace(//g,'Y'); // 221 DD
        sTexte = sTexte.replace(//g,''); // 222 DE
        sTexte = sTexte.replace(//g,''); // 223 DF
        sTexte = sTexte.replace(//g,'a'); // 224 E0
        sTexte = sTexte.replace(//g,'a'); // 225 E1
        sTexte = sTexte.replace(//g,'a'); // 226 E2
        sTexte = sTexte.replace(//g,'a'); // 227 E3
        sTexte = sTexte.replace(//g,'a'); // 228 E4
        sTexte = sTexte.replace(//g,'a'); // 229 E5
        sTexte = sTexte.replace(//g,'ae'); // 230 E6
        sTexte = sTexte.replace(//g,'c'); // 231 E7
        sTexte = sTexte.replace(//g,'c'); // 232 E8
        sTexte = sTexte.replace(//g,'e'); // 233 E9
        sTexte = sTexte.replace(//g,'e'); // 234 EA
        sTexte = sTexte.replace(//g,'e'); // 235 EB
        sTexte = sTexte.replace(//g,'i'); // 236 EC
        sTexte = sTexte.replace(//g,'i;'); // 237 ED
        sTexte = sTexte.replace(//g,'i'); // 238 EE
        sTexte = sTexte.replace(//g,'i'); // 239 EF
        sTexte = sTexte.replace(//g,'d'); // 240 F0
        sTexte = sTexte.replace(//g,'n'); // 241 F1
        sTexte = sTexte.replace(//g,'o'); // 242 F2
        sTexte = sTexte.replace(//g,'o'); // 243 F3
        sTexte = sTexte.replace(//g,'o'); // 244 F4
        sTexte = sTexte.replace(//g,'o'); // 245 F5
        sTexte = sTexte.replace(//g,'o'); // 246 F6
        sTexte = sTexte.replace(//g,''); // 247 F7
        sTexte = sTexte.replace(//g,''); // 248 F8
        sTexte = sTexte.replace(//g,'u'); // 249 F9
        sTexte = sTexte.replace(//g,'u'); // 250 FA
        sTexte = sTexte.replace(//g,'u'); // 251 FB
        sTexte = sTexte.replace(//g,'u'); // 252 FC
        sTexte = sTexte.replace(//g,'y'); // 253 FD
        sTexte = sTexte.replace(//g,''); // 254 FE
        sTexte = sTexte.replace(//g,'y'); // 255 FF
        
        return sTexte;
    }
    
    /* From : http://www.somacon.com/p355.php */
    String.prototype.trim = function() {
    	return this.replace(/^\s+|\s+$/g,"");
    }
    String.prototype.ltrim = function() {
    	return this.replace(String.fromCharCode(160), ' ').replace(/^\s+/,"");
    }
    String.prototype.rtrim = function() {
    	return this.replace(/\s+$/,"");
    }
    String.prototype.mtrim = function() {
    	return this.replace(/\s/g,"_");
    }
    String.prototype.strim = function() {
    	return this.replace(/\s/g,"");
    }
    
    String.prototype.shave = function() {
    	return str_shave(this);
    }
}

// ###### Array prototype ######
{    
    Array.prototype.in_array = function ( obj ) {
        var len = this.length;
        for(var x = 0; x <= len; x++) {
            if(this[x] == obj) {
                return true;
            }
        }
        return false;
    }
    
    Array.prototype.removeItems = function(itemsToRemove) {
        if (!/Array/.test(itemsToRemove.constructor)) {
            itemsToRemove = [ itemsToRemove ];
        }
        
        var j;
        for(var i = 0; i < itemsToRemove.length; i++) {
            j = 0;
            while(j < this.length) {
                if(this[j] == itemsToRemove[i]) {
                    this.splice(j, 1);
                }
                else {
                    j++;
                }
            }
        }
    }
}

// ###### Number prototype ######
{
    Number.prototype.formatMoney = function(c, d, t) {
        var n = this, c = isNaN(c = Math.abs(c)) ? 2 : c, d = d == undefined ? "," : d, t = t == undefined ? "." : t, s = n < 0 ? "-" : "",
        i = parseInt(n = Math.abs(+n || 0).toFixed(c)) + "", j = (j = i.length) > 3 ? j % 3 : 0;
        return s + (j ? i.substr(0, j) + t : "") + i.substr(j).replace(/(\d{3})(?=\d)/g, "$1" + t)
        + (c ? d + Math.abs(n - i).toFixed(c).slice(2) : "");
    };
    
    Number.prototype.round2 = function() {
        var n = this;
        return Math.round(n*100+((n*1000)%10>4?1:0))/100;
    };
}

function insertAtCursor(myField, myValue) {
    //IE support
    if (document.selection) {
        myField.focus();
        sel = document.selection.createRange();
        sel.text = myValue;
    }

    //MOZILLA/NETSCAPE support
    else if (myField.selectionStart || myField.selectionStart == '0') {
        var startPos = myField.selectionStart;
        var endPos = myField.selectionEnd;
        myField.value = myField.value.substring(0, startPos) + myValue + myField.value.substring(endPos, myField.value.length);
    } else {
        myField.value += myValue;
    }
}

// ###### PHP function ######
{
    
    
    function trimTextAreas()
    {
        for(iForm = 0; iForm < document.forms.length; iForm ++)
        {
            oForm = document.forms[iForm];
            for(iElement = 0; iElement < oForm.elements.length; iElement ++)
            {
                oElement = oForm.elements[iElement];
                if(oElement.nodeName.toLowerCase() == 'textarea')
                {
                    oElement.value = oElement.value.trim();
                }
            }   
        }
    }
    
    function array_key_exists ( key, search ) {
        // Checks if the given key or index exists in the array  
        // 
        // version: 1008.1718
        // discuss at: http://phpjs.org/functions/array_key_exists
        // +   original by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
        // +   improved by: Felix Geisendoerfer (http://www.debuggable.com/felix)
        // *     example 1: array_key_exists('kevin', {'kevin': 'van Zonneveld'});
        // *     returns 1: true
        // input sanitation
        if (!search || (search.constructor !== Array && search.constructor !== Object)){
            return false;
        }
     
        return key in search;
    } 
    
    function array_keys (input, search_value, argStrict) {
        // Return just the keys from the input array, optionally only for the specified search_value  
        // 
        // version: 1008.1718
        // discuss at: http://phpjs.org/functions/array_keys
        // +   original by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
        // +      input by: Brett Zamir (http://brett-zamir.me)
        // +   bugfixed by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
        // *     example 1: array_keys( {firstname: 'Kevin', surname: 'van Zonneveld'} );
        // *     returns 1: {0: 'firstname', 1: 'surname'}
        
        var tmp_arr = {}, strict = !!argStrict, include = true, cnt = 0;
        var key = '';
        
        for (key in input) {
            include = true;
            if (search_value != undefined) {
                if (strict && input[key] !== search_value){
                    include = false;
                } else if (input[key] != search_value){
                    include = false;
                }
            }
            
            if (include) {
                tmp_arr[cnt] = key;
                cnt++;
            }
        }
        
        return tmp_arr;
    }   

    function str_pad (input, pad_length, pad_string, pad_type) {
        // Returns input string padded on the left or right to specified length with pad_string  
        // 
        // version: 909.322
        // discuss at: http://phpjs.org/functions/str_pad    // +   original by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
        // + namespaced by: Michael White (http://getsprink.com)
        // +      input by: Marco van Oort
        // +   bugfixed by: Brett Zamir (http://brett-zamir.me)
        // *     example 1: str_pad('Kevin van Zonneveld', 30, '-=', 'STR_PAD_LEFT');    // *     returns 1: '-=-=-=-=-=-Kevin van Zonneveld'
        // *     example 2: str_pad('Kevin van Zonneveld', 30, '-', 'STR_PAD_BOTH');
        // *     returns 2: '------Kevin van Zonneveld-----'
        var half = '', pad_to_go;
         var str_pad_repeater = function (s, len) {
            var collect = '', i;
     
            while (collect.length < len) {collect += s;}
            collect = collect.substr(0,len); 
            return collect;
        };
     
        input += '';    pad_string = pad_string !== undefined ? pad_string : ' ';
        
        if (pad_type != 'STR_PAD_LEFT' && pad_type != 'STR_PAD_RIGHT' && pad_type != 'STR_PAD_BOTH') { pad_type = 'STR_PAD_RIGHT'; }
        if ((pad_to_go = pad_length - input.length) > 0) {
            if (pad_type == 'STR_PAD_LEFT') { input = str_pad_repeater(pad_string, pad_to_go) + input; }        else if (pad_type == 'STR_PAD_RIGHT') { input = input + str_pad_repeater(pad_string, pad_to_go); }
            else if (pad_type == 'STR_PAD_BOTH') {
                half = str_pad_repeater(pad_string, Math.ceil(pad_to_go/2));
                input = half + input + half;
                input = input.substr(0, pad_length);        }
        }
     
        return input;
    }
}

// ###### Detect function ######
{
    function getInternetExplorerVersion() {
    
        var rv = -1; // Return value assumes failure.
    
        if (navigator.appName == 'Microsoft Internet Explorer') {
    
            var ua = navigator.userAgent;
    
            var re = new RegExp("MSIE ([0-9]{1,}[\.0-9]{0,})");
    
            if (re.exec(ua) != null)
    
                rv = parseFloat(RegExp.$1);
    
        }
    
        return rv;
    
    }
    
    function getFunctionTypeOf() {
        var v_typeof = "function";
        if(document.all) { // IE
            v_typeof = "object";
        }
        
        return v_typeof;
    }
    
    function checkPopupBlocked(oPopup, funcName) {
        checkPopupBlocked.funcName = funcName;
        
        // if any other browser than Chrome, and popup is blocked...
        if(!oPopup) {
            // _checkPopupBlocked_result(true);
            return true;
        }
        else {
            oPopup.onload = function() {
                setTimeout(function() {
                    // if Chrome, and popup is blocked...
                    if(oPopup.screenX === 0) {
                        // alert("Failed for Chrome");
                        _checkPopupBlocked_result(true);
                        // return true;
                    }
                    else {
                        _checkPopupBlocked_result(false);
                    }
                }, 0);
            };
        }
        // var isBlocked = checkPopupBlocked.isBlocked;
        // checkPopupBlocked.isBlocked = null;
        // return isBlocked;
    }
    checkPopupBlocked.funcName = null;
    
    function _checkPopupBlocked_result(result) {
        if(checkPopupBlocked.funcName && checkPopupBlocked.funcName != "") {
            var oArgs = new Array();
            oArgs[oArgs.length] = result;
            
            window[checkPopupBlocked.funcName].apply(window, oArgs);
        }
    }
}

// ###### Currency function ######
{
    function getCurrencySign()
    {
        var sign = "$";
        var currencyCode = User.getCurrencyCode();
        
        // Euro
        if(currencyCode == "EUR")
        {
            //sign = "&#8364;";    
            sign = "\u20ac";
        }
        
        return sign;
    }
}
