<!--// 2009 Intelygenz  - www.intelygenz.com <%//-->

i_exml_nVersion=1.234;
/*
	[VER] 	 P:\IG_IntelyGenZ\IG11_Desarrollo_Librerias\IG11_01_Js\docs\i_exml.txt
	[DOC]	 http://intranet-asp.intelygenz.com/ig05_intranet/desarrollo/areas/dev/docs/i_exml.html
	[UPDATE] P:\IG_IntelyGenZ\IG11_Desarrollo_Librerias\IG11_01_Js\src\i_exml.js
*/

function IEXML(sObj){
	this.m_sObj=sObj;
	this.m_nVersion=i_exml_nVersion;
	this.m_sKeyName = "[i_exml v"+this.m_nVersion+"]";	// ("+sObj+")";
	this.m_sMArrayBase = "";
	this.m_vTagsSet = 0;
	this.m_sEXMLReturn = null;

	this.f_optionSelected = function (sValor,vValorSelected){
		var bSelected=false;
		if ( IsArray(vValorSelected) ){
			if (vValorSelected.f_indexOf( sValor ) != -1) bSelected=true;
		}
		else if (sValor == vValorSelected) {
			bSelected=true;
		}
		return (bSelected)
	}

	this.f_addColEXML = function (maDatos,sCampo,sEXML){
		var	f,nRegs,vValor
		if (maDatos.f_maGetColPos (sCampo)!=-1) {
			ErrorJS ("[i_exml.f_addColEXML] ya existe el campo '"+sCampo+"', asi que lo modificamos",maDatos,2)
			maDatos.f_modColEXML (sCampo,sEXML)	//Lo modificamos
		}
		else {
			nRegs = maDatos.f_maGetRegs ()
			maDatos.f_maAddCol (sCampo, "")
			for (f=0;f<nRegs;f++){
				vValor = ParseEXMLs(sEXML,"",maDatos,f)
				maDatos.f_maSetVal (sCampo, vValor, f)
			}
		}
	}
	
	this.f_eval = function (sFun,sTag,nRegistro){		//nRegistro porque algunos eval de DATO la usan
		var sError = oIEXML.m_sKeyName+" ParseEXML: el eval del registro "+nRegistro+" de "+sTag+" no existe, no es global o da error."+"\n"+sTag+": <B>"+sFun+"</B>"
		var sDato = "<DIV style='background-color:#A00;color:#fff;'>"+sError+"</DIV>"
		try {
			var nRegistros = oIEXML.m_sMArrayBase.f_maGetRegs ()	//nRegistros porque algunos eval de DATO la usan
			sDato = eval (sFun)
		}
		catch (ex){
			ErrorJS (sError,"")     							
		}	
		return sDato;
	}

	this.f_modColEXML = function (maDatos,sCampo,sEXML){
		var	nCol,nRegs,vValor,f
		nRegs = maDatos.f_maGetRegs ()
		if (nRegs) {
			nCol = maDatos.f_maGetColPos (sCampo)
			if (nCol==-1) {
				ErrorJS ("[i_exml.f_modColEXML] no existe el campo '"+sCampo+"', asi que lo creamos",maDatos,2)
				maDatos.f_addColEXML (sCampo,sEXML)	//Lo añadimos
			}
			else {
				for (f=0;f<nRegs;f++){
					vValor = ParseEXMLs(sEXML,"",maDatos,f)
					maDatos.f_maSetVal (sCampo, vValor, f)
				}
			}
		}
	}

	this.m_maOwnTAGsEXML = [["sTAGName", "sVal"], []];
	this.f_addOwnTAG = function (sTAGName, sVal) {
		this.m_maOwnTAGsEXML.f_maNewRow( [sTAGName, sVal] );
	}
	this.f_setOwnTAG = function (sTAGName, sVal) {
		this.m_maOwnTAGsEXML.f_maSetValIf("sTAGName", sTAGName, "sVal", sVal);
	}

	this.f_parseOwnTag = function (sEXML, sTAGName, sVal) {
		if ( IsNull(sVal) ) sVal = this.m_maOwnTAGsEXML.f_maGetValIf("sTAGName", sTAGName, "sVal");
		if ( IsNull(sVal) ) ErrorJS(this.m_sKeyName+" - No hay ningún tag '"+sTAGName+"' en el Array de OwnTags de este objeto EXML o no se pasó ningún valor "+sVal+"\n"+this.m_maOwnTAGsEXML.f_maDebug());
		return sEXML.f_replace( sTAGName, sVal );
	}

	this.f_parseOwnTags = function (sEXML) {
		for ( var f=0, F=this.m_maOwnTAGsEXML.f_maGetRegs(); f<F; f++ ) {
			sEXML = sEXML.f_replace( this.m_maOwnTAGsEXML.f_maGetVal("sTAGName", f), this.m_maOwnTAGsEXML.f_maGetVal("sVal", f) );
		}
		return sEXML;
	}

	this.m_maBlock  = [["sBlockName", "sEXML"], []];
	this.f_addBlock = function (sBlockName, sEXML) {
		var nReg = this.m_maBlock.f_maGetReg("sBlockName", sBlockName);
		if ( nReg==-1 ) {
			this.m_maBlock.f_maNewRow( [sBlockName, sEXML] );
		}
		else {

			this.m_maBlock.f_maSetVal("sEXML", sEXML, nReg );
		}
	}
	this.f_parseBlock = function (sEXML) {
		for ( var f=0, F=this.m_maBlock.f_maGetRegs(); f<F; f++ ) {
			sEXML = sEXML.f_replace( this.m_maBlock.f_maGetVal("sBlockName", f), this.m_maBlock.f_maGetVal("sEXML", f) );
		}
		return sEXML;
	}



	/** BETA NO USAR [ **/
	this.m_maPattern  = [["sBlockName", "sEXML_Pre", "sEXML_Pattern", "sEXML_Post", "maData"], []];
	this.f_addPattern = function (sBlockName, sEXML_Pre, sEXML_Pattern, sEXML_Post, maData) {
		this.m_maPattern.f_maNewRow( [sBlockName, sEXML_Pre, sEXML_Pattern, sEXML_Post, maData] );
	}
	this.f_parsePattern = function (sEXML) {
		var sBlockName, sEXML_Pre, sEXML_Pattern, sEXML_Post, maData;
		for ( var f=0, F=this.m_maPattern.f_maGetRegs(); f<F; f++ ) {
			a_sEXML		  = [];
			sBlockName 	  = this.m_maPattern.f_maGetVal("sBlockName" ,f );
			if ( sEXML.indexOf(sBlockName)!=-1 ) {
				sEXML_Pre	  = this.m_maPattern.f_maGetVal("sEXML_Pre" ,f );
				sEXML_Pattern = this.m_maPattern.f_maGetVal("sEXML_Pattern" ,f );
				sEXML_Post    = this.m_maPattern.f_maGetVal("sEXML_Post" ,f );
				maData        = this.m_maPattern.f_maGetVal("maData" ,f );

				a_sEXML.push(sEXML_Pre);
				for ( var g=0, G=maData.f_maGetRegs(); g<G; g++ ) {
					a_sEXML.push( this.f_parseEXMLs(sEXML_Pattern, maData, g) );
				}
				a_sEXML.push(sEXML_Post);

				sEXML = sEXML.f_replace(sBlockName, a_sEXML.join("") );
			}
		}
		return sEXML;
	}
	/** BETA NO USAR  ] **/

	this.f_buildBlocks =  function (sEXML) {
		sEXML = this.f_parseBlock( sEXML );
		sEXML = this.f_parseOwnTags( sEXML );
		return sEXML;
	}


	/** BETA NO USAR [ **/
	this.f_drawCombo = function (sName, sTitulo, sXtraSelect, maData, sXtraOptionEXML, sTextEXML, sValueEXML, sTextOrValueSelected, sOrderColName, sDistinctColName) {
		var sSelected = "";
		var a_sHTML   = [];
		var a_nRegs   = [];
		var nReg;
		if ( IsMArrayOld( maData ) ) ErrorJS("oIEXML.f_drawCombo() No funciona con MArray antiguo. Usar DrawComboEXML()");
		else {
			if ( IsNull(sXtraSelect) ) sXtraSelect = "";
			a_sHTML.push("<SELECT name='"+sName+"' "+sXtraSelect+">");

			if ( IsNull(sTitulo) ) {
				if ( !IsArray(a_sTitulo) ) a_sTitulo = [a_sTitulo, a_sTitulo];
				if ( this.f_optionSelected(sValor, vTextOrValueSelected) ) sSelected =" selected ";

				a_sHTML.push("<OPTION value='"+a_sTitulo[0]+"' "+sSelected+">"+a_sTitulo[1]+"</OPTION>");
			}

			if ( IsNull(sDistinctColName) && IsNull(sOrderColName) ){
				for ( var f=0, F=a_nRegs.length; f<F; f++ ) {
					nReg = f;
					if (sDistinctColName) nOption = a_nPos[i];
					sValue = this.f_parseEXMLs(sValueEXML, maData, nReg);
					// sText;
					if (sTextEXML==sValueEXML) sText = sValue;
					else sText = this.f_parseEXMLs(sTextEXML, maData, nReg);
					a_sHTML.push( "<OPTION value='"+sValue+"'>"+sValue+"</OPTION>" );
				}
			}
			else {
				if ( !IsNull(sDistinctColName) ) {
					a_nRegs = maData.f_subDistinct (sDistinctColName, 1);
				}
				if ( !IsNull(sOrderColName) ) {
					var maDataTmp = maData;
					if ( !IsNull(sDistinctColName) ) maDataTmp = maDataTmp.f_subRows(a_nRegs, 1);
					a_nRegs = maDataTmp.f_sort(sOrderColName, 1);
				}

				var sText, sValue;
				for ( var f=0, F=a_nRegs.length; f<F; f++ ) {
					nReg = a_nRegs[f];
					if (sDistinctColName) nOption = a_nPos[i];
					sValue = this.f_parseEXMLs(sValueEXML, maData, nReg);
					// sText;
					if (sTextEXML==sValueEXML) sText = sValue;
					else sText = this.f_parseEXMLs(sTextEXML, maData, nReg);
					a_sHTML.push( "<OPTION value='"+sValue+"'>"+sValue+"</OPTION>" );
				}
			}
		}
	}

	this.f_parseEXMLs = function (sEXML,sJSarrayBase,nRegistro,vTags,oObj) {		//5.3
		var a_sTags,sError,f,s
	// Es muy importante el orden !!
	// 	["ifBD","SUMAEXML","SUMA","INPUT","SELECT","CHECKBOX","RADIO","RADIOS","BD","OBJ","FUN","ifFUN"]
		if (!vTags){
		 	if (oObj && String(oObj.m_vTagsEXML)!="undefined") vTags = oObj.m_vTagsEXML
			else vTags = oIEXML.m_vTagsSet
		}
		if (IsArray(vTags)) {
			a_sTags = vTags
		}
		else {
			switch (vTags){
			case 1:
				a_sTags = ["SUMAEXML","IF","SUMA","BD","DATO","OBJ","FUN"]
				break
			default:
				a_sTags = ["DATO","ifBD","SUMAEXML","SUMA","CAMPO","BD","OBJ","FUN","ifFUN","IF"]
			}
		}
	// Deprecar ifBD / ifFUN / SUMAEXML (parte de MATH)
	//			Crear campo MATH que sirva para todo tipo de operaciones ¿MATHEXML?
	//			¿CAMPO? / ¿Fusionar DATO y OBJ? (son casi un FUN)

		if (typeof(sEXML)=="undefined") {
			var nAlertMode = 1
			if (oObj) {
				sError = "ParseEXMLs() Le faltan datos al "+oObj.m_sObj+".f_createStyle"
			}
			else {
				sError = "ParseEXMLs() No hay sEXML"
				nAlertMode = 3
			}
			ErrorJS (oIEXML.m_sKeyName +sError,oObj,nAlertMode)
			return ("")
		}
		if (!sJSarrayBase) {
			if (oObj) sJSarrayBase=eval (oObj.m_sObj+".m_sJSarrayBase")
			else if (!g_sJSarrayBase) ErrorJS (oIEXML.m_sKeyName +" ParseEXMLs() No hay ningun MArray definido en sJSarrayBase",oObj,1)
			else sJSarrayBase = g_sJSarrayBase
		}
		g_sJSarrayBase = sJSarrayBase;

		for (f=0;f<a_sTags.length;f++){
			if (sEXML.indexOf(a_sTags[f])!=-1){
				if(this.m_sObj) sEXML = this.f_parseEXML(a_sTags[f],sEXML,sJSarrayBase,nRegistro,oObj);
				else sEXML = ParseEXML(a_sTags[f],sEXML,oObj,sJSarrayBase,nRegistro);
			}
		}

		return sEXML;
	}
	this.f_parseEXML  = function ( sTag,sEXML,sJSarrayBase,nRegistro,oObj ){
		var nRegistros,nPos1,nPos1Fin,nPos2,nPos1T,sEXMLanidado,sDato
		var sTagInit = "<"+sTag+">", sTagFin = "</"+sTag+">";
		var sTagIni = sTagInit;
		var sFinal=""
		var nTag1=sTagInit.length, nTag2=sTagFin.length

		if (!sJSarrayBase && oObj) sJSarrayBase=eval (oObj.m_sObj+".m_sJSarrayBase")
		if (sJSarrayBase){
			oIEXML.m_sMArrayBase = sJSarrayBase
			nRegistros = sJSarrayBase.f_maGetRegs ()
			if (nRegistros<=nRegistro) {
				if (sEXML.indexOf("BD>")!=-1 && sEXML.indexOf("</SUMA")==-1){
					sError = "ParseEXML() no existe el registro "+ nRegistro + " en 'a_v"+sJSarrayBase+"' "
					if (nRegistros) sError += "[0-"+(nRegistros-1)+"]"
					else sError += "(no hay ningun dato)"
					sError = this.f_error (sError)
//alert (sError,oObj,0)
					return (sError)		//sEXML
				}
			}
		}

		var sEXMLReturn = oIEXML.m_sEXMLReturn
		if (oObj && oObj.m_bEXMLReturn) sEXMLReturn = oObj.m_sEXMLReturn

		nPos1	= sEXML.indexOf(sTagInit)
		if (nPos1==-1){
			sTagInit = "<"+sTag
			nPos1	= sEXML.indexOf(sTagInit)
		}

	/*
	var oT1 = new Date()
	var nC = 0
	*/
		while (nPos1!=-1 && nPos2!=-1){
	//nC++
			nPos1	= sEXML.indexOf(sTagInit)
			nPos2 = -1

			if (nPos1!=-1 ) {
				sEXMLanidado = ""
				nPos1T = nPos1
	//if (sTag=="IF") alert ("GET:"+ sEXML.substring(nPos1) + "\n" +GetInitTag (sTag,sEXML.substring(nPos1)))
				nPos1Fin = nPos1 + GetInitTag (sTag,sEXML.substring(nPos1))
				sTagIni = sEXML.substring(nPos1,nPos1Fin)
				nTag1 = sTagIni.length
				nPos2 = sEXML.indexOf(sTagFin,nPos1+nTag1)
				if (nPos2!=-1 && sTag=="IF"){	// IF anidados / && sTag=="IF"
					nPos1T = sEXML.lastIndexOf(sTagInit,nPos2)
	//alert(nPos1 + "_" + nPos1T + "_" + sDato)
					if (nPos1T!=nPos1) {
						sEXMLanidado = sEXML.substring(nPos1,nPos1T)

						nPos1Fin = nPos1T + GetInitTag (sTag,sEXML.substring(nPos1T))
						sTagIni = sEXML.substring(nPos1T,nPos1Fin)
						nTag1 = sTagIni.length

	//					nPos1 += nPos1T + nTag1
	//					nPos1	= sEXML.indexOf(sTagInit,nPos1)
	//sOld = sEXML.substring(nPos1,nPos2+nTag2)
	//alert ("DUPE: "+nPos1+"_"+sTagInit+"\nInutil: "+sEXML.substr(0,nPos1)+"\nPre: "+sEXMLanidado+"\nDato: "+sEXML.substring(nPos1T,nPos2+nTag2))
					}
				}
			}
	//if (sTag=="BD") alert (sTag +"....."+ sDato + "\n" +nPos1+ "\n" +nPos2+ "\n" +nPos1Fin+ "\n")

			if (nPos1!=-1 && nPos2!=-1){
				sFinal	+= sEXML.substr(0,nPos1)
				sDato	= sEXML.substring(nPos1T+nTag1,nPos2)
	//if (sTag=="BD") alert (sTag+": "+nPos1+"_"+nPos1T+"_"+sTagInit+"\nsDato: "+sDato+"\nsFinal: "+sFinal)
	//alert(sFinal+"\n"+sDato)
				switch (sTag){
				case "BD":
	//				sDato = BuscaMultiarrayBlock (sDato,sJSarrayBase,nRegistro)
					sDato = sJSarrayBase.f_maGetVal (sDato,nRegistro,sEXMLReturn)	//1.233
					break
				case "FUN":
//					window.onerror = function ErrorTrapJS(sError,sURL,nLinea) { sError="\n\n"+sURL+"\nLinea "+nLinea + " : " + sError;ErrorJS (oIEXML.m_sKeyName +"ParseEXML: <FUN> no existe, no es global o da error la funcion JS:\n\t"+sDato+sError,oObj,1); return (true);}
		//			sDato = sDato.replace (/[\"]/gi, "\\\"");
		//			sDato = sDato.replace (/[\']/gi, "\\\'");
					if (sDato) {
						sDato = this.f_eval (sDato,sTag,nRegistro)	//1.233
					}
					break
				case "OBJ":
					if (sDato.indexOf("_")!=1) {
						sDato = "m_" + sDato
					}
					sDato = this.f_eval (oObj.m_sObj+"."+sDato,sTag,nRegistro)	//1.233
					break
				case "DATO":		// nRegistro, nRegistros
//					sDato = eval (sDato)
					sDato = this.f_eval (sDato,sTag,nRegistro)	//1.233
					break
				case "SUMA":
					if (oObj && oObj.m_bCacheTagSUMA==1){
						var sDatoClean = sDato.replace(/[^a-z,0-9]/gi,"")
						sDatoClean = oObj.m_sObj+".m_n"+sTag+sDatoClean
						vDato = this.f_eval (sDatoClean,sTag,nRegistro)	//1.233	
						if (typeof(vDato)=="undefined" ) {
	//						vDato = OperarMultiEXML(sJSarrayBase,"<BD>"+sDato+"</BD>")	//Sustituir por f_maSumaColIf !!!
							vDato = sJSarrayBase.f_maSumaColIf (sDato)
//							eval (oObj.m_sObj+".m_n"+sTag+sDatoClean+"=vDato")
							this.f_eval (sDatoClean+"=vDato",sTag,nRegistro)	//1.233	
						}
					}
					else{
	//					vDato = OperarMultiEXML(sJSarrayBase,"<BD>"+sDato+"</BD>",oObj)	//Sustituir por f_maSumaColIf !!!
						vDato = sJSarrayBase.f_maSumaColIf (sDato)
					}
					sDato = vDato
					break
				case "SUMAEXML":
					sDato = OperarMultiEXML(sJSarrayBase,sDato,oObj)
					break
				case "IF":
	//alert(sTag +" IF: "+sDato)
					window.onerror = function ErrorTrapJS(sError,sURL,nLinea) { sError="\n\n"+sURL+"\nLinea "+nLinea + " : " + sError;ErrorJS (oIEXML.m_sKeyName +"ParseEXML: <IF> no existe o da error:\n\t"+sDato+sError,oObj,1); return (true);}
					var a_sDatos = TagELSE(sDato)
					sDato = a_sDatos[0]
					var sBD = GetPropEXML(sTagIni,"bd",1)
					if (sBD){
	//					bValidar= BuscaMultiarrayBlock (sBD,sJSarrayBase,nRegistro)
						bValidar=sJSarrayBase.f_maGetVal (sBD,nRegistro)
						if (CheckFalse (bValidar)){
							sDato = a_sDatos[1]
						}
					}
					else {
						var sFUN = GetPropEXML(sTagIni,"fun",1)
						if (sFUN){
							window.onerror = function ErrorTrapJS(sError,sURL,nLinea) { sError="\n\n"+sURL+"\nLinea "+nLinea + " : " + sError;ErrorJS (oIEXML.m_sKeyName+" ParseEXML: <IF fun> no existe o da error la funcion JS:\n\t"+sFUN+sError,oObj,1); return (true);}
							sFUN = ParseEXMLs (sFUN,oObj,sJSarrayBase,nRegistro)
//							bValidar = eval (sFUN)
							bValidar = this.f_eval (sFUN,sTag,nRegistro)	//1.233
							if (CheckFalse (bValidar)){
								sDato = a_sDatos[1]
							}
						}
					}
	//alert ("sDato: "+sTagIni + "\n sBD:"+sBD + "\n sFUN: "+sFUN)
	//alert ("[IF] sDato: "+sDato + "\n sBD:"+sBD + "\n sFUN: "+sFUN)
					break
				case "ifFUN":
					window.onerror = function ErrorTrapJS(sError,sURL,nLinea) { sError="\n\n"+sURL+"\nLinea "+nLinea + " : " + sError;ErrorJS (oIEXML.m_sKeyName +" ParseEXML: <ifFUN> no existe o da error la funcion JS:\n\t"+sDato+sError,oObj,1); return (true);}
//					bValidar = eval (sDato)
					bValidar = this.f_eval (sDato,sTag,nRegistro)	//1.233

					if (CheckFalse (bValidar)){
		//				sEXML=""
						sDato = GetPropEXML(sTagIni,"false")
						if (sDato) sFinal +=sDato
						else if (!GetPropEXML(sTagIni,"true")) sEXML=""
					}
					else{ 				//Verdadero
		//				sFinal=""
						sDato = GetPropEXML(sTagIni,"true")
						if (sDato) sFinal +=sDato
						else if (!GetPropEXML(sTagIni,"false")) sFinal=""
					}
					sDato=""

					break
				case "ifBD":
	//				bValidar= BuscaMultiarrayBlock (sDato,sJSarrayBase,nRegistro)
					bValidar = sJSarrayBase.f_maGetVal (sDato,nRegistro)
					if (CheckFalse (bValidar)){
						sDato = GetPropEXML(sTagIni,"false")
						if (sDato) sFinal +=sDato
						else if (!GetPropEXML(sTagIni,"true")) sEXML=""
					}
					else{ 				//Verdadero
						sDato = GetPropEXML(sTagIni,"true")
						if (sDato) sFinal +=sDato
						else if (!GetPropEXML(sTagIni,"false")) sFinal=""
					}
					sDato=""
					break
				case "CAMPO":
					var sProp = GetPropEXML(sTagIni,"tipo")
					var sExtras = GetPropEXML(sTagIni,"extras")

					switch (sProp){
					case "INPUT":
						var sCampo = sDato.substr(2)
	//					var sValue = BuscaMultiarrayBlock (sCampo,sJSarrayBase,nRegistro)
						var sValue= sJSarrayBase.f_maGetVal (sCampo,nRegistro)
						var nSize = sValue.length
						sDato = '<INPUT name="'+ sDato +'" type="text" value="'+ sValue + '" ' + sExtras +'/>'
						break
					case "SELECT":
						var sTitulo = ""
						var sCampo = sDato.substr(2)
		//eval (oObj.m_sObj+".m_nSUMA"+sCampo+"='12'")
						var sTexto = "<BD>"+sCampo+"</BD>"
	//					var sValue = BuscaMultiarrayBlock (sCampo,sJSarrayBase,nRegistro)
						var sValue= sJSarrayBase.f_maGetVal (sCampo,nRegistro)
						if (!sValue) sTitulo = " - Elige -"
						sDato = DrawComboEXML(sDato,sExtras,"",sJSarrayBase,sTexto,sTexto,sValue,sCampo,sCampo)
						break
					case "CHECKBOX":
						var sChecked = " "
						var sCampo = sDato.substr(2)
	//					var sValue = BuscaMultiarrayBlock (sCampo,sJSarrayBase,nRegistro)
						var sValue= sJSarrayBase.f_maGetVal (sCampo,nRegistro)
						if (sValue && sValue!="0" && sValue!="False" && sValue!="Falso") {
							sChecked = " checked "
							sValue = ' value="'+ sValue + '"'
						}
						else {
							sValue =""
						}
						sDato = '<INPUT type="checkbox" name="'+ sDato +'"' + sValue + sChecked + ' ' + sExtras +'/>'
						break
					case "RADIO":
						var sChecked = " "
						var sCampo = sDato.substr(2)
	//					var sValue = BuscaMultiarrayBlock (sCampo,sJSarrayBase,nRegistro)
						var sValue= sJSarrayBase.f_maGetVal (sCampo,nRegistro)
						if (sValue && sValue!="0" && sValue!="False" && sValue!="Falso") {
							sChecked = " checked "
							sValue = ' value="'+ sValue + '"'
						}
						else {
							sValue =""
						}
						sDato = '<INPUT type="radio" name="'+ sDato +'"' + sValue + sChecked + ' ' + sExtras +'/>'
						break
					case "RADIOS":
						var sChecked = " "
						var	sChecked2 = " checked "
						var sName = sDato
						var sCampo = sDato.substr(2)
	//					var sValue = BuscaMultiarrayBlock (sCampo,sJSarrayBase,nRegistro)
						var sValue= sJSarrayBase.f_maGetVal (sCampo,nRegistro)
						if (sValue && sValue!="0" && sValue!="False" && sValue!="Falso") {
							sChecked = " checked "
							sChecked2 = " "
		//					sValue = ' value="'+ sValue + '"'
						}
						else {
							sValue ="1"
						}
						sDato = 'Si<INPUT type="radio" name="'+ sName +'" value="' + sValue + '"' + sChecked + ' ' + sExtras +'/>'
						sDato += '&nbsp;No<INPUT type="radio" name="'+ sName +'" value="0"' + sChecked2 + ' ' + sExtras +'/>'
						break
					case "HIDDEN":
						var sCampo = sDato.substr(2)
	//					var sValue = BuscaMultiarrayBlock (sCampo,sJSarrayBase,nRegistro)
						var sValue= sJSarrayBase.f_maGetVal (sCampo,nRegistro)
						var nSize = sValue.length
						sDato = '<INPUT name="'+ sDato +'" type="hidden" value="'+ sValue + '" ' + sExtras +'/>'
						break
					default:
						ErrorJS (oIEXML.m_sKeyName +" ParseEXML: Tag <CAMPO> de tipo invalido: "+sTagIni,oObj,1)
					}
					break
				}
				if (!oCore.m_bIsServer) window.onerror = g_oOnErrorEvent

		//		if (IsDate(vDato)) then vDato=FechaFormatoBD (vDato, "ES")	'Fechas BD
		//		if (IsNumeric(vDatoBD)) then vDato=Round(vDato,2)
	//			sFinal	= sFinal + sDato
				if (sEXMLanidado) {
					sEXML	= sEXMLanidado + sDato + sEXML.substr(nPos2+nTag2)			//v1.12 el +1 es nuevo!!!
				}
				else {
					sFinal	+= sDato
					sEXML	= sEXML.substr(nPos2+nTag2)			//v1.12 el +1 es nuevo!!!
				}
	//if (sTag=="IF") alert (sTag +"[FINAL] "+ sDato + "\nEXML:" +sEXML+ "\nHTML:" +sFinal + "\n")
			}
	//alert("B. "+nPos1 +"("+nPos1T +")\n"+nPos2)
		}
		sFinal	+= sEXML

	/*
	if (oCore.m_sServer=="DEV"){
		var nT = (new Date()-oT1)
		if (nT>60) status += sTag + "("+nC+"): " + nT 	//+ "\n" + sFinal
	}
	//alert (sTag + "______\n" + sEXML)
	*/
		return sFinal
	}

	this.f_error  = function ( sError ){
		sError = oIEXML.m_sKeyName + "\n" + oIEXML.m_sMArrayBase.f_maDebug() + "\n" + sError
		return (sError)
	}

	this.f_subMArray = function (sJSarrayBase,a_nPos) {
		var ma;
		if (IsMArray(sJSarrayBase)) {		//1.229
			ma = sJSarrayBase.f_subRows(a_nPos, 1) 
		}
		else {
			var a_sArray1
			if(IsArray(sJSarrayBase)){
				a_sArray1 = sJSarrayBase[0];
			}
			else{
				a_sArray1 = eval ("a_s"+sJSarrayBase)
			}
			ma = [a_sArray1,[]]
			SubMArray(sJSarrayBase,ma[1],a_nPos)	
		}	
		return ma;	
	}

}
oIEXML = new IEXML("oIEXML");

if(typeof(oIGZ)!="undefined") {
	oIGZ.f_loadLib("i_exml",oIEXML.m_nVersion);
	new oIGZ.f_keyEvent (["CTRL","F12"], function (){ ErrorJS(LastMArray(),null,4,1)} )
	oIGZ.f_require ("i_core",0.552);
}
else if (!oCore.m_bIsServer) {			//no es imprescindible
//	sPage = sPage.substr (1+sPage.lastIndexOf("/"))
	window.status = location.pathname +"\n"+ oIEXML.m_sKeyName + " Falta 'i_core.js' o 'i_igz.js'"
}

g_oOnErrorEvent= "";
g_sJSarrayBase = "";

if (!oCore.m_bIsServer) g_oOnErrorEvent=window.onerror

// [vTags] nVersion = 0 (TAGS antiguas) / a_sTags (TAGS que nos interesan)
// Deprecated!!! Usar -> oIEXML.f_parseEXMLs();
function ParseEXMLs (sEXML,oObj,sJSarrayBase,nRegistro,vTags) { return oIEXML.f_parseEXMLs( sEXML,sJSarrayBase,nRegistro,vTags,oObj ); }

// Deprecated!!! Usar -> oIEXML.f_parseEXMLs();
//Bug: tags dentro de otros tags
function ParseEXML(sTag,sEXML,oObj,sJSarrayBase,nRegistro) { return oIEXML.f_parseEXML( sTag,sEXML,sJSarrayBase,nRegistro,oObj ); }


function CheckFalse (bValidar){
	var bFalse = 0
	if (bValidar) bValidar = bValidar.toString().toLowerCase()
	if (!bValidar || bValidar=="0" || bValidar=="null" || bValidar=="false" || bValidar=="falso") bFalse=1
	return (bFalse)
}

function TagELSE(sDato){
	var a_sDatos = []
	var sTagElse = "<ELSE />"
	a_sDatos[0]=sDato
	a_sDatos[1]=""
	var nPos = sDato.f_indexOf (sTagElse,0)
	if (nPos!=-1){
		a_sDatos[0] = sDato.substring(0,nPos)
		a_sDatos[1] = sDato.substring(nPos+sTagElse.length)
	}
	return (a_sDatos)
}

// vTitulo [s y a] y vArrayBase [s y ma]
function PrintComboEXML(sSelectName,sFuncion,vTitulo,vArrayBase,sEXMLtexto,sEXMLvalor,vValorSelected,sCampoOrden,sCampoDistinct) {
	document.write( DrawComboEXML(sSelectName,sFuncion,vTitulo,vArrayBase,sEXMLtexto,sEXMLvalor,vValorSelected,sCampoOrden,sCampoDistinct) );
}


/**
 * @description Esta función devuelve el HTML de un combo generado a partir de los parámetros enviados en la llamada a la función. 
 * @param {string} sSelectname Nombre del SELECT en el HTML.
 * @param {string} sFuncion Parámetros adicionales que se incluiran en el SELECT: puedes ser eventos javascript, el estilo, atributos...
 * @param {vector} vTitulo Opción inicial del combo (es opcional).
 * @param {vector} vArrayBase MultiArray(MA) que se usa para crear el combo.
 * @param {string} sEXMLtexto Texto de las opciones del combo. Es muy util usar EXML para solo generar opciones para algunos datos del MA
 * @param {string} sEXMLvalor Valor para cada opción del combo.
 * @param {vector} vValorSelected Indica la opción del combo que aparecera seleccionada inicialmente (SELECTED).
 * @param {string} sCampoOrden Ordena las opciones del combo por este campo del MA.
 * @param {string} sCampoDistinct Agrupa los resultados por el valor de este campo del MA de modo que solo muestra 1 opción .
 * @example
 * DrawComboEXML('S_idPersonaCopia',*'style="width:200px"'*,'',maPersonasCopia,'<IF bd="activa"><BD>apellido1</BD> <BD>apellido2</BD>, <BD>nombre</BD></IF>','<BD>idUser</BD>',g_nIdUser,'apellido1')
 * DrawComboEXML("s_fk_id_abogado_reparto", "onchange='CheckDistribucionCC(this)'", ["-- elige --",""], maUsuariosIntranet, "<FUN>GetNombreInversoUsuario(<BD>idUsuario</BD>)</FUN>", "<BD>idUsuario</BD>", g_a_nDistribucionCC, "", "idUsuario")
 *
 *NOTA: Si queremos que nuestro combo permita hacer selecciones múltiples, le pasamos como parámetro adicional (en sFuncion) el valor multiple y un size(tamaño) que indica el número de líneas que se muestran
 */
function DrawComboEXML(sSelectName,sFuncion,vTitulo,vArrayBase,sEXMLtexto,sEXMLvalor,vValorSelected,sCampoOrden,sCampoDistinct) {
	if (oIGZ.f_checkLib("i_form",1.335)) oISelect.m_a_sSelects.push(sSelectName);

	var nFilas,sCombo,f,i,nOption,sValor="",sOption=""
	var a_sTextos = []
	var a_sOptions = []
	var a_vOrden = []
	var a_nPos = []

	nFilas = vArrayBase.f_maGetRegs()
//	if (nFilas==0) return ("")						Mirar porque Manuel hacia esto !!!
	if (sEXMLvalor=="") sEXMLvalor=sEXMLtexto

	sCombo ='<SELECT NAME="'+sSelectName+'" id="SELECT_'+sSelectName+'" '
	if (sFuncion) sCombo+= " " +sFuncion
	sCombo+='>'

	if (vTitulo!=""){
		var sTitulo=vTitulo
		var sOptionXtra=""
		if (IsArray(vTitulo)){
			sTitulo = vTitulo[0]
			sValor = vTitulo[1]
			if (vTitulo.length>=3) sOptionXtra = vTitulo[2]
		}
		sCombo += "<OPTION value='"+sValor+"' "+sOptionXtra
//		if (sValue==vValorSelected) sCombo +=" selected"
//		if (oIEXML.f_optionSelected(sValor,vValorSelected)) sOption +=" SELECTED"		//Primera opcion no tiene sentido
		sCombo += ">" + sTitulo + "</OPTION>"
	}

	if (sCampoDistinct){
//		a_nPos = DistinctMArray(vArrayBase,sCampoDistinct,1)
		a_nPos = vArrayBase.f_maSubDistinct (sCampoDistinct,1)
		nFilas = a_nPos.length
		if (nFilas==0) return ("")
	}

	if (sCampoOrden) {		//1.225
		if (sCampoDistinct) a_nPos = vArrayBase.f_maSubSort (a_nPos,sCampoOrden,1)
		else a_nPos = vArrayBase.f_maSort (sCampoOrden,1)
	}
	for (i=0;i<nFilas;i++){
		nOption = i
		if (sCampoDistinct || sCampoOrden) nOption = a_nPos[i]
		sValor = ParseEXMLs (sEXMLvalor,"",vArrayBase,nOption)
		sOption = "<OPTION value='" + sValor + "'"
		/*** QUIQUE ***/
		//if (sValor==vValorSelected)  sOption +=" SELECTED"
		if (oIEXML.f_optionSelected(sValor,vValorSelected))  sOption +=" SELECTED"
		/*** QUIQUE ***/
		if (sEXMLvalor==sEXMLtexto) sTexto=sValor
		else sTexto = ParseEXMLs (sEXMLtexto,"",vArrayBase,nOption)
		sOption +=  ">" + sTexto + "</OPTION>"

//if (sSelectName=="s_fkIdSociedad@Solicitud") {
//	alert (i+"\n"+nOption+"\n"+sEXMLvalor+"\n"+sEXMLtexto+"\n"+sTexto)
//}

		a_sOptions[i] = sOption
		a_sTextos[i] = sTexto
/*
		if (sCampoOrden) {	//DEP: 1.222
			a_vOrden[i] = vArrayBase.f_maGetVal (sCampoOrden,nOption)
		}
*/
	}

/*
	if (sCampoOrden) {		//DEP 1.224
		if (sCampoDistinct) a_vOrden = vArrayBase.f_maSubSort (a_nPos,sCampoOrden,1)
		else a_vOrden = vArrayBase.f_maSort (sCampoOrden,1)
	}
	if (sCampoOrden) {		//DEP: 1.222
		a_vOrden = a_vOrden.f_sort (1,0)
	}
*/

	var a_sCombo = [];
	for (f=0;f<nFilas;f++){
//		nOption = f
//        if (sCampoOrden) nOption = a_vOrden[f]		//1.224
//        if (sCampoOrden && !sCampoDistinct) nOption = a_vOrden[f]		//1.224
//	    if (a_sTextos[nOption]!="") a_sCombo.push(a_sOptions[nOption]);	//1.222
	    if (a_sTextos[f]!="") a_sCombo.push(a_sOptions[f]);		//1.225
	}
	sCombo += a_sCombo.join("")
	sCombo+='</SELECT>'

//if (sSelectName=="s_fkIdSociedad@Solicitud") alert(nFilas+"_"+sCombo)

	return sCombo
}
/* Dep */
function CreaComboEXML(sSelectName,sFuncion,vTitulo,vArrayBase,sEXMLtexto,sEXMLvalor,vValorSelected,sCampoOrden,sCampoDistinct) {
	return DrawComboEXML(sSelectName,sFuncion,vTitulo,vArrayBase,sEXMLtexto,sEXMLvalor,vValorSelected,sCampoOrden,sCampoDistinct);
}




// Usar solo desde oIEXML.f_subMArray que es mucho más rápida con los arrays nuevos
function SubMArray(sJSarrayBase,a_sArrayD,a_nPos){		//3.5 Crea un subarray de otro array
	var nCampos,nPos,f,g=0,h,a_sArray1,a_sArray2
	if (IsMArray(sJSarrayBase)) {
		ErrorJS ("SubMArray deprecated: usa oIEXML.f_subMArray","",5)	//1.229
		
		sJSarrayBase = sJSarrayBase.f_toMArrayOld()
//alert(sJSarrayBase.f_maDebug())
	}
/*
	if(sJSarrayBase.m_sObj && sJSarrayBase.m_sObj.toUpperCase().indexOf("MARRAY")!=-1){
		a_sArray1 = sJSarrayBase.m_sCOLs;
		a_sArray2 = [sJSarrayBase.m_a_aROWs.join("")];
	}
*/
	if(IsArray(sJSarrayBase)){
		a_sArray1 = sJSarrayBase[0];
		a_sArray2 = sJSarrayBase[1];
	}
	else{
		a_sArray1 = eval ("a_s"+sJSarrayBase)
		a_sArray2 = eval ("a_v"+sJSarrayBase)
	}	

	nCampos = a_sArray1.length
	for (f=0; f < a_nPos.length ; f++){
		nPos = a_nPos[f]*nCampos
		for (h=0;h<nCampos;h++){			//Copia todo el registro
			a_sArrayD[g++]=a_sArray2[nPos++]
		}
	}
}


function BuscarSubMArray(sArrayBase,sCampo,sTexto,bIndices,bCaseDep,bExact,bAcentoDep){
	var bParte = 1
	if (bExact) bParte=0
	return (sArrayBase.f_maSubIndexOf(sCampo,sTexto,bIndices,bCaseDep,bParte,bAcentoDep))
}

function BuscarSubArray(a_vArray,sTexto,bIndices,bCaseDep,bExact,bAcentoDep){			//3.14 Crea un array con los datos que contienen el texto
	var bParte = 1
	if (bExact) bParte=0
	return (a_vArray.f_subIndexOf (sTexto,bIndices,bCaseDep,bParte,bAcentoDep))
}



//Permita a_vMArray de Jonas (Valgan: sMArrayBase / a_vMArray )
//Anadir param para: bCaseInd
//sLogic = AND / OR
function MAcountMatches (sMArrayBase,a_sCampos,a_vValues,sLogic){
var f,g;
var sEXML=""
var sCampoAND = ""
var vValueAND = ""
var nMatches =0;

	if (sLogic=="AND" && a_sCampos.length>1) {
		for (f=0;f<a_sCampos.length;f++){
			sEXML += "<BD>"+ a_sCampos[f] + "</BD>"
			sCampoAND += a_sCampos[f]
			vValueAND += ("" + a_vValues[f])
		}
		AddCampo2Multiarray (sMArrayBase,sCampoAND,sEXML)
		a_sCampos = [sCampoAND]
		a_vValues = [vValueAND]
	}
	nRegs = sMArrayBase.f_maGetRegs()
	for (f=0;f<nRegs;f++){
		for (g=0;g<a_sCampos.length;g++){
			if (a_vValues[g]==sMArrayBase.f_maGetVal (a_sCampos[g],f)){
				nMatches++
				break
			}
		}
	}
	return (nMatches)
}

// [bIndices] : 0=array de Datos 1=array de Pos
function DistinctMArray(sArrayBase,sCampo,bIndices){					//3.22
	return (sArrayBase.f_maSubDistinct (sCampo,bIndices))
}


// aMatriz: nombre del array con los valores a ordenar
// [bIndices]			Devuelve array con valores/indices				0/1
// [bOrdenacion]		Ordenado creciente/decreciente					0/1
// [nOrden]				""=auto 0=numerica 1=alfabetica 2=fecha
// [bCaseDep]	0=AaBb		1=AaBb
function OrdenarArray(a_vArray,bIndices,bOrdenacion,nOrden,bCaseDep){
	return (a_vArray.f_sort (bIndices,bOrdenacion,nOrden,bCaseDep) )
}

/**
 * @description Devuelve un array ordenado con los valores del campo indicado.
 * @param {marray} maArrayBase MArray para ordenar.
 * @param {string} sCampo Nombre del campo que va a ser ordenado.
 * @param {boolean} bIndices En caso de cumplirse devolverá un array con los índices en vez de los valores.
 * @param {boolean} bOrdenacion Si se cumple se ordenará ascendentemente, en otro caso descendentemente.
 * @param {integer} nOrden Indica el tipo de ordenación: ""=Auto 0=Numérica 1=Alfabética 2=Fecha
 * @param {boolean} bCaseDep Si se cumple ordenará antes las mayúsculas. (Ej.: 0=AaBb 1=ABab)
 * @example
 *
 * El siguiente código devolverá un array con los nombres de los clientes ordenados ascendentemente:
 *
 * OrdenarMultiarray(maClientes, "Nombre");
 *
 */
function OrdenarMultiarray(maArrayBase,sCampo,bIndices,bOrdenacion,nOrden,bCaseDep){
	return (maArrayBase.f_maSort (sCampo,bIndices,bOrdenacion,nOrden,bCaseDep))
}




// sEXML	<DIA/> <DIAXX/> <DIATEXTO/> <MES/> <MESXX/> <MESTEXTO/> <ANYO/> <HORAS/> <MINUTOS/> <SEGUNDOS/>
// (sEXML,[dFecha],[sSinFecha])
// [sSinFecha] (si dFecha es nula): [0/string] : devuelve la fecha de hoy(por defecto)/devuelve la cadena sSinFecha
function FechaHoraEXML(sEXML,dFecha,sSinFecha){
var a_mes=new Array (0,"Enero", "Febrero", "Marzo", "Abril", "Mayo", "Junio", "Julio","Agosto","Septiembre", "Octubre", "Noviembre", "Diciembre")
var a_dia=new Array ("Domingo","Lunes","Martes","Miércoles","Jueves","Viernes","Sábado")
var dia,diaxx,diatexto,mes,mesxx,mestexto,anyo,horas,minutos,segundos
var sTag,sTagValue

	if (dFecha) {
		if (typeof(dFecha)!="object" || dFecha.constructor!=Date){
			dFecha = CambiaFecha(dFecha)	//Paso fecha a formato USA
			dFecha = new Date(dFecha); 		//Fecha que le pasamos
		}
	}
	else {
		if (typeof(sSinFecha)!="undefined") return (sSinFecha)
		dFecha = new Date(); 			//Fecha de hoy
	}

	if (isNaN(dFecha)) return ("")		//Fecha invalida

	dia		= dFecha.getDate()
	diaxx	= dia
	if (diaxx<10) diaxx="0" + dia
	diatexto= a_dia[dFecha.getDay()]
	mes 	= dFecha.getMonth() + 1
	mesxx	= mes
	if (mesxx<10) mesxx="0" + mes
	mestexto= a_mes[mes]
	anyo 	= dFecha.getFullYear()		//En NS3 getYear() !!!

	horas 	= dFecha.getHours()
	minutos = dFecha.getMinutes()
	if (minutos<10) minutos="0" + minutos
	segundos = dFecha.getSeconds()
	if (segundos<10) segundos="0" + segundos

	sTag = BuscaTagEXML (sEXML,1)
	while (sTag){
		if ( eval("typeof("+sTag.toLowerCase()+")") != "undefined") {
			sTagValue = eval(sTag.toLowerCase())
		}
		else {
			sTagValue = "<"+sTag+">"
		}
		sEXML= SetTagEXML (sEXML,sTag,sTagValue,1)
		sTag = BuscaTagEXML (sEXML,1)
	}
	return (sEXML)
}


function CambiaFecha(sFecha) {				//1.6 Cambia entre dd/mm/aa y mm/dd/aa
	nBarra1 = sFecha.indexOf("/")
	nBarra2 = sFecha.lastIndexOf("/")

	if (nBarra1!=-1 || nBarra2!=-1){
		sDia= sFecha.substring(0,nBarra1)
		sMes= sFecha.substring(nBarra1+1,nBarra2)
		sAno= sFecha.substring(nBarra2+1)

		sFecha = sMes + "/" + sDia + "/" + sAno
	}
	return sFecha
}

function Fecha2Date(sFecha,cSeparador){		//1.9
var nBarra1,nBarra2,nEspacio,sDia,sMes,sAno,dFecha
var nDosPuntos1,sHora="",sMins="",sSecs=""

	if (!cSeparador) {
		cSeparador = sFecha.substr (1,1)
		if (!isNaN(cSeparador)) cSeparador = sFecha.substr (2,1)
		if (!isNaN(cSeparador)) cSeparador="/"
	}

	nBarra1 = sFecha.indexOf(cSeparador)
	nBarra2 = sFecha.lastIndexOf(cSeparador)

	if (nBarra1!=-1 && nBarra2!=-1){
		sDia= sFecha.substring(0,nBarra1)
		sMes= sFecha.substring(nBarra1+1,nBarra2)
		nEspacio= sFecha.indexOf(" ")				//Por si tiene hora
		if (nEspacio==-1){
			sAno= sFecha.substring(nBarra2+1)
		}
		else{
			sAno= sFecha.substring(nBarra2+1,nEspacio)

			nDosPuntos1 = sFecha.indexOf(":")
			if (nDosPuntos1!=-1){
				sHora = sFecha.substring(nEspacio+1,nDosPuntos1)
				nDosPuntos2 = sFecha.indexOf(":",nDosPuntos1+1)
				if (nDosPuntos2==-1){
					sMins = sFecha.substring(nDosPuntos1+1)
				}
				else{
					sMins = sFecha.substring(nDosPuntos1+1,nDosPuntos2)
					sSecs = sFecha.substring(nDosPuntos2+1)
				}
			}
		}
		if (ValidaFecha(sDia,sMes,sAno,sHora,sMins,sSecs)) dFecha = new Date(sAno,sMes-1,sDia,sHora,sMins,sSecs)
//alert(sDia+"."+sMes+"."+sAno+" "+sHora+":"+sMins+":"+sSecs+"_"+dFecha)
	}
	return dFecha
}

/*
function ValidaFecha (nDD,nMM,nAAAA){		//1.7 0/1  Invalida/Valida
	if (!nDD || !nMM || !nAAAA) return false
	if (isNaN(nDD)|| isNaN(nMM)|| isNaN(nAAAA)) return false
	if (nAAAA < 100) nAAAA+=1900			//Chapucilla
	var dFecha=new Date(nAAAA,nMM-1,nDD)
	if (nDD!=dFecha.getDate()) return false
	if (nMM!=(dFecha.getMonth()+1)) return false
	if (nAAAA!=dFecha.getFullYear()) return false
	return true;
}
*/

// Esta funcion esta duplicada en i_form.js !!!
function ValidaFecha (nDD,nMM,nAAAA,nHora,nMins,nSecs){
	if (!nDD || !nMM || !nAAAA) return false
	if (isNaN(nDD)|| isNaN(nMM)|| isNaN(nAAAA)) return false
	nAAAA = Number (nAAAA)
	if (nAAAA < g_nY2K) nAAAA = 2000 + nAAAA
	if (nAAAA < 100) nAAAA = 1900 + nAAAA
	if (!nHora) nHora=0;
	if (!nMins) nMins=0;
	if (!nSecs) nSecs=0;
	var dFecha=new Date(nAAAA,nMM-1,nDD,nHora,nMins,nSecs)
	if (nHora!=dFecha.getHours()) return false
	if (nMins!=dFecha.getMinutes()) return false
	if (nSecs!=dFecha.getSeconds()) return false
	if (nDD!=dFecha.getDate()) return false
	if (nMM!=(dFecha.getMonth()+1)) return false
	if (nAAAA!=dFecha.getFullYear()) return false
	return true;
}



// Devuelve sEXML con el TAG reemplazado por su valor
function SetTagEXML (sEXML,sTag,vValor,bSimple) {
var nPosIni,nPosFin

	if (bSimple){
		sTag = "<"+sTag+"/>"
		nPosIni = sEXML.indexOf(sTag)
		if (nPosIni!=-1) sEXML = sEXML.f_replace (sTag,vValor,0,1)
		//CambiaTexto(0,sEXML,sTag,vValor,0)
	}
	else{
		var sTagIni = "<"+sTag
		var sTagFin = "</"+sTag+">"
		var nTagIni=sTagIni.length

		nPosIni	= sEXML.indexOf(sTagIni)
		nPosFin	= sEXML.indexOf(sTagFin,nPosIni+nTagIni)
		if (nPosIni!=-1 && nPosFin!=-1){
			sTag = sEXML.substr(nPosIni,nPosFin+sTagFin.length-nPosIni)
			sEXML = sEXML.f_replace (sTag,vValor,0,1)
//			CambiaTexto(0,sEXML,sTag,vValor,0)
		}
	}
	return sEXML
}


// [nModo]
// 0/defecto = Devuelve sTagValue o "" si lo no encuentra
// 1 = Devuelve FullTag o "" si lo no encuentra
function GetTagEXML (sEXML,sTag,nModo) {
var nPosIni,nPosFin,nTagFinA,nTagFinB,nTagFinA2
var nPropEnd = 0
var sTagIni = "<" + sTag
var sTagFin = "</"+ sTag + ">"

var sTagValue=""

	nPosIni	= sEXML.indexOf(sTagIni)
	nPosFin	= sEXML.indexOf(sTagFin)
	if (nPosIni!=-1 && nPosFin!=-1){
		if (nModo==1){
			sTagValue =  sEXML.substring(nPosIni,nPosFin+sTagFin.length)
		}
		else{
			nTagFinA= sEXML.indexOf(">")
			nTagFinB= sEXML.lastIndexOf(">",nPosFin)

			while (nTagFinA!=nTagFinB) {		//Busco comillas
				nTagFinA2 = 0
				nPropIni = sEXML.indexOf("=",nPropEnd)
				if (nPropIni!=-1) {
					cChar = sEXML.charAt (++nPropIni)
					while (cChar==" ") cChar = sEXML.charAt (++nPropIni)
					if (cChar=="'" || cChar=='"') {
						nPropEnd = sEXML.indexOf(cChar,nPropIni+1)
					}
					if (nPropEnd!=-1) nTagFinA2= sEXML.indexOf(">",nPropEnd)
					if (nTagFinA2-nPropEnd<5) nTagFinA2=0		// Por que antes ponia <1 !!!
				}
				if (nTagFinA2==0) nTagFinB = nTagFinA
				else nTagFinA = nTagFinA2
			}
			nTagFinA++
			sTagValue = sEXML.substr(nTagFinA,nPosFin-nTagFinA)
//			nPosFin	= sEXML.indexOf(sTagFin,nPosIni+nTagIni)
//			if (nPosFin!=-1) sTagValue = sEXML.substr(nPosIni+nTagIni,nPosFin-nPosIni-nTagIni)
		}
	}
	return sTagValue
}


//Devuelve el valor de la Propiedad que le pedimos en el Tag que le damos
//[bPropUnica]
function GetPropEXML(sTag,sPropName,bPropUnica){
var nPropIni,nPropEnd,cChar
var sPropValue = ""
var cCharEnd = ""
	if (bPropUnica) cCharEnd = ">"

	nPropIni = sTag.indexOf(sPropName+"=")
	if (nPropIni!=-1) {
		nPropIni += 1 + sPropName.length
		cChar = sTag.charAt (nPropIni++)
//		while (cChar==" ") cChar = sEXML.charAt (++nPropIni)
		if (cChar=="'" || cChar=='"') {
			nPropEnd1 = sTag.indexOf(cChar+">",nPropIni)
			nPropEnd2 = sTag.indexOf(cChar+" "+cCharEnd,nPropIni)
			nPropEnd = Math.min (nPropEnd1,nPropEnd2)
			if (nPropEnd==-1) nPropEnd = Math.max (nPropEnd1,nPropEnd2)
			if (nPropEnd!=-1) sPropValue = sTag.substring (nPropIni,nPropEnd)
		}
	}

	return (sPropValue)
}


// Devuelve sTag o "" si no encuentra ninguno
// [bSimple] : Tag unico que se autocierra <Simple/>
// [nPos] : Busca el nombre a partir de esa posicion de la cadena (por defecto es 0)
function BuscaTagEXML (sEXML,bSimple,nPos){			//11.3
var sTag=""

	if (!nPos) nPos=0

	if (bSimple){
		var nPosIni,nPosFin,nPosIniCheck
		var sTagSimple1 = "<"
		var sTagSimple2 = "/>"
		var nTagSimple1=sTagSimple1.length

		while (nPos!=-1 && sTag==""){
			nPosIni		= sEXML.indexOf(sTagSimple1,nPos)
			nPosFin		= sEXML.indexOf(sTagSimple2,nPosIni+nTagSimple1)
			nPosIniCheck= sEXML.lastIndexOf(sTagSimple1,nPosFin)
//alert (nPosIni+"_"+nPosFin+"_"+nPosIniCheck)
			if (nPosIni!=-1 && nPosFin!=-1 && nPosIni==nPosIniCheck) sTag = sEXML.substr(nPosIni+nTagSimple1,nPosFin-nPosIni-nTagSimple1)
			if (nPosIni==-1) nPos=-1
			else nPos = nPosIni+1
		}
	}
	else{
		var nPosIni1
		var sTagIni1 = "<"
		var sTagIni2 = ">"
		var nTagIni1=sTagIni1.length

		while (nPos!=-1 && sTag==""){
			nPosIni1 = sEXML.indexOf(sTagIni1,nPos)
			nPosIni2 = sEXML.indexOf(sTagIni2,nPosIni1+nTagIni1)
			if (nPosIni1!=-1 && nPosIni2!=-1) {
				nPos = nPosIni1+1
				nPosIni2b = sEXML.indexOf(" ",nPosIni1+nTagIni1)
				if (nPosIni2b!=-1 && nPosIni2b<nPosIni2) nPosIni2 = nPosIni2b		// Caso Tag con propiedades
				sTag = sEXML.substr(nPosIni1+nTagIni1,nPosIni2-nPosIni1-nTagIni1)
				if (GetTagEXML (sEXML,sTag)=="") sTag=""	// No existe ese nombre
			}
			else{
				nPos = -1
			}
		}
	}
	return (sTag)
}

// sEXML = <OUT>...<IN>...</IN>..</OUT>
// sInnerFullTag = <IN>...</IN>
// sOuterTag = OUT
function GetOuterTag (sEXML,sInnerFullTag,sOuterTag){
var sOutTagIni = "<" + sOuterTag
var sOuterFullTag= "";

	var nPos = sEXML.indexOf (sInnerFullTag)
	if (nPos!=-1){
		var nPosIni = sEXML.lastIndexOf(sOutTagIni,nPos)
		if (nPosIni!=-1){
			sOuterFullTag = GetTagEXML (sEXML.substr(nPosIni),sOuterTag,1)
		}
	}
	return (sOuterFullTag)
}

// Devuelve '<TAGxxxxxxx >'
// sEXML = '<TAG...'
// [sTagEnd] = '>' y ' >'	(por defecto)
function GetInitTag (sTag,sEXML,sTagEnd){
	var nPos1Fin = -1
	if (!sTagEnd) {
		nPos1Fin = sEXML.indexOf("<"+sTag+">")
		if (nPos1Fin==0) {
			return (sTag.length+2)
		}
		nPos1Fin = -1
		sTagEnd = ' >'
	}
	while (sTagEnd && nPos1Fin==-1) {
		nPos1Fin = sEXML.indexOf(sTagEnd)
		sTagEnd = sTagEnd.substring(1)
	}
	return (nPos1Fin+(1+sTagEnd.length))
}


// Deprecated : usar GetInitTag
// Devuelve '<TAGxxxxxxx >'
// sEXML = '<TAG...'
// [sTagEnd] = ' >'	(por defecto)
function GetOpenTag (sEXML,sTagClose){
	var nPos1Fin = -1
	if (!sTagClose) sTagClose = ' >'

	while (sTagClose && nPos1Fin==-1) {
		nPos1Fin = sEXML.indexOf(sTagClose,0)
		sTagClose = sTagClose.substring(1)
	}
	return (nPos1Fin+(1+sTagClose.length))
}



function CambiaTexto(nAccion,sTexto,sBuscado,sNuevo,bMultiple){
	bOnlyOne=1
	if (bMultiple) bOnlyOne=0
	return (sTexto.f_replace (sBuscado,sNuevo,nAccion,bOnlyOne))
}


function _BuscaMultiarrayBlock (sCampo,sArrayBase,nRegistro){
var sPre,nBlockPos,a_sArray1,a_vArray1

	if (sCampo.indexOf(".")==2 && typeof(g_a_vBlockFormat)!="undefined"){
		sPre = sCampo.substr(0,2)

		nBlockPos = g_a_vBlockFormat.f_indexOf (sPre)
		if (nBlockPos!=-1){
			nBlockPos = g_a_vBlockFormat[nBlockPos+1]
			sCampo = sCampo.substr(3)

			if(IsArray(sArrayBase)){
				a_sArray1 = sArrayBase[0];
				a_vArray1 = sArrayBase[1];
			}
			else{
				a_sArray1 = eval ("a_s"+sArrayBase)
				a_vArray1 = eval ("a_v"+sArrayBase)
			}

			a_sBlockData = a_sArray1[nBlockPos]
			nBlockPos += a_sArray1.length*nRegistro
			a_vBlockData = a_vArray1[nBlockPos]
			return (BuscaMultiarrayBlock (sCampo,"BlockData",0))
		}
	}
	return (sArrayBase.f_maGetVal (sCampo,nRegistro))
}

function BuscaMultiarray (sCampo,sArrayBase,nRegistro){		//3.7 Busca sCampo en CampoArray1 y devuelve el valor que esta en la misma posicion en el nRegistro(0-N) del MultiArray2
	return (sArrayBase.f_maGetVal (sCampo,nRegistro))
}

function BuscaMArrayValor(sArrayBase,sCampo,vValor){		//3.16	Busca un valor en un MA y devuelve el nReg
	return (sArrayBase.f_maGetReg (sCampo,vValor))
}

function SetMArray(sArrayBase,sCampo,nRegistro,vValor){	//3.20 Busca sCampo de nRegistro y lo modifica
	return (sArrayBase.f_maSetVal (sCampo,vValor,nRegistro))
}

function GetMArray(sArrayBase,sCampo,nRegistro){
	return (sArrayBase.f_maGetVal (sCampo,nRegistro))
}


// [DEP] Indica si un valor para un combo debe estar seleccionado o no
function Seleccionado(sValor,vValorSelected){
	return (oIEXML.f_optionSelected (sValor,vValorSelected))
/*
	  if ( IsArray( vValorSelected ) ){
	  	return vValorSelected.f_indexOf( sValor ) != -1;
	  }else{
	  	return sValor == vValorSelected;
	  }
*/
}

// [DEP]  DEPRECATED ***
function AddCampo2Multiarray (sArrayBase,sCampo,sEXML){
	ErrorJS ("[EXML] AddCampo2Multiarray() deprecated: usa ma.f_addColEXML","",5)

	if (typeof(sArrayBase)=="string") {
		sArrayBase = sArrayBase.f_maBArray2MArray ()
	}
	sArrayBase.f_addColEXML (sCampo,sEXML)

/*
	if(IsArray(sArrayBase)){
		sArrayBase[0]=a_sArray1;
		sArrayBase[1]=a_sArray2;
	}
	else{
		eval ("a_s"+sArrayBase+"=a_sArray1")
		eval ("a_v"+sArrayBase+"=a_sArray2")
	}
*/

}

// [DEP] DEPRECATED ***
function ModMultiarray(sArrayBase,sCampo,sEXML){		// Modifica un campo del MBArray (hay que programar lo que necesitemos y renombrar la funcion)
	ErrorJS ("[EXML] ModMultiarray() deprecated: usa ma.f_modColEXML","",5)

	if (typeof(sArrayBase)=="string") {
		sArrayBase = sArrayBase.f_maBArray2MArray ()
	}
	sArrayBase.f_modColEXML (sCampo,sEXML)
}


//sMArrayFrom,sMArrayTo,sCampoFrom,[sCampoTo],[a_sCamposFrom]
// MArrays con distinto numero de elementos
function JoinMArray(sMArrayTo,sMArrayFrom,sCampoTo,sCampoFrom,a_sCamposFrom){
	sMArrayTo.f_maCopyCols (sMArrayFrom,[sCampoFrom,sCampoTo],a_sCamposFrom)
}

function _JoinMArray(sMArrayTo,sMArrayFrom,sCampoTo,sCampoFrom,a_sCamposFrom){
	var nReg,f,g,vValor
	var nFromToPos=0
	if (!sCampoFrom) sCampoFrom = sCampoTo
	if (!a_sCamposFrom) a_sCamposFrom = eval ("a_s"+sMArrayFrom)	//mal para Jonas !!!
	a_sMArrayFromTo = a_sCamposFrom			//MArrayFromTo tiene que ser global !!!
	a_vMArrayFromTo = []
	var nRegistrosTo = sMArrayTo.f_maGetRegs()
	var nCamposFrom = a_sCamposFrom.length
	for (f=0;f<nRegistrosTo;f++){
		vValor = sMArrayTo.f_maGetVal (sCampoTo,f)
		nReg = sMArrayFrom.f_maGetReg (sCampoFrom,vValor)
		if (nReg==-1){	//Campos vacios
			for (g=0;g<nCamposFrom;g++){
				a_vMArrayFromTo[nFromToPos++] = ""
			}
		}
		else{
			for (g=0;g<nCamposFrom;g++){
				a_vMArrayFromTo[nFromToPos++] = sMArrayFrom.f_maGetVal (a_sCamposFrom[g],nReg)
			}
		}
	}
	for (g=0;g<nCamposFrom;g++){
		AddCampo2Multiarray (sMArrayTo,a_sCamposFrom[g],"<FUN>'MArrayFromTo'.f_maGetVal ('"+a_sCamposFrom[g]+"',nRegistro)</FUN>")
	}
}

function InsertArray (a_vArrayDest,a_vArrayMed,nPos){		//3.6 a_vNewArray = InsertArray (a_vArray,"B",2)
	return (a_vArrayDest.f_insert (a_vArrayMed,nPos))
}

function BuscaEnArray (a_vArray,vValor,bCaseIndepen){			//3.1 Busca la posicion en el array del ultimo valor que se le pasa (Devuelve -1 si no encuentra ninguna)
	return (a_vArray.f_indexOf (vValor,"",bCaseIndepen))
}

function RegsMultiarray (sArrayBase){			//Para compatibilidad con cosas antiguas
	return (sArrayBase.f_maGetRegs())
}

function _RegsMultiarray (sArrayBase){			//DEPRECATED
var a_sArray2,nRegs,nRegsInt
	window.onerror = function ErrorTrapJS(sError,sURL,nLinea) { sError="\n\n"+sURL+"\nLinea "+nLinea + " : " + sError;ErrorJS (oIEXML.m_sKeyName +" RegsMultiarray() No existen los arrays con datos 'a_s"+sArrayBase+"' y/o 'a_v"+sArrayBase+"'"+sError,"",1); return (true);}
	var a_sArray1, a_vArray1;
	if(IsArray(sArrayBase)){
		a_sArray1 = sArrayBase[0];
		a_sArray2 = sArrayBase[1];
	}
	else{
		a_sArray1 = eval ("a_s"+sArrayBase)
		a_sArray2 = eval ("a_v"+sArrayBase)
	}
	window.onerror=g_oOnErrorEvent

	nRegs= (a_sArray2.length / a_sArray1.length)
	nRegsInt = Math.ceil (nRegs)		//Por si el array esta incompleto
	if (nRegsInt!=nRegs){
		a_sArray2 [(nRegsInt*a_sArray1.length)-1] = ""
	}
	return nRegsInt
}


// [vMArrayBase]	: "sManuel" / a_maJonas  / MAjonas
// [a_sCampos]	: campos a mostrar
function DebugMArray (vMArrayBase,a_sCampos) {
	var sText= ""
	if (!vMArrayBase) vMArrayBase = oIEXML.m_sMArrayBase
	if (!IsArray(vMArrayBase)) {
		if (!vMArrayBase) sText += "Error: No ha usado ningun MArray"
	}
	else {
		sText+= vMArrayBase.f_maDebug(a_sCampos)
/*
		if (IsMArray (vMArrayBase)) {
			sText+= vMArrayBase.f_debug()
		}
		else {
			sText+= vMArrayBase.f_maDebug(a_sCampos)
		}
*/
	}
	return (sText)
}

function LastMArray (vMArrayBase,a_sCampos) {
	if (!vMArrayBase) vMArrayBase = oIEXML.m_sMArrayBase
	return (vMArrayBase)
}


function _DebugMArray (vMArrayBase,a_sCampos) {
var f, nRegistrosMax=3
	var sHTML= "[i_exml.js v" + oIEXML.m_nVersion + "]\n\n"

	if (!vMArrayBase) vMArrayBase = oIEXML.m_sMArrayBase
	if (!IsArray(vMArrayBase)) {
		if (!vMArrayBase) return ("Error: No ha usado ningun MArray")
		sHTML += "MultiArray '"+vMArrayBase+"'\n"
		vMArrayBase = vMArrayBase.f_maBArray2MArray()
	}
	var nRegistros = vMArrayBase.f_maGetRegs()
	if (nRegistros<nRegistrosMax) nRegistrosMax = nRegistros

	sHTML += "\tETIQUETAS ("+vMArrayBase[0].length+" etiquetas)\n[" + vMArrayBase[0] + "]\n"
	sHTML += "\tVALORES (" + nRegistros+ " registros)\n"
	for (f=0;f<nRegistrosMax;f++){
		sHTML += DebugMArrayReg (vMArrayBase,a_sCampos,f)
	}
	if (nRegistrosMax<nRegistros){
		sHTML += "\t.....\n\t.....\n\t.....\n"
		sHTML += DebugMArrayReg (vMArrayBase,a_sCampos,nRegistros-1)
	}

	return sHTML
}

function _DebugMArrayReg (vMArrayBase,a_sCampos,nReg) {
	var nDatos = vMArrayBase[0].length
	var sHTML = "["
	for (var g=0;g<nDatos;g++){
		if (g) sHTML += ","
		if (!a_sCampos || a_sCampos.f_indexOf(vMArrayBase[0][g],0,1)!=-1 ) sHTML += vMArrayBase[1][(nReg*nDatos)+g]
	}
	sHTML += "] (Reg. " + nReg + ")\n"
	return (sHTML)
}

function OperarMultiEXML(sArrayBase,sEXML,oObj){		// Ejecuta una funcion de EXML con todos los regs de un Multiarray
	var	nRegs,f
	var vValor=0

/*
	if (String(oObj)=="undefined") oObj = ""
	if(IsArray(sArrayBase)){
		a_sArray1 = sArrayBase[0];
		a_sArray2 = sArrayBase[1];
	}
	else{
		a_sArray1 = eval ("a_s"+sArrayBase)
		a_sArray2 = eval ("a_v"+sArrayBase)
	}
	nCampos = a_sArray1.length
	nRegs = (a_sArray2.length) / nCampos
*/
	if (typeof(sArrayBase)=="string") {
		sArrayBase = sArrayBase.f_maBArray2MArray ()
	}
	nRegs = sArrayBase.f_maGetRegs ()

//alert("x:"+sEXML2 +"_"+ oObj.f_plegarEsPadre())
//	var regExp = /[\x2c]/g
	for (f=0;f<nRegs;f++){
//		sValor = eval (ParseEXMLs(sEXML,"",sArrayBase,f))
//		status = sValor.toString(10).replace(regExp,"\x2e")
//		vValor += sValor
//alert (ParseEXMLs(sEXML,"",sArrayBase,f))
///		vValor += parseFloat(ParseEXMLs(sEXML,"",sArrayBase,f))
////		vValorC = Number (ParseEXMLs(sEXML,"",sArrayBase,f))
////		if (!isNaN(vValorC)) vValor += vValorC

		vValor += (parseFloat ("0"+ParseEXMLs(sEXML,oObj,sArrayBase,f)))		//Con el 0 no piensa que es octal la cifra???
	}
//alert (sEXML + "[" + vValor +"]")
//vValor="0.444"
//alert(vValor)
	return (vValor)
}



function XML2aForm (sXML,sJSarrayBase) {
var sValue
var f=0
var	sVacio = ""
	if (sJSarrayBase) {
		a_sFormNames = eval ("a_s"+sJSarrayBase)
		a_vFormValues = eval ("a_v"+sJSarrayBase)
	}
	sFullTag = GetTagEXML (sXML,"FORM",1)
	while (sFullTag){
		a_sFormNames[f] 	= GetPropEXML(sFullTag,"name")
		sValue = GetTagEXML (sFullTag,"FORM")
		sValue = RemoveIniFin (sValue,"<![CDATA[","]]>")
		a_vFormValues[f]	= sValue
		f++
		sXML = SetTagEXML (sXML,"FORM",sVacio,0)
		sFullTag = GetTagEXML (sXML,"FORM",1)
	}
}

function RemoveIniFin (sText,sStart,sEnd){		// 9.11 Borra cadena del principio y del final
	var nPos
	if (sStart) {
		nPos = sText.indexOf(sStart)
		if (nPos==0) {
			sText = sText.substring (sStart.length)
		}
	}
	if (sEnd) {
		nPos = sText.lastIndexOf(sEnd)
		if (nPos+sEnd.length==sText.length) {
			sText = sText.substring (0,nPos)
		}
	}
	return (sText)
}

function FixAcentos (sTexto){					//9.9
	return (sTexto.f_removeAcentos())
}

//<!--%>//-->