/* RUBRIQUES
	_NOMBRES_   _DATES_   _TABLEAUX_   _COORDONNEES_   _GET_PUT_   _FORM_   _DHTML_   _ManipDOM_   _Rech_DHTML_   _OBJETS_JS_   _JSON_   _EVENT_   _INTERACTIF_
	_FICHIER_  _COOKIES_   _SYSTEM_   _AJAX_   _DIVERS_
	UniqueID

re = Sql.match(/@[0-9]+/g);	if (re) { for (i=0; i<re.length; i++) {  : rech ts les @1, @2 de Sql
$.browser.mozilla
? Vu instanceof VueClass
*/

var Bug=0
var WinBug;
(function() { // retourne - pour effacer la div bug, + pour ajouter au contenu
	var T, t1 = new Date();  T = { DivH:t1, Post:t1, Fo:t1, Contenu:t1, Act:t1, JS:t1, wh:t1 }
	noBug = function(Nom) {
		var c, i, R, t2 = new Date()
		if (!Nom)  Nom = 'wh'
		R = T[Nom]
		if (t2-R>900)  c='-';  else  c='+';
		T[Nom] = t2
		return c
	}
})();
//alert(noBug()+','+noBug());  alert('pause');

var Y
var pixX, pixY
var cr = "\n", crr=cr + cr
var ie = (document.all) ? 1:0;  var navV = 0
if (navigator.appVersion.indexOf("MSIE")!=-1) {  S=navigator.appVersion.split("MSIE");  navV=parseFloat(S[1]); }
//if (window.jQuery)  jQuery.each(jQuery.browser, function(i, val) { alert(i+"="+val+crr) })


function ClassFO(){}    //var App = new Object()
if (!window.App) { var App = {}  /*new ClassFO()*/ }
if (!App.Vars)  App.Vars = {};  if (!App.Modul)  App.Modul = {};  if (!App.Ajax)  App.Ajax = {}
if (!App.Kiwi)  App.Kiwi = {};  if (!App.Kiwi.Pointeurs)  App.Kiwi.Pointeurs = {};  if (!App.CB)  App.CB = {};  if (!App.Banq)  App.Banq = {}    //alert(JSW(App))

var Tables = []

var AjUrl = ''
var TRClic

var TDataCal = [
 ["FR",
  ["Dimanche", "Lundi", "Mardi", "Mercredi", "Jeudi", "Vendredi", "Samedi"],
  ["Janvier", "Février", "Mars", "Avril", "Mai", "Juin", "Juillet", "Aout", "Septembre", "Octobre", "Novembre", "Décembre"],
  ["Mois précédent", "Mois suivant", "Année précédente", "Année suivante"],
  "Veuillez vérifier le format de la date."
 ],
 ["EN",
  ["S", "M", "T", "W", "T", "F", "S"],
  ["JANUARY", "FEBRUARY", "MARCH", "APRIL", "MAY", "JUNE", "JULY", "AUGUST", "SEPTEMBER", "OCTOBER", "NOVEMBER", "DECEMBER"],
  ["Previous month", "Next month", "Previous year", "Next year"],
  "Please check date format."
 ]
];
var TJour = TDataCal[0][1]
var TMois = TDataCal[0][2]
//document.onmousemove = PosMouse  //nécessaire pour clic-droit sur Tree : Tor.PosWinEvent


function Var(Nom) {
	if (typeof(window[Nom])!='undefined')  return window[Nom]
}

var TableClass = function() {}


function isStr(V) { return (typeof(V)=='string') }
function isObj(V) { return (typeof(V)=='object') }
function isArray(obj) { if (!obj)  return false;  if (obj.constructor.toString().indexOf("Array") == -1)  return false;  else  return true; }


// ====================================     _STRING_      ===============================
(function () {  // id = UniqueID()
	var n = 0
	UniqueID = function () { return n++	}
})();

function AddStr (V1, V2, Separ) {
	var S, L
	if (!V2)  return V1;  if (!V1)  return V2
	if (!Separ)  Separ = ","
	V1+="";  V2+="";  L = Separ.length
	//if (Separ=="&" && V1.indexOf("?")<0)  Separ="?"
	if (V1.substring(V1.length-L)==Separ)  V1 = V1.substring(0,V1.length-L)
	if (V2.substr(0,L)==Separ)  V2 = V2.substr(L)
	S = V1+Separ+V2
	return S
}

function AjPath() {
	var i, Li=''
	for (i in arguments) {
		Li = AddStr(Li,arguments[i],'/');		//alert(arguments[i]+crr+Li)
	}
	return Li
}

function AddV (Chaine, V) {
	if (!Chaine || !V)  return ''
  return Chaine+V
}

function Quot(Li) { return Replace(Li,"'","''") }

function ChercheListCar(Chaine, Liste) {
	var i, l
	l = Liste.length
	for (i=0; i<l; i++) {
		if (Chaine.indexOf(Liste.substr(i,1))>=0)  return i
	}
	return -1
}

function Minus(Li) {  if (CasseUniq(Li))  return Li.toLowerCase();  else  return Li }
function Majus(Li) {  if (CasseUniq(Li))  return Li.toUpperCase();  else  return Li }

function NomPropre(SMot, Opt) {
	var Lig, C1, C2, C3, C4, C5, Mot, Mx
	if (!SMot) return ""
	Mx = SMot.length
	if (!Opt && !CasseUniq(SMot))  return SMot

	Mot = SMot.toLowerCase()
	Lig = Mot.substr(0,1).toUpperCase()
	for (C=1; C<Mx; C++) {
		C1 = Mot.substr(C-1,1)
		C2 = Mot.substr(C,1)
		if (C+1<Mx)  C3 = Mot.substr(C+1,1);  else  C3=" "
		if (C+2<Mx)  C4 = Mot.substr(C+2,1);  else  C4=" "
		if (C+3<Mx)  C5 = Mot.substr(C+3,1);  else  C5=" "
		M1 = C2 + C3 + C4;  M2 = M1 + C5
		if ("de du d' le la l' et ".indexOf(M1)>=0 || "rue des les ".indexOf(M2)>=0) {
			Lig=Lig + C2
		}else{
			if (" ,;./-'".indexOf(C1)>=0)  Lig += C2.toUpperCase();  else  Lig += C2
		}
	}
	return Lig
}

function CasseUniq(Mot) {
	var C, C1, nbMin=0, nbMaj=0
	var Mx = Mot.length
	for (C=0; C<Mx; C++) {
		C1 = Mot.substr(C,1)
		if (C1>="A" && C1<="Z")  nbMaj++
		if (C1>="a" && C1<="z")  nbMin++
	}
	return !(nbMin>0 && nbMaj>0)
}

function ClearText (Chaine, Test) {
		//Tel : ClearText(V, "isNaN(C) || C=='.' || C==' '")
	var S, V='', i, l, C
	l = Chaine.length
	for (i=0; i<l; i++) {
		C = Chaine.substr(i,1)
		if (!eval(Test))  V+=C
	}
	return V
}

function SupprAccent(Valeur) {
  var S
  S = Valeur + ""
  S = Replace(S,"é","e");  S = Replace(S,"è","e");  S = Replace(S,"ë","e");  S = Replace(S,"ê","e")
  S = Replace(S,"à","a");  S = Replace(S,"â","a");  S = Replace(S,"ô","o");  S = Replace(S,"û","u");  S = Replace(S,"ù","u")
  S = Replace(S,"ï","i");  S = Replace(S,"î","i")
  S = Replace(S,"ç","c")
  return S
}

function strPad(V, n, Car, aGauche) {
	var i
	if (!V)  return "";  V=V+'';  if (V.length>n)  return V.substr(0,n)
	if (!Car)  Car=' '
	if (aGauche)	for (i=V.length; i<n; i++)  V=Car+V;  else  for (i=V.length; i<n; i++)  V+=Car;
	return V
}
function InitString(V, n, Car, aGauche) { return strPad(V, n, Car, aGauche) }

function Mot (Chaine, n) {
	var arr, reg
	if (!Chaine)  return ''
	arr = Chaine.match(/\w+/g);
	if (n!=undefined && n<=arr.length) return arr[n-1];  else  return arr
  //var regEx = /\w+/g;  var arr;  while ((arr = regEx.exec(src)) != null)  alert(arr.length + ", " + arr.index + "-" + arr.lastIndex + "\t" + arr);
}

function Isole (Li, Separ, no) {
  var T, P, L
  if (!Li)  return ""
  if (no==1) { if ((P=Li.indexOf(Separ))>=0)  return Li.substr(0,P);  else  return Li }
	T = Li.split(Separ);  L = T.length
 	if (no<0)  P = L + no;  else  P = no-1
	if (P>=0 && P<L)  return T[P];  else  return null
}

function Isol (Chaine, Separ, n) {
  var regEx = new RegExp
  //regEx.Pattern = "([^" & Separ & "]+)":  regEx.IgnoreCase = True:  regEx.Global = True
  //Set Matches = regEx.Execute(Chaine)
  //If n<=Matches.Count Then  Isolc=Matches(n-1)
}

function Gauche(Chaine, n) {
	return (Chaine) ? Chaine.substr(0,n) : ''
}

function Left(Chaine, n, Separ) {
	if (!Chaine)  return ""
	if (Separ) {
		var S = Right(Chaine, n, Separ)
		n = S.length+1
	}
	return Chaine.substr(0, Chaine.length - n)
}

function Right(Chaine, n, Separ) {
	// avec Separ = Isole inversé. Ex : Ext = Right(Fic,1,".")
	if (!Chaine)  return ""
	if (Separ) {
		var T = Chaine.split(Separ)
		var P = T.length - n
		if (P>=0)  return T[P]
	}
	else
	  return Chaine.substr(Chaine.length-n)
}

function IsoleTag(H, Tag) {
	var h = H.toLowerCase(), tag = Tag.toLowerCase(), d, f
  d = h.indexOf('<'+tag);
	d = h.indexOf('>',d)
  f = h.indexOf('</'+tag+'>',++d)
	if (f>=0)  return H.substr(d,f-d);  else  return H.substr(d)
}


String.prototype.lTrim = String.prototype.trimLeft = function() {   return this.replace(/^\s*/, "");  }
String.prototype.rTrim = String.prototype.trimRight = function() {    return this.replace(/\s*$/, "");  }
function Trim(S) { if (S && isStr(S)) return S.replace(/^\s*|\s*$/g,'');  else  return S }

function Replace(Chaine, Li, V, nb, SiMinus) {
  if (!Chaine)  return "";  if (V==undefined)  V=""
  var Ch2, i=0, n=0
  if (SiMinus) Li = Li.toLowerCase()
  while (i!=-1) {  // && (nb && n<nb)
	  if (SiMinus)  Ch2=Chaine.toLowerCase();  else  Ch2 = Chaine
    i = Ch2.indexOf(Li,i)
    if (i>=0) {
      Chaine = Chaine.substring(0,i) + V + Chaine.substring(i + Li.length)
      i+=V.length;  n++
    }
  }
  return Chaine
}

//"hello".replace(/e|o/g, "x") // "hxllx"
function RegReplace (Chaine, Reg_exp, V, Opt) {
	// RegReplace(H, "<o:p><\/o:p>", "<br />"),  (html, "<st1:.*?>", ""),  (value, "[ \t\r\n]|%20", ""),  (content, "\r\n", "<br />", "gi"),  (url, '(http|https):///', '/')
	if (!Chaine)	return Chaine
	if (!Opt) Opt = 'g'
	var re = new RegExp(Reg_exp, Opt)
	return Chaine.replace(re, V)
}


function MajValeurs(C1, C2, Sep, Opt) {
	//alert(MajValeurs(";a=1;b=2;", "a=11;b=;c=33", "=;"))
	var Li, i, V, S, T, T1, T2, key, SepV, SepL, SepZ
	if (!C2)  return;  if (!Opt)  Opt = new Object()
	if (!Sep)  Sep=",;";  else if (Sep.length<2)  Sep+=";";		SepV = Sep.substr(0,1);  SepL = Sep.substr(1,1);  SepZ = Sep.substr(2,1);
	T1 = Tableau1D(C1,Sep);  T2 = Tableau1D(C2,Sep)
	for (key in T2) {
		T1[key] = T2[key]
	}
	Li=""
	for (key in T1) {
		V = T1[key]
		if (SepZ && V.indexOf(SepZ)>=0) { T = V.split(SepZ);  V = T[0];  if (V==T[1]) V="" }
		if (V)  Li+=SepL + key + SepV + V
	}
	if (Li) { Li = Li.substr(1);  if (Opt.Cadre)  Li=SepL+Li+SepL }
	return Li
}

function ReplaceVar(Chaine) {
		//	VueAct.TBody = "<TD class=Ongl_Menu><div>{Obj.Cle} $Lib</div></TD>"
	var i, p, p2, S, V, Nom, Obj, O, Li
	if (!Chaine || !isStr(Chaine))  return Chaine
	
	p = Chaine.indexOf("$")
	var nbArg = arguments.length
	while (p>=0) {
		Nom = Mot(Chaine.substr(p+1),1)
		for (i=1; i<nbArg; i++) {
			O = arguments[i];  if (!O)  continue
			if (O.tagName) {
				V = O.getAttribute(Nom)
			}else{
				V = O[Nom];
				if (V==undefined && O.nod)  V = O.nod[Nom]
			}
			if (V!=undefined)  break
		}
		if (!V)  V=""
		Chaine = Chaine.substr(0,p) + V + Chaine.substr(p + Nom.length + 1);  //alert(Chaine + ", " + V + ", " + p + ", ")
		p = Chaine.indexOf("$")
	}
	Li = Chaine
	p = Li.indexOf("{")
	while (p>=0) {
		p2 = Li.substr(p+1).indexOf("}")
		Nom = Li.substr(p+1, p2)
		V = ""
		for (i=1; i<nbArg; i++) {
			Obj = arguments[i]
			try { V = eval(Nom) }catch(e){}
			if (V!=undefined)  break
		}
		if (!V) {
			try { V = eval(Nom) }catch(e){}
		}
		if (!V)  V=""
		Li = Li.substr(0,p) + V + Li.substr(p + p2 + 2)
		p = Li.indexOf("{")
	}
	return Li
}

function VarListe(Chaine, NomVar, Separ, Egal, Opt) {
	if (!Separ)   Separ=";";  if (!Egal)   Egal="="
	var T = Tableau1D(Chaine, Egal+Separ)
	return T[NomVar]
}


function MajListe(Chaine, NomVar, Valeur, Separ, Egal, Ajout, Bascule) {
		// location = MajListe(location.href, "Pgm", V, "&", "="), MajListe(location.href, "Archiv", "o", "&", "=", true, "n")  si Archiv=o alors Archiv=n et vice versa
		//location.href=MajListe(location.href,'Mode','admin','&','=',1,'normal')
	var p, S, V, oldV, re
	if (!Separ)   Separ=";";  if (!Egal)   Egal="="
	if ((oldV=VarListe(Chaine, NomVar, Separ, Egal))!=undefined) {
		if (oldV && Bascule!=undefined && oldV==Valeur)  Valeur=Bascule
		re = Replace(Chaine, NomVar + Egal + oldV, NomVar + Egal + Valeur)
	}else{
		if (Ajout) {
			if (Separ=="&" && Chaine.indexOf('?')<0)  Separ='?'
			re = Chaine + Separ + NomVar + Egal + Valeur;
		}else
			re = Chaine
	}
	return re
}

function InsereLien(Chaine) {
		//ex : InsereLien("Cliquez sur ce lien http://www.google.fr ou sur celui-ci http://www.google.com !")
		var reg=new RegExp("((http://)[a-zA-Z0-9/.]+)+","gi");
		return Chaine.replace(reg, "<A href='$1' target=_blank>$1</A>")
}

function MakeMP(nb) {
	return MakePwd(nb, '', true, true, true, false, true, true, true, false)
}

function MakePwd(length, extraChars, firstNumber, firstLower, firstUpper, firstOther, latterNumber, latterLower, latterUpper, latterOther) {
	// MakePwd(8, '', true, true, true, false, true, true, true, false);
	var rc = '';
	if (length>0)  rc = rc + getRandomChar(firstNumber, firstLower, firstUpper, firstOther, extraChars);
	for (var idx=1; idx<length; ++idx) {
		rc = rc + getRandomChar(latterNumber, latterLower, latterUpper, latterOther, extraChars);
	}
	return rc;
}

function getRandomChar(number, lower, upper, other, extra) {
	var numberChars = "0123456789";
	var lowerChars = "abcdefghijklmnopqrstuvwxyz";
	var upperChars = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
	var otherChars = "`~!@#$%^&*()-_=+[{]}\\|;:'\",<.>/? ";
	var charSet = extra;
	if (number==true)  charSet += numberChars;
	if (lower==true)  charSet += lowerChars;
	if (upper==true)  charSet += upperChars;
	if (other==true)  charSet += otherChars;
	return charSet.charAt(getRandomNum(0, charSet.length));
}

function getRandomNum(lbound, ubound) { return (Math.floor(Math.random() * (ubound - lbound)) + lbound); }


// ====================================      _NOMBRES_        ===============================
function FormatN(Valeur, nbDec, Opt) {
	var deci = Math.round( Math.pow(10,nbDec)*(Math.abs(Valeur)-Math.floor(Math.abs(Valeur)))) ;
	var val = Math.floor(Math.abs(Valeur));
	if (!Opt)  Opt=", ";  Separ = Opt.substr(0,1);  CarMil = Opt.substr(1,1);  Symbol = Opt.substr(2)
	if ((nbDec==0)||(deci==Math.pow(10,nbDec))) {val=Math.floor(Math.abs(Valeur)); deci=0;}
	var val_format=val + "";
	var nb = val_format.length;
	for (var i=1;i<4;i++) {
		if (val>=Math.pow(10,(3*i))) {
			val_format = val_format.substring(0,nb-(3*i)) + CarMil + val_format.substring(nb-(3*i));
		}
	}
	if (nbDec>0) {
		var decim="";
		for (var j=0;j<(nbDec-deci.toString().length);j++) {decim+="0";}
		deci=decim+deci.toString();
		val_format = val_format + Separ + deci;
	}
	if (parseFloat(Valeur)<0) {val_format="-"+val_format;}
	return val_format + Symbol;
}

function DecToHex(d) {
	var Chif="0123456789ABCDEF";
	var h = Chif.substr(d&15,1);
	while(d>15) {d>>=4;h=Chif.substr(d&15,1)+h;}
	return h
}

function HexToDec(h) {
	return parseInt(h,16);
}

function SeparMill(nStr) {
	var x, x1, x2, nStr
	nStr += '';
	x = nStr.split('.');
	x1 = x[0];
	x2 = x.length > 1 ? '.' + x[1] : '';
	var rgx = /(\d+)(\d{3})/;
	while (rgx.test(x1)) {
		x1 = x1.replace(rgx, '$1' + ' ' + '$2');
	}
	return x1 + x2;
}

function Bit(N, P, V) {
	//Si V positionne le bit P à 1, sinon à 0
	var PP, M
	if (V==undefined)  V=1
	PP = Math.pow(2,P-1)
	if (V) {
		N = N | PP;    //alert(PP+cr+N)
	}else{
	  M = Math.pow(2,16)-1 ^ PP
	  N = N & M
	}
  return N
}

function Round(Num, dec) {
	if (dec==undefined)  dec = 2
	var V = Math.pow(10,dec)
  return Math.round(Num * V)/V
}

function ze(Num) {
	Rep = parseInt(Num,10);  if (isNaN(Rep))  Rep = 0
  return Rep
}

function zed(Num) {
	if (typeof(Num)=="string")  Num = Replace(Num,',','.')
	var r = parseFloat(Num);  if (isNaN(r))  r = 0
  return r
}

// ====================================     _DATES_         ===============================
// Aujourd'hui = FormatDate(new Date(),5)

function DateJS(D) {
	if (typeof(D)=="string") {
	  D = Replace(D,"-","/")
		if (D.indexOf("/")>=0)  D = ConvDate(D,"USA")
		return new Date(D)
	}else{
		return D
	}
}

function Annee(D) {
	var A
	if (!D)  D = new Date();  else  D=DateJS(D);
	A = D.getFullYear();  if (A<200)  A=A-100+2000
	return A
}

function CalcDate(D, Quoi, Nb) {
	if (isStr(D))  D = DateJS(D)
	J = D.getDate();  M = D.getMonth()+1;  A = D.getFullYear()
	switch (Quoi) {
		case "J":  J+=Nb;  break
		case "M":  M+=Nb;  if (M>12) { A+=1;  M-=12 };  break
		case "A":  A+=Nb;  break
	}
	return new Date(A, M-1, J)
}

function calcJ(d) { if (isStr(d))  d = DateJS(d);  return new Date(d.getTime()) / 86400000 }
function calcAge(d) {
	if (isStr(d))  d = DateJS(d);
	var N = diffDays(d,new Date())
	return N/365.25
}
function addDays(d,j) { d = DateJS(d);  return new Date(d.getTime() + (1000 * 60 * 60 * 24 * j)) }
//function diffDays(d1,d2) { return (new Date(d1.getTime())-new Date(d1.getTime())) / 86400000 }
function diffDays(d1,d2) { return (d2-d1) / 86400000 }
function twoDigits(N) { return ((N <= 9) ? "0" : "") + N }
function CalcSec(Sec) {
	var SecJ = 86400, J, H, M, S, V, re=''
	V = Sec
	if ((J=parseInt(V/SecJ,10))>0) { V-= J*SecJ;  re = J+'j ' }
	if ((H=parseInt(V/3600,10))>0) { V-= H*3600;  re+= H+"h " }
	if ((M=parseInt(V/60,10))>0) { V-= M*60;  re+= M+"' " }
	return re
}

function CalcTps(mn, Unite) {
	var V=mn, U='mn';  if (!V)  return
	switch(Unite) {
		case 'J':  V = Round(V/1440,2);  break
		case 'H':  V = Round(V/60,2);  break
		case 'mn': break
		default:
			if (V>=1440) { U='J';  V = V/1440; }else if (V>=60) { U='H';  V = V/60; }
			V = {Tps:V, Unite:U}
	}
	return V
}

function ConvDate(DateTexte, FormAff) {
  var S, D, J, M, A, H, Mn, Sec, T, lg, p, Today, M1
  J = A = H = Mn = T = ''

  var DatText = Trim(DateTexte);  if (!DatText)  return ''
  if (DatText=='0') { DatText = FormatDate(new Date()) }
  S = DatText.substr(0,1);  if (S=='+' || S=='-') { S = addDays(new Date(),ze(DatText));  DatText = FormatDate(S,5) }
  S = Replace(DatText,"/"," ").toLowerCase()
  S = Replace(S,"-"," ")
  M1 = Isole(S," ",1);  T = Isole(S," ",2);  if (isNaN(M1) || isNaN(T))  return DatText   // pour entre 1/2 et 1/4 ou 5 derniers jours

  Today = new Date()
  D = Isole(DatText," ",1);  D = Replace(D,"-","/");  lg = D.length

  if (D.indexOf('/')<0) {
    J = D.substr(0,2)
    if (lg<3)  M = Today.getMonth() + 1
    else {
	    M = D.substr(2,2)
	    if (lg==6)  A = D.substr(4,2)
	    if (lg==8)  A = D.substr(4,4)
	  }
  }else{
    J = Isole(D,"/",1);  M = Isole(D,"/",2);  A = Isole(D,"/",3)
    if (J.length==4) {  S=J;  J=A;  A=S; }
  }
  if (J=='00')  return
		//alert(D+", "+J+", "+M+", "+A)
  S=''
  if (A) {
  	T = A;  A = parseInt(A,10)
  	if (T.length<3) {
  		if (A<30)  A+=2000;  else if (A<1900)  A+=1900
  	}
  }
	else{
		A = Today.getFullYear()
    if (A<200)  A=A-100+2000  //Bug Chrome ??
	}
	J = strPad(J, 2, '0', 1);  M = strPad(M, 2, '0', 1)

  switch (FormAff) {
    case "SQL":   S = A + "-" + M + "-" + J;  break
    case "USA":   S = M + "/" + J + "/" + A;  break
    default:      S = J + "/" + M + "/" + A
  }

  T = Isole(DatText," ",2)
  if (T) {
    Sec=""
    lg = T.length
    p = T.indexOf(":")
    if (p>=0) {
    	var TH = T.split(":")
    	H = TH[0];  Mn = TH[1];  if (TH.length>2)  Sec = TH[2]
    }else{
      H = T
    	p = T.indexOf("h")
	    if (p>=0) {
	      H  = T.substr(0,2)
	      Mn = T.substr(p+1,2)
      }
    }
    if (!Mn)  Mn="00";  if (ze(Sec))  Sec=":" + Sec;  else  Sec=''
    M1 = H+':'+Mn+Sec;  if (M1=='00:00')  M1='';  else  M1 = ' '+M1
    S = S+M1
  }
  return S
}

function FormatDate(DD, Format) {
	var S, SH, D, J, M, A, SH
  if (typeof(DD)=="date")  D = new Date(DD)
	else if (DD) {
  	D = DateJS(DD)
  }
 	if (!D)  return ''
  //if (!Format)  Format = "JJ/MM/AAAA"
	var J = D.getDate(), M = D.getMonth()+1, A = D.getFullYear();
	if (A<200)  A=A-100+2000  //Bug Chrome ??
		//alert(D+crr+J+cr+M+cr+A+crr+Format+crr+typeof(Format))
	if (typeof(Format)=="string") {
    S=Format
    S=Replace(S,"JJJJ",TJour[D.getDay()]);  S=Replace(S,"JJ",twoDigits(J));  S=Replace(S,"J",J)
    S=Replace(S,"MMMM",TMois[M-1]);  S=Replace(S,"MM",twoDigits(M));  S=Replace(S,"M ",M + " ")
    S=Replace(S,"AAAA",A)
    S=Replace(S,"AA",Right(A+"",2))
    return S
  }else {
  	switch(Format) {
	    case 2:   return TJour[D.getDay()] + " " + J + " " + TMois[M-1] + " " + A;  break
	    case 3:   return twoDigits(M) + "/" + twoDigits(J) + "/" + A;  break
	    case 4:   return twoDigits(A) + "/" + twoDigits(M) + "/" + J;  break
	    case 5:   return twoDigits(J) + "/" + twoDigits(M) + "/" + twoDigits(A);  break
	    case 1:
	 	  default:
	 	    S  = twoDigits(J) + "/" + twoDigits(M) + "/" + A
	 	    SH = twoDigits(D.getHours()) + ":" + twoDigits(D.getMinutes())
	 	    if (Format==1)  SH += ":" + twoDigits(D.getSeconds())
	 	    if (SH!="00:00" && SH!="00:00:00" )  S+= " " + SH
	 	    return S
	 	    break
	 	}
  }
}



// ====================================      _TABLEAUX_        ===============================

// http://www.java2s.com/Tutorial/JavaScript/0220__Array/UsingcontainsmethodfromzArrayLibrary.htm
function Tclone(T) { return T.concat(); };
function Tin(T,V) {	if (!T)  return;  var S = ','+T.toString()+',';  return (S.indexOf(','+V+','))>-1; }

//jQuery.inArray("John", arr));   répond 3
function InArray(T, V) {    // InArray(T,'ax*')
	var i, L, c, nbc
	c = Right(V,1);
	if (c=='*')  V = V.substr(0,V.length-1)
	else if (Array.prototype.indexOf)  return T.indexOf(V)
	L = T.length;  nbc = V.length
	if (c=='*')
		for (i=0; i<L; i++) {
			if (T[i].substr(0,nbc)==V)  return i
		}
	else
		for (i=0; i<L; i++)  if (T[i]==V)  return i
	return -1;
}

function RechArray(T, VRech, noRech, noV, Opt) {
	var i, L, R, vr, va, vt=-1
	if (noRech==undefined)  noRech = 0;  if (noV==undefined)  noV = 1
	L = T.length
	for (i=0; i<L; i++) {
		R = T[i]
		vr = R[noRech];  va = R[noV]
		switch(Opt) {
			case '>':  if (vr>VRech)  return vt;  else  vt = va;  break
			default:  if (vr==VRech)  return va
		}
	}
	return vt;
}

function Tableau1D(Def, Sep, Opt) {
	var SepV, SepL, T, T1, T2, i, j, S, lim
	Sep = Sep || ',;';  Opt = Opt || {}
	SepV = Sep.substr(0,1);  SepL = Sep.substr(1)
	if (!Def)  return new Array()
	T1 = Def.split(SepL)
	var T = {}
	for (i=0; i<T1.length; i++) {
		S = T1[i]
		if (S.indexOf(SepV)>0) {
			T2 = S.split(SepV)
			T[Trim(T2[0])] = Trim(T2[1])
		}
	}
	//alert(JSW(T)+crr+Def)
	return T
}

function Tableau2D(Def, Sep, Opt){
		//Transform une chaine en tableau multidimensionnel
	var SepV, SepL, T, T1, T2, i, j, S, lim=-1
	Sep = Sep || ',;';  Opt = Opt || {}
	SepV = Sep.substr(0,1);  SepL = Sep.substr(1)
	//if (Opt.avecListVide)  lim = -1;
	T1 = Def.split(SepL)
	var T = new Array(T1.length)
	for (i=0; i<T1.length; i++) {
		S = T1[i]
		if (S.indexOf(SepV)>lim) {
			T[i] = new Array();
			T2 = T1[i].split(SepV)
			for (j=0; j<T2.length; j++) {
				T[i][j] = T2[j]
			}
		}
	}
	//alert(JSW(T)+crr+Def)
	return T
}


// ====================================      TABLEAUX_HTML        ===============================
function AddTR(TA,TR0) {
	if (!TA)  return
	var TR, TD, i, nbL, nbC
	nbL = TA.rows.length;  if (!TR0)  TR0 = TA.rows[nbL-1]
	nbC = TR0.cells.length
	TR = MakeDom('TR')
	for (i=0; i<nbC; i++) {
		TD = MakeDom('TD',TR)
	}
	TA.appendChild(TR)
	return TR
}

function AddCol(TA,TD0,avant) {
	if (!TA)  return
	var TR, TD, i, ind, nbL, nbC, fin=0
	TR = TA.rows[0];  nbL = TA.rows.length;  nbC = TR.cells.length
	if (!TD0)  TD0 = TR.cells[nbC-1];  ind = TD0.cellIndex
	if (!avant)  if (ind==nbC-1)  fin = 1;  else  ind++
	for (i=0; i<nbL; i++) {
		TR = TA.rows[i]
		TD = MakeDom('TD')
		if (fin)  TR.appendChild(TD);  else  InsertBef(TR, TD, TR.cells[ind])
	}
}

function TConvert(TA, Opt) {  // Converti un tableau HTML en array. Minus=colonnes à convertir en minus, Mime = col à doublonner texte + html
	var T=[], TL, TR, TD, i, j, V, Min, Key, nbCol, Mime
	if (!TA || (TA && !TA.rows.length))  return
	Opt=Opt||{};  Key = Opt.Key;  Min = Opt.Minus;  Mime = Opt.Mime
	nbCol = TA.rows[0].cells.length;  //if (Mime)  nbCol+=Mime.length
	for (i=0; i<TA.rows.length; i++) {
		TR = TA.rows[i]
		TL = []
		for (j=0; j<TR.cells.length; j++) {
			TD = TR.cells[j]
			V = Trim(LText(TD));  if (Min && Tin(Min,j))  V = V.toLowerCase()
			if (Mime && Tin(Mime,j))  V+='|-|'+TD.innerHTML
			TL.push(V)
		}
		if (isNaN(Key))
			T.push(TL);
		else{
			V = TL[Key];  TL.splice(Key,1)
			if (nbCol==2)  T[V] = TL[0];  else  T[V] = TL
		}
	}
  return T
}

function TLookUp(Obj, Rech, ColExtract) {
	var T, TR, i, j, VR, nbOk, nbColRech, NbCol, NbLig, noExtract
		// si Rech="Toto;;5",  renvoi la colonne ColExtract lorsque la 1°col=Toto et la 3°col=5. Renvoi TR si !ColExtract
	if (typeof(Obj)=="string")  Obj = LID(Obj)
	T = LID(Obj);  if (!T)  return null
	NbLig = T.rows.length;  if (!T || !NbLig)  return null
	noExtract = (ColExtract)?ColExtract:0
	if (isNaN(noExtract)) noExtract = TRLookUp(T.rows[0], noExtract)
  var TRech = Rech.split(";");  nbColRech = TRech.length
  var NbCol = T.rows[0].cells.length
	if (NbCol<noExtract)  return null
	for (i=0; i<T.rows.length; i++) {
		TR = T.rows[i]
		nbOk = 0
		for (j=0; j<nbColRech; j++) {
			VR = TRech[j]
			if (!VR) nbOk++
			else {
				if (VR=="!" && LText(TR.cells[j])=="") nbOk++
				else if (LText(TR.cells[j])==VR) {
					nbOk++
				}
					//alert(j + ", " + VR + " =? " + LText(TR.cells[j]) + ", " + nbOk + ", " + nbColRech + ", " + ColExtract)
			}
		}
		if (nbOk==nbColRech)
			if (ColExtract) {
				return LText(TR.cells[noExtract]);
			}else  return TR
	}
	return null
}

function TRLookUp(TR, Rech, noL) {
 	// TD = TRLookUp(TR, "=LX(TD,'Champ')=='Titre'", -1)
	var i, TD, S, Rechl, Test, ok
	if (!TR)  return null
	if (Rech.substr(0,1)=="=")  Test = Rech.substr(1);  else  Rechl = Rech.toLowerCase()
	for (i=0; i<TR.cells.length; i++) {
		TD = TR.cells[i]
		if (Test) {  if (eval(Test))  ok=true;  /*alert(Test + ", " + eval(Test));*/  }
		else if (Trim(LText(TD)).toLowerCase()==Rechl)  ok=true
		if (ok) {
			if (!noL)  return i
			else if (noL<0)  return TD
			else {
				var TR2 = TR.parentNode.rows[noL];  if (TR2)  return LText(TR2.cells[i])
			}
		}
	}
}

function LTD(TR, n) {
	if (!TR)  return
	n = ze(n);  if (n>=TR.cells.length) return
	return LText(TR.cells[n])
}



// ====================================     _COORDONNEES_         ===============================
function PosMouse(e){
 	try {
  if(e){
    pixX = e.pageX;
    pixY = e.pageY;
  }else if (event) {
    pixX = event.clientX + document.body.scrollLeft;
    pixY = event.clientY + document.body.scrollTop;
  }
	}catch(e){}
	if (window.PosMouse2)  window.PosMouse2(e)
}

function Contains(Paren, O, SansElem) {
	Paren = LID(Paren);  O = LID(O)
	if (SansElem && O)  O = O.parentNode
  while (O && Paren!=O && O!=null)  O = O.parentNode
  return Paren==O;
}

function ContainsXY(O,x,y,d) {
	var Rep, dX, dY, fX, fY
	if (!O)  return 0;  if (!d)  d=5;  x = (x)?x:pixX;  y = (y)?y:pixY
	if (document.all) { x-=2; x-=2; }
  dX = CalcPos(O,"left");  dY = CalcPos(O,"top");  fX = dX + O.offsetWidth;  fY = dY + O.offsetHeight
  Rep = (x+d>dX && x-d<fX && y+d>dY && y-d<fY) ? 1:0;
  	//wb("Contains : " + Rep + " : (" + dX + "," + dY + ") (" + fX + "," + fY + "), x=" + x + ", y=" + y + ", d="+d+ " IN=" + (x+5>dX && x-5<fX && y+5>dY && y-5<fY) + "\n")
  return Rep
}

function CalcPos(O, Styl) {
	var p = 0
	O = LID(O)
	while (O.offsetParent) {
		switch (Styl) {
			case 'top':			p += O.offsetTop;			break;
			case 'left':		p += O.offsetLeft;		break;
			case 'width':		p += O.offsetWidth;		break;
			case 'height':	p += O.offsetHeight;	break;
		}
		O = O.offsetParent;
	}
	return p
}

function CalcXY(D, opt) {
	var OP, O, X=0, Y=0, x, y, p
	D = LID(D);  O = D
	while ((OP=O.offsetParent)) {
 		p = getStyle(O,'position')
		x = O.offsetLeft;  y = O.offsetTop;  X+=x;  Y+=y;  wh('CalcXY, x='+x+', y='+y+', X='+X+', Y='+Y+', pos='+p);  wh(O)
		O = OP
 		if (p=='absolute')  break
 		if (getStyle(OP,'position')=='relative')  break
// 		if (!opt && p!='static')  break
// 		if (opt && getStyle(OP,'position')!='static')  break
	}
	return { left:X, top:Y, width:D.offsetWidth, height:D.offsetHeight }
}

function getOffset( el ) {
	var _x = 0;
	var _y = 0;
	while( el && !isNaN( el.offsetLeft ) && !isNaN( el.offsetTop ) ) {
		_x += el.offsetLeft - el.scrollLeft;
		_y += el.offsetTop - el.scrollTop;
		// chrome/safari
		if ($.browser.webkit) {
			el = el.parentNode;
		} else {	// firefox/IE
			el = el.offsetParent;
		}
	}
	return { top: _y, left: _x };
}

function Ecran(J) {
	var L=0, H=0, W=window, D=document, DD=document.documentElement, B=document.body
	if (!J)  J = App
	if (typeof(W.innerWidth)=='number') {
	  L = W.innerWidth;
	  H = W.innerHeight;
	}else if (DD && (DD.clientWidth || DD.clientHeight)) {
	  L = DD.clientWidth
	  H = DD.clientHeight
	}else if (B && (B.clientWidth || B.clientHeight)) {
	  L = B.clientWidth;
	  H = B.clientHeight;
	}else{
	  L = -1;
	  H = -1;
	}
	J.WinW = L;  J.WinH = H
}

function CenterDiv(NomDiv, xmin, ymin) {
	//alert(App.WinW);
	var D, H, W, X, Y
	D=LID(NomDiv);  if (!D)  return
	if (!xmin)  xmin=1;  if (!ymin)  ymin=1;
	if (!App.WinW)  Ecran(App)
	Aff(D)
	W = D.offsetWidth;   if (W>App.WinW)  X=xmin;  else  X = Math.round((App.WinW-W)/2)
	H = D.offsetHeight;  if (H>App.WinH)  Y=ymin;  else  Y = Math.round((App.WinH-H)/2)
	//alert(App.WinH + ", " + H + ", " + D.offsetWidth + ", " + D.offsetHeight)
 	with(D.style) {
		left = X + "px"
 		top  = Y + "px";
 	}
}

function PosWin(D, O, pm) {
	var X, Y, J
	//if (isStr(pm))  pm = { dX:parseInt(getStyle(D,'width')) + 6 }
	pm = pm||{}
	if (O) {
		J = CalcXY(O);  X = J.left;  Y = J.top
		//if (pm=='D')  X-= parseInt(getStyle(D,'width')) - 6
	}else{
		X = pixX;  Y = pixY
	}
	if (pm.dx) { X+=pm.dx;  delete(pm.dx) };  if (pm.dy) { Y+=pm.dy;  delete(pm.dy) }
	Aff(D)
	//X+=10;  Y+=18
	D.style.position = 'absolute'
	D.style.left = X + document.body.scrollLeft + 'px'
	D.style.top  = Y + document.body.scrollTop + 'px'
	if (hasNod(pm))  $(D).css(pm)
}

function OutDiv(NomDiv) {
	var D = LID(NomDiv)
	if (ContainsXY(D,pixX,pixY))  setTimeout("OutDiv('" + NomDiv + "')",800);  else  Hide(D)
}

function WhenOutObj(O, fct) {
	if (ContainsXY(LID(O),pixX,pixY,0)) { setTimeout(function(){ WhenOutObj(O,fct) },800) }  else if (fct)  fct(O)
}


// ====================================     _GET_PUT_         ===============================
function $G(stor,n) { if (isStr(stor)) return $(stor,n).get(0);  else  return stor }

function $E(Nom,n) {
	var V
	if (isStr(Nom)) {
		var c = Nom.substr(0,1)
		if (c=='#' || c=='.') V = $(Nom,n).get(0);  else  V = $(Nom,n).get(0) || $('#'+Nom,n).get(0) || $('.'+Nom,n).get(0)
		if (!V) {
			V = document.getElementsByName(Nom);  //if (TypOf(V)=='NodeList')
			if (V)  V = V[0]
		}
		return V
	}else
		return $(Nom,n).get(0)
}

function $GS(stor,nodDeb,first) {
	// #barLogo>td>div:nth-of-type(2) - nth-child
	// #nav ul:first-of-type > li:not(.selected) = first ul not class selected
	var $O, O
	$O = $(stor,nodDeb)
	if ($O) { if (first!=undefined)  O = $O.get(first);  else  O = $O.get() }
	return O
}

function $w(expr,Msg,aj) { var O = $E(expr);  if (O)  if (aj)  O.innerHTML+= Msg;  else  O.innerHTML = Msg;  return O }

function G$(Nom) {
	var i, L, T, O
  if (arguments.length > 1) {
    for (var i=0, T=[], L=arguments.length; i<L; i++)  T.push(document.getElementById(arguments[i]))
    return T
  }
  if (typeof Nom=='string')  O = document.getElementById(Nom);  else  O = Nom
	if (!O) {  O = Doc.getElementsByName(Nom);  if (O)  O=O[0] 	}
  return O
}

function LID(Nom, Doc) {
	var O, F, S
	if (!Nom)  return null
	if (!Doc)  Doc = document
	if (typeof(Nom)=='string') {
		S = Nom.substr(0,1);  if (S=='#' || S=='.')  return $(Nom,Doc).get(0)
		if (Doc.tagName=='FORM')
			F = Doc
		else{
		  var BD = App.BD;  if (BD)  BD=BD.BD;  if (BD && BD[0] && BD[0].Form)  F = BD[0].Form;
		}
		if (F)  O = F.elements[Nom]
		if (!O)  O = Doc.getElementById(Nom);
	}else
		O = Nom
	if (!O) {  O = Doc.getElementsByName(Nom);  if (O)  O=O[0] 	}
	return O
}

function LText(O, Col, Opt) {
	var V
	O = LID(O)
	if (!O)  return ''
	if (O.tagName=='TR' && Col!=undefined)  O = O.cells[Col]
	//if (O.tagName) {
		if (ie)  V = O.innerText;  else  V = O.textContent
	//}else
	//	V = O.textContent
	if (V && Opt)  V = V.toLowerCase()
	//V = O.innerHTML.replace(/<[^>]+>/g,”");  innerText firefox
	return Trim(V)
}

function PText(O, V) {
	O = LID(O);	if (!O)  return
	if (ie)  O.innerText=V;  else  O.textContent=V;
}

function Lout(O, Max) {
	if (!O)  return
	O=LID(O);  if (!O)  return;  if (!O.tagName)  return typeof(O)
	var S = (O.outerHTML) ? O.outerHTML : getouterHTML(O)
	if (Max)  S=S.substr(0,Max)
	return S
}

function LOUT(O, Max) { S = Lout(O,Max)+'';  return CodeHtml(S) }

function getouterHTML(O) {
	var tn, el, H
	tn = O.cloneNode(true);  el = document.createElement('div');  el.appendChild(tn);
	//H = el.innerHTML;  //el.removeNode(true)
	return el.innerHTML;
}

function LTags(Div, Nom, index) {
	if (!Div)  return
	if (!Nom) { Nom=Div;  Div=document.body }
	var O =  Div.getElementsByTagName(Nom)
	if (index!=undefined) { if (O.length>index)  O = O[index];  else  O=null }
	return O
}

function LTag(Div, Nom, no) {
	if (no==undefined)  no = 0
	var O = LTags(Div,Nom);  if (!O)  return
	if (O.length>0)  return O[no]
}

function LTagt(Div, Nom, index) {
	var i, T=[], Os = LTags(Div,Nom);  for (i=0; i<Os.length; i++)  T.push(Os[i]);  return T
}

function LX(Obj, Nom, NotText, Col) {
	// renvoie l'attribut Nom de Obj ou "". Si NotText=1, renvoie null au lieu de ""
	var O, R
	if (typeof(Obj)=="string")  O = LID(Obj);  else  O = Obj
	if (O && O.tagName) {
	  Nom = Nom.toLowerCase()
		if (O.tagName=="TR" && Col!=undefined)  O = O.cells[Col]
		R = O.getAttribute(Nom);
	}else
		R = null
	if (!NotText && R===null)  R=''
	return R
}

function PX(Obj, Nom, V, Suppr) {
	var O, Sep, S
	if (!(O=LID(Obj)))  return
	if (V)  O.setAttribute(Nom,V);  else  if (Suppr)  RX(O,Nom)
}

function RX(O,Nom) { if ((O = LID(O)))  O.removeAttribute(Nom) }

function SetAt(Nom, Chaine) {
	var O, T, i
	O = LID(Nom)
	T = Chaine.split(";")
	for (i=0; i<T.length; i++) {
		P = T[i].split("=")
		if (P.length>1)  O.setAttribute(Trim(P[0]),Trim(P[1]))
	}
}


// ====================================    _FORM_    ===============================
function LVal(Ctl, SiText) {
	var O, V, Tag
	O = LID(Ctl);  if (!O)  return
	Tag = O.tagName
	if (Tag=="SELECT") {
	  if (SiText) V=LitSelect(O);  else  V=O.value
	}else if (O.type)
		switch(O.type) {
			case "checkbox":  if (SiText) V=(O.checked)?"x":"";  else  V = O.checked;  break;
			case "radio":  V = LitRadio(O);  break;
			default:  V = O.value
		}
	else if (O.tagName) {
	  switch (O.tagName.toLowerCase()) {
		  case "img": case "imagedata":  V = O.src;  break
		  case "input":  V = O.value;  break
		  case "a":  V = O.href;  break
		  case 'script':  V = O.innerHTML;  break;
		  default:  V = LText(O)
	  }
	}
	return V
}

function PVal(Ctl, V) {
	var O
	if (typeof(Ctl)=="string") O = LID(Ctl);  else  O = Ctl;
	if (!O)  return
	if (V==undefined)  V=''
	if (O.type) {
		switch(O.type) {
			case "checkbox":  O.checked = V;  break;
			case "radio":   LitRadio(O, V);  break;
			case "file":   break;
			default:  O.value = V
		}
	}else if (O.tagName) {
		switch (O.tagName.toLowerCase()) {
			case "img": case "imagedata":  O.src = V;  break
			case "input":  O.value = V;  break
			default:  try { O.innerHTML = V }catch(e){ }
		}
	}
}

function LitRadio(O, V) {
	var Nom, Doc
	//if (typeof(O)=="string") { Nom = O;  Doc = document } else  { Nom = O.name;  if (O.document)  Doc = O.document;  else  Doc = document }
	Doc = document;  Nom = O.name;
	var Os = Doc.getElementsByName(Nom)
	for (i=0; i<Os.length; i++) {
 		O = Os[i];  //alert(Nom + ", V=" + V + crr + O.outerHTML + crr + Doc.location)
		if (V!=undefined) {
			if (O.value==V) {  O.checked = true;  return V  }
		}else
			if (O.checked)  return O.value
	}
	return ''
}

function LitSelect(Ctl,Obj) {
	Ctl = LID(Ctl);  if (!Ctl)  return
	if (!Ctl.options || Ctl.selectedIndex<0)  return ''
	var O = Ctl.options[Ctl.selectedIndex]
	if (Obj)  return O;  else  return O.text
}

function ListCtl(D) {
	var O1, O2, O3, O4, i
	D = LID(D)
	O1 = LTagt(D,'INPUT');  O2 = LTagt(D,'SELECT');  O3 = LTagt(D,'TEXTAREA')
	O1 = O1.concat(O2,O3)
	O4 = LTags(D,'SPAN');  for (i=0; i<O4.length; i++) { if (LX(O4[i],'bd'))  O1.push(O4[i]) }
	return O1
}

// ============================     _DHTML_    ======================
function ElemSup(O, Tag) {
	O = LID(O)
	if (Tag) {
	  D = LID(Tag);  if (!D && !(D=ElemPTag(O,Tag.toUpperCase())))  return
	  O = D
	}
	return O
}

function Aff(O, Tag, Test)  {
	var S, D
	O = ElemSup(O,Tag);  if (!O)  return
// 	if (!(O=LID(O)))  return
// 	if (Tag) {
// 	  D = LID(Tag);  if (!D && !(D=ElemPTag(O,Tag.toUpperCase())))  return;  //alert(Lout(O)+crr+Test)
// 	  O = D
// 	}
	if ((S=LX(O,'conteneur')))  O = LID(S)
	S = (Test!=undefined && !Test) ? 'none':'block'
	if (!(ie && navV<8) && O.tagName=='TD' && S=='block')  S = 'table-cell'
	if (O.style.display!=S)  O.style.display = S
	return SiAff(O)
}
function Hide(O, Tag, Opt) {
	var S
	O = ElemSup(O,Tag);  if (!O)  return
	if (!Opt && (S=LX(O,'conteneur')))  O = LID(S)
	if (O)  O.style.display = 'none'
	return O
}
function AFF(O,bool) { if (bool==undefined)  bool=1;  if ((O=LID(O)))  O.style.display = (bool)?'block':'none' }
function Disp(O)  { if ((O=LID(O)))  return O.style.display }
function SiAff(O, Tag) {
	O = ElemSup(O,Tag);  if (!O)  return
	return (getStyle(O,'display')!="none")
}
function Hauteur(D) { if ((D=LID(D)))  return D.offsetWidth }

function InverseDisplay(O, O2, Param) {
	var S
	if (typeof(O)=="string") O = LID(O);  if (typeof(O2)=="string") O2 = LID(O2)
	if (O && O2) {
		if (Param) {
			O.style.display = Param;  O2.style.display = (getStyle(O,'display')=="none") ? 'block':'none'
		}else{
			S = O.style.display;  O.style.display = O2.style.display;  O2.style.display = S
		}
	}else{
    if (O)  O.style.display = (getStyle(O,'display')=='none') ? 'block' : 'none'
  }
  if (O)  return O.style.display
}

function getStyle(O, stylIE, stylMoz) {
	O = LID(O);  if (!stylMoz)  stylMoz = stylIE
	if (O.currentStyle)  return O.currentStyle[stylIE];
	else if (window.getComputedStyle)  return window.getComputedStyle(O, null)[stylMoz];
	//document.defaultView.getComputedStyle(obj, null).getPropertyValue(stylMoz);
}

// function setStyle(O, stylIE, V, stylMoz) {
// 	O = LID(O);  if (!stylMoz)  stylMoz = stylIE
// 	if (O.currentStyle)  O.currentStyle[stylIE] = V;
// 	else if (window.getComputedStyle)  window.getComputedStyle(O, null)[stylMoz] = V;
// }


// ============================     _ManipDOM_    ======================
function getID(D) {
	var D = LID(D)
	if (!D.id)  PX(D,'id','id'+UniqueID())
	return D.id
}

function InsertBef(Dest, O, O2) {
	var N
	if (!O2)  O2 = Dest.firstChild
	if (document.all)  N = Dest.insertBefore(O);  else  N = Dest.insertBefore(O,O2)
	return N
}

function InsertHtml(H, Dest, htmlP) {
	if (!htmlP)  htmlP = 'div'
	if (!Dest)  Dest = document.body;  else  Dest = LID(Dest)
	var D = document.createElement(htmlP);  D.innerHTML = H
	InsertBef(Dest,D)
}

function ReplaceNod(Dest, O) {  // Dest peut être un tableau de nod à remplacer. O est un seul nod
	var i, TD
	if (isArray(Dest))  TD = Dest;  else  TD = [Dest]
	TD[0].parentNode.replaceChild(O,TD[0])
	for (i in TD)  if (i>0)  RMNod(TD[i])
}

function MakeDom(el, Div, JS, Txt) {
	//D = MakeDom('div',Dest, {Niv:1, Class:'divTree'})  => écrire class Class, car mot réservé par JS
	var D, O, i, L
	JS = JS || {}
	if (!(O=LID(el))) {
		if (Div==='')  Div = 'body'
		if (typeof(Div)=='string')  Div = (Div=='body') ? document.documentElement.childNodes[1] : LID(Div)
		O = document.createElement(el);
		if (Div)  Div.appendChild(O)
	}
	for(i in JS) {
		switch(i) {
			case 'Class':  O.className = JS[i];  break
			case 'css':  $(O).css(JS[i]);  break
			default:  O.setAttribute(i, JS[i])
		}
	}
	if (Txt)  O.appendChild(document.createTextNode(Txt))
	//L = arguments.length;  for (i=2; i<L; i+=2)  O.setAttribute(arguments[i],arguments[i+1])
	return O
}

function MakeTxt(D,txt) { D.appendChild(document.createTextNode(txt)) }

function ReplaceTag(O1, Tag) {  // http://help.dottoro.com/ljncfoxj.php
	var As, i, O2 = document.createElement(Tag)
	As = O1.attributes;  for (i=0; i<As.length; i++)  O2.setAttribute(As[i].nodeName,As[i].nodeValue)
	O2.innerHTML = O1.innerHTML
	O1.parentNode.insertBefore(O2,O1)
	O1.parentNode.removeChild(O1)
	return O2
}

function hasChild(O) { if (O)  return O.childNodes.length }

function RMNod(O) {
	if (O) O = LID(O)
	if (O) O.parentNode.removeChild(O)
}

function ClearDiv(D) {
	var i, O
	if (D) D = LID(D);  if (!D)  return
	for (i in D.childNodes) {
		if (isNaN(i))  continue
	  O = D.childNodes[i]
	  D.removeChild(O)
	}
}

function AdImg(D, Path) {
	$('img',D).each(function(index, O) { var S;  if (O.src.indexOf(Path)<0)  O.src = Replace(O.src, RootSite+'/', RootSite+Path+'/'); })
}


// ============================     _Rech_DHTML_     =====================
function CalcIndex(El, Test) {
	var ElemP, i, O
	El = LID(El);  if (!Test)  Test = true
	ElemP = El.parentNode
	//var Os = ElemP.getElementsByTagName('*');  for (i=0; i<Os.length; i++) {  if (Os[i]==O)  return i	}
	O = ElemP.firstChild
	i = -1
	while(O) {
		if (O.nodeType==1 && eval(Test))  i++
		if (O==El)  return i
		O = O.nextSibling
	}
}

function PosIndex(ElemP, pos, Test) {
	var Os, O, i
	if (!Test)  Test = true
	O = ElemP.firstChild;  i = -1
	while(O) {
		if (O.nodeType==1 && eval(Test))  i++;  //alert(i+crr+Lout(O))
		if (i==pos)  return O
		O = O.nextSibling
	}
}

function Elem(El, Test, SiUp) {
	var O, i=0
	O = El
	while (O) {
		if (O.nodeName.substr(0,1)!="#") {
			if (Test && eval(Test))  return O
			i++
		}
		if (SiUp)  O = O.previousSibling;  else  O = O.nextSibling
	}
}

function ElemFils(Obj, Test) {
	var O, R, L
	if (!Obj || !Test)  return;
	R = null
	L = Obj.childNodes.length
	for (var i=0; i<L; i++) {
		O = Obj.childNodes[i]
		if (O.nodeName=="#text") {
			if (Eval(Test))  R = O;  else  return null
		}else {
			//alert(O.outerHTML + ", " + "==>" + eval("O"))
			if (eval(Test))  R = O;  else  R = ElemFils(O,Test)
		}
		if (R)  return R
	}
}

function ElemIn (ElemP, Test, In, Opt) {
	// ElemIn(Div, "cl1='2'", true, "Tag=DIV")
	// TA = ElemIn('DivTags','O.tagName=="TABLE"', false, 0) => extrait 1° table dans les fils direct
	// P = ElemIn(TR, "@C='DivIn'", true);  if (P)  P = P[0]
	var Os, O, i, Res = []
	ElemP = LID(ElemP);  if (!ElemP)  return
	if (!isNaN(Opt)) { i=Opt;  Opt={};  Opt.Index = i}  else if (!Opt)  Opt={}
	var Action = Opt.Action
	var Tag = Opt.Tag || '*'
	if (typeof(Test)=="string") {
		if (Test=="Ctl")
			Test = "'INPUT,SELECT,TEXTAREA'.indexOf(O.tagName)>=0";
		else{
			Test = Replace(Test,'@C','O.className')
		}
	}
		//alert(Test)
	if (Opt.Avec) {   // inclure le père dans la rech
		O = ElemP
		if (eval(Test)) {
			if (Action)	{	eval(Action) 	}else  return O
		}
	}
	if (ElemP.length)  Os = ElemP
  else if (In)  Os = ElemP.getElementsByTagName(Tag)
	else  Os = ElemP.childNodes
	if (!Os.length)  return

	var L = Os.length
	for (i=0; i<L; i++) {
		O = Os[i]
		if (O.nodeName.substr(0,1)!="#") {
			//if (ie)  wb (i + ", " + O.outerHTML.substr(0,150));  else  alert(O.innerHTML)
			if (eval(Test)) {
				if (Opt.Index!=undefined && Res.length==Opt.Index)  return O
				Res.push(O);  //alert(Test+crr+cl1+crr+Lout(O))
				if (Action)	{
					eval(Action)
				}
			}
		}
	}
	if (Opt.Index!=undefined && !Res.length)  Res = null
	return Res
}

function ElemAt(O, At, V, Opt) {
	//ElemAt(Obj, "Obj", "LibTree", {Avec:1})
	var O, S
	S = "O.getAttribute('" + At + "')";  if (V) S+="=='" + V + "'";  else  S+="!=null";  //alert(S+crr+Lout(O))
 	return ElemIn(O, S, true, Opt)
}

function ElemParent(Obj, Test) {
	var O, R
	O = Obj;	if (!O)  return
	if (O.nodeName=="#text")  O = O.parentNode
	while (O && O.nodeName.substr(0,1)!="#") {
		  //if (Bug==8)  alert(Test + crr + eval(Test) + crr + O.outerHTML)
		if (eval(Test))  return O
		if (O.tagName=='BODY')  return
    O = O.parentNode
  }
}

function ElemPTag(Obj, Tag, pm) {   // O=ElemPTag(D,'TD',{Jusqua:DivP})
	var Fin, Plusieurs, O = Obj, Tg;  if (!O)  return
	if (Tag.indexOf(',')) { Tag=','+Tag+',';  Plusieurs=1 }
	pm = pm || {}
	Fin = pm.Jusqua || document.body
	if (O.nodeName=="#text")  O = O.parentNode
	//while (O && O.nodeName.substr(0,1)!="#") {
	while (O!=Fin) {
		Tg = O.tagName
		if (Plusieurs && Tag.indexOf(','+Tg+',')>=0)  return O
		else if (Tg == Tag) 	return O
		O = O.parentNode
	}
	return null
}

function ElemPAt(Obj, At, V) {
	var O, S, car
	Obj = LID(Obj)
	if ((car=At.substr(0,1))=='!')  At = At.substr(1)
	S = "O.getAttribute('" + At.toLowerCase() + "')";  if (V) S+="=='" + V + "'";  else  S+="!=null"
	O = ElemParent(Obj,S)
	if (car=='!') return LX(O,At);  else  return O
}

function ElemPVar(Obj, At, V) {
	var O, S, car
	if ((car=At.substr(0,1))=='!')  At = At.substr(1)
	S = "O." + At;  if (V) S+="=='" + V + "'";  else  S+="!=null"
	O = ElemParent(LID(Obj),S)
	if (O && car=='!') return O[At];  else  return O
}

function ElemPClass(Obj, V) {
	var S
	//S = "O.className.indexOf('" + V + "')>=0";
	S = "Tin(O.className.split(' '),'" + V + "')"
 	return ElemParent(Obj,S)
}

function ElemPrev(O) { do{ O = O.previousSibling; }while (O && O.nodeType!=1);  return O; }
function ElemNext(O) { do{ O = O.nextSibling; }while (O && O.nodeType!=1);  return O; }

// ====================================       _OBJETS_JS_      ===============================
function hasNod(Obj) { if (!Obj)  return 0;  for (var S in Obj)  return 1;  return 0 }
function ObjAsChild(Obj) { return hasNod(Obj) }
function CountNod(Obj) {
	var S, n=0
	if (!Obj)  return n;
	if (TypOf(Obj)=='Array')  return Obj.length;
	for (S in Obj)  n++
	return n
}

function TypOf(O) {   // TypOf(R)=='Array'
	if (!O)  return typeof(O);
	if (O.tagName)  return 'OH '+O.tagName+' '+O.id
	if (O && O.constructor && O.constructor.toString) {   // Pour un objet VueClass, constructor = function VueClass(). Pour un objet, = function Object()
		var arr = O.constructor.toString().match(/function\s*(\w+)/);
		if (arr && arr.length==2)  return arr[1];
	}
	return typeof(O);
}

function Heriter(De, So) { for (var el in So) { De[el] = So[el]; } }

// Object.prototype.clone = function() {
// 	var i,  newObj = (this instanceof Array) ? [] : {};
// 	for (i in this) {
// 		if (i=='clone') continue;
// 		if (this[i] && typeof this[i] == "object") {
// 			newObj[i] = this[i].clone();
// 		}else
// 			newObj[i] = this[i]
// 	}
// 	return newObj;
// };

function ObjClone(O,recur,Opt) {  // O = new ObjClone(Memo)
	var avec, sauf, c
	if (Opt) {
		c = Opt.substr(0,1)
		if (c=='>')  avec = ','+Opt.substr(1)+',';  else  sauf=','+Opt+','
	}
	for (var K in O) {
		if (isNaN(K) && avec && avec.indexOf(','+K+',')<0)   continue;		//wh(K)
		if (sauf && sauf.indexOf(','+K+',')>=0)  continue;		//wh(K)
		if (recur && typeof O[K]=='object')  this[K] = new ObjClone(O[K],true,Opt);  else  this[K] = O[K];
	}
}

function cloneObj(O,recur,Opt) {
	var JS = {}, avec, sauf, c
	if (Opt) {
		c = Opt.substr(0,1)
		if (c=='>')  avec = ','+Opt.substr(1)+',';  else  sauf=','+Opt+','
	}
	for (var K in O) {
		if (isNaN(K) && avec && avec.indexOf(','+K+',')<0)   continue;		//wh(K)
		if (sauf && sauf.indexOf(','+K+',')>=0)  continue;		//wh(K)
		if (recur && typeof O[K]=='object')  JS[K] = new cloneObj(O[K],true,Opt);  else  JS[K] = O[K];
	}
	return JS
}

function copyObj(o1,o2) {   // copie o2 dans o1. Si pas de o2, duplication de o2
  var O, JS, i
  if (!o2) { JS={};  o2 = o1 }else  JS = o1
	if (!JS)  JS={};
	for (i in o2) {
	  O = o2[i];
		if (typeof(O)=='object') {
			if (!JS[i])  JS[i] = {};  copyObj(JS[i],O);
		}else
			JS[i] = O
	}
	return JS
}

function NodtoXml(Obj, Tag, Niv, Exclus) {
	var ret, H="", avt="", i, Typ
	if (!Obj)  return ""
	for (i=0; i<Niv; i++)  avt+= "\t"
	for (NomObj in Obj) {
		if (!Exclus.indexOf(NomObj + ","))  continue
  	O = Obj[NomObj]
		V = O;  Typ = typeof(O)
		if (Typ!="function" && Typ!="object" && V)  H+= ' ' + NomObj + '="' + V + '"'
  }
  if (!H) return ""
  if (Tag) return avt + "<" + Tag + H + "/>\n";  else  return H
}

function PosPath(Root, Path, PM) {  // Pointe ou crée une ligne de nods. make = crée les nods manquants
	var T, S, V, i, K, nod, Separ
	if (!Root)  Root = {};  if (!Path)  return Root
	if (!isObj(PM))  if (isStr(PM))  PM = { Separ:PM };  else  PM = { make:PM }
	Separ = PM.Separ || '.'
	nod = n = Root
	T = Path.split(Separ);
	for (i in T) {
		K = T[i]
		if (nod[K]==undefined) { if (PM.make) { nod[K] = {}; }  else  return }
		nod = nod[K]
	}
	return nod
}

function PutJ(Root, Path, V, pm) { return PutPath(Root, Path, V, pm); }
function PutPath(Root, Path, V, pm) {     // Attention, Root doit exister. var O = {};  PutPath(O, "Vues.Site.BoX.A", 555);  alert(JSW(O))
	var nod, T, K, S
	T = Path.split('.');  K = T.pop();  Path = T.join('.')
	if ((nod=PosPath(Root, Path, 1))) {
		if (pm) {
			switch(pm) {    // Test : O = {};  PutJ(O,'P',1);  alert(JSW(O));  PutJ(O,'P',2,'&');  alert(JSW(O))
				case '+':  if (!nod[K])  nod[K] = 0;  nod[K]+=V;  break;
				case '&':
					if (!nod[K])  nod[K] = [];  else if (!isArray(nod[K]))  nod[K] = [nod[K]]
					if (!Tin(nod[K],V))  nod[K].push(V)
					break;
	 		}
		}else
			nod[K] = V
		return nod[K]
	}
}

function DelJ(Root, Path) { return DelPath(Root, Path); }
function DelPath(Root, Path) {    // DelPath(O, "Vues.Site.BoX.A");
	var nod, T, K
	T = Path.split('.');  K = T.pop();  Path = T.join('.')
	if ((nod=PosPath(Root, Path)))  delete(nod[K])
	while(T.length) {
		if (ObjAsChild(nod))  break
		K = T.pop();  Path = T.join('.')
		nod = PosPath(Root, Path)
		delete(nod[K])
	}
  return nod
}



// ====================================       _JSON_      ===============================
function JST(J, Nom) {
	var c
	if (!isStr(J))  return J
	c = J.substr(0,1)
	if (c=='[' || c=='{')
		return JSOND(J)
	else
		if (Nom)  return {Nom:J};  else  return J
}

function JSONS(Obj, Opt) {
	//alert(JSONS({'a':1, 'b':"2'4", 'c':{'x':'ab','a':1, 'b':"2'4"}}))
	if (!Obj) return
	if (window.JSON) {
		var S = JSON.stringify(Obj, JSONS_accept, Opt);
		if ((App.Ajax && App.Ajax.sansAccent) || (window.jQuery && $.browser.mozilla))  S = SupprAccent(S)
		if (S=='undefined')  S=undefined;
		return S
	}
	return JSO(Obj)
}

function JSONS_accept(key,V) {
	if (typeof V!='object' && V===undefined) {
		//alert(key+cr+V)
		return undefined
	}else if (V==null)  return undefined
	else if (typeof(V)=='object') {
	  if  (!hasNod(V))  return undefined
	}
	return V
}

function JSONS_accept2(key,V) {
	if (typeof V!='object' && V===undefined) {
		return undefined
	}else if (V==null)  return undefined
	else if (typeof(V)=='object') {
		if (TypOf(V)!='Object' && TypOf(V)!='Array')  return undefined
	  if  (!hasNod(V))  return undefined
	}
	return V
}

function JSO(Obj, Opt) {
	//alert(JSON({'a':1, 'b':"2'4", 'c':{'x':'ab','a':1, 'b':"2'4"}}))
	var H, H1='', Nom, nb=0, V
	//if (typeof(Obj)=="string") { S = XmlPost('Pgm=JSONDecode&Chaine='+escape(Obj));  return S }
	if (!Obj)  return '';  if (!Opt)  Opt = {}
	for (Nom in Obj) {
		V = Obj[Nom];  if (!V && V!==0) continue
		switch (typeof(V)) {
			case 'boolean':  V = (V) ? 1:0;  break
			case "string":   V = '"' + Replace(V,'"','\\"') + '"';  break
			case 'object':   V = JSO(V);  if (!V)  V='{}';  break
		}
		//if (!(Opt.nonVide && (!V || V=="''"))) {
		if (!(!V || V=="''")) {
			if (isNaN(Nom)) { H1+= ', "' + Nom + '":' + V;  nb++; }else  H1+= ", "+V;
		}
	}
	if (H1)  H1 = H1.substr(2);  else  return ''
	if (nb)	H = '{' + H1 + '}';  else  H = '[' + H1 + ']';
	return H
}

function JSW(Obj, htm) {
	if (window.JSON)  H = JSON.stringify(Obj, JSONS_accept2, 4);  else  H = JSS(Obj)
	if (htm) { H = Replace(H,' ','&nbsp;'); H = Replace(H,'\n','<br>') }
	return H
}

function JSS(Obj, Opt, niv) {
	var H, V, cr, H1='', Nom, nb=0, bl=''
	if (!Obj)  return '';  if (!Opt)  Opt = {cr:'\n'}
	if (!niv)  niv=0;  else  if (niv>20)  return
	if (!(cr=Opt.cr))  cr='';  else  bl = strPad(' ', niv*2, ' ')
	//if (typeof(Obj)=="string") { S = XmlPost('Pgm=JSONDecode&Chaine='+escape(Obj));  return S }
	for (Nom in Obj) {
		V = Obj[Nom];  if (!V && V!==0) continue
		switch (typeof(V)) {
			case 'boolean':  V = (V) ? 1:0;  break
			case "string":   V = '"' + Replace(V,'"','\\"') + '"';  break
			case 'object':
				H = TypOf(V);  if (H.indexOf('Class')>0)  continue
				//alert(H)
				switch (TypOf(V)) {
				case 'Array':
				case 'Object':
					V = JSS(V,Opt,niv+1);
					break
				}
				break
			case 'function':  continue
		}
		if (!(Opt.nonVide && (!V || V=="''"))) {
		  if (isNaN(Nom)) { H1+= ', "' + Nom + '":' + V;  nb++; }else  H1+= ", "+V;
		}
	}
	if (H1)  H1 = H1.substr(2);  else  return ''
	if (nb)	H = '{' + cr + bl + H1 + bl + cr + bl + '}\n';  else  H = '[' + cr+ H1 + cr + ']';
	return H
}

function JSOND(Chaine) {
	var e, S, c
	if (!Chaine) return;  if (typeof(Chaine)=='object')  return Chaine
	S = Trim(Chaine);  c = S.substr(0,1);  if (c=='[' || c=='{')  Chaine = S;  else  return Chaine
	//Chaine = Replace(Chaine,'\\"','"');  Chaine = Replace(Chaine,'\\"','"')
	try {
		if (window.JSON)  return JSON.parse(Chaine)
		if (window.jQuery)  return jQuery.parseJSON(Chaine)
	  e = eval('('+Chaine+')')
		return e
	}catch(e){
		try {
		  return eval('('+Chaine+')')   // JSON de ie a besoin de "Cle":"valeur" : des guillemets sur la clé. Avec eval, pas besoin
		}catch(e){
			//alert('Chaine invalide : '+crr+(typeof(Chaine))+crr+Chaine)
			return Chaine
		}
		//S = '{\"AdImg\":\"biblio/img/arist/banniere780.jpg\"}'
    //alert(S+crr+Chaine)
		//alert(JSOND(S))
	}
	//return JSON_Decode(Chaine);
}

function Encode(S) { return encodeURIComponent(S) }
//escape


// ====================================    _EVENT_    ===============================

function AttachEvent(O,Nom,fct) { O = LID(O);  if (document.attachEvent)  O.attachEvent('on'+Nom,fct);  else  O.addEventListener(Nom,fct,false) }
function DetachEvent(O,Nom,fct) { O = LID(O);  if (document.detachEvent)  O.detachEvent('on'+Nom,fct);  else  O.removeEventListener(Nom,fct,false) }

function Event_Attach(Nom,OE) {
	if (!OE)  OE = document.body;  if (document.attachEvent)  OE.attachEvent('on'+Nom,ExecEvent);  else  OE.addEventListener(Nom,ExecEvent,false)

	function ExecEvent(e) {
		var O, OP, fct, NomE
		if (!(O=EventCtrl(e))) return;  if (!O.tagName) return;
		NomE = (Nom=='mouseout') ? 'mouseover': Nom
		//if (!(OP=ElemPAt(O,'ev_'+NomE)))  return
		OP = ElemPAt(O,'ev_'+NomE)
		if ((S=LX(OP,'ElemOn'))) {
			$(S,OP).each(function() {
				switch(Nom) {
					case 'mouseover': if (Contains(this,O))  AddClass(this,'Over');  else  RMClass(this,'Over');  break
					case 'mouseout':  RMClass(this,'Over');  break;
					default:  alert(Nom)
				}
			})
		}else{
			if (!(S = LX(OP,'ev_'+NomE)))
				switch(NomE) {
					case 'click':  S = 'onClic';  break
				}
			//if (NomE!='mouseover')  alert(Nom+crr+Lout(O)+crr+Lout(OP)+crr+S)
			if (window[S])  window[S](O)
		}
		//if ((fct=window['ev_'+Nom]))  fct(OP,e)
	}
}

function EventCtrl(e) {
	var O
	if (typeof(e)=="string")  e = LID(e)
	if (e && e.tagName)  O=e;  else  O = (ie) ? window.event.srcElement : e.target;  //alert(Lout(O))
	return O
}

function AnnulEvent(e) {
	if(!e) var e = window.event;
	e.cancelBubble = true;
	e.returnValue = false;
	if (e.stopPropagation) {
		e.stopPropagation();
		e.preventDefault();
	}
	return false;
}

function dragStart(e) {
	var O, D = EventCtrl(e)
	if ((O=ElemPAt(D,'draggable'))) {
  	getID(O)
		e.dataTransfer.effectAllowed = 'move';
		e.dataTransfer.setData("Text", O.id);
	}
}

function dragOver(e) { return false }

function Drop(e) {
	var P, D
	D = EventCtrl(e)
	if (P=ElemPClass(D,'Vue')) {
		if (P.Vue.Drop)  P.Vue.Drop(e,D)
	}//else  D.appendChild(O);
	AnnulEvent(e)
	return false;
}

KeyDown = function(e) {
	var W, key, O, P, S, ck='Key_', Vu
	e = window.event||e;		//alert(ev.keyCode+crr+ev.shiftKey)
	key = (ie)?e.keyCode:e.which;		//alert(key)
	if (e.ctrlKey)  ck+='ctrl_';  if (e.altKey)  ck+='alt_';  if (e.shiftKey)  ck+='shift_'
	ck+=key
	O = EventCtrl(e);  P = ElemPClass(O,'Vue')
	if (P)  Vu = P.Vue
	W = Vu || window
	//wh('Key : '+TypOf(W)+'.'+ck)
	if (Vu)  Vu.KeyDown(key, O, ck)
	if (W[ck])  W[ck](O);  else{ ck = Replace(ck,'shift_','');  if (W[ck])  W[ck](O) }
}


// -------------  Evt Listes --------------------   voir E.classList
//function hasClass(O, Class) { if ((O=LID(O)))  return Tin(LID(O).className.split(' '),Class) }
function hasClass(O, Class) {  if (!(O=LID(O)))  return;  return (InArray(O.className.split(' '),Class)>=0) ? 1:0 }
function AddClass(O, Class) {
	if (!(O=LID(O)))  return;  var S = O.className;  if (!Tin(S.split(' '),Class))   O.className = AddStr(S,Class,' ');
}
function RMClass(O, Class) { DelClass(O, Class) }
function DelClass(O, Class) {
	var T, p
	if (!(O=LID(O)))  return
	T = O.className.split(' ');  while ((p=InArray(T,Class))>=0)  T.splice(p,1)
	if (T.length)  O.className = T.join(' ');  else  RX(O,'class')
}
function InverseClass(O, Class1, Class2) {
	if (!(O=LID(O)))  return
	if (Tin(O.className.split(' '),Class1)) { DelClass(O, Class1);  if (Class2) AddClass(O, Class2)	}else{ if (Class2) DelClass(O, Class2);  AddClass(O, Class1) }
}



// ====================================      _INTERACTIF_       ===============================
function Focus(Ctl) {
	var Nom
	if (typeof(Ctl)=="string")  Ctl = LID(Ctl)
	try {
		Nom = Ctl.name
	  Ctl.focus()
	}catch(e){
		window.status="Contrôle " + Nom + " non prêt"
	}
}

function FocusEnd(Ctl) {
	try {
	  Ctl.focus();  Ctl.select()
	  var txtR = Ctl.createTextRange();  txtR.moveEnd("textedit");  txtR.moveStart("textedit");  txtR.select()
	}catch(e){
		window.status="Ctl non trouvé"
	}
}

function FocusCh(Ctl) {
	var Msg=LX(Ctl,'Msg')
	if (!Msg) { Msg=Ctl.value;  PX(Ctl,'Msg',Msg) }
	if (Ctl.value==Msg)  Ctl.value=''
}

function BlurCh(Ctl) {
	if (!Ctl.value)  Ctl.value=LX(Ctl,"Msg")
}

function OutPopup(Ad,Param) {
  if (Ad.indexOf('?')<0)  Ad+='?';
	Ad+= AjUrl
	window.open(Ad, '', AddStr("toolbar=no,menubar=no,scrollbars=yes,resizable=yes,status=yes,width=760,height=600",Param,','))
}

function CloseWindow() {
	ww = window.open(window.location, "_self");
	ww.close();
}


// ====================================     _FICHIER_      ===============================
function TypFic(Path) {
	var Ext
	if (!Path)  return
	if (Path.indexOf('.')<0)  Ext = Path;  else  Ext = Right(Path,1,'.')
	Ext = Ext.toLowerCase()
	if (',jpg,gif,png,bmp,'.indexOf(','+Ext+',')>=0)  return 'I';
	else if (',php,exe,com,'.indexOf(','+Ext+',')>=0)  return 'P';
	else if (',htm,html,'.indexOf(','+Ext+',')>=0)  return 'H';
	else return (Ext) ? 'D':'R';
}

function ChoixIco(Adr, pm) {
	var Ext, Ico, Typ, Dir, H
	pm=pm || {}
	if ((Ext=Right(Adr,1,'.')))  Ext = Ext.toLowerCase().substr(0,3)
	Dir = 'typdoc/'
	switch(Ext) {
		case 'htm': case 'mht': case 'asp':  Ico='Page';  Typ='htm';  break;
		case 'doc':  Ico = 'doc1';  break;
		case 'xls':  Ico = 'xls1';  break;
		case 'csv':  Ico = 'xls';   break;
		case 'ppt':  Ico = 'ppt1';  break;
		case 'pdf':  Ico = 'pdf1';  break;
		case 'jpg':  Ico = 'jpg1';  break;
		case 'gif':  Ico = 'gif1';  break;
		default:  Ico = 'Generic';  Dir = 'tree/'
	}
	H = "<IMG src='/biblio/img/"+Dir+Ico+".gif'>";
	//if (Adr)  H = "<a href='"+AddStr(RootSite,Adr,'/')+"' target=_blank>" + H + "</a>";
	if (Adr)  H = "<a href='"+Adr+"' target=_blank>" + H + "</a>";
	return H
}

function FicPartie (Chemin, Partie, Separ, noCasse) {
	var S, p, r = Chemin, Ch, Nom, Ext
	if (!Chemin)  return r
	if (!Separ)  Separ="/"
  if ((p=Chemin.indexOf("?"))<0)  Ch = Chemin;  else  Ch = Chemin.substr(0,p)
	if (Partie!='Ext')  Ext = FicPartie(Ch, "Ext", Separ)
	switch(Partie) {
		case "Ext":
		  if ((p=Ch.lastIndexOf("."))<0)  r = "";  else  r = Ch.substr(p+1);
		  if (r.length>9)  r=""
		  break
		case "NomFic":
			if ((p=Ch.lastIndexOf(Separ))<0)  r = Ch;
			else{
				r = Ch.substr(p+1);  if (r.indexOf('.')<0)  r=''
			}
			break
		case "Nom":  //sans ext
			r = FicPartie (Ch, "NomFic", Separ)
		  if (Ext)  r = r.substr(0,r.length - Ext.length - 1)
		  break
		case "FicLie":
			if (Ext.toLowerCase().substr(0,3)=="htm")  r = FicPartie (Ch, "Nom", Separ) + "_fichiers";
		  break
		case "RepLie":
			if (Ext.toLowerCase().substr(0,3)=="htm")  r = Ch.substr(0,Ch.length-4) + "_fichiers";  else  r = FicPartie (Ch, "Path", Separ)
		  break
		case "Path":
			S = FicPartie (Ch, "NomFic", Separ);  if (S)  r = Ch.substr(0,Ch.length - S.length - 1)
		  break
	}
	if (noCasse) r = r.toLowerCase()
	return r
}

// -------------  _COOKIES_  ----------  http://www.actulab.com/les-cookies-en-javascript.php
function GetCookie(nom) {
	var arg  = nom+"=";
	var alen = arg.length;
	var clen = document.cookie.length;  //alert(document.cookie)
	var i=0
	while (i<clen) {
		var j=i+alen;
		if (document.cookie.substring(i,j)==arg) return getCookieVal(j);
		i=document.cookie.indexOf(" ",i)+1;
		if (i==0) break
	}
	return null
}

	function getCookieVal(offset) {
		var endstr = document.cookie.indexOf (";", offset);
		if (endstr==-1) endstr=document.cookie.length;
		return unescape(document.cookie.substring(offset, endstr))
	}

function SetCookie(nom, V) {		// SetCookie("nombredevisites", 1, 1, "/")
	var S
	if (!V)  V='';  else if (isObj(V))  V = JSONS(V)
	var argv=SetCookie.arguments;
	var argc=SetCookie.arguments.length;
	var fin=(argc > 2) ? argv[2] : null;  if (fin==0)  fin=null;  if (fin && !isNaN(fin)) { S=fin;  fin = new Date;  fin.setMonth(fin.getMonth()+S); }
	var path=(argc > 3) ? argv[3] : null;
	var domain=(argc > 4) ? argv[4] : null;
	var secure=(argc > 5) ? argv[5] : false;
	var S = nom + "=" + escape(V) + ((fin==null) ? "" : ("; expires="+fin.toGMTString())) + ((path==null) ? "" : ("; path="+path)) + ((domain==null) ? "" : ("; domain="+domain)) + ((secure==true) ? "; secure" : "");   //alert(S)
	document.cookie = S
}

function DelCookie(nom, path) {
	date = new Date
	date.setFullYear(date.getFullYear()-1)
	SetCookie(nom, null, date, path)
}


// ====================================      _SYSTEM_     ===============================
function Eval(Chaine, SiMsg) {
	try {
		return eval(Chaine)
  }catch(e){
  	if (SiMsg)  alert(e.description)
  	return null
	}
}

function LoadHtm(List, CallB) {
	var T, k=0, L = List.length
	LoadHtmExec()
	
	function LoadHtmExec() {
		var T, D, Ad
		T = List[k].split('|');  Ad = T[0]
		if (T.length>1)  D = $E(T[1]);  else  { D = MakeDom('DIV', document.body) }
		$(D).load(Ad, {NomApp:App.Nom, Proj:Proj, Bug:Bug}, function(re, e, xhr) {
			if (e=='error') { alert("Echec chargement");  return }		//if (J.js) { $.getScript(J.js, function(data,e) { if (e!='success') { alert("Echec chargement module");  return } VueMake('#'+Nom, pm); if (Call)  Call() }); }
			if (++k<L) {
				LoadHtmExec()
			}else if (CallB) {
				CallB()
			}
		})
	}
}

function LoadJS(Ad, JS) {
	if (JS)  App['Pgm_'+Right(Ad,1,'/')] = JS
	try {
		with (document.getElementsByTagName('head')[0].appendChild(document.createElement('script'))) {
			setAttribute('id', 'newscript', 0);setAttribute('type', 'text/javascript', 0);setAttribute('src', Ad + ".js", 0);setAttribute('charset', 'utf-8');
		}
	}catch(e){}
}

function LoadCSS(Ad) {
	var O = document.createElement('link');
	O.setAttribute("href",Ad);  O.setAttribute("rel","stylesheet");  O.setAttribute("type","text/css");
	try {
		document.getElementsByTagName("head").item(0).appendChild(O);
	}catch(e){}
}

function FileSystem(Opt) {
	var fso
	try {
  	fso = new ActiveXObject("Scripting.FileSystemObject")
  }catch(e){
		fso = null
		switch (Opt) {
			case 0:  alert("Le navigateur n'est pas configuré pour ce type d'opération\n\n" + e.description);  break
			case 1:  window.open("/sites/i2g/synchro/install sécurité.asp", "InstallSecur", "width=450,height=500,resizable=yes");	break;
		}
  }
  return fso
}

// ====================================      _AJAX_     ===============================
function XmlPost(LigParam, Ad, fct, Param) {
	var Mess, Post = null, S
	if (!Ad)  Ad = AddStr(RootServ,'kiwi/php/bdbox.php','/')
	if ((S=window['RootServ']))  Ad = AddStr(S,Ad,'/');			//alert(Ad + crr + LigParam);  //return
	if (!LigParam)  LigParam=''
	Param = Param || {}

	if (window.XMLHttpRequest)
		Post = new XMLHttpRequest();
	else if (window.ActiveXObject)
		Post = new ActiveXObject("Microsoft.XMLHTTP");
	else {
		alert("Votre navigateur ne supporte pas les objets XMLHTTPRequest...");  return
	}
		//alert(LigParam.length+crr+Ad.length+crr+LigParam+crr+Ad)
	Post.open("POST", Ad, true)
	Post.onreadystatechange = function() {
		if (Post.readyState==4) {
			var reJ, S, M
			if(Post.status==200) {
				S = Post.responseText;    //alert(S)
				if (S.indexOf("Fatal error")>=0)  alert(S)
				PHB(S, Param.NomAction)
				if (window.DecoupeJS) { reJ = DecoupeJS(S);  if (reJ)  reJ = reJ.backVal || reJ.re || reJ }		//alert(JSW(reJ))
				if (Ad.indexOf('bdbox')>=0) { PHB(S,'XmlPost '+Param,'Contenu');  PHB(reJ,'XmlPost.reJ','Act') }
				if (fct)  fct(S, Param, reJ)
				//if (fct)  if (Param.This)  Param.This.fct(S, Param, reJ);  else  fct(S, Param, reJ)
			}else{
				alert("Anomalie de transaction : "+Post.status+crr+Ad+crr+LigParam)
			}
		}
	}
	//Post.setRequestHeader("content-type", "content='text/plain; charset=UTF-8'")  //UTF-8  windows-1252  iso-8859-1
	Post.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
	Post.send(LigParam);
}

//====================================      _DIVERS_      ===========================
function CalcAd(Ad) { if (Ad.substr(0,1)!='/')  Ad = AddStr(RootSite,Ad,'/');  return Ad }

function LitXMP(Div,Cod) {  // ex : LitXMP.call(this,D,'infoVue')
	var Me = this
	$('xmp.'+Cod,Div).each(function() {
		var S, JS;  if (this.parentNode!=Div)  return
		JS = JSOND(LText(this))
//alert(LText(this)+crr+JSW(JS))
		if ((S=LX(this,'Typ'))) { // ex Typ : BD.Header : créer Header dans BD,
			var A, O, i, V, T = S.split('.');  O = Me
			for (i in T) {
				V = T[i];  A = O
				if (O[V]==undefined) O[V] = {};
				O = O[V]
			}
			A[V] = JS
		}else{
			if (!isStr(JS))  for (S in JS)  Me[S] = JS[S]
		}
	})
}

//====================================      _DEBUG_      ===========================
function PHB(V, Titre, D, aj) { if (Bug)  PH(V, Titre, D, aj) }

function PH(V, Titre, D) {
	var c, NomD, S, L=0
	V = JST(V)
	if (isObj(V)) {
		D = D || 'JS'
		S = JSW(V);  if (S && (L=S.length)<5000)  V = JSW(V,1);  else  V = S   // sinon c'est très lent
		V = wDiv(Titre+','+L,V);
	}else{
		D = D || 'Post'
		V = '<h1>'+Titre+'</h1>'+V+'<hr>'
	}
	NomD = D+'Bug';  c = noBug(D);
	if (!(D=LID(NomD)))  return
	if (c=='-')  D.innerHTML = ''
	if (D.insertAdjacentHTML)  D.insertAdjacentHTML("BeforeEnd", V);  else  D.innerHTML+=V
}

function wl(D, n) {
	D = LID(D);  if (!n)  n=100;  var S = LText(D);  if (S)  S = ", <b>"+S.substr(0,30)+"</b>"
	return "<xmp style='display:inline'>"+LX(D,'id')+', '+Lout(D,n)+"</xmp>"+S
}

function wh(Msg, NomDiv) {
	if (!Bug)  return
	var X, D = LID(NomDiv) || LID('whBug');  if (!D) { console.log(Msg);  return }
	if (isStr(Msg)) {
		if (Msg.substr(0,1)=='!') { Msg = Msg.substr(1);  D.innerHTML='' }
	}else if (Msg.tagName) {
		Msg = "<xmp style='display:block'>"+Lout(Msg).substr(0,300)+'</xmp><br>'
	}else{
		if (!LID(NomDiv)) D = LID('JSBug');
		Msg = "<h2>"+NomDiv+"</h2><xmp style='display:block'>"+JSW(Msg)+'</xmp><br>'
	}
	if (D.insertAdjacentHTML)  D.insertAdjacentHTML("BeforeEnd", Msg + "<br>");  else  D.innerHTML+=Msg
}

function wobj(O, max) {
	if (!O)  return 'neant';  var S = '['+O.id+','+O.tagName+','+O.className+']-'+LX(O,'cl1')+'-'
	if (max)  S+= Lout(O,Max);
	return S
}

function CodeHtml(S) { S = S.replace(/</g,"&lt;");  S = S.replace(/>/g,"&gt;");  S = S.replace(/\[/g,"<");  S = S.replace(/\]/g,">");  S = Replace(S,"\n","<br>");  return S }

function wb(Msg) {
  var D, S = Msg;  if (!S) return
  if (!(D=LID('whBug')))  return;  if (!SiAff(D))  return
  if (S.substr(0,1)=='!')  D.innerHTML=''
  if (typeof(S)=="string") {
    S = CodeHtml(S)
	}else
	  S = StructObj(S, 2)
	  //S = S.Nom
	//S+="<br>"
  if (ie)  D.insertAdjacentHTML("BeforeEnd", S);  else  D.innerHTML+=S
}

function wDiv(Titre, H, opt) {
	if (opt) {
		bal = 'pre';  H = Replace(H,'<','&lt;');  H = Replace(H,'\n\n','<br>');  H = Replace(H,'\n','<br>');
	}else
		bal = 'div'
	return "<fieldset xclass=hide><legend onclick='InverseDisplay(ElemNext(this))' style='cursor:pointer'>" + Titre + "</legend><" + bal + " style='display:none'>" + H + "</" + bal + "></fieldset>"
}


