//Fonctions utilitaires GENERALES, en javascript
 
window.liste_default_couleur_surlignage='rgb(97%,99%,35%)';


var is_IE=user_navigator_is_IE();  //true si IE.


//Renvoie true si le navigateur du client est Inetrnet Explorer.
function user_navigator_is_IE()
{
  var is_IE=(new RegExp("internet[ ]*explorer","gi")).test(window.navigator.appName);
  return(is_IE);
}


//-----------------------------------------------------------------------------
//-------------------- Contrôles de type --------------------------------------
//-----------------------------------------------------------------------------

//Renvoie true si x est une chaîne.
function is_string(x)
{
  return( (typeof(x)=="string") || (x instanceof String) );
}

//Renvoie true si x est un booléen.
function is_boolean(x)
{
  return( (typeof(x)=="boolean") || (x instanceof Boolean) );
}

//Renvoie true si x est une fonction.
function is_function(x)
{
  return( (typeof(x)=="function") || (x instanceof Function) );
}

//Renvoie true si x est un number.
function is_number(x)
{
  return( (typeof(x)=="number") || (x instanceof Number) );
}

//Renvoie true si x est un objet NON nul !!
function is_object(x)
{
  var ok=( (typeof(x)=="object") || (x instanceof Object) ) && x!=null;
  return(ok);
}

//Renvoie true si x est un tableau.
function is_array(x)
{
  return( (x instanceof Array) );
}


// ----- Fonctions de vérification --------------------------------------
//-----------------------------------------------------------------------


//Retourne true si la date "jj/mm/aaaa" passée en param. est valide.
//Vérification NON exhaustive pour l'instant.
function date_valide(date)
{
  var dateOK=( new RegExp("^[0-9]{2}/[0-9]{2}/[0-9]{4}$") ).test(date);
  if (dateOK)
  {
    var jour=date.substr(0,2);
    var mois=date.substr(3,2);
    var annee=date.substr(6,4);
    //alert(jour+" - "+mois+" - "+annee);
    dateOK=(jour>0 && jour<32) && (mois>0 && mois<13) && annee>0;
  }    
  
  return(dateOK);
}


//Renvoie true si le code postal semble valide.
//Contrôle NON exhaustif.
function CP_valide(CP)
{
  if (is_number(CP)) 
  { CP=""+CP+""; }//Convertit en chaîne si besoin

  var CPOK=(new RegExp("^[0-9]{5,}$")).test(CP) && (parseInt(CP)>0);
  return(CPOK);
}



//Renvoie true si montant est bien un montant.
function montant_valide(montant)
{
  var ok=is_number(montant);
  
  if (!ok)
  ok=(new RegExp("^[ ]*[\-]?[ ]*[0-9]+([.][0-9]+)?[ ]*$","gi")).test(montant);
  
  return(ok);
}


//Renvoie true si entier est bien un entier.
function entier_valide(entier)
{
  if (is_number(entier)) entier=""+entier+"";  //Conversion en chaîne
  
  var ok=(new RegExp("^[\-+]?[0-9]+$","g")).test(entier);
  
  return(ok);
}


//Renvoie true si le numéro de téléphone a un format correct.
//Test non exhaustif.
function tel_valide(numtel)
{
  if (is_number(numtel)) numtel=""+numtel+"";  //Conversion en chaîne
  
  //var ok=(new RegExp("^[ ]*([+]?[ ]*[(][ ]*[0-9]{1,4}[ ]*[)])?[ ]*([0-9]{1,4}[ ]*([/]|[.]|[ ]|\-)?[ ]*){5}[ ]*$")).test(numtel);
  var ok=(new RegExp("^[ ]*([+]?[ ]*[(]?[ ]*[0-9]{1,4}[ ]*[)]?)?[ ]*([0-9]{1,4}[ ]*([/]|[.]|[ ]|\-)?[ ]*){5}[ ]*$")).test(numtel);
  
  return(ok);
}  



//Renvoie true si l'URL passée en param. semble valide.
//Test non exhaustif.
function URL_valide(_URL)
{
  var ok=_URL.trim() && !(new RegExp("('|[ ]|\")","gi")).test(_URL);
  return(ok);
}


//Renvoie true si l'adresse e-mail passée en param. semble valide.
//Test non exhaustif.
function mail_valide(email)
{
  var ok=email.trim() &&
         (new RegExp("^([a-z0-9]+([-_]?[a-z0-9]+)*[.])*[a-z0-9]+([-_]?[a-z0-9]+)*@([a-z0-9]+([-_]?[a-z0-9]+)*[.])+[a-z0-9]{2,4}$","gi")).test(email);
  return(ok);
}


//Renvoie true si le nom ou prénom passé en param. semble valide.
//Test non exhaustif.
function nom_valide(nom) //Ne fonctionne que via via PHP
{
  //var chars_accentues="<?=_CHARS_ACCENTUES_?>";
  /*var ok=nom.trim() &&
         (new RegExp("^[ ]*[a-z"+chars_accentues+"]{1,}((-|'[ ]*|[ ]*)?[a-z"+chars_accentues+">]{1,})*[ ]*$","gi")).test(nom);
  */
  /*var ok=nom.trim() &&
         (new RegExp("^[ ]*[a-z"+chars_accentues+"]{1,}((-|'[ ]*|[ ]*)?[a-z"+chars_accentues+">]{1,})*[ ]*$","gi")).test(nom);*/
  var ok=nom.trim() && !(new RegExp("[0-9]")).test(nom);     //Pas de chiffres     
             
  return(ok);
}


//Renvoie true si le libellé de pays passé en param. semble valide.
//Test non exhaustif.
function pays_valide(pays)
{
  return( nom_valide(pays) );
}

//Renvoie true si le libellé de ville passé en param. semble valide.
//Test non exhaustif.
function ville_valide(ville)
{
  var ok=nom_valide(ville) || (new RegExp("[ ]+cedex[ ]+[0-9]{1,4}","gi")).test(ville);
  return( ok );
}

//Renvoie true si le libellé de nationalité passé en param. semble valide.
//Test non exhaustif.
function nationalite_valide(nationalite)
{
  return( nom_valide(nationalite) );
}


//Renvoie true si le login contient bien des caractères autorisés, 
//et a une taille mini de taille_mini caractères.
function login_valide(login, taille_mini)
{
  var ok=login.trim() &&
        (new RegExp("^[0-9a-z]{"+taille_mini+",}$","gi")).test(login);
  
  return(ok);
}

//Renvoie true si le password contient bien des caractères autorisés,
//et a une taille mini de taille_mini caractères.
function password_valide(password, taille_mini)
{
  var ok=password.trim() &&
        (new RegExp("^[0-9a-z]{"+taille_mini+",}$","gi")).test(password);
  
  return(ok);
}



//Applique la couleur de surlignage à la couleur de fond
//de l'élément DOM représenté par l'objet oTableLine. 
function table_line_select(oTableLine, _couleur_surlignage)
{
  if (!_couleur_surlignage) _couleur_surlignage=window.liste_default_couleur_surlignage;
  
  oTableLine.style.backgroundColor=_couleur_surlignage;  //Couleur surlignage
} 


//Enlève la couleur de surlignage et rétablit la couleur de fond d'origine
//de l'élément DOM représenté par l'objet oTableLine.
function table_line_unSelect(oTableLine)
{
  oTableLine.style.backgroundColor='';  //<<Rétablit le fond initial!!
}



//Retourne un tableau d'objets représentant les tags enfants
//de l'objet oObject (lui-même tag , parent donc).
//SEULS les tags enfants dont l'attribut name vaut Name
//seront considérés. 
//aChildrenByName est à passer égal à []. (tableau vide)
//OU à ne pas passer du tout. Il sert juste de param. pour la récursivity.
function children_get_byName(oObject, Name, aChildrenByName)
{

  if (!aChildrenByName) aChildrenByName=Array();  //Initialisation
  
  var aChildren=oObject.childNodes;
  var nbChildren=aChildren.length;
  
  if (nbChildren>0)
  {
    var numChild,oChild;
    for(numChild=0; numChild<nbChildren; numChild++) //Lecture du tableau aChildren.
    {
      oChild=aChildren[numChild];
 
      if (oChild.name && oChild.name==Name)  //Si l'enfant a le name searched.
      aChildrenByName[aChildrenByName.length]=oChild; //On l'ajoute au tableau aChildrenByName.

      if (oChild.firstChild) //Si l'enfant a lui-même au moins 1 enfant
      children_get_byName(oChild, Name, aChildrenByName); //Récursivity
    }
  }
   
  return(aChildrenByName);
}



// ----- Fonctions relatives aux LISTES DEROULANTES ---------------------
//-----------------------------------------------------------------------

//Dans la liste déroulante de name comboName, sélectionne les options
//dont la value est mentionnée dans le tableau aValuesSelected passé
//en param.  
//Renvoie true si au moins une option a été selected.
function liste_values_set(comboName, aValuesSelected)
{
  var ok=false;
  
  var oCombo=window.document.getElementsByName(comboName);
  if (oCombo.length) //Si l'élément graphique existe bien
  {
    var aOptions;
    
    oCombo=oCombo[0];
    aOptions=oCombo.getElementsByTagName("option");
    
    var n;
    var numItem;
    var nbItems=aOptions.length;
    var nbSelected=aValuesSelected.length;
    var numSelected;
    for(numSelected=0; numSelected<nbSelected; numSelected++)
    {
      for(numItem=0; numItem<nbItems; numItem++)
      {
        if (aOptions[numItem].value==aValuesSelected[numSelected])
        { aOptions[numItem].selected=1; ok=true; }
      }
    }
  }
  
  return(ok);
}


//Renvoie un tableau contenant l'ensemble des value des options
//qui ont été sélectionnées dans la liste déroulante de name
//comboName.
//Renvoie un tableau vide si rien est selected.
function liste_values_get(comboName)
{
  var aValuesSelected=Array();
  
  var oCombo=window.document.getElementsByName(comboName);
  if (oCombo.length) //Si l'élément graphique existe bien
  {
    var aOptions;
    
    oCombo=oCombo[0];
    aOptions=oCombo.getElementsByTagName("option");
    
    var numItem;
    var nbItems=aOptions.length;
    for(numItem=0; numItem<nbItems; numItem++)
    {  
      if (aOptions[numItem].selected)
      aValuesSelected[aValuesSelected.length]=aOptions[numItem].value;
    }
  }
  
  return(aValuesSelected);
}  


// ----- Fonctions relatives aux RADIO GROUPS ---------------------------
//-----------------------------------------------------------------------  

//Dans le groupe de radio boutons de name radioGroupName, 
//sélectionne l'option dont la value vaut optionValue.
//Renvoie true si option selected.
function radioGroup_value_set(radioGroupName, optionValue)
{
  var ok=false;
  
  var aRadios=window.document.getElementsByName(radioGroupName);
  if (aRadios) //Si l'élément graphique existe bien
  {
    var numItem;
    var nbItems=aRadios.length;
    for(numItem=0; numItem<nbItems; numItem++)
    {
      if (aRadios[numItem].value==optionValue)
      {aRadios[numItem].checked=1; ok=true; break;}
    }  
  }
  
  return(ok);  
}


//Renvoie la value de l'option sélectionnée dans le radio groupe de name
//radioGroupName.
//Renvoie null si rien est selected.
function radioGroup_getValue(radioGroupName)
{
  var optionValue=null;
  
  var aRadios=window.document.getElementsByName(radioGroupName);
  
  if (aRadios) //Si l'élément graphique existe bien
  {  
    var numItem, nbItems=aRadios.length;
    for(numItem=0; numItem<nbItems; numItem++)
    {
      if (aRadios[numItem].checked)
      { optionValue=aRadios[numItem].value; break; }
    }
  }
  
  return(optionValue);
}
  
  
// ----- Fonctions relatives aux CHECKBOX GROUPS ------------------------
//-----------------------------------------------------------------------
  
//Dans le groupe de cases à cocher de nane checkBoxGroupName, 
//coche les options dont la value est mentionnée dans le tableau aValuesSelected 
//passé en param.
//Renvoie true si au moins une option a été sélected.  
function checkBoxGroup_values_set(checkBoxGroupName, aValuesSelected)
{
  
  var ok=false;
  
  var aCheckBoxes=window.document.getElementsByName(checkBoxGroupName);
  if (aCheckBoxes)  //Si l'élément graphique existe bien
  {
    var n;
    var numItem;
    var nbItems=aCheckBoxes.length;
    for(n in aValuesSelected)
    {
      for(numItem=0; numItem<nbItems; numItem++)
      {
        if (aCheckBoxes[numItem].value==aValuesSelected[n])
        {aCheckBoxes[numItem].checked=1; ok=true; }
      }
    }
  }
  
  return(ok);
}


//Renvoie un tableau contenant l'ensemble des value des options
//qui ont été cochées dans le groupe de cases à cocher de name checkBoxGroupName.
//Renvoie un tableau vide si rien n'a été est selected.
function checkBoxGroup_values_get(checkBoxGroupName)
{
  var aValuesSelected=Array();
  
  var aCheckBoxes=window.document.getElementsByName(checkBoxGroupName);
  if (aCheckBoxes)  //Si l'élément graphique existe bien
  {  
    var numItem, nbItems=aCheckBoxes.length;
    for(numItem=0; numItem<nbItems; numItem++)
    {
      if (aCheckBoxes[numItem].checked)
      aValuesSelected[aValuesSelected.length]=aCheckBoxes[numItem].value;
    }
  }
  
  return(aValuesSelected);
}




//Petite conversion de nom de propriétés.
//aEntities: tableau indicé dont chaque élément est un objet
//(décrivant une entité quelconque), qui a au moins 2 propriétés, 
//l'une étant l'ID , l'autre le libellé associé à cet ID.
//Le but est de renvoyer un tableau semblable, sauf que le nom de propriété
//pour l'ID passera de ID_name_avant à "value", et de lib_name_avant à "libelle".
//avec un objet JSON oConversion, de la forme; { "value":ID_name_avant, "libelle": lib_name_avant }.
//Cette fonction sert notamment pour "formater correctement un tableau d'options
//à transmettre à un checkBoxGroup par exemple.
function properties_name_convert(aEntities, oConversion)
{
  var aResult=Array();
  var n, _value, libelle;
  var nom_champ_value=oConversion.value;
  var nom_champ_libelle=oConversion.libelle;
  
  for(n=0; n<aEntities.length; n++)
  {
    _value=aEntities[n][nom_champ_value];
    libelle=aEntities[n][nom_champ_libelle];
    aResult[aResult.length]={"value": _value, "libelle": libelle};
  }
  
  return(aResult);
}    



//------------- Fonction relatives aux traitements de chaîne -----------------
//----------------------------------------------------------------------------

//Rajout de la méthode trim() à la classe String.
//La méthode trim() renvoie this, privée de ses espaces de début et de fin.
//this n'est pas modified.
String.prototype.trim=function()
{
  return( this.replace( new RegExp("^[ ]*","g"), "").replace( new RegExp("[ ]*$","g"), "") ) ;
}

//Rajout de la méthode prefix_set() à la classe String.
//Renvoie this préfixé de prefix, si celui-ci n'y était pas déjà.
//this n'est pas modified.
String.prototype.prefix_set=function(prefix)
{
  var result=this.substr(0, this.length);

  if ( result.substr(0,prefix.length)!=prefix )
  result=prefix+result;
  
  return(result);
}


//Renvoie la chaîne this répétée nFois.
String.prototype.repeat=function(nFois)
{
  var s="";
  for(var n=0; n<nFois; n++)
  s+=this.substr(0,this.length);
  return(s);
}


//Renvoie la chaîne this sans espace du tout.
String.prototype.no_spaces=function()
{
  var s=this.replace(new RegExp("[ ]","g"),"");
  return(s);
}


 
//---------------------------------------------------------------------------
//---------------------------------------------------------------------------

//Renvoie true si le navigateur du client accepte les cookies.
function user_navigator_cookies_enabled()
{
  return(window.navigator.cookieEnabled);
}


//Vérifie si le navigateur accepte les cookies ou non.
//Si non, alors fait un window.history.go(goTo).
function user_navigator_cookies_enabled_check(goTo)
{
  if (!user_navigator_cookies_enabled())
  {
    alert("Merci de paramétrer votre navigateur afin qu'il accepte les cookies.\n"+
          "(Menu Outils->Options)\n"+
          "Ceci est indispensable pour pouvoir poursuivre !");
    window.history.go(goTo);
  }
}
//---------------------------------------------------------------------------
//---------------------------------------------------------------------------
//Fonctions de cryptage
String.prototype.crypt=function()
{
  return( md5(md5(md5( this.substr(0,this.length) ))) );
}


//Crypte la value (via la méthode crypt() ci-dessus), des éléments HTML
//dont le name est mentionné dans le tableau indicé aInputsName passé en
//paramètre.
function HTML_inputs_crypt(aInputsName)
{
  var nbInputs=aInputsName.length;
  var n;
  var inputName, oInput;
  for( n=0; n<nbInputs; n++)
  {
    inputName=aInputsName[n];
    oInput=window.document.getElementsByName(inputName)[0];
    if (oInput)
    {
      oInput.value=oInput.value.crypt();
    }
  }
}

//Message Digest 5 hash code function (Fonction repiquée sur Internet)
//String	message
//bool	upper_case
//bool	unicode
function md5(message, upper_case, unicode) 
{

	var add = function(x, y) {
		var lsw = (x & 0xFFFF) + (y & 0xFFFF);
		var msw = (x >>> 16) + (y >>> 16) + (lsw >>> 16);
		return (msw << 16) | (lsw & 0xFFFF);
	}
	
	var rol = function(x, y){
		return (x << y) | (x >>> (32 - y));
	}
	
	var hex = function(abcd) {
		var hex_string = "";
		var hex_buffer = "0123456789abcdef";
								   
		if(upper_case) hex_buffer = hex_buffer.toUpperCase();
		
		for(var i = 0; i < abcd.length; i++) for(var j = 0; j < 32; j += 8)
			hex_string += hex_buffer.charAt( (abcd[i] >> (j+4)) & 0xF) + hex_buffer.charAt( (abcd[i] >> j) & 0xF);
		
		return hex_string;
	}
	
	//md5 functions
	
	var xx = function(q, a, b, x, s, ac) {
		return add(rol(add(add(a, q), add(x, ac)), s),b);
	}
	
	var ff = function(a, b, c, d, x, s, ac) {
		return xx((b & c) | ((~b) & d), a, b, x, s, ac);
	}
	
	var gg = function(a, b, c, d, x, s, ac) {
		return xx((b & d) | (c & (~d)), a, b, x, s, ac);
	}
	
	var hh = function(a, b, c, d, x, s, ac) {
		return xx(b ^ c ^ d, a, b, x, s, ac);
	}
	
	var ii = function(a, b, c, d, x, s, ac) {
		return xx(c ^ (b | (~d)), a, b, x, s, ac);
	}
	
	//message digest buffer
	
	message = message.toString();
	
	var i;
	var buffer = [];
	var char_size = unicode ? 16 : 8;
	var char_mask = (1 << char_size) - 1;
	
	for(i = 0; i < message.length * char_size; i += char_size)
		buffer[i >> 5] |= (message.charCodeAt(i / char_size) & char_mask) << (i & 0x1F);
	
	//message digest padding
	
	buffer[i >> 5] |= 0x80 << (i & 0x1F);
	buffer[(((i + 64) >>> 5) & ~0xF) + 14] = i;
	
	//message digest loop
	
	var a = 0x67452301;
	var b = 0xEFCDAB89;
	var c = 0x98BADCFE;
	var d = 0x10325476;
	
	for(i = 0; i < buffer.length; i += 16) {
		var temp_a = a;
		var temp_b = b;
		var temp_c = c;
		var temp_d = d;
		
		a = ff(a, b, c, d, buffer[i+ 0],  7, 0xD76AA478);
		d = ff(d, a, b, c, buffer[i+ 1], 12, 0xE8C7B756);
		c = ff(c, d, a, b, buffer[i+ 2], 17, 0x242070DB);
		b = ff(b, c, d, a, buffer[i+ 3], 22, 0xC1BDCEEE);
		a = ff(a, b, c, d, buffer[i+ 4],  7, 0xF57C0FAF);
		d = ff(d, a, b, c, buffer[i+ 5], 12, 0x4787C62A);
		c = ff(c, d, a, b, buffer[i+ 6], 17, 0xA8304613);
		b = ff(b, c, d, a, buffer[i+ 7], 22, 0xFD469501);
		a = ff(a, b, c, d, buffer[i+ 8],  7, 0x698098D8);
		d = ff(d, a, b, c, buffer[i+ 9], 12, 0x8B44F7AF);
		c = ff(c, d, a, b, buffer[i+10], 17, 0xFFFF5BB1);
		b = ff(b, c, d, a, buffer[i+11], 22, 0x895CD7BE);
		a = ff(a, b, c, d, buffer[i+12],  7, 0x6B901122);
		d = ff(d, a, b, c, buffer[i+13], 12, 0xFD987193);
		c = ff(c, d, a, b, buffer[i+14], 17, 0xA679438E);
		b = ff(b, c, d, a, buffer[i+15], 22, 0x49B40821);
		
		a = gg(a, b, c, d, buffer[i+ 1],  5, 0xF61E2562);
		d = gg(d, a, b, c, buffer[i+ 6],  9, 0xC040B340);
		c = gg(c, d, a, b, buffer[i+11], 14, 0x265E5A51);
		b = gg(b, c, d, a, buffer[i+ 0], 20, 0xE9B6C7AA);
		a = gg(a, b, c, d, buffer[i+ 5],  5, 0xD62F105D);
		d = gg(d, a, b, c, buffer[i+10],  9, 0x02441453);
		c = gg(c, d, a, b, buffer[i+15], 14, 0xD8A1E681);
		b = gg(b, c, d, a, buffer[i+ 4], 20, 0xE7D3FBC8);
		a = gg(a, b, c, d, buffer[i+ 9],  5, 0x21E1CDE6);
		d = gg(d, a, b, c, buffer[i+14],  9, 0xC33707D6);
		c = gg(c, d, a, b, buffer[i+ 3], 14, 0xF4D50D87);
		b = gg(b, c, d, a, buffer[i+ 8], 20, 0x455A14ED);
		a = gg(a, b, c, d, buffer[i+13],  5, 0xA9E3E905);
		d = gg(d, a, b, c, buffer[i+ 2],  9, 0xFCEFA3F8);
		c = gg(c, d, a, b, buffer[i+ 7], 14, 0x676F02D9);
		b = gg(b, c, d, a, buffer[i+12], 20, 0x8D2A4C8A);
		
		a = hh(a, b, c, d, buffer[i+ 5],  4, 0xFFFA3942);
		d = hh(d, a, b, c, buffer[i+ 8], 11, 0x8771F681);
		c = hh(c, d, a, b, buffer[i+11], 16, 0x6D9D6122);
		b = hh(b, c, d, a, buffer[i+14], 23, 0xFDE5380C);
		a = hh(a, b, c, d, buffer[i+ 1],  4, 0xA4BEEA44);
		d = hh(d, a, b, c, buffer[i+ 4], 11, 0x4BDECFA9);
		c = hh(c, d, a, b, buffer[i+ 7], 16, 0xF6BB4B60);
		b = hh(b, c, d, a, buffer[i+10], 23, 0xBEBFBC70);
		a = hh(a, b, c, d, buffer[i+13],  4, 0x289B7EC6);
		d = hh(d, a, b, c, buffer[i+ 0], 11, 0xEAA127FA);
		c = hh(c, d, a, b, buffer[i+ 3], 16, 0xD4EF3085);
		b = hh(b, c, d, a, buffer[i+ 6], 23, 0x04881D05);
		a = hh(a, b, c, d, buffer[i+ 9],  4, 0xD9D4D039);
		d = hh(d, a, b, c, buffer[i+12], 11, 0xE6DB99E5);
		c = hh(c, d, a, b, buffer[i+15], 16, 0x1FA27CF8);
		b = hh(b, c, d, a, buffer[i+ 2], 23, 0xC4AC5665);
		
		a = ii(a, b, c, d, buffer[i+ 0],  6, 0xF4292244);
		d = ii(d, a, b, c, buffer[i+ 7], 10, 0x432AFF97);
		c = ii(c, d, a, b, buffer[i+14], 15, 0xAB9423A7);
		b = ii(b, c, d, a, buffer[i+ 5], 21, 0xFC93A039);
		a = ii(a, b, c, d, buffer[i+12],  6, 0x655B59C3);
		d = ii(d, a, b, c, buffer[i+ 3], 10, 0x8F0CCC92);
		c = ii(c, d, a, b, buffer[i+10], 15, 0xFFEFF47D);
		b = ii(b, c, d, a, buffer[i+ 1], 21, 0x85845DD1);
		a = ii(a, b, c, d, buffer[i+ 8],  6, 0x6FA87E4F);
		d = ii(d, a, b, c, buffer[i+15], 10, 0xFE2CE6E0);
		c = ii(c, d, a, b, buffer[i+ 6], 15, 0xA3014314);
		b = ii(b, c, d, a, buffer[i+13], 21, 0x4E0811A1);
		a = ii(a, b, c, d, buffer[i+ 4],  6, 0xF7537E82);
		d = ii(d, a, b, c, buffer[i+11], 10, 0xBD3AF235);
		c = ii(c, d, a, b, buffer[i+ 2], 15, 0x2AD7D2BB);
		b = ii(b, c, d, a, buffer[i+ 9], 21, 0xEB86D391);
		
		a = add(a, temp_a);
		b = add(b, temp_b);
		c = add(c, temp_c);
		d = add(d, temp_d);
	}

  return hex( [a, b, c, d] );
}
//--------------------------------------------------------------------------
//--------------------------------------------------------------------------    
//Rend invisible ou visible, les champs HTML dont le name est mentionné dans le 
//tableau indicé aInputs. Passer hide_show à true pour rendre visible, à false sinon.
function HTML_inputs_hide_show(aInputsName, hide_show)
{
  var nbInputs=aInputsName.length;
  var n;
  var inputName, oInput;
  for( n=0; n<nbInputs; n++)
  {
    inputName=aInputsName[n];
    oInput=window.document.getElementsByName(inputName)[0];
    if (oInput)
    {
      oInput.style.display=(hide_show)? "":"none";
    }
  }
}

//----------------------------------------------------------------------------
//----------------------------------------------------------------------------
if (!Function.prototype.call) //Si call n'existe pas. (pour les vieilles versions d'IE)
{
  //Le but est que toute fonction fonc() qui appelera sa méthode call()
  // (fonc.call(Obj,param)) soit elle-même appelée(avec en 1er paramètre param, 
  // facultatif),  mais qu'à son exécution, le this présent dans son corps 
  // représente ponctuellement oObj.
  Function.prototype.call=function(oObj,param) //<<Ajout de la méthode call() à la classe Function.
  { 
    oObj.fonc=this; //this représente la fonction ayant appelée call(). 
                    //Ici, on ajoute donc en ligne, une méthode nommée fonc() à 
                    //l'objet oObj passé en param. .
                    //Et le corps de cette méthode vaut: this. 
    
    //Ainsi le this dans le corps de fonc() vaudra oObj!
    if (typeof("param")!="undefined")
      oObj.fonc(param); 
    else
      oObj.fonc();  //Pas de param.
  }
}
//----------------------------------------------------------------------------
//----------------------------------------------------------------------------
//Retourne sous forme de chaîne le contenu d'un objet 
//(tableau ou non).
//profondeurMax: si elle est passé, doit être un nombre>0. Celui-ci définit la 
//profondeur maximum autorisée pour la récursivité de la méthode. 
//Cela permet ainsi d'éviter une imbrication trop étendue voir de faire
//tourner le navigateur en boucle quasi-infinie (notamment sous Firefox
//pour les objets de type DOM réel).
//Si profondeurMax n'est pas passé, alors il aura une valeur de 10.
//Pour n'avoir aucune limite de récursivité, le passer à null.
//
//(oOffsetLeft et oProfondeur ne servent qu'en interne pour la récursivity
//ils ne sont donc pas à passer en param.).
Object.prototype._toString=function(profondeurMax, oOffsetLeft, oProfondeur)
{
  var s="";

  if (typeof(profondeurMax)=="undefined") profondeurMax=10;
  
  if (profondeurMax>0 || profondeurMax==null)
  {
    var CRLF="\n";  //Et <br/> pour HTML
    var space=" ";  //Et &nbsp; pour HTML
    var LIB;
    
    if (typeof(oOffsetLeft)=="undefined") oOffsetLeft={"value":0}; //Au tout premier appel: initialisation.
    if (typeof(oProfondeur)=="undefined") oProfondeur={"value":0}; //Au tout premier appel: initialisation.
    
    oProfondeur.value++;  
  
    var oSpace=new String(space);
    var _is_array, ouvre, ferme;
    var key, val, skey;
    for(key in this)
    {
      val=this[key];
      if ( !is_function(val))
      {
        skey="`"+key+"`=>";
        s+=CRLF+oSpace.repeat(oOffsetLeft.value)+skey;
        
        if (val instanceof Object)
        { 
            _is_array=is_array(val);
            ouvre=(_is_array)? "[" : "{";  //{} pour un objet non tableau.
            ferme=(_is_array)? "]" : "}";
            LIB=(_is_array)? "ARRAY" : "OBJECT";
            oOffsetLeft.value+=2*skey.length;
            s+=CRLF+oSpace.repeat(oOffsetLeft.value)+ouvre;
            
            oOffsetLeft.value+=3;
            
            if (profondeurMax!=null && (oProfondeur.value>=profondeurMax))  //True si on ne souhaite plus de récursivity
              { s+=CRLF+oSpace.repeat(oOffsetLeft.value)+LIB; }
            else 
              { s+=val._toString(profondeurMax,oOffsetLeft,oProfondeur); }
 
            
            oOffsetLeft.value-=3;
            s+=CRLF+oSpace.repeat(oOffsetLeft.value)+ferme;
            oOffsetLeft.value-=2*skey.length;
        }        
        else 
        {
          s+="'"+val+"'";
        }
      }
    }
    
    oProfondeur.value--;
  }
    
  return(s);
}
//----------------------------------------------------------------------------
//----------------------------------------------------------------------------

// -Cas 1: AND vaut true.
//        La méthode renvoie true si TOUS les éléments du tableau indicé aListe
//        existent bien (même valeur/même type) dans notre tableau indicé this.
// -Cas 2: AND vaut false.
//        La méthode renvoie true si l'un des éléments du tableau indicé aListe
//        existe (même valeur/même type) dans notre tableau indicé this.
//
// Si caseSensitive est passé à false (valeur par défaut : true), alors les
// comparaisons de chaîne ne tiendront pas compte de la casse.
// 
//Renvoie null en cas d'erreur. 
//Ajout de la méthode include() à la classe Array.
Array.prototype.include=function(aListe, AND , caseSensitive)
{
  OK=null;
  
  if (typeof(caseSensitive)=="undefined") caseSensitive=true;
  
  var params_ok=is_array(aListe) && is_boolean(AND) && is_boolean(caseSensitive);
  
  if (params_ok)
  {
    var OK=false;
    var liste_nbElem=aListe.length;
    var n, m;
    var array_elem, liste_elem;
    var egal;
    for (m=0; m<liste_nbElem; m++)
    {    
      liste_elem=aListe[m];
      OK=false;      
      for(n=0; n<this.length; n++)
      {
        array_elem=this[n];
        
        if ( !caseSensitive && is_string(array_elem) && is_string(liste_elem) )
        { array_elem=array_elem.toLowerCase();  liste_elem=liste_elem.toLowerCase(); }
        
        egal=(array_elem==liste_elem) && (typeof(array_elem)==typeof(liste_elem));
        
        OK=egal;  //aListe[m] trouvé dans this[].
        if (OK) break;
      }
      if (!AND && OK) {break;} //Si une seule égalité suffit
      if (AND && !OK) {break;} //Si aListe[m] doit forcément exister dans this[]
    }
  }
  else alert("Array.include(): params invalides!");
   
  return(OK);   
}
