
/********************************************************************/
//gestion du curseur dans un champ
/********************************************************************/
var carPos=0;

var os = 0
var oe = 0
/** renommage de la fonction */
function input_update(o) {
	var t = o.value, s = getSelectionStart(o), e = getSelectionEnd(o)
	if (s == os && e == oe) return
		carPos=s;
		os = s
		oe = e
		return true
}

function getSelectionStart(o) {
	if (o.createTextRange) {
		var r = document.selection.createRange().duplicate()
		r.moveEnd('character', o.value.length)
		if (r.text == '') return o.value.length
		return o.value.lastIndexOf(r.text)
	} else return o.selectionStart
}

function getSelectionEnd(o) {
	if (o.createTextRange) {
		var r = document.selection.createRange().duplicate()
		r.moveStart('character', -o.value.length)
		return r.text.length
	} else return o.selectionEnd
}
/********************************************************************/
//gestion de la conversion ACE
/********************************************************************/
//Javascript UTF16 converter created by some@domain.name
//This implementation is released to public domain
var utf16 = {
    decode:function(input){
        var output = [], i=0, len=input.length,value,extra;
        while (i < len) {
                value = input.charCodeAt(i++);
                if ((value & 0xF800) === 0xD800) {
                        extra = input.charCodeAt(i++);
                        if ( ((value & 0xFC00) !== 0xD800) || ((extra & 0xFC00) !== 0xDC00) ) {
                                throw new RangeError("UTF-16(decode): Illegal UTF-16 sequence");
                        }
                        value = ((value & 0x3FF) << 10) + (extra & 0x3FF) + 0x10000;
                }
                output.push(value);
        }
        return output;
    },
    encode:function(input){
        var output = [], i=0, len=input.length,value;
        while (i < len) {
                value = input[i++];
                if ( (value & 0xF800) === 0xD800 ) {
                        throw new RangeError("UTF-16(encode): Illegal UTF-16 value");
                }
                if (value > 0xFFFF) {
                        value -= 0x10000;
                        output.push(String.fromCharCode(((value >>>10) & 0x3FF) | 0xD800));
                        value = 0xDC00 | (value & 0x3FF);
                }
                output.push(String.fromCharCode(value));
        }
        return output.join("");
    }
}

//Javascript Punycode converter derived from example in RFC3492.
//This implementation is created by some@domain.name and released to public domain    
var punycode = new function Punycode() {
    var initial_n = 0x80;
    var initial_bias = 72;
        var delimiter = "\x2D";
    var base = 36;
    var damp = 700;
    var tmin=1;
    var tmax=26;
    var skew=38;

    var maxint = 0x7FFFFFFF;
    // decode_digit(cp) returns the numeric value of a basic code 
    // point (for use in representing integers) in the range 0 to
    // base-1, or base if cp is does not represent a value.

    function decode_digit(cp) {
        return  cp - 48 < 10 ? cp - 22 :  cp - 65 < 26 ? cp - 65 : cp - 97 < 26 ? cp - 97 : base;
    }

    // encode_digit(d,flag) returns the basic code point whose value      
    // (when used for representing integers) is d, which needs to be in   
    // the range 0 to base-1.  The lowercase form is used unless flag is  
    // nonzero, in which case the uppercase form is used.  The behavior   
    // is undefined if flag is nonzero and digit d has no uppercase form. 

    function encode_digit(d, flag) {
        return d + 22 + 75 * (d < 26) - ((flag != 0) << 5);
        //  0..25 map to ASCII a..z or A..Z 
        // 26..35 map to ASCII 0..9         
    }
    //** Bias adaptation function **
    function adapt(delta, numpoints, firsttime ) {
        var k;
        delta = firsttime ? Math.floor(delta / damp) : (delta >> 1);
        delta += Math.floor(delta / numpoints);

        for (k = 0;  delta > (((base - tmin) * tmax) >> 1);  k += base) {
                delta = Math.floor(delta / ( base - tmin ));
        }
        return Math.floor(k + (base - tmin + 1) * delta / (delta + skew));
    }

    // encode_basic(bcp,flag) forces a basic code point to lowercase if flag is zero,
    // uppercase if flag is nonzero, and returns the resulting code point.
    // The code point is unchanged if it  is caseless.
    // The behavior is undefined if bcp is not a basic code point.                                                   

    function encode_basic(bcp, flag) {
        bcp -= (bcp - 97 < 26) << 5;
        return bcp + ((!flag && (bcp - 65 < 26)) << 5);
    }

    // Main decode
    this.decode=function(input,preserveCase) {
        // Dont use uft16
        var output=[];
        var case_flags=[];
        var input_length = input.length;

        var n, out, i, bias, basic, j, ic, oldi, w, k, digit, t, len;

        // Initialize the state: 

        n = initial_n;
        i = 0;
        bias = initial_bias;

        // Handle the basic code points:  Let basic be the number of input code 
        // points before the last delimiter, or 0 if there is none, then    
        // copy the first basic code points to the output.                      

        basic = input.lastIndexOf(delimiter);
        if (basic < 0) basic = 0;

        for (j = 0;  j < basic;  ++j) {
                if(preserveCase) case_flags[output.length] = ( input.charCodeAt(j) -65 < 26);
                if ( input.charCodeAt(j) >= 0x80) {
                        throw new RangeError("Illegal input >= 0x80");
                }
                output.push( input.charCodeAt(j) );
        }

        // Main decoding loop:  Start just after the last delimiter if any  
        // basic code points were copied; start at the beginning otherwise. 

        for (ic = basic > 0 ? basic + 1 : 0;  ic < input_length; ) {

                // ic is the index of the next character to be consumed,

                // Decode a generalized variable-length integer into delta,  
                // which gets added to i.  The overflow checking is easier   
                // if we increase i as we go, then subtract off its starting 
                // value at the end to obtain delta.
                for (oldi = i, w = 1, k = base;  ;  k += base) {
                        if (ic >= input_length) {
                                throw RangeError ("punycode_bad_input(1)");
                        }
                        digit = decode_digit(input.charCodeAt(ic++));

                        if (digit >= base) {
                                throw RangeError("punycode_bad_input(2)");
                        }
                        if (digit > Math.floor((maxint - i) / w)) {
                                throw RangeError ("punycode_overflow(1)");
                        }
                        i += digit * w;
                        t = k <= bias ? tmin : k >= bias + tmax ? tmax : k - bias;
                        if (digit < t) { break; }
                        if (w > Math.floor(maxint / (base - t))) {
                                throw RangeError("punycode_overflow(2)");
                        }
                        w *= (base - t);
                }

                out = output.length + 1;
                bias = adapt(i - oldi, out, oldi === 0);

                // i was supposed to wrap around from out to 0,   
                // incrementing n each time, so we'll fix that now: 
                if ( Math.floor(i / out) > maxint - n) {
                        throw RangeError("punycode_overflow(3)");
                }
                n += Math.floor( i / out ) ;
                i %= out;

                // Insert n at position i of the output: 
                // Case of last character determines uppercase flag: 
                if (preserveCase) { case_flags.splice(i, 0, input.charCodeAt(ic -1)  -65 < 26);}

                output.splice(i, 0, n);
                i++;
        }
        if (preserveCase) {
                for (i = 0, len = output.length; i < len; i++) {
                        if (case_flags[i]) {
                                output[i] = (String.fromCharCode(output[i]).toUpperCase()).charCodeAt(0);
                        }
                }
        }
        return utf16.encode(output);            
    };

    //** Main encode function **

    this.encode = function (input,preserveCase) {
        //** Bias adaptation function **

        var n, delta, h, b, bias, j, m, q, k, t, ijv, case_flags;

        if (preserveCase) {
                // Preserve case, step1 of 2: Get a list of the unaltered string
                case_flags = utf16.decode(input);
        }
        // Converts the input in UTF-16 to Unicode
        input = utf16.decode(input.toLowerCase());
        //input = utf16.decode(input);

        var input_length = input.length; // Cache the length

        if (preserveCase) {
                // Preserve case, step2 of 2: Modify the list to true/false
                for (j=0; j < input_length; j++) {
                        case_flags[j] = input[j] != case_flags[j];
                }
                }

        var output=[];


        // Initialize the state: 
        n = initial_n;
        delta = 0;
        bias = initial_bias;

        // Handle the basic code points: 
        for (j = 0;  j < input_length;  ++j) {
                if ( input[j] < 0x80) {
                        output.push(
                                String.fromCharCode(
                                        case_flags ? encode_basic(input[j], case_flags[j]) : input[j]
                                )
                        );
                }
        }

        h = b = output.length;

        // h is the number of code points that have been handled, b is the  
        // number of basic code points 

        if (b > 0) output.push(delimiter);

        // Main encoding loop: 
        //
        while (h < input_length) {
                // All non-basic code points < n have been     
                // handled already. Find the next larger one: 

                for (m = maxint, j = 0;  j < input_length;  ++j) {
                        ijv = input[j];
                        if (ijv >= n && ijv < m) m = ijv;
                }

                // Increase delta enough to advance the decoder's    
                // <n,i> state to <m,0>, but guard against overflow: 

                if (m - n > Math.floor((maxint - delta) / (h + 1))) {
                        throw RangeError("punycode_overflow (1)");
                }
                delta += (m - n) * (h + 1);
                n = m;

                for (j = 0;  j < input_length;  ++j) {
                        ijv = input[j];

                        if (ijv < n ) {
                                if (++delta > maxint) return Error("punycode_overflow(2)");
                        }

                        if (ijv == n) {
                                // Represent delta as a generalized variable-length integer: 
                                for (q = delta, k = base;  ;  k += base) {
                                        t = k <= bias ? tmin : k >= bias + tmax ? tmax : k - bias;
                                        if (q < t) break;
                                        output.push( String.fromCharCode(encode_digit(t + (q - t) % (base - t), 0)) );
                                        q = Math.floor( (q - t) / (base - t) );
                                }
                                output.push( String.fromCharCode(encode_digit(q, preserveCase && case_flags[j] ? 1:0 )));
                                bias = adapt(delta, h + 1, h == b);
                                delta = 0;
                                ++h;
                        }
                }

                ++delta, ++n;
        }
        return output.join("");
    }
}();


/********************************************************************************************************************************************************/
/********************************************************************************************************************************************************/
// requeteDomaine : class de gestion de la requete 
//		Variables:	
//			nom= nom de la variable definie avec l'objet (pour pouvoir s'y referer)
//			indexExtension= index extension selectionne dans le tableau 'extensions' des objets extensionNNR
//			indexExtensionAlphabet= index de l'alphabet selectionne dans l'extension en cours
//			extension = refernce � l'objet extensionNNR courant (consecutif a indexExtension)
//			domaine = chaine saisie dans le champ d'entree (en unicode)
//			domaineACE = chaine domaine encodee en ACE string (�gale a domaine si domaine ne contient que des caracteres ascii)
//			check = resultat du test de validite de la syntaxe du nom de domaine dans l'extension et l'alphabet en cours (si le test a ete lance)
//			resultat = message en relation avec l'etat de check (vide si check a true, message d'erreur en rapport avec l'erreur sinon)
//
//		Methodes:
//			addValue = ajout d'un caract�re dans le champ de saisie � la position du curseur
//			changeExtension = changement de l'extension sur action de l'utilisateur
//			checkDomain = application des r�gles de v�rification sur le domaine saisi
//			changeKeyboard = changement du clavier virtuel
//			showDebug = affiche des informations de debug
/********************************************************************************************************************************************************/
/********************************************************************************************************************************************************/
function requeteDomaine(nom)
{
	this.nom = nom ; // nom de la variable courante;
	this.indexExtension=-1;
	this.indexExtensionAlphabet=0;
	this.extension="";
	this.domaine="";
	this.domaineACE="";
	this.check=false;
	this.resultat="";
		
	this.idDivAlphabet="idDivAlphabet" ; // id du div contenant l'alphabet

	this.idChampInput='id-form-preRequis_checkNDD_idNDD';  // id du champ de saisie
		
	this.idChampSelect='id_extension';  // id du champ de sélection
	this.idDivKeyboard='keyboardDiv'; //  id du champ contenant le clavier (inclus dans div de l'alphabet
	
	this.debug=true;   // affichage d'un div avec champ ACE
	this.idDivDebug='debugACE';
	
}

		/*-----------------------------------------------------------*/
		// m�thode addValue = ajout d'une valeur dans le champ de saisie
		//
		//		Variables en entr�e:	
		//			valeur : caract�re � ajouter
		//
		//		Valeur retourn�e:	aucune
		/*-----------------------------------------------------------*/	
function addValue(valeur) 
{
		var tmp= document.getElementById(requeteNDD.idChampInput).value;
	
		document.getElementById(requeteNDD.idChampInput).value = tmp.substring(0,carPos) + valeur + tmp.substring(carPos,tmp.length) ;
		carPos++;
}

		/*-----------------------------------------------------------*/
		// m�thode addValue = changement de l'extension sur action de l'utilisateur
		//
		//		Variables en entr�e:	
		//			indexExt : num�ro d'index de l'extension choisie
		//
		//		Valeur retourn�e:	aucune
		/*-----------------------------------------------------------*/	
function changeExtension(indexExt, textWarningEU, textWarningALL) {
	if(indexExt) {
		var textWarningEU;
		var textWarningALL;
		var navName = navigator.appName;
		var navVersionIE6 = navigator.userAgent.indexOf("MSIE 6");
		
		this.indexExtension = indexExt;
		this.extension = extensions[indexExt];	
		this.indexExtensionAlphabet=0;

		/* Si IE6 et les domaines internationalisés, on n'affiche pas le clavier */
		if ( navName == 'Microsoft Internet Explorer' && navVersionIE6 != '-1' ) {
			if(indexExt=='eu' || indexExt=='com' || indexExt=='net' || indexExt=='org' || indexExt=='info' || indexExt=='biz') {
					if(document.getElementById('idDivAlphabet')) document.getElementById('idDivAlphabet').style.display="";
					if(document.getElementById('warningTextSelected')) document.getElementById('warningTextSelected').style.display="none";
					if(document.getElementById('warningTextId')) document.getElementById('warningTextId').style.display="none";
					if(document.getElementById('idDivAlphabet')) $('idDivAlphabet').addClassName("warning_text");
					if(document.getElementById('idDivAlphabet')) document.getElementById('idDivAlphabet').innerHTML= "Votre navigateur n\'est pas compatible avec notre clavier virtuel.<br/>Veuillez utiliser : Internet Explorer 7 ou +, Mozilla Firefox 3 ou +, Chrome…";
					if(document.getElementById('idDivAlphabet')) document.getElementById('idDivAlphabet').style.color = "#FF0000";
			}
			else {
				if(document.getElementById('warningTextId_2')) document.getElementById('warningTextId_2').innerHTML='';
				if(document.getElementById('warningTextId')) document.getElementById('warningTextId').style.display="none";
			}
		}
		else if(document.getElementById(this.idChampSelect)) {
			if(document.getElementById(this.idDivAlphabet)) { // affiche le clavier virtuel
				this.extension.displayUI(this);
			}						
			if((textWarningEU) && (textWarningALL)) {

                                if(indexExt=='eu' || indexExt=='com' || indexExt=='net' || indexExt=='org' || indexExt=='info' || indexExt=='biz')
					document.getElementById('warningTextId').innerHTML=textWarningEU;
				else
					document.getElementById('warningTextId').innerHTML=textWarningALL;
			}
			else if(textWarningEU) {
                           if(indexExt=='eu' || indexExt=='com' || indexExt=='net' || indexExt=='org' || indexExt=='info' || indexExt=='biz'){
                               if(textWarningEU !=1) { // Texte variable JS
                                   if($('warningTextId_2')) document.getElementById('warningTextId_2').innerHTML=textWarningEU;
                                   if($('warningTextId')) document.getElementById('warningTextId').style.display="";
                                   if($('warningTextId_2')) document.getElementById('warningTextId_2').style.display="";
                                }
                                else { // Texte dans la page
                                     if($('warningTextId')) document.getElementById('warningTextId').style.display = "";
                                     if($('warningTextId_2')) document.getElementById('warningTextId_2').style.display = "";
                                }
                            }
                            else {
                                   if($('warningTextId_2')) document.getElementById('warningTextId_2').innerHTML='';
                                   if($('warningTextId_2')) document.getElementById('warningTextId_2').style.display="none";
                                   if($('warningTextId')) document.getElementById('warningTextId').style.display="none";
                            }
			}
							
			var optionSelect = document.getElementById(this.idChampSelect);
			for (i=0;i<optionSelect.length;i++)
    		{
    			if(optionSelect.options[i].value==indexExt) {
    				optionSelect.options[i].selected=true;
    			}
    		}			
		}
	}
}

		/*-----------------------------------------------------------*/
		// m�thode addValue = application des r�gles de v�rification sur le domaine saisi
		//
		//		Variables en entr�e: aucune 
		//
		//		Valeur retourn�e:	aucune
		/*-----------------------------------------------------------*/	
function checkDomain(flux,myChampInput)
	{

			this.domaine=document.getElementById(myChampInput).value.toLowerCase();
			this.domaineACE =this.extension.encodeACE(this.domaine);				
			if (this.domaineACE.substring(4,this.domaineACE.length-1)==this.domaine) this.domaineACE=this.domaine;
			
			this.resultat = this.extension.verifySyntax(this.domaine,this.indexExtensionAlphabet);
			
			if (this.resultat!='') 	{
				this.domaineACE="";
				this.check=false;
				}
			else  {
				this.check=true;
			}
				
			if (this.debug)
					{
					if(document.getElementById(this.idDivDebug)) {
						document.getElementById(this.idDivDebug).innerHTML=this.domaineACE ;
					}
				}
			
			if(flux=="retour") {
				if (this.resultat!='' && this.resultat!=undefined) {return (this.resultat)};
			}
			else {
				if (this.resultat!='') alert(this.resultat);
			}
	}

		/*-----------------------------------------------------------*/
		// m�thode changeKeyboard = changement du clavier virtuel
		//
		//		Variables en entr�e:	
		//			kbIndex : num�ro d'index du clavier choisi
		//
		//		Valeur retourn�e:	aucune
		/*-----------------------------------------------------------*/	
function changeKeyboard(kbIndex)
 {
 		document.getElementById(this.idChampInput).value="";
		carPos=0;
		this.indexExtensionAlphabet=kbIndex;
 		this.extension.alphabets[kbIndex].displayKeyBoard(this);	
 }

		/*-----------------------------------------------------------*/
		// m�thode showDebug = affiche des informations de debug
		//
		//		Variables en entr�e:aucune
		//
		//		Valeur retourn�e:	aucune
		/*-----------------------------------------------------------*/	
function showDebug()
	{
		if (this.debug && this.idDivDebug)
				return '<div id="'+this.idDivDebug+'" ></div>'
		else
				return '';
	}

	
requeteDomaine.prototype.changeExtension = changeExtension;
requeteDomaine.prototype.checkDomain = checkDomain;
requeteDomaine.prototype.changeKeyboard = changeKeyboard;
requeteDomaine.prototype.addValue = addValue;
requeteDomaine.prototype.showDebug = showDebug;

/********************************************************************************************************************************************************/
/********************************************************************************************************************************************************/
// rule : class de gestion d'une regle de test sur une chaine de caracteres
//		Variables:	
//			ruleType= type de r�gle "eval" pour une valeur � �valuer / "regexp" pour une expression r�guli�re
//			ruleValue= la regle a tester
//			ruleExpectedResult= boolean: resultat attendu sur le test (true/false)
//			IDNEncoded = faut-il faire le test sur le domaine encode en ACE String ou sur la chaine initiale ?
//			msg = message renvoy� si le r�sultat n'est pas celui attendu (non respect de la r�gle �tablie compar�e au r�sultat attendu)
//
//		Methodes:
//			verifySyntax = application des r�gles de l'extension + celle de l'alphabet selectionne
//			encodeACE = encodage ACE du nom de domaine saisi
//			decodeACE = decodage ACE d'une chaine encod�e en ACE (sans les xn--)
//			displayUI = affiche la zone avec liste d�roulante des alphabets + emplacement pour clavier virtuel de l'alphabet selectionne
/********************************************************************************************************************************************************/
/********************************************************************************************************************************************************/
function rule(ruleType, ruleValue,IDNencoded,msg,ruleExpectedResult) {
	this.ruleType = ruleType.toLowerCase();
	this.ruleValue = (ruleType=='regexp')? (new RegExp(ruleValue)):ruleValue ;
	this.ruleExpectedResult = ruleExpectedResult;
	this.IDNEncoded=IDNencoded;
	this.msg=msg;
}


		/*-----------------------------------------------------------*/
		// m�thode check = verification de la validite d'une regle par rapport a la valeur fournie en entree
		//
		//		Variables en entr�e:	
		//			valueToCheck : valeur a tester
		//
		//		Valeur retourn�e:	
		//			vide si regle valide, le message d'erreur sinon
		/*-----------------------------------------------------------*/	
function check(valueToCheck) {

	switch (this.ruleType)
		{		
		case 'regexp':		// cas de l'expression reguliere
	  	if (valueToCheck.match(this.ruleValue)) {
    		return (this.ruleExpectedResult)? '':this.msg ;
  			}
  		else {
    		return (this.ruleExpectedResult)? this.msg:'' ;
    	}
    	break;
    case 'eval':			// cas d'un eval
    	if (eval(this.ruleValue.replace(/%X%/g,"'"+valueToCheck+"'"))==this.ruleExpectedResult) {			// on remplace dans la chaine de test tous les %X% par la valeur a tester
    		return '';
  			}
  		else {
    		return this.msg;
    	}
    		    	
    	break;
  	}
	
}

rule.prototype.check=check;

/********************************************************************************************************************************************************/
/********************************************************************************************************************************************************/
// extensionNNR: class de gestion d'une extension
//		Variables:	
//			label=nom de l'extension
//			IDN=l'extension accepte t'elle les DIN, pour une gestion de la conversion ACE et l'affichage des alphabets sous forme de claviers virtuels
//			alphabets= tableau des alphabets support�s (tableau d'objets charsetTable)
//			rules = tableau de regles de test de la validit� d'une saisie (tableau d'objets rules)
//			
//		Methodes:
//			verifySyntax = application des r�gles de l'extension + celle de l'alphabet selectionne
//			encodeACE = encodage ACE du nom de domaine saisi
//			decodeACE = decodage ACE d'une chaine encod�e en ACE (sans les xn--)
//			displayUI = affiche la zone avec liste d�roulante des alphabets + emplacement pour clavier virtuel de l'alphabet selectionne
/********************************************************************************************************************************************************/
/********************************************************************************************************************************************************/
function extensionNNR(label,IDN,isStandard,alphabetString,regles,reglesalphabet) {
	this.label=label;
	this.IDN=IDN;
	this.alphabets=new Array();
	this.rules = new Array();
	
	if (isStandard) {
		// si extension avec alphabet A-Z 0-9 + '-', alors d�finition standard
		this.alphabets[0] = new charsetTable("standard",alphabetString);
		this.rules= regles;
		this.alphabets[0].rules= reglesalphabet;
		}
	}

		/*-----------------------------------------------------------*/
		// m�thode verifySyntax = application des r�gles de l'extension + celle de l'alphabet selectionne
		//
		//		Variables en entr�e:	
		//			domainValue=valeur du domaine a tester sans l'extension
		//			indexAlphabets= index de l'alphabet a utiliser dans le tableau d'objets alphabets de la classe (pour application des regles specifiques a l'alphabet)
		//
		//		Valeur retourn�e:	
		//			vide si pas d'erreur, sinon le message d'erreur
		/*-----------------------------------------------------------*/
function verifySyntax(domainValue,indexAlphabet)	{

		
		var resultat=''; 
		for (var i=0; i<this.rules.length && resultat=='';i++)
			{
			if (this.rules[i].IDNEncoded)
					resultat=this.rules[i].check(this.encodeACE(domainValue))
			else
					resultat=this.rules[i].check(domainValue);
			}
			
		for (i=0; i<this.alphabets[indexAlphabet].rules.length && resultat=='';i++)
			{
			if (this.rules[i].IDNEncoded)
					resultat=this.alphabets[indexAlphabet].rules[i].check(this.encodeACE(domainValue))
			else
					resultat=this.alphabets[indexAlphabet].rules[i].check(domainValue);
			}
			
		return resultat;
	}

		/*-----------------------------------------------------------*/
		// m�thode encodeACE = encodage en ACE string d'un nom de dmaine
		//
		//		Variables en entr�e:	
		//			valeur=valeur du domaine a convertir sans l'extension
		//			
		//		Valeur retourn�e:	
		//			la valeur encod�e en ACE
		/*-----------------------------------------------------------*/
	function encodeACE(domaine) {
			return "xn--"+punycode.encode(domaine);	
	}
	
		/*-----------------------------------------------------------*/
		// m�thode decodeACE = decodage d'une chaine ACE string
		//
		//		Variables en entr�e:	
		//			valeur=valeur de la chaine a decoder
		//			
		//		Valeur retourn�e:	
		//			la valeur decodee
		/*-----------------------------------------------------------*/	
	function decodeACE(valeur) {
			return punycode.decode(valeur.substring(4,valeur.length));
	}
	
		/*-----------------------------------------------------------*/
		// m�thode displayUI = affiche la zone avec liste d�roulante des alphabets + emplacement pour clavier virtuel de l'alphabet selectionne
		//
		//		Variables en entr�e:	
		//			requete : objet de reference qui contient tout le referentiel (pour generation du code javascript)
		//			
		//		Valeur retourn�e:	
		//			aucune
		/*-----------------------------------------------------------*/	
function displayUI(requete)	{
	var buff="";	
	if(document.getElementById(requete.idDivAlphabet)) {	
			document.getElementById(requete.idDivAlphabet).style.display="none";
		if (this.IDN) {  // affichage des alphabets uniquement pour les extensions IDN
			buff+='<select  onchange="'+requete.nom+'.changeKeyboard(this.selectedIndex);"  name="alphabet_id" id ="AlphabetSelect">';
			for (var i=0;i<this.alphabets.length;i++)
				{
				buff+='<option value="'+this.alphabets[i].label+'" >'+this.alphabets[i].label+'</option>';		
				}
				buff+='</select>'; 
			buff+='<div  id="'+requete.idDivKeyboard+'" ></div>'; 
		
		  /*buff+=requete.showDebug() ;*/
			document.getElementById(requete.idDivAlphabet).style.display="";		
			document.getElementById(requete.idDivAlphabet).innerHTML=buff;
			// selection du 1er alphabet
			document.getElementById("AlphabetSelect").selectedIndex=0;
			// affichage du clavier du premier alphabet
			this.alphabets[0].displayKeyBoard(requete);
			}
		else
			{
			/*buff+=requete.showDebug() ;*/ 
				if(document.getElementById(requete.idDivAlphabet)) {
				document.getElementById(requete.idDivAlphabet).innerHTML=buff;
				}
			}
	}		
}
	
	extensionNNR.prototype.verifySyntax=verifySyntax;
	extensionNNR.prototype.encodeACE=encodeACE;
	extensionNNR.prototype.decodeACE=decodeACE;
	extensionNNR.prototype.displayUI=displayUI;

/********************************************************************************************************************************************************/
/********************************************************************************************************************************************************/
// class de gestion des tables de caracteres
//		Variables:	
//			label=nom de l'alphabet
//			chars=table de caracteres au format unicode : \uXXXX
//			rules = tableau de regles de test de la validit� d'une saisie (tableau d'objets rules)
//
//		Methodes:
//			displayKeyBoard=construction d'un clavier virtuel de l'alphabet
/********************************************************************************************************************************************************/
/********************************************************************************************************************************************************/
	function charsetTable(label,chars)
		{
		this.label=label;							
		this.chars=chars;							
		this.rules = new Array();			
		}

		/*-----------------------------------------------------------*/
		// m�thode displayKeyBoard = construction d'un clavier virtuel de l'alphabet
		//
		//		Variables en entr�e:	
		//			requete : objet de reference qui contient tout le referentiel (pour generation du code javascript)
		//
		//		Valeur retourn�e:	
		//			aucune
		/*-----------------------------------------------------------*/
	function displayKeyBoard(requete) {
			
			var buff='<ul id=\'keyboardID\'>'
			for (var i=0;i<this.chars.length;i++)
			{
				var car = this.chars.charAt(i);
//				buff+='<input type="button" value="'+car+'" class="KBButton" onClick="'+requete.nom+'.addValue(this.value);">';
				buff+='<li onClick="'+requete.nom+'.addValue(\''+car+'\');"><a class="lettre" title="'+car+'">'+car+'</a></li>';
			}
			
			buff+='</ul>';
			
			document.getElementById(requete.idDivKeyboard).innerHTML=buff ;
		}

charsetTable.prototype.displayKeyBoard=displayKeyBoard;	
		
		
/*
function decimalToHex(d, padding) {
    var hex = Number(d).toString(16);
    padding = typeof (padding) === "undefined" || padding === null ? padding = 2 : padding;

    while (hex.length < padding) {
        hex = "0" + hex;
    }

    return hex;
}

	
var chaine="-0123456789";
for (var i=0; i<chaine.length; i++) {
document.write("\\u00"+decimalToHex(chaine.charCodeAt(i)));
}
*/