//var ECSYS = {};
//%TC at some point this code should be namespaced to avoid any potential conflicts with other
// javascript libs eg google maps, but we need to fix all the current js calls to this code
//lots a work
//%TC this script is used by both public facing web pages & internal cms htc files
//$Id: lib.js 17178 2011-04-28 10:47:37Z trclark $
//<script language='JavaScript'> //fool VI6 to do color coding
var MS_MSADORS    = "ADODB.Recordset"
var MS_FTXMLDOM	  = "Microsoft.FreeThreadedXMLDOM";
var MS_XMLDOM	  = "Microsoft.XMLDOM";
var MS_XMLHTTP    = "Microsoft.XMLHTTP"; 
var MS_WINHTTP    = "WinHttp.WinHttpRequest.5"; //only for SVR Side
var MS_XSLTPL     = "Msxml2.XSLTemplate";
var defaultEmptyOK = false;

function getCookie(name) {
   var prefix = name + "="
   var cookieStartIndex = document.cookie.indexOf(prefix)
   var sTmp
   
   if (cookieStartIndex == -1)
      return "" //null
      
   var cookieEndIndex = document.cookie.indexOf(";", cookieStartIndex + prefix.length)
   
   if (cookieEndIndex == -1)
      cookieEndIndex = document.cookie.length;
      //To Do figure why + is not replaced after unescape ...
   //re=/\+/g; 
   return unescape(document.cookie.substring(cookieStartIndex + prefix.length, cookieEndIndex)).replace(/\+/g," ")
   //return unescape(document.cookie.substring(cookieStartIndex + prefix.length, cookieEndIndex))

}

function GetUserData()
{
var oXMLDom;
var xmlhttp;
var sURL;
var oRoot;
var sOpen;
var oResponse;

  oXMLDom = CreateSOAP("GetUserData");
  oRoot = oXMLDom.selectSingleNode(".//m:GetUserData");

  xmlhttp = new ActiveXObject(MS_XMLHTTP);
  sURL = getServerName() + "/" + getCompanyPath() + "/software/XML/XML.asp"; //+ "UserGUID=" + getUserGUID();
  xmlhttp.open ("POST",sURL,false); //sync
  xmlhttp.send(oXMLDom);

  oResponse = xmlhttp.responseXML.documentElement.selectSingleNode(".//UserData");
  if (oResponse == null) 
      oResponse = xmlhttp.responseXML.documentElement.selectSingleNode(".//m:Login");

  if (oResponse == null) 
  	alert(xmlhttp.responseXML.XML);
  else
	  return oResponse;
  
  
  oXMLDom = null;
  xmlhttp = null;
}

function getUserGUID() {
var UserGUID;
var sSearch;
var cUserGUID;
var oWin;


  if (typeof(document.defaultView) == "object") //modzilla doc obj model
    oWin = document.defaultView;
  else
    oWin = document.parentWindow
  sSearch = oWin.document.location.search;
  UserGUID = getToken(sSearch,"UserGUID");
  if (UserGUID.length == 0) {	//' try top window
    sSearch = oWin.top.location.search;
    UserGUID = getToken(sSearch,"UserGUID")
  }
  if (UserGUID.length == 0) {	
    UserGUID = getCookie("UserGUID");
    //WebEMail "getUserGUID,getCookie,url=" + UserGUID + ":" & location.href + ":" + window.top.location.href
  }
  else {
    cUserGUID = getCookie("UserGUID");
    if (UserGUID != cUserGUID) {
      sSearch = "";
    }
  }
  return UserGUID
}

function WebEMail(sText) 
{
var sqlObj
var ServerName
var ADS
  //ServerName = getServerName();
  //ADS = CreateObject("RDS.DataSpace");
  //sqlObj = ADS.createobject("ecResources.ecSQL",ServerName);
  //Obj.WebEMail sText;
  //sqlObj = null;
  //set ADS = null;
}

function getToken(s,token)
{
var i;
var j;
var sArray; //' array of strings

  //debugger;
 //alert("s,token=" + s + ":" + token);
  if (s.length == 0) 
	  return "";
  else {
    if (s.indexOf("?") > -1)
     s = s.substr(s.indexOf("?")+1);
  }

  if (s.length > 0 ) {
    sArray = s.split("&");
    // look at each split string
    for (i=0; (i < sArray.length); i++)
    {
		  //if (sArray.length == i)
		  //	return "";		
		  //alert ( "sArray=" + i + ":" + sArray[i]);
		  j = sArray[i].indexOf("=");
		  if (j > -1) {
		    if (sArray[i].substr(0,j) == token)
		      return  sArray[i].substr(j+1);
		  }
    }
    return "";
  }

}
/*
function convertNull(s)
{  
  if (s == null) 
    s=""
return s
}
*/
function trim (string) {
    return string.replace(/^\s+/, '').replace(/\s+$/, '');
}

function EatWhite(str)
{
   if(str.value.length > 0) 
	   str.value = str.value.replace(/^[ ]+/,"");
	return;
}

function IsEmpty(s)
{   return ((s == null) || (s.length == 0))
}

function IsDigit (c)
{   return ((c >= "0") && (c <= "9"))
}

function stripwithMask (s, sMask)

{   var i;
    var sStr = "";

    // Search through s characters one by one.
    // If character Is NOT in sMask, append to sStr.

    for (i = 0; i < s.length; i++)
    {   
        // Check that current character Isn't whitespace.
        var c = s.charAt(i);
        if (sMask.indexOf(c) == -1) sStr += c;
    }
    return sStr;
}

function IsNumber (s)
{   var i;
    var bDecimalPoint = false;
    var decimalPointDelimiter = ".";
    
    if (IsEmpty(s)) 
       if (IsNumber.arguments.length == 1) return defaultEmptyOK;
       else return (IsNumber.arguments[1] == true);

    if (s == decimalPointDelimiter) return false;

    // Search through string's characters one by one
    // until we find a non-numeric character.
    // When we do, return false; if we don't, return true.

    for (i = 0; i < s.length; i++)
    {   
        // Check that current character Is number.
        var c = s.charAt(i);

        if ((c == decimalPointDelimiter) && !bDecimalPoint) bDecimalPoint = true;
        else if (!IsDigit(c)) return false;
    }

    // All characters are numbers. or the decimal pt
    return true;
}

function IsInteger (s)
{   var i;

    if (IsEmpty(s)) 
       if (IsInteger.arguments.length == 1) return defaultEmptyOK;
       else return (IsInteger.arguments[1] == true);

    // Search through string's characters one by one
    // until we find a non-numeric character.
    // When we do, return false; if we don't, return true.

    for (i = 0; i < s.length; i++)
    {   
        // Check that current character Is number.
        var c = s.charAt(i);

        if (!IsDigit(c)) return false;
    }

    // All characters are numbers.
    return true;
}

/* use StringBuffer just like in dot net when doing 
any large string build ops like a fragments of a web page
perf with string concation is poor


var buf = new StringBuffer();

buf.append("hello");
buf.append("world");

alert(buf.toString());

*/

function repeat(pattern, count) {
  if (count < 1) return '';
  var result = '';
  while (count > 0) {
    if (count & 1) result += pattern;
    count >>= 1, pattern += pattern;
  };
  return result;
};function StringBuffer() {
  this.buffer = [];
}

StringBuffer.prototype.append = function append(string) {
  this.buffer.push(string);
};

StringBuffer.prototype.toString = function toString() {
  return this.buffer.join("");
};


//#_start xml x-browser ajax helpers
var NS_SOAP = "'http://schemas.xmlsoap.org/soap/envelope/'"; //"http://schemas.xmlsoap.org/soap/envelope/"
var NS_EC = "'http://www.e-courier.com/schemas/'";

function xCreateSOAP(MethodName) {
// Use text string to create xmlDom FF does not support in memory xml node creation eg createNode
  var sXML = "<SOAP:Envelope xmlns:SOAP=" + NS_SOAP + ">" +
  "<SOAP:Body xmlns:SOAP=" + NS_EC + " UserGUID='" + getUserGUID() + "'>" +
  "<m:" + MethodName + " xmlns:m=" + NS_EC + 
  " HttpReferer='"  + window.document.location + "'" +
  " UserGUID='"+ getUserGUID() + "' />" +
  "</SOAP:Body>" +
  "</SOAP:Envelope>"
  oXMLDom = CreateXMLDomFromString(sXML);
return oXMLDom;

}
function CreateSOAP(MethodName) {
//%TC this method is used by both public facing web pages & internal cms htc files
var oXMLDom;//As MSXML.DOMDocument,
var oRoot; //As MSXML.IXMLDOMNode
var oBody; //As MSXML.IXMLDOMNode
var oMethod; //As MSXML.IXMLDOMNode
var s;
var i;

  oXMLDom = CreateXMLDom();
  oRoot = oXMLDom.createNode("element", "SOAP:Envelope", NS_SOAP);

  oBody = oXMLDom.createNode("element", "SOAP:Body", NS_EC);
  oBody.setAttribute( "UserGUID",getUserGUID() );

  switch (typeof(MethodName)) {
	case "object":
	    for (var i=0; (i<MethodName.length); i++) {
	      oMethod = oXMLDom.createNode("element", "m:" + MethodName[i], NS_EC);
              oMethod.setAttribute("HttpReferer",window.document.location); 
	      oBody.appendChild( oMethod);
	    }
	  break;
	  
	case "string":
	  if (MethodName.length > 0) {
	      oMethod = oXMLDom.createNode("element", "m:" + MethodName, NS_EC);
              oMethod.setAttribute("HttpReferer",window.document.location); 
	      oBody.appendChild (oMethod);
	  }
	  break;  
	default:
	  break;
	  //'No Method Name(s) just return SOAP:Envelope
  }
  
  oRoot.appendChild (oBody);
  oXMLDom.appendChild (oRoot);
  

  return oXMLDom;
  
}

function CreateXMLDom() {
  try {
    var xmlParser = new DOMParser();
    var oXMLDom = xmlParser.parseFromString("<xml />", "text/xml");
  }
  catch (Err) {
    try {
      var oXMLDom = new ActiveXObject(MS_XMLDOM);
      oXMLDom.async = "false";
    }
    catch (Err) {
      alert("Browser does not support XML parsing.");
      return false;
    }
  }

  return oXMLDom;
}

function CreateXMLDomFromString(sXML) {
  try {
    var xmlParser = new DOMParser();
    var oXMLDom = xmlParser.parseFromString(sXML, "text/xml");
  }
  catch (Err) {
    try {
      var oXMLDom = new ActiveXObject(MS_XMLDOM);
      oXMLDom.async = "false";
      oXMLDom.loadXML(sXML);
    }
    catch (Err) {
      alert("Browser does not support XML parsing.");
      return false;
    }
  }

  return oXMLDom;
}

function CreateElement(TagName ) {
var oXMlDom

  //var element = createElementNS("http://www.w3.org/1999/xhtml", TagName); //FF createElement
  oXMLDom = CreateSOAP("");
  return oXMLDom.createElement(TagName);
  oXMLDom = "";

}

function xml2string(oXMLDom) {
  //FF  new DOMParser() does not have ANY toString or xml attribute so you cant
  //return a string of the oXMLDom eg oXMLDom.xml
  var sStr = null;
  var oXMLDoc = oXMLDom.documentElement;
  if (oXMLDoc.xml == undefined)
    sStr = (new XMLSerializer()).serializeToString(oXMLDom);
  else
    sStr = oXMLDoc;
  return sStr;
}

function SelectSingleNode(oXMLDoc, sXPath) {
  if (window.ActiveXObject) {
    return oXMLDoc.selectSingleNode(sXPath);
  }
  else {
    var xpe = new XPathEvaluator();
    var nsResolver = xpe.createNSResolver(oXMLDoc.ownerDocument == null ? oXMLDoc.documentElement : oXMLDoc.ownerDocument.documentElement);
    var results = xpe.evaluate(sXPath, oXMLDoc, nsResolver, XPathResult.FIRST_ORDERED_NODE_TYPE, null);
    return results.singleNodeValue;
  }
}

if (!window.ActiveXObject) {
  //http://www.wrox.com/WileyCDA/Section/XPath-Support-in-Browsers-Page-2.id-291861.html
  Element.prototype.selectNodes = function(sXPath) {
  var oXPEvaluator = new XPathEvaluator();
  var oNSResolver = oXPEvaluator.createNSResolver(this.ownerDocument == null ? this.documentElement : this.ownerDocument.documentElement);
  //var oResult = oEvaluator.evaluate(sXPath, this, null, XPathResult.ORDERED_NODE_ITERATOR_TYPE, null);
  var oResult = oXPEvaluator.evaluate(sXPath, this, oNSResolver, XPathResult.ORDERED_NODE_ITERATOR_TYPE, null);
    var aNodes = new Array();
    if (oResult != null) {
      var oElement = oResult.iterateNext();
      while (oElement) {
        aNodes.push(oElement);
        oElement = oResult.iterateNext();
      }
    }
    return aNodes;
  } //Element.prototype.selectNodes

  Element.prototype.selectSingleNode = function(sXPath) {
  //see  //http://www.w3.org/TR/DOM-Level-3-XPath/xpath.html#XPathEvaluator
  var oXPEvaluator = new XPathEvaluator();
 /*%TC note NSResolver would be a local function of the following form
  function ecNSResolver(prefix) {
  var ns = {
  'gpxx': 'http://www.garmin.com/xmlschemas/GpxExtensions/v3'
  };
  return ns[prefix] || null;
  }    
  */
  var oNSResolver = oXPEvaluator.createNSResolver(this.ownerDocument == null ? this.documentElement : this.ownerDocument.documentElement);
    // FIRST_ORDERED_NODE_TYPE returns the first match to the xpath.
    //DOMXPathString expression,Node contextNode, XPathNSResolver resolver, unsigned short type, DOMObject result)
    //If 3rd arg XPathNSResolver is specified as null, any namespace prefix within the expression will result in DOMException being thrown with the code NAMESPACE_ERR.
  //var oResult = oXPE.evaluate(sXPath, this, null, XPathResult.FIRST_ORDERED_NODE_TYPE, null);
  var oResult = oXPEvaluator.evaluate(sXPath, this, oNSResolver, XPathResult.FIRST_ORDERED_NODE_TYPE, null);
    if (oResult != null) {
      return oResult.singleNodeValue;
    } else {
      return null;
    }
  } //Element.prototype.selectSingleNode

  Node.prototype.__defineGetter__("innerXml", function() {
    var oSerializer = new XMLSerializer();
    var frag = this.ownerDocument.createDocumentFragment();
    for (var i = 0; i < this.childNodes.length; i++) {
      frag.appendChild(this.childNodes[i]);
    }
    return oSerializer.serializeToString(frag, "text/xml");
  });
  
  //http://www.webreference.com/programming/javascript/domwrapper/4.html
  //make ff like ie by adding xml & loadXML
  Document.prototype.onreadystatechange = null;
  Document.prototype.readyState = "0";  
  //add the loadXML() method to the Document class
  //fake it my removing current document node tree then pase xml into a new XMLDom & 
  //& import the new docs node tree into the current XMLDFom node tree
  Document.prototype.loadXML = function(sXML) {
    //change the readystate
    changeReadyState(this, 1);
    //create a DOMParser
    var oDOMParser = new DOMParser();
    //create new document from string
    var oXMLDoc = oDOMParser.parseFromString(sXML, "text/xml");
    //remove all nodes from the document
    while (this.hasChildNodes())
      this.removeChild(this.lastChild);
    //add the nodes from the new document
    for (var i=0; i < oXMLDoc.childNodes.length; i++) {
      //import the node
      var oNode = this.importNode(oXMLDoc.childNodes[i], true);
      //append the child to the current document
      this.appendChild(oNode);
    } //(var i=0; i < oXMLDoc.childNodes.length; i++)

    changeReadyState(this, 4);
  } //Document.prototype.loadXML
  
  Element.prototype.__defineGetter__("xml", function() {
    return (new XMLSerializer()).serializeToString(this);
  } //Element.prototype.xml
  ) // this is a closing parenthesis ("xml ...

  Document.prototype.__defineGetter__("xml", function() {
    return (new XMLSerializer()).serializeToString(this);
  } //Document.prototype.xml
  ) // this is a closing parenthesis ("xml ...

  function changeReadyState(oXMLDom, iReadyState) {

    //change the readyState
    //oXMLDom.readyState = iReadyState;

    //if there is an onreadystatechange event handler, run it
    if (oXMLDom.onreadystatechange != null && typeof oXMLDom.onreadystatechange == "function")
      oXMLDom.onreadystatechange();
  } //function changeReadyState
  
} //(!window.ActiveXObject)

//#_end xml x-browser ajax helpers
function getParametersFromQueryString(sMethod, s) 
{
var oXMLDom;
var oRoot, oParms, oParm;
var i,j;
var sArray;

	oXMLDom = CreateSOAP(sMethod);
	oRoot = oXMLDom.selectSingleNode("//m:" + sMethod);
	oParms = oXMLDom.createElement("Parameter" + "s");
	oRoot.appendChild (oParms);	

  sArray = s.split("&");
  for (i=0; (i < sArray.length); i++) //'convert each name-value pair to a ParameterNode
  {
	  j = sArray[i].indexOf("=");
	  if (j > -1) {
	    sName = trim(sArray[i].substr(0,j));
	    sValue =trim(sArray[i].substr(j+1));
	    oNode = oParms.selectSingleNode ("Parameter[@name='" + sName + "']");
	    if (oNode == null) {
        oNode = oXMLDom.createElement("Parameter");
        oParms.appendChild (oNode);	    
	    }
      oNode.setAttribute ("name", sName);
      oNode.setAttribute ("value", sValue);
      //''need to pass some other special NameTitle element after the sValue        
      oNode.setAttribute ("title", sValue);	    
	  }
  }

	return oXMLDom;
		
}

function getServerName() 
{
var s; //hostname, host, protocol,port, pathname
//s = document.location.href.split("/"); //fails in htc bcus document is the htc
  if (document.parentWindow)
    s = document.parentWindow.document.location.href.split("/");
  else
    s = document.location.href.split("/");
  if (s.length > 1)
    //return document.location.protocol + "//" + document.location.host;
    return s[0] + "//" + s[2];
  else
    return null;
}

function getCompanyPath() 
{
var s; //looks like "http://w2ktopcat/ecourier/software
                   // 0   1    2         3          4
//s = document.location.href.split("/"); //fails in htc bcus document is the htc not the html page
  if (document.parentWindow)
    s = document.parentWindow.document.location.href.split("/");
  else
    s = document.location.href.split("/");  
  if (s.length > 1)
     return s[3];
  else
    return null;
}

function getXML(){
	strXML="<XML>\n<rootElement>\n";

	el=document.XMLform;
	   for(x=0;x<el.length;x++){
	     strXML+="<"+el[x].name+">"+el[x].value+"</"+el[x].name+">\n"
	   }
	strXML+="</rootElement>\n</XML>";

}

function cancelEvent() {
    window.event.returnValue = false;
    window.event.cancelBubble = true;
  }

function Populate(combo, oRS, txtCol, valueCol) {
  var IsArray = false
  //combo.tagName=="SELECT"  use new option
  //combo.tagName=="DIV"     use innerHTML of parent & array join fast for big SELECT

  //IsArray=((typeof(oRS)=='object') && (typeof(oRS.constructor)!='undefined'))?true:false;
  if (typeof (oRS.constructor) == "function")
    IsArray = true; //assume it is an IXMLDOMNodeList


  if (typeof (combo.options) == "object") { //(combo.tagName == "SELECT") {  	
    //debugger;
    combo.options.length = 0; //delete the options in the select element
    //var oOption = new Option('text', 'value', true/false, true/false) 	
    //pad with 25 spaces so all select's line up, yet another NN face plant
    //var option = new Option("                         ", "",false,false);
    combo.options[0] = new Option("                         ", "", false, false);
    for (var i = 0; i < oRS.length; i++) {
      //eval("combo.options[i]=option" ) ;
      if (IsArray) {
        aFlds = oRS[i].split(getDelimiter("COL"));
        option = new Option(aFlds[txtCol], aFlds[valueCol], false, false);
      }
      //IXMLDOMNodeList
      else {
        option = new Option(oRS[i].getAttribute(txtCol), oRS[i].getAttribute(valueCol), false, false);
      }
      eval("combo.options[i+1]=option");
    }
    if (IsArray) { combo.options[i] = new Option("                         ", "", false, false) };
    //add extra blank at end so a standard reset in NN picks this			
    combo.selectedIndex = 0; //NN does not respect the 'true' to set the option as selected
    //NN does not support DOM document.createElement("OPTION") brain dead !
  }
  else // "DIV"
  {
    var aCombo = new Array(); //array to contain the new option we are going to create
    aCombo[0] = "<option value=''></option>";
    for (var i = 0; i < oRS.length; i++) {
      if (IsArray) {
        aFlds = oRS[i].split(getDelimiter("COL"));
        aCombo[i + 1] = "<option value=" + aFlds[valueCol] + ">" + aFlds[txtCol] + "</option>";
      }
      //IXMLDOMNodeList
      else
        aCombo[i + 1] = "<option value=" + oRS[i].getAttribute(valueCol) + ">" + oRS[i].getAttribute(txtCol) + "</option>";
    }
    //style=';width:275px;font-size=9pt;' <select class=" + combo.className + 

    combo.innerHTML = "<select id=" + combo.id + "ID >" + aCombo.join() + "</select>";
    aCombo = "";

  }



}

function SetSelected(combo, value) {
  var sValue
  var sArray
  for (var i = 0; (i < combo.length); i++) {
    if (SetSelected.arguments.length == 2)
      combo[i].selected = false;
    sValue = combo[i].value;
    if (SetSelected.arguments.length == 3) {
      sArray = sValue.split("|");
      sValue = sArray[0];
    }

    if (sValue == value)
      combo[i].selected = true;

  }
}

function isValidCreditCard(cardtype, ccnumber) {
    if (cardtype == "Visa") 
    {
        // Prefix: 4, Lenght: 16
        var regEx = /^4\d{3}-?\d{4}-?\d{4}-?\d{4}$/;
    } 
    else if (cardtype == "MasterCard") 
    {
        // Prefix: 51-55, Length: 16
        var regEx = /^5[1-5]\d{2}-?\d{4}-?\d{4}-?\d{4}$/;
    } 
    else if (cardtype == "Discover") 
    {
        // Prefix: 6011, Length: 16
        var regEx = /^6011-?\d{4}-?\d{4}-?\d{4}$/;
    } 
    else if (cardtype == "AmericanExpress") 
    {
        // Prefix: 34 or 37, Length: 15 
        var regEx = /^3[4,7]\d{13}$/;
    } 
    else if (cardtype == "Diners") 
    {
        // Prefix: 30, 36, or 38, Length: 14
        var regEx = /^3[0,6,8]\d{12}$/;
    }
    
    if (!regEx.test(ccnumber)) return false;
    
    // Remove all dashes. 
    ccnumber = ccnumber.split("-").join("");
    
    // Add even digits in even length strings or odd digits in odd length strings.
    var digit = 0 ; //    
    var checksum = 0;
    
    for (var cnt=(2-(ccnumber.length % 2)); cnt<=ccnumber.length; cnt+=2) 
    {
        checksum += parseInt(ccnumber.charAt(cnt-1));
    }
/*
    for (var cnt=(ccnumber.length % 2) + 1; cnt+=1)  {
        digit =parseInt(ccnumber.charAt(cnt-1)) * 2;
        if (digit < 10) 
            checksum += digit; 
        else 
            checksum += (digit-9); 
    }
*/    

  if ((checksum % 10) == 0)
      return true; 
  else 
      return false;


}

function classOf(V) {
  if (undefined === V) return "Undefined";
  if (null === V) return "Null";
  return {}.toString.call(V).slice(8, -1);
}

function isArray(V) {
  if ("Array" == classOf(V)) return true;
  return false;
}

function IsNullEmpty(V) {
  var bIsNullEmpty = false;
  if ((undefined === V) | (null === V) )
    bIsNullEmpty = true;
  else {
    if (V.length == 0)
      bIsNullEmpty = true;
  }
  return bIsNullEmpty;
}

function ConvertNull(V) {
  var sConvertNull = ""
  if (IsNullEmpty(V))
    sConvertNull = "";
  else
    sConvertNull = V.trim;

  return sConvertNull;    
}

function createXMLHttp() {
  var activexmodes = ["Msxml2.XMLHTTP", "Microsoft.XMLHTTP"] //activeX versions to check for in IE
  if (window.ActiveXObject) { //Test for support for ActiveXObject in IE first (as XMLHttpRequest in IE7 is broken)
    for (var i = 0; i < activexmodes.length; i++) {
      try {
        return new ActiveXObject(activexmodes[i]);
      }
      catch (e) {
        //suppress error
      }
    }
  }
  else if (window.XMLHttpRequest) // if Mozilla, Safari etc
    return new XMLHttpRequest();
  else
    return null;
}


function GetRS(V, ReadOnly, ID, UserGUID, sFormat) {
var oXMLDom;
var oBody;
var oRoot;
var bArray; // as boolean
var oVs;
var oV;
var oIDs;
var oID;
var rs;
var oXMLHttp;
var oXMLDoc;
var s;
var oResponse;
var sURL;
var i;
var oXML;
var oXMLs;
  
  oXMLDom = CreateSOAP("GetRSXML");
  oBody = oXMLDom.selectSingleNode(".//SOAP:Body");

  if (!IsNullEmpty(UserGUID)) {
    if (!(IsNullEmpty(oBody.getAttribute("UserGUID")))) {
          oBody.removeAttribute("UserGUID");
    }
    oBody.setAttribute("UserGUID",UserGUID) ;   
  }
 
	oRoot = oXMLDom.selectSingleNode(".//m:GetRSXML");
  oRoot.setAttribute( "ReadOnly", "False");
  if (readonly)
    oRoot.setAttribute( "ReadOnly", "True");

  bArray = false;
  if (isArray(V)) {
    bArray = true;
  	oVs = CreateElement("VS")
	  oRoot.appendChild( oVs);
      for (var i = 0; i < V.length; i++){ 
    	  oV = CreateElement("V");
	      oVs.appendChild(oV);
	      oV.setattribute ("value",V(i));
      }
  }
  else {
  	oV = CreateElement("V");
	  oRoot.appendChild( oV);
	  oV.setattribute( "value",convertnull(V));
  }

  if (isArray(ID)) {
  	oIDs = CreateElement("IDS");
	  oRoot.appendChild(oIDs);
    for (var i = 0; i < ID.length; i++){ 
	    oID = CreateElement("ID");
      oIDs.appendChild( oID);
      oID.setattribute( "value",ID(i));
    }	  
  }
  else {
  	oID = CreateElement("ID")
	  oRoot.appendChild (oID);
	  oID.setattribute ("value", convertnull(ID));
  }
  
  oXMLHttp = XMLSend(oXMLDom);
  
  if (bArray) {
    i = 0;
    oXMLs = oXMLHttp.responseXML.documentElement.selectSingleNode(".//xmls");
    sURL = convertNull(oXMLs.getAttribute("HttpURL")); 
    if (sURL.length > 0) {
      oXMLHttp =XMLGet(sURL);
      oXMLs = oXMLHttp.responseXML.selectSingleNode("./xmls");    
    }
    var aV = new Array(oXMLs.childNodes.length - 1); 
    //for (var i = 0; i < ID.length; i++){ 
    //}	 
    for ( var oXML in oXMLs.selectNodes("xml") ) {
      oXMLDoc=CreateSOAP("");
      if (window.DOMParser) {
        oXMLDoc = oXMLDoc.parseFromString(oXML.xml, "text/xml");
      }
      else {
        oXMLDoc.async = "false";
        oXMLDoc.loadXML(oXML.xml);
      }
      rs = new ActiveXObject(MS_MSADORS);
      rs.Open(oXMLDoc);  
      aV(i) = rs;
      i = i + 1;
    }
       
    oXMLHttp = null;
    GetRS = aV;
  }
  else {
    oXMLs = oXMLHttp.responseXML.documentElement.selectSingleNode(".//xmls");
    sURL = convertNull(oXMLs.getAttribute("HttpURL")); 
    if (sURL.length > 0) {
      oXMLHttp =XMLGet(sURL);
    }  
    oXML = oXMLHttp.responseXML.documentElement.selectSingleNode(".//xml") ;   
    if (sFormat == "adoxml") {
      oXML.setAttribute ("UserGUID", UserGUID) ;   
      GetRS = oXML.xml;
    }
    else {
      oXMLDoc=CreateSOAP("")
      oXMLDoc.async="false";
      oXMLDoc.loadXML (oxml.xml);
      rs = new ActiveXObject(MS_MSADORS);
      rs.Open(oXMLDoc);
      GetRS = rs;
    }
  }
  oXMLHttp = null;

} //GetRS


function XMLSend(oXMLDom) {
var oXMLHttp;
var gzipcompressrpts = "0";
var sURL = ""
var sGzip = "";
var oResponse;
var iErrCnt = 0;

  //' this is for new code that will use DOTNET xml.asmx
  if (1==0) {
    if (IsNullEmpty(gDOTNET)) {
      gDOTNET = "0";  //' so we do not perform infinite recursive loop
      gDOTNET = GetDOTNET();    
    }
    sURL = getServerName() + "/" + getCompanyPath() + "/software/XML/XML.asp";
    if (ConvertNull(gDOTNET) == "1")
      sURL = getServerName() + "/" + getCompanyPath() + "/software/XML/XML.asmx/XML";  

  }    
  else {
    //' this is for the existing code that uses xml.asp
    sURL = getServerName() + "/" + getCompanyPath() + "/software/XML/XML.asp";
  }

  if (!IsNullEmpty(getUserGUID())) {
    if (window.document.location.toString().indexOf("login.asp") == 0) { //' login.asp calls CheckSpeed and we probably do not have a valid UserGUID yet
//' NOTE: do not need to do the ?GZip=True compression since we have turned on compression in IIS
    //'  gzipcompressrpts = GetConfigItemXML("gzipcompressrpts","")
    }
    if (gzipcompressrpts == "1" )
      sGZip = "?GZip=True"

  }
   
  if (sURL.indexOf("localhost") > 0) {
    iErrCnt = 2 //'only try once against local host, debug issues
  }
 
  while (iErrCnt < 3) {
    oXMLHttp = createXMLHttp();
    oXMLHttp.open ("POST", sURL + sGzip , false);
    oXMLHttp.send (oXMLDom);
    if (oXMLHttp.status == 200) {
      break;
    }
    else {
      if (iErrCnt > 0) { //' postaplus does this every time
        //LogError "XMLSend failed(" + iErrCnt + ") with Http status: " + oXMLHttp.status + " at " + formatdatetime(now(),vbshorttime) + vbcrlf _
        //+ "URL=" + sURL + vbcrlf _
        //+ "oXMLDom.xml=" + oXMLDom.xml + vbcrlf _
        //+ "oXMLhttp.responseText=" + oXMLhttp.responseText
      }
      sGzip = "";
    }
    iErrCnt++;
  }  
  if (oXMLHttp.status != 200) {
    //'support email sent in above loop
    alert( "XMLSend,transaction failed errorlog sent to support oXMLHttp.status=" + oXMLHttp.status);
    return null;
  }

  if (_xml._xml2str(oXMLHttp.responseXML).length == 0) {
    //LogError "lib.vbs: XMLSend,No ResponseXML" + vbcrlf & "oXMLDom.xml=" + _xml._xml2str(oXMLDom) + vbcrlf & "oXMLHttp.responseText=" & oXMLHttp.responseText
    alert ("lib.vbs:XMLSend No ResponseXML" + "\n" );
    return null;
  }

  oResponse = oXMLHttp.responseXML.documentElement.selectSingleNode(".//faultstring");
  if (!(oResponse == null)) {
    //LogError "XMLSend,fault" & vbcrlf + "oResponse.xml=" + oResponse.xml + "oXMLDom.xml=" + oXMLDom.xml;
    alert( "Error:XMLSend,fault " + _xml._xml2str(oResponse))
    return null;
  }

 return oXMLHttp;
}

function getWindowWidth() {
 if (document.documentElement.clientWidth) { return document.documentElement.clientWidth; }
 if (document.body.clientWidth) { return document.body.clientWidth; }
  return 0; 
}
function getWindowHeight() {
  if (window.self && self.innerHeight) { return self.innerHeight; }
  if (document.documentElement && document.documentElement.clientHeight) { return document.documentElement.clientHeight; }
  return 0; 

}var Base64 = {
  // private property
  _keyStr: "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=",

  // public method for encoding
  encode: function(input) {
    var output = "";
    var chr1, chr2, chr3, enc1, enc2, enc3, enc4;
    var i = 0;

    input = Base64._utf8_encode(input);
    var buf = new StringBuffer();
    while (i < input.length) {
      chr1 = input.charCodeAt(i++);
      chr2 = input.charCodeAt(i++);
      chr3 = input.charCodeAt(i++);
      enc1 = chr1 >> 2;
      enc2 = ((chr1 & 3) << 4) | (chr2 >> 4);
      enc3 = ((chr2 & 15) << 2) | (chr3 >> 6);
      enc4 = chr3 & 63;
      if (isNaN(chr2)) {
        enc3 = enc4 = 64;
      } else if (isNaN(chr3)) {
        enc4 = 64;
      }
      buf.append(this._keyStr.charAt(enc1) + this._keyStr.charAt(enc2));
      buf.append(this._keyStr.charAt(enc3) + this._keyStr.charAt(enc4));
    }

    return buf.toString();
  },

  // public method for decoding
  decode: function(input) {
    var output = "";
    var chr1, chr2, chr3;
    var enc1, enc2, enc3, enc4;
    var i = 0;
    input = input.replace(/[^A-Za-z0-9\+\/\=]/g, "");
    var buf = new StringBuffer();
    while (i < input.length) {
      enc1 = this._keyStr.indexOf(input.charAt(i++));
      enc2 = this._keyStr.indexOf(input.charAt(i++));
      enc3 = this._keyStr.indexOf(input.charAt(i++));
      enc4 = this._keyStr.indexOf(input.charAt(i++));
      chr1 = (enc1 << 2) | (enc2 >> 4);
      chr2 = ((enc2 & 15) << 4) | (enc3 >> 2);
      chr3 = ((enc3 & 3) << 6) | enc4;
      buf.append(String.fromCharCode(chr1));
      if (enc3 != 64) {
        buf.append(String.fromCharCode(chr2));
      }
      if (enc4 != 64) {
        buf.append(String.fromCharCode(chr3));
      }

    }

    return Base64._utf8_decode(buf.toString());
  },

  // private method for UTF-8 encoding
  _utf8_encode: function(string) {
    string = string.replace(/\r\n/g, "\n");
    var utftext = "";
    var buf = new StringBuffer();
    for (var n = 0; n < string.length; n++) {
      var c = string.charCodeAt(n);
      if (c < 128) {
        buf.append(String.fromCharCode(c));
      }
      else if ((c > 127) && (c < 2048)) {
        buf.append(tring.fromCharCode((c >> 6) | 192));
        buf.append(String.fromCharCode((c & 63) | 128));
      }
      else {
        buf.append(String.fromCharCode((c >> 12) | 224));
        buf.append(String.fromCharCode(((c >> 6) & 63) | 128));
        buf.append(String.fromCharCode((c & 63) | 128));
      }
    }

    return buf.toString();
  },

  // private method for UTF-8 decoding
  _utf8_decode: function(utftext) {
    var string = "";
    var i = 0;
    var c = c1 = c2 = 0;
    var buf = new StringBuffer();
    while (i < utftext.length) {
      c = utftext.charCodeAt(i);
      if (c < 128) {
        buf.append(String.fromCharCode(c));
        i++;
      }
      else if ((c > 191) && (c < 224)) {
        c2 = utftext.charCodeAt(i + 1);
        buf.append(String.fromCharCode(((c & 31) << 6) | (c2 & 63)));
        i += 2;
      }
      else {
        c2 = utftext.charCodeAt(i + 1);
        c3 = utftext.charCodeAt(i + 2);
        buf.append(String.fromCharCode(((c & 15) << 12) | ((c2 & 63) << 6) | (c3 & 63)));
        i += 3;
      }

    }

    return buf.toString();
  }

} //Base64

