if(!window.freeance_loaded_js)window.freeance_loaded_js={};
FREEANCE_VERSION='5.3.1.3315';
/* FILE:FreeanceWeb/Common/lib/contrib/json.js */ if(!window.freeance_loaded_js['d8c03ff2f5916a16aad927fb30669b7e']){window.freeance_loaded_js['d8c03ff2f5916a16aad927fb30669b7e']=1;
/*
    json.js
    2007-03-06

    Public Domain

    This file adds these methods to JavaScript:

        array.toJSONString()
        boolean.toJSONString()
        date.toJSONString()
        number.toJSONString()
        object.toJSONString()
        string.toJSONString()
            These methods produce a JSON text from a JavaScript value.
            It must not contain any cyclical references. Illegal values
            will be excluded.

            The default conversion for dates is to an ISO string. You can
            add a toJSONString method to any date object to get a different
            representation.

        string.parseJSON(filter)
            This method parses a JSON text to produce an object or
            array. It can throw a SyntaxError exception.

            The optional filter parameter is a function which can filter and
            transform the results. It receives each of the keys and values, and
            its return value is used instead of the original value. If it
            returns what it received, then structure is not modified. If it
            returns undefined then the member is deleted.

            Example:

            // Parse the text. If a key contains the string 'date' then
            // convert the value to a date.

            myData = text.parseJSON(function (key, value) {
                return key.indexOf('date') >= 0 ? new Date(value) : value;
            });

    It is expected that these methods will formally become part of the
    JavaScript Programming Language in the Fourth Edition of the
    ECMAScript standard in 2008.
*/

// Augment the basic prototypes if they have not already been augmented.

if (!Object.prototype.toJSONString) {

    Array.prototype.toJSONString = function () {
        var a = ['['],  // The array holding the text fragments.
            b,          // A boolean indicating that a comma is required.
            i,          // Loop counter.
            l = this.length,
            v;          // The value to be stringified.

        function p(s) {

// p accumulates text fragments in an array. It inserts a comma before all
// except the first fragment.

            if (b) {
                a.push(',');
            }
            a.push(s);
            b = true;
        }

// For each value in this array...

        for (i = 0; i < l; i += 1) {
            v = this[i];
            switch (typeof v) {

// Values without a JSON representation are ignored.

            case 'undefined':
            case 'function':
            case 'unknown':
                break;

// Serialize a JavaScript object value. Ignore objects thats lack the
// toJSONString method. Due to a specification error in ECMAScript,
// typeof null is 'object', so watch out for that case.

            case 'object':
                if (v) {
                    if (typeof v.toJSONString === 'function') {
                        p(v.toJSONString());
                    }
                } else {
                    p("null");
                }
                break;

// Otherwise, serialize the value.

            default:
                p(v.toJSONString());
            }
        }

// Join all of the fragments together and return.

        a.push(']');
        return a.join('');
    };


    Boolean.prototype.toJSONString = function () {
        return String(this);
    };


    Date.prototype.toJSONString = function () {

// Ultimately, this method will be equivalent to the date.toISOString method.

        function f(n) {

// Format integers to have at least two digits.

            return n < 10 ? '0' + n : n;
        }

        return '"' + this.getFullYear() + '-' +
                f(this.getMonth() + 1) + '-' +
                f(this.getDate()) + 'T' +
                f(this.getHours()) + ':' +
                f(this.getMinutes()) + ':' +
                f(this.getSeconds()) + '"';
    };


    Number.prototype.toJSONString = function () {

// JSON numbers must be finite. Encode non-finite numbers as null.

        return isFinite(this) ? String(this) : "null";
    };


    Object.prototype.toJSONString = function () {
        var a = ['{'],  // The array holding the text fragments.
            b,          // A boolean indicating that a comma is required.
            k,          // The current key.
            v;          // The current value.

        function p(s) {

// p accumulates text fragment pairs in an array. It inserts a comma before all
// except the first fragment pair.

            if (b) {
                a.push(',');
            }
            a.push(k.toJSONString(), ':', s);
            b = true;
        }

// Iterate through all of the keys in the object, ignoring the proto chain.

        for (k in this) {
            if (this.hasOwnProperty(k)) {
                v = this[k];
                switch (typeof v) {

// Values without a JSON representation are ignored.

                case 'undefined':
                case 'function':
                case 'unknown':
                    break;

// Serialize a JavaScript object value. Ignore objects that lack the
// toJSONString method. Due to a specification error in ECMAScript,
// typeof null is 'object', so watch out for that case.

                case 'object':
                    if (v) {
                        if (typeof v.toJSONString === 'function') {
                            p(v.toJSONString());
                        }
                    } else {
                        p("null");
                    }
                    break;
                default:
                    p(v.toJSONString());
                }
            }
        }

// Join all of the fragments together and return.

        a.push('}');
        return a.join('');
    };


    (function (s) {

// Augment String.prototype. We do this in an immediate anonymous function to
// avoid defining global variables.

// m is a table of character substitutions.

        var m = {
            '\b': '\\b',
            '\t': '\\t',
            '\n': '\\n',
            '\f': '\\f',
            '\r': '\\r',
            '"' : '\\"',
            '\\': '\\\\'
        };


        s.parseJSON = function (filter) {

// Parsing happens in three stages. In the first stage, we run the text against
// a regular expression which looks for non-JSON characters. We are especially
// concerned with '()' and 'new' because they can cause invocation, and '='
// because it can cause mutation. But just to be safe, we will reject all
// unexpected characters.

            try {
                if (/^("(\\.|[^"\\\n\r])*?"|[,:{}\[\]0-9.\-+Eaeflnr-u \n\r\t])+?$/.
                        test(this)) {

// In the second stage we use the eval function to compile the text into a
// JavaScript structure. The '{' operator is subject to a syntactic ambiguity
// in JavaScript: it can begin a block or an object literal. We wrap the text
// in parens to eliminate the ambiguity.

                    var j = eval('(' + this + ')');

// In the optional third stage, we recursively walk the new structure, passing
// each name/value pair to a filter function for possible transformation.

                    if (typeof filter === 'function') {

                        function walk(k, v) {
                            if (v && typeof v === 'object') {
                                for (var i in v) {
                                    if (v.hasOwnProperty(i)) {
                                        v[i] = walk(i, v[i]);
                                    }
                                }
                            }
                            return filter(k, v);
                        }

                        j = walk('', j);
                    }
                    return j;
                }
            } catch (e) {

// Fall through if the regexp test fails.

            }
            throw new SyntaxError("parseJSON");
        };


        s.toJSONString = function () {

// If the string contains no control characters, no quote characters, and no
// backslash characters, then we can simply slap some quotes around it.
// Otherwise we must also replace the offending characters with safe
// sequences.

            if (/["\\\x00-\x1f]/.test(this)) {
                return '"' + this.replace(/([\x00-\x1f\\"])/g, function(a, b) {
                    var c = m[b];
                    if (c) {
                        return c;
                    }
                    c = b.charCodeAt();
                    return '\\u00' +
                        Math.floor(c / 16).toString(16) +
                        (c % 16).toString(16);
                }) + '"';
            }
            return '"' + this + '"';
        };
    })(String.prototype);
}}
/* FILE:FreeanceWeb/Client/PublicKiosk1/lib/Main.js */ if(!window.freeance_loaded_js['9948bfc86a64d5d7ffa456605e7a8a6c']){window.freeance_loaded_js['9948bfc86a64d5d7ffa456605e7a8a6c']=1;
XMLRPC_URL = '../../Server/Dzeims3.php';         //Location of server code.  This must be on the same server.
      FREEANCE_XMLRPC_URL = XMLRPC_URL = '../../Server/Dzeims3.php';         //Location of server code.  This must be on the same server.
      dprintf = function (nilvar) { return; };
      function $() {var es = new Array();for (var i=0;i<arguments.length;i++) {var e=arguments[i];if (typeof e == 'string') e = document.getElementById(e);if (arguments.length == 1) return e;es.push(e);};return es;};
      
      /****************************************************************
          Functions for handling URL parameters 
      ****************************************************************/
      function parseURLParameters()
      {
        var params = Array();
        var paramStr = unescape(location.search.slice(1));  // skip the question mark
        var tempParams = paramStr.split('&');
        for(var lcv=0;lcv < tempParams.length;lcv++)
        {
          var paramNameValuePair = tempParams[lcv].split('=');
          params[paramNameValuePair[0].toUpperCase()] = '';
          for(var i = 1; i < paramNameValuePair.length; i++){
            params[paramNameValuePair[0].toUpperCase()] += paramNameValuePair[i];
            if(i < paramNameValuePair.length - 1)
              params[paramNameValuePair[0].toUpperCase()] += '=';
          }
        }
        return(params);
      };
      APP_URLParameters = parseURLParameters();
      
      var appConfigName = '';
      if (APP_URLParameters["APPCONFIG"] != null)
      {
        appConfigName = escape(APP_URLParameters["APPCONFIG"]);
        LOAD_APP = true;
      }
      else
      {
        LOAD_APP = false;
        window.location = '../appNotFound.html';
      }
      if ((APP_URLParameters["COMPRESS"] != null) && (APP_URLParameters["COMPRESS"].toUpperCase() == "Y"))  // enable compression
        XMLRPC_URL += "?autocompress=Y";
      /*************
        Set the full path to the application config file.
        Append the current date and time to the path string to trick IE6 into ignoring any cached copies
      ***************/
      CONFIG_XML  = './etc/config-'+appConfigName+'.xml?time='+(new Date());
      /****************************************************************
          Function for getting the language engine started 
      ****************************************************************/
      
	  function languageHandler()
      {
        document.APP_LANGUAGE = (APP_URLParameters["LANG"])?APP_URLParameters["LANG"]:'EN';
        document.babelfish = new Babelfish();
        if ((APP_URLParameters["LANG"] != null) && (APP_URLParameters["LANG"] != "EN"))
        {
          var vocabJS = XmlHttp.loadTextSync('./lang/lang.'+document.APP_LANGUAGE+'.js?time='+(new Date()));
          try { 
          eval(vocabJS);
          document.babelfish.addLanguage(document.APP_LANGUAGE,document.APP_LANGUAGE_DATA);
          document.babelfish.setActiveLanguage(document.APP_LANGUAGE);
          }
          catch(e) { alert('Unable to load '+document.APP_LANGUAGE+' language file. '+e.description); document.APP_LANGUAGE = ''; }
        }
        else  // unspecified defaulting to EN or requested EN
        {
          document.APP_LANGUAGE_DATA = new Array();
          document.babelfish.addLanguage(document.APP_LANGUAGE,document.APP_LANGUAGE_DATA);
          document.babelfish.setActiveLanguage(document.APP_LANGUAGE);
        }
      };
      //declare global variables
      document.setSessionID = function(newID){ document.sessionID = newID; };
      document.getSessionID = function() { return(document.sessionID); };
      document.templateFunctions = new Array();
      document.getTemplate = function(templateName,noBuild,specialRequestOptions)
      {
        var js = null;
        if(typeof noBuild == "undefined")
        noBuild = false;
        if (noBuild == null)
          noBuild = false;
        if((typeof specialRequestOptions == "undefined") || (specialRequestOptions == null))
          specialRequestOptions = Array();
        if (document.templateFunctions[templateName])
          return(document.templateFunctions[templateName]);
        var templateObject = document.getGuiValue('templates');
        var templateString = templateObject[templateName];
        var _TemplateSearchString = '-!CURRENT_THEME!-';
        var _TemplateReplaceWith = document.getGuiValue('ApplicationConfig').stylesheet;
        templateString = templateString.replace(_TemplateSearchString,_TemplateReplaceWith);
        
        templateString = templateString.replace(/-!CURRENT_THEME!-/g,'default');
        
        if (templateString)
        {
            /* email search results */
            var _TemplateReplaceWith = 'img style="display:none;"';
            var _TemplateSearchFor = 'img template_enabled="y" template_type="" template_visibility_eval="..OBJECT_MANAGER.getGuiValueById..extensions....email...enabled. && .OBJECT_MANAGER.getGuiValueById..emailConfig...allowSearchResults.."';
            var _TemplateSearchString = new RegExp (_TemplateSearchFor,"");
            templateString = templateString.replace(_TemplateSearchString,_TemplateReplaceWith);
            /* email buffer results */
            var _TemplateReplaceWith = 'img style="display:none;"';
            var _TemplateSearchFor = 'img template_enabled="y" template_type="" template_visibility_eval="..OBJECT_MANAGER.getGuiValueById..extensions....email...enabled. && .OBJECT_MANAGER.getGuiValueById..emailConfig...allowBufferResults.."';
            var _TemplateSearchString = new RegExp (_TemplateSearchFor,"");
            templateString = templateString.replace(_TemplateSearchString,_TemplateReplaceWith);
            /* exportBufferToCSV */
            var includeExportBufferToCSV = false; // OBJECT_MANAGER.getGuiValue('extensions')['exportBufferToCSV'].enabled;
            if ((typeof specialRequestOptions["includeExportBufferToCSV"] == "boolean") && (specialRequestOptions["includeExportBufferToCSV"] == true))
              includeExportBufferToCSV = true;
            if (includeExportBufferToCSV)
              var _TemplateReplaceWith = 'img ';
            else var _TemplateReplaceWith = 'img style="display:none;"';
            var _TemplateSearchFor = 'img template_enabled="y" template_type="" template_visibility_eval=".OBJECT_MANAGER.getGuiValueById..extensions....exportBufferToCSV...enabled."';
            var _TemplateSearchString = new RegExp (_TemplateSearchFor,"");
            templateString = templateString.replace(_TemplateSearchString,_TemplateReplaceWith);
        };
        if (noBuild)
        {
          js = new Object();
          js.html = templateString;
        }
        else
          js = TW.templateToJS(templateString);
        document.templateFunctions[templateName] = js;
        return(js);
      };
      document.toClipboard = function(txt)
      {
        var ta = document.createElement('TEXTAREA');
        ta.innerText = txt;
        var tr = ta.createTextRange();
        tr.execCommand("Copy");
      };
      document.clipDebug = function(desc,txt)
      {
        document.toClipboard(txt);
        alert(desc+txt);
      };
      
      document.getPrintTarget = function()
      {
        element = document.getElementById("scratchpad");
        return element;
      };

      document.setScratchpadData = function(newData)
      {
        document.getElementById("scratchpad").innerHTML = newData;
      };
      
      document.printCurrentData = function()
      {
        element = self.frames['printFrame'].getPrintElement();
        element.innerHTML = document.getElementById("scratchpad").innerHTML;
        self.frames['printFrame'].focus();
        self.frames['printFrame'].print();
      };
      function downloadFile(url) { document.getElementById('downloadIFrame').src = url; };}
/* FILE:FreeanceWeb/Common/lib/XML/XMLHttp.js */ if(!window.freeance_loaded_js['91a768e718efb0d32d0601821ed5b419']){window.freeance_loaded_js['91a768e718efb0d32d0601821ed5b419']=1;
/**
 * From http://webfx.eae.net/dhtml/xmlextras/xmlextras.html
 * 
*/
/********************************************************************************/
/**
 * Handle DOM XML model quirk flags
 * 
*/
var _isIEmodel = false;
var _isMOZmodel = false;
var _isOP8model = false;
var _isKonqmodel = false;
var _isSafarimodel=false;
if ((document.all) && (document.getElementById) && (window.XMLDocument))
  _isIEmodel = true;
if ((!document.all) && (document.getElementById) && (window.XMLDocument))
  _isMOZmodel = true;
if ((navigator.userAgent.indexOf("Opera") > -1) && (document.implementation.createLSParser) && (document.implementation.createLSSerializer))
  _isOP8model = true;
var kxstest = null;
try { kxstest = new XMLSerializer(); } catch(e) {}
if ((navigator.userAgent.indexOf('KHTML') > -1) && (document.loadXML) && (typeof(kxstest)=="object"))
  _isKonqmodel = true;
if ((navigator.userAgent.indexOf('AppleWebKit') > -1) && (navigator.userAgent.indexOf('Safari')>-1) && (typeof(kxstest)=="object"))
  _isSafarimodel = true;
/********************************************************************************/
/**
 * Add two useful functions to mozilla if it doesn't already have them
 * 
*/
document.sharedinstances = new Object();  // recycle, reduce, reuse
if (_isSafarimodel)
{
  document.sharedinstances.domparser = new DOMParser();
  document.sharedinstances.xmlserializer = new XMLSerializer();
}
if (_isOP8model)
{
  document.sharedinstances.domparser = document.implementation.createLSParser(document.implementation.MODE_SYNCHRONOUS,'http://www.w3.org/TR/REC-xml'); // creating a new one each time is expensive
  document.sharedinstances.xmlserializer = document.implementation.createLSSerializer();
}
if (_isKonqmodel)
{
  //document.sharedinstances.domparser = document.implementation.createLSParser(document.implementation.MODE_SYNCHRONOUS,'http://www.w3.org/TR/REC-xml'); // creating a new one each time is expensive
  document.sharedinstances.xmlserializer = new XMLSerializer();
}
if ((_isMOZmodel) && (!_isOP8model))
{
  if (!Document.prototype.loadXML)
  {
    document.sharedinstances.domparser = new DOMParser(); // creating a new one each time is expensive
	// XMLDocument did not extend the Document interface in some versions
	// of Mozilla. Extend both! -- some versions? all versions!
	XMLDocument.prototype.loadXML = 
	Document.prototype.loadXML = function (s) {
		// parse the string to a new doc	
		var doc2 = document.sharedinstances.domparser.parseFromString(s, "text/xml");
		// remove all initial children
		while (this.hasChildNodes())
			this.removeChild(this.lastChild);
		// insert and import nodes
		childNodeCount = doc2.childNodes.length;
		for (var i = 0; i < childNodeCount; i++) {
			this.appendChild(this.importNode(doc2.childNodes[i], true));
		}
	};
  }
  if (!Document.prototype.xml)
  {
	  /**
	   * xml getter
	   * This serializes the DOM tree to an XML String
	   * Usage: var sXml = oNode.xml
	   *
	   */
	  // XMLDocument did not extend the Document interface in some versions
	  // of Mozilla. Extend both! -- some versions? all versions!
    document.sharedinstances.xmlserializer = new XMLSerializer(); // creating a new one each time is expensive
    if (window.navigator.userAgent.search(/FireFox/g)!=-1)  //this causes problems in Firefox 1.0.3+
    {
      XMLDocument.prototype.__defineGetter__("xml", function () {
          return document.sharedinstances.xmlserializer.serializeToString(this);
	    });
    }
    Element.prototype.__defineGetter__("xml", function () {
      return document.sharedinstances.xmlserializer.serializeToString(this);
    });
    Document.prototype.__defineGetter__("xml", function () {
      return document.sharedinstances.xmlserializer.serializeToString(this);
	  });

  }
};
/********************************************************************************/
function getControlPrefix() {
   if (getControlPrefix.prefix)
      return getControlPrefix.prefix;

   var prefixes = ["MSXML2", "Microsoft", "MSXML", "MSXML3"];
   var o, o2;
   for (var i = 0; i < prefixes.length; i++) {
      try {
         // try to create the objects
         o = new ActiveXObject(prefixes[i] + ".XmlHttp");
         o2 = new ActiveXObject(prefixes[i] + ".XmlDom");
         /* Clean up after our little experiment */
         delete o;
         delete o2;
         return getControlPrefix.prefix = prefixes[i];
      }
      catch (ex) {};
   }
   throw new Error("Could not find an installed XML parser");
};
/********************************************************************************/
// XmlHttp factory
function XmlHttp() {}
XmlHttp.create = function () {
   try {
      if (window.XMLHttpRequest) {
         var req = new XMLHttpRequest();
         
         // some older versions of Moz did not support the readyState property
         // and the onreadystate event so we patch it!
         if (req.readyState == null) {
            req.readyState = 1;
            req.addEventListener("load", function () {
               req.readyState = 4;
               if (typeof req.onreadystatechange == "function")
                  req.onreadystatechange();
            }, false);
         }
         
         return req;
      }
      if (window.ActiveXObject) {
         return new ActiveXObject(getControlPrefix() + ".XmlHttp");
      }
   }
   catch (ex) {}
   // fell through
   return null;
};
   /*******************************************************/
XmlHttp.loadSync = function(sUri)  // may leak, need to be able to get rid of original xmlHttp ?
{
  var xmlHttp = XmlHttp.create();
  var async = false;
  xmlHttp.open("GET", sUri, async);
  xmlHttp.send(null);
  if (_isOP8model)
  {
    xmlHttp.responseXML.loadXML = XmlDocument.loadXML;
    xmlHttp.responseXML.xml = XmlDocument.xml;
  }
  if (_isKonqmodel)
    xmlHttp.responseXML.xml = XmlDocument.xml;
  return (xmlHttp.responseXML);
};
   /*******************************************************/
XmlHttp.loadAsync = function (sUri,callback) 
{
  var xmlHttp = XmlHttp.create();
  var async = true;
  xmlHttp.open("GET", sUri, async);
  xmlHttp.onreadystatechange = function () 
  {
    if (xmlHttp.readyState == 4)
    {
      if (_isOP8model)
      {
        xmlHttp.responseXML.loadXML = XmlDocument.loadXML;
        xmlHttp.responseXML.xml = XmlDocument.xml;
      }
      if (_isKonqmodel)
        xmlHttp.responseXML.xml = XmlDocument.xml;
      callback(xmlHttp.responseXML); // responseXML : XmlDocument
      delete xmlHttp;
    }
  };
  xmlHttp.send(null);
};
   /*******************************************************/
XmlHttp.loadTextAsync2 = function (sUri,newCallback, request_type) 
{
  var xmlHttp = XmlHttp.create();
  var async = true;
  xmlHttp.open("GET", sUri, async);
  xmlHttp.onreadystatechange = function () 
  {
    if (xmlHttp.readyState == 4)
    {
      if (DataTypeOf(newCallback) == 'function')
        newCallback(xmlHttp.responseText, request_type);
      else
        newCallback.callback(xmlHttp.responseText);
      delete xmlHttp;
    }
  };
  xmlHttp.send(null);
};
   /*******************************************************/
XmlHttp.postSync = function(sUri, xmlDoc)  // may leak, need to be able to get rid of original xmlHttp ? 
{
  var xmlHttp = XmlHttp.create();
  var async = false;
  xmlHttp.open("POST", sUri, async);
  if (_isSafarimodel)
    xmlHttp.setRequestHeader('Content-Type','text/xml');
  xmlHttp.send(xmlDoc);
  if (_isOP8model)
  {
    xmlHttp.responseXML.loadXML = XmlDocument.loadXML;
    xmlHttp.responseXML.xml = XmlDocument.xml;
  }
  if (_isKonqmodel)
    xmlHttp.responseXML.xml = XmlDocument.xml;
  return (xmlHttp.responseXML);
};

XmlHttp.postAsync = function(sUri, xmlDoc, newCallback, request_type) 
{
  var xmlHttp = XmlHttp.create();
  var async = true;
  xmlHttp.open("POST", sUri, async);
  if (_isSafarimodel)
    xmlHttp.setRequestHeader('Content-Type','text/xml');
  xmlHttp.onreadystatechange = function () 
  {
    if (xmlHttp.readyState == 4)
    {
      if (_isOP8model)
      {
        xmlHttp.responseXML.loadXML = XmlDocument.loadXML;
        xmlHttp.responseXML.xml = XmlDocument.xml;
      }
      if (_isKonqmodel)
        xmlHttp.responseXML.xml = XmlDocument.xml;
      if (DataTypeOf(newCallback) == 'function')
        newCallback(xmlHttp.responseXML, request_type);
      else
        newCallback.callback(xmlHttp.responseXML, request_type); // responseXML : XmlDocument
      delete xmlHttp;
    }
  };
  xmlHttp.send(xmlDoc);
};

   /*******************************************************/
//XmlHttp.postAsync = function(sUri, xmlDoc, newCallback) 
//  9-09:  modified to accept a request_type parameter

XmlHttp.postAsync_ = function(sUri, xmlDoc, newCallback) 
{
  var xmlHttp = XmlHttp.create();
  var async = true;
  xmlHttp.open("POST", sUri, async);
  if (_isSafarimodel)
    xmlHttp.setRequestHeader('Content-Type','text/xml');
  xmlHttp.onreadystatechange = function () 
  {
    if (xmlHttp.readyState == 4)
    {
      if (_isOP8model)
      {
        xmlHttp.responseXML.loadXML = XmlDocument.loadXML;
        xmlHttp.responseXML.xml = XmlDocument.xml;
      }
      if (_isKonqmodel)
        xmlHttp.responseXML.xml = XmlDocument.xml;
      newCallback(xmlHttp.responseXML);
      delete xmlHttp;
    }
  };
  xmlHttp.send(xmlDoc);
};


XmlHttp.loadTextSync = function(sUri)  // may leak, need to be able to get rid of original xmlHttp ?
{
  var xmlHttp = XmlHttp.create();
  var async = false;
  xmlHttp.open("GET", sUri, async);
  xmlHttp.send(null);
  return (xmlHttp.responseText);
};
   /*******************************************************/
XmlHttp.loadTextASync = function(sUri,callback)
{
  var xmlHttp = XmlHttp.create();
  var async = true;
  xmlHttp.open("GET", sUri, async);
  xmlHttp.onreadystatechange = function () 
  {
    if (xmlHttp.readyState == 4)
    {
      callback(xmlHttp.responseText); // responseXML : XmlDocument
    }
  };
  xmlHttp.send(null);
};
   /*******************************************************/
XmlHttp.postTextSync = function(sUri,xmlDoc)  // may leak, need to be able to get rid of original xmlHttp ?
{
  var xmlHttp = XmlHttp.create();
  var async = false;
  xmlHttp.open("POST", sUri, async);
  xmlHttp.send(xmlDoc);
  return (xmlHttp.responseText);
};
/********************************************************************************/
// XmlDocument factory
function XmlDocument() {};
           XmlDocument.loadXML = function(xmlstr)
           {
             var xinput = document.implementation.createLSInput();
             xinput.stringData = xmlstr;
		         // parse the string to a new doc	
		         var doc2 = document.sharedinstances.domparser.parse(xinput);
		         // remove all initial children
             if(this.documentElement)
               this.removeChild(this.documentElement);
		         // insert and import nodes
		         var childNodeCount = doc2.childNodes.length;
		         for (var i = 0; i < childNodeCount; i++)
             {
			         this.appendChild(this.importNode(doc2.childNodes[i], true));
		         }
           };
           XmlDocument.xml = function()
           {
             if (arguments.length==1) // is set
             {
               this.loadXML(arguments[0]);
             }
             else // is get
             {
               if (_isOP8model)
                 return(document.sharedinstances.xmlserializer.writeToString(this));
               if (_isKonqmodel||_isSafarimodel)
               {
                 var timpstr = document.sharedinstances.xmlserializer.serializeToString(this);
                 return(timpstr);
               }
             }
           };
XmlDocument.create = function () {
   try {
      // DOM2
      if (document.implementation && document.implementation.createDocument) {
         var doc = document.implementation.createDocument("", "", null);
         // some versions of Moz do not support the readyState property
         // and the onreadystate event so we patch it!
         if (doc.readyState == null) {
            doc.readyState = 1;
            doc.addEventListener("load", function () {
               doc.readyState = 4;
               if (typeof doc.onreadystatechange == "function")
                  doc.onreadystatechange();
            }, false);
         }
         if (_isOP8model)
         {
           doc.loadXML = XmlDocument.loadXML;
           doc.xml = XmlDocument.xml;
         }
         if (_isKonqmodel)
           doc.xml = XmlDocument.xml;
         if (_isSafarimodel)
         {
           if(typeof(doc.loadXML)=='undefined'){
             doc.loadXML = function (s) {
               // parse the string to a new doc	
               var doc2 = document.sharedinstances.domparser.parseFromString(s, "text/xml");
               // remove all initial children
               while (this.hasChildNodes())
                 this.removeChild(this.lastChild);
               // insert and import nodes
               childNodeCount = doc2.childNodes.length;
               for (var i = 0; i < childNodeCount; i++) {
                 this.appendChild(this.importNode(doc2.childNodes[i], true));
               }
             };
           }
           if(typeof(doc.xml)=='undefined')
             doc.xml = XmlDocument.xml;
         }
         return doc;
      }
      else
      if (window.ActiveXObject)
      {
         return new ActiveXObject(getControlPrefix() + ".XmlDom");
      }
   }
   catch (ex) { alert('XmlDocument.create error: '+ex); }
   return null;
};}
/* FILE:FreeanceWeb/Common/lib/contrib/cssQuery.js */ if(!window.freeance_loaded_js['bfecf67eee7ff1ce5282ad6d28016e6a']){window.freeance_loaded_js['bfecf67eee7ff1ce5282ad6d28016e6a']=1;
/*
	cssQuery, version 2.0.2 (2005-08-19)
	Copyright: 2004-2005, Dean Edwards (http://dean.edwards.name/)
	License: http://creativecommons.org/licenses/LGPL/2.1/
*/

// the following functions allow querying of the DOM using CSS selectors
var cssQuery = function() {
var version = "2.0.2";

// -----------------------------------------------------------------------
// main query function
// -----------------------------------------------------------------------

var $COMMA = /\s*,\s*/;
var cssQuery = function($selector, $$from) {
try {
	var $match = [];
	var $useCache = arguments.callee.caching && !$$from;
	var $base = ($$from) ? ($$from.constructor == Array) ? $$from : [$$from] : [document];
	// process comma separated selectors
	var $$selectors = parseSelector($selector).split($COMMA), i;
	for (i = 0; i < $$selectors.length; i++) {
		// convert the selector to a stream
		$selector = _toStream($$selectors[i]);
		// faster chop if it starts with id (MSIE only)
		if (isMSIE && $selector.slice(0, 3).join("") == " *#") {
			$selector = $selector.slice(2);
			$$from = _msie_selectById([], $base, $selector[1]);
		} else $$from = $base;
		// process the stream
		var j = 0, $token, $filter, $arguments, $cacheSelector = "";
		while (j < $selector.length) {
			$token = $selector[j++];
			$filter = $selector[j++];
			$cacheSelector += $token + $filter;
			// some pseudo-classes allow arguments to be passed
			//  e.g. nth-child(even)
			$arguments = "";
			if ($selector[j] == "(") {
				while ($selector[j++] != ")" && j < $selector.length) {
					$arguments += $selector[j];
				}
				$arguments = $arguments.slice(0, -1);
				$cacheSelector += "(" + $arguments + ")";
			}
			// process a token/filter pair use cached results if possible
			$$from = ($useCache && cache[$cacheSelector]) ?
				cache[$cacheSelector] : select($$from, $token, $filter, $arguments);
			if ($useCache) cache[$cacheSelector] = $$from;
		}
		$match = $match.concat($$from);
	}
	delete cssQuery.error;
	return $match;
} catch ($error) {
	cssQuery.error = $error;
	return [];
}};

// -----------------------------------------------------------------------
// public interface
// -----------------------------------------------------------------------

cssQuery.toString = function() {
	return "function cssQuery() {\n  [version " + version + "]\n}";
};

// caching
var cache = {};
cssQuery.caching = false;
cssQuery.clearCache = function($selector) {
	if ($selector) {
		$selector = _toStream($selector).join("");
		delete cache[$selector];
	} else cache = {};
};

// allow extensions
var modules = {};
var loaded = false;
cssQuery.addModule = function($name, $script) {
	if (loaded) eval("$script=" + String($script));
	modules[$name] = new $script();;
};

// hackery
cssQuery.valueOf = function($code) {
	return $code ? eval($code) : this;
};

// -----------------------------------------------------------------------
// declarations
// -----------------------------------------------------------------------

var selectors = {};
var pseudoClasses = {};
// a safari bug means that these have to be declared here
var AttributeSelector = {match: /\[([\w-]+(\|[\w-]+)?)\s*(\W?=)?\s*([^\]]*)\]/};
var attributeSelectors = [];

// -----------------------------------------------------------------------
// selectors
// -----------------------------------------------------------------------

// descendant selector
selectors[" "] = function($results, $from, $tagName, $namespace) {
	// loop through current selection
	var $element, i, j;
	for (i = 0; i < $from.length; i++) {
		// get descendants
		var $subset = getElementsByTagName($from[i], $tagName, $namespace);
		// loop through descendants and add to results selection
		for (j = 0; ($element = $subset[j]); j++) {
			if (thisElement($element) && compareNamespace($element, $namespace))
				$results.push($element);
		}
	}
};

// ID selector
selectors["#"] = function($results, $from, $id) {
	// loop through current selection and check ID
	var $element, j;
	for (j = 0; ($element = $from[j]); j++) if ($element.id == $id) $results.push($element);
};

// class selector
selectors["."] = function($results, $from, $className) {
	// create a RegExp version of the class
	$className = new RegExp("(^|\\s)" + $className + "(\\s|$)");
	// loop through current selection and check class
	var $element, i;
	for (i = 0; ($element = $from[i]); i++)
		if ($className.test($element.className)) $results.push($element);
};

// pseudo-class selector
selectors[":"] = function($results, $from, $pseudoClass, $arguments) {
	// retrieve the cssQuery pseudo-class function
	var $test = pseudoClasses[$pseudoClass], $element, i;
	// loop through current selection and apply pseudo-class filter
	if ($test) for (i = 0; ($element = $from[i]); i++)
		// if the cssQuery pseudo-class function returns "true" add the element
		if ($test($element, $arguments)) $results.push($element);
};

// -----------------------------------------------------------------------
// pseudo-classes
// -----------------------------------------------------------------------

pseudoClasses["link"] = function($element) {
	var $document = getDocument($element);
	if ($document.links) for (var i = 0; i < $document.links.length; i++) {
		if ($document.links[i] == $element) return true;
	}
};

pseudoClasses["visited"] = function($element) {
	// can't do this without jiggery-pokery
};

// -----------------------------------------------------------------------
// DOM traversal
// -----------------------------------------------------------------------

// IE5/6 includes comments (LOL) in it's elements collections.
// so we have to check for this. the test is tagName != "!". LOL (again).
var thisElement = function($element) {
	return ($element && $element.nodeType == 1 && $element.tagName != "!") ? $element : null;
};

// return the previous element to the supplied element
//  previousSibling is not good enough as it might return a text or comment node
var previousElementSibling = function($element) {
	while ($element && ($element = $element.previousSibling) && !thisElement($element)) continue;
	return $element;
};

// return the next element to the supplied element
var nextElementSibling = function($element) {
	while ($element && ($element = $element.nextSibling) && !thisElement($element)) continue;
	return $element;
};

// return the first child ELEMENT of an element
//  NOT the first child node (though they may be the same thing)
var firstElementChild = function($element) {
	return thisElement($element.firstChild) || nextElementSibling($element.firstChild);
};

var lastElementChild = function($element) {
	return thisElement($element.lastChild) || previousElementSibling($element.lastChild);
};

// return child elements of an element (not child nodes)
var childElements = function($element) {
	var $childElements = [];
	$element = firstElementChild($element);
	while ($element) {
		$childElements.push($element);
		$element = nextElementSibling($element);
	}
	return $childElements;
};

// -----------------------------------------------------------------------
// browser compatibility
// -----------------------------------------------------------------------

// all of the functions in this section can be overwritten. the default
//  configuration is for IE. The functions below reflect this. standard
//  methods are included in a separate module. It would probably be better
//  the other way round of course but this makes it easier to keep IE7 trim.

var isMSIE = true;

var isXML = function($element) {
	var $document = getDocument($element);
	return (typeof $document.mimeType == "unknown") ?
		/\.xml$/i.test($document.URL) :
		Boolean($document.mimeType == "XML Document");
};

// return the element's containing document
var getDocument = function($element) {
	return $element.ownerDocument || $element.document;
};

var getElementsByTagName = function($element, $tagName) {
	return ($tagName == "*" && $element.all) ? $element.all : $element.getElementsByTagName($tagName);
};

var compareTagName = function($element, $tagName, $namespace) {
	if ($tagName == "*") return thisElement($element);
	if (!compareNamespace($element, $namespace)) return false;
	if (!isXML($element)) $tagName = $tagName.toUpperCase();
	return $element.tagName == $tagName;
};

var compareNamespace = function($element, $namespace) {
	return !$namespace || ($namespace == "*") || ($element.scopeName == $namespace);
};

var getTextContent = function($element) {
	return $element.innerText;
};

function _msie_selectById($results, $from, id) {
	var $match, i, j;
	for (i = 0; i < $from.length; i++) {
		if ($match = $from[i].all.item(id)) {
			if ($match.id == id) $results.push($match);
			else if ($match.length != null) {
				for (j = 0; j < $match.length; j++) {
					if ($match[j].id == id) $results.push($match[j]);
				}
			}
		}
	}
	return $results;
};

// for IE5.0
if (![].push) Array.prototype.push = function() {
	for (var i = 0; i < arguments.length; i++) {
		this[this.length] = arguments[i];
	}
	return this.length;
};

// -----------------------------------------------------------------------
// query support
// -----------------------------------------------------------------------

// select a set of matching elements.
// "from" is an array of elements.
// "token" is a character representing the type of filter
//  e.g. ">" means child selector
// "filter" represents the tag name, id or class name that is being selected
// the function returns an array of matching elements
var $NAMESPACE = /\|/;
function select($$from, $token, $filter, $arguments) {
	if ($NAMESPACE.test($filter)) {
		$filter = $filter.split($NAMESPACE);
		$arguments = $filter[0];
		$filter = $filter[1];
	}
	var $results = [];
	if (selectors[$token]) {
		selectors[$token]($results, $$from, $filter, $arguments);
	}
	return $results;
};

// -----------------------------------------------------------------------
// parsing
// -----------------------------------------------------------------------

// convert css selectors to a stream of tokens and filters
//  it's not a real stream. it's just an array of strings.
var $STANDARD_SELECT = /^[^\s>+~]/;
var $$STREAM = /[\s#.:>+~()@]|[^\s#.:>+~()@]+/g;
function _toStream($selector) {
	if ($STANDARD_SELECT.test($selector)) $selector = " " + $selector;
	return $selector.match($$STREAM) || [];
};

var $WHITESPACE = /\s*([\s>+~(),]|^|$)\s*/g;
var $IMPLIED_ALL = /([\s>+~,]|[^(]\+|^)([#.:@])/g;
var parseSelector = function($selector) {
	return $selector
	// trim whitespace
	.replace($WHITESPACE, "$1")
	// e.g. ".class1" --> "*.class1"
	.replace($IMPLIED_ALL, "$1*$2");
};

var Quote = {
	toString: function() {return "'"},
	match: /^('[^']*')|("[^"]*")$/,
	test: function($string) {
		return this.match.test($string);
	},
	add: function($string) {
		return this.test($string) ? $string : this + $string + this;
	},
	remove: function($string) {
		return this.test($string) ? $string.slice(1, -1) : $string;
	}
};

var getText = function($text) {
	return Quote.remove($text);
};

var $ESCAPE = /([\/()[\]?{}|*+-])/g;
function regEscape($string) {
	return $string.replace($ESCAPE, "\\$1");
};

// -----------------------------------------------------------------------
// modules
// -----------------------------------------------------------------------

// -------- >>      insert modules here for packaging       << -------- \\

loaded = true;

// -----------------------------------------------------------------------
// return the query function
// -----------------------------------------------------------------------

return cssQuery;

}(); /* cssQuery */}
/* FILE:FreeanceWeb/Common/lib/Language/babelfish.js */ if(!window.freeance_loaded_js['b1eb9e4b20480bfb6e35a416a66a4800']){window.freeance_loaded_js['b1eb9e4b20480bfb6e35a416a66a4800']=1;
/*
  Babelfish - A simple Javascript language translator/dictionary.
  Copyright (C) 2004 James White
  License: LGPL
  Notes:
    - Currently only tested with English and Latvian languages.
    - Requires the cssQuery function at http://dean.edwards.name/my/cssQuery.js.html
  
  This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License
  as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version.
  This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
  You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to the 
  Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/

function Babelfish()
{
  this.activeLanguage = '';
  this.languages = Array();
  
  /*** Language Maint ***/
  this.addLanguage = function(langName,langVocab)
  {
    langName = langName.toUpperCase();
    this.languages[langName] = langVocab;
  };
  this.hasLanguage = function(langName)
  {
    langName = langName.toUpperCase();
    if(this.languages[langName]) return(true); else return(false);
  };
  this.removeLanguage = function(langName)
  {
    langName = langName.toUpperCase();
    if (this.languages[langName])
      delete(this.languages[langName]);
  };
  this.getLanguage = function(langName)
  {
    langName = langName.toUpperCase();
    if(this.languages[langName]) return(this.languages[langName]); else return(false);
  };
  /*** Active Language ***/
  this.setActiveLanguage = function(langName)
  {
    this.activeLanguage = langName.toUpperCase();
  };
  this.getActiveLanguage = function()
  {
    return(this.activeLanguage);
  };
  /*** Translate ***/
  this.translate = function(params)
  {
    if ((typeof(params) != 'array') && (typeof(params) != 'object'))
    {
      params = Array();
      params.langName = this.getActiveLanguage();
    };
    params.langName = params.langName.toUpperCase();
    if (this.hasLanguage(params.langName)==false) { return(false); };
    if (!params.translateSource) params.translateSource = document.body;
    if (!params.matchMethod) params.matchMethod = "[translate_word]";
    var tags = cssQuery(params.matchMethod,params.translateSource);
    for(var tagidx in tags)
    {
      if(tagidx=='toJSONString')continue;
      var word=tags[tagidx].attributes.translate_word.value;  // faster, less safe?
      if (this.languages[params.langName][word])
        tags[tagidx].innerHTML = this.languages[params.langName][word];
    };
    return(true);
  };
  /*** TranslateWord ***/
  this.translateWord = function(params)
  {
    if ((typeof(params) != 'array') && (typeof(params) != 'object'))
      if (typeof(params) == 'string')
      {
        var word = params;
        params = Array();
        params.langName = this.getActiveLanguage();
        params.word = word;
      }
      else return(false);
    params.langName = params.langName.toUpperCase();
    if (this.hasLanguage(params.langName)==false) { return(false); };
    if (typeof(params['word']) != 'string') return(false);
    if (this.languages[params.langName][params.word])
      return(this.languages[params.langName][params.word]);
    return(params.word);
  };
  /*** Word Lookup ***/
  this.lookup = function(langName,word)
  {
    langName = langName.toUpperCase();
    //word = word.toLowerCase();
    if (this.languages[langName])
      if (this.languages[langName][word])
        return(this.languages[langName][word]);
    return('');
  };
};}
/* FILE:FreeanceWeb/Common/lib/util.js */ if(!window.freeance_loaded_js['0453cc8ac18d3694c271b6bda1261675']){window.freeance_loaded_js['0453cc8ac18d3694c271b6bda1261675']=1;
String.replaceStr = function(orig,lookfor,replacewith,ignorecase)  // JPW::Jan 6, 2003
{
  // QUESTION: what is the point of this function?
  //alert('String.replaceStr');
  var str = new String();
  str += orig;
  var type = 'g';
  if (ignorecase)
    type += 'i';
  var re = new RegExp (lookfor, type);
  return(str.replace(re,replacewith));
};  

stripWhitespace = String.prototype.stripWhitespace = function()
{
  if ((arguments.length>0) && (typeof(arguments[0])=='object') && (arguments[0] == null)) arguments[0] = '';
  return ((arguments.length>0)?((typeof(arguments[0])=='string')?arguments[0]:arguments[0].toString()):this).replace(/[\s\t\r\n]/g,'');
};

escapeHTML = String.prototype.escapeHTML = function()
{
  if ((arguments.length>0) && (typeof(arguments[0])=='object') && (arguments[0] == null)) arguments[0] = '';
  return ((arguments.length>0)?((typeof(arguments[0])=='string')?arguments[0]:arguments[0].toString()):this).replace(/&/g,'&amp;').replace(/</g,'&lt;').replace(/>/g,'&gt;').replace(/\"/g,'&quot;');
};

unescapeHTML = String.prototype.unescapeHTML = function()
{
  if ((arguments.length>0) && (typeof(arguments[0])=='object') && (arguments[0] == null)) arguments[0] = '';
  return ((arguments.length>0)?((typeof(arguments[0])=='string')?arguments[0]:arguments[0].toString()):this).replace(/&lt;/g,'<').replace(/&gt;/g,'>').replace(/&quot;/g,'"').replace(/&amp;/g,'&');
};

stripQuotes = String.prototype.stripQuotes = function()
{
  if ((arguments.length>0) && (typeof(arguments[0])=='object') && (arguments[0] == null)) arguments[0] = '';
  return ((arguments.length>0)?((typeof(arguments[0])=='string')?arguments[0]:arguments[0].toString()):this).replace(/['"]/g,'');
};

escapeQuotes = String.prototype.escapeQuotes = function()
{
  if ((arguments.length>0) && (typeof(arguments[0])=='object') && (arguments[0] == null)) arguments[0] = '';
  var newString = ((arguments.length>0)?((typeof(arguments[0])=='string')?arguments[0]:arguments[0].toString()):this);
  newString = newString.replace(/\\/g,'\\\\');
  newString = String.replaceStr(newString,'\'','\\\'',false);
  newString = String.replaceStr(newString,'"','&quot;',false);
  return newString;
};

unescapeQuotes = String.prototype.unescapeQuotes = function()
{
  if ((arguments.length>0) && (typeof(arguments[0])=='object') && (arguments[0] == null)) arguments[0] = '';
  var newString = ((arguments.length>0)?((typeof(arguments[0])=='string')?arguments[0]:arguments[0].toString()):this);
  newString = newString.replace(/\\\\/g,'\\');
  newString = String.replaceStr(newString,'\\\'','\'',false);
  newString = String.replaceStr(newString,'&quot;','"',false);
  return newString;
};

String.prototype.ltrim = function()
{
  return this.replace(/^\s+/,'');
};

String.prototype.rtrim = function()
{
  return this.replace(/\s+$/,'');
};

String.prototype.strtrim = function()
{
  return this.replace(/^\s+/,'').replace(/\s+$/,'');
};

function getArrayLength (arr)
{
  /* since in some instances involving delete, JS seems to get it wrong */
  var count = 0;
  for(var idx in arr){
    if(idx=='toJSONString')continue;
    if ((typeof(arr[idx]) != 'undefined') && (arr[idx]!=null))
      count++;
  }
  return(count);
};

/* TODO: prevent recursion */
function describeObject(stringPrefix, object)
{
  var totalString = '';
  var lineTerminator = ((arguments.length >= 3)?(arguments[2]):("<br>"));
  var depth = ((arguments.length >= 4)?(arguments[3]):(-1));
  var objectType = typeof(object);
  if (objectType.toLowerCase() == "object")
    for (var i in object)
    {
      if(i=='toJSONString')continue;
      var currentPrefix = stringPrefix+'['+i+']';
      if (depth>0)
        totalString = totalString + describeObject(currentPrefix,object[i],lineTerminator,depth-1);
      else
        if (depth==-1)
          totalString = totalString + describeObject(currentPrefix,object[i],lineTerminator,-1);
    }
  else
    totalString = totalString + stringPrefix+' = ' + object + lineTerminator;
  return totalString;  
};

function DataTypeOf(o){
  // identifies the data type
  var type = typeof(o);
  type = type.toLowerCase();
  switch(type){
    case "number":
      if (Math.round(o) == o) type = "i4";
      else type = "double";
      break;
    case "object":
      var con = o.constructor;
      if (con == Date) type = "date";
      else if (con == Array) type = "array";
      else type = "struct";
      break;
  }
  return type;
};

function duplicateNodeTreeEmbeddingStyles(theNode)
{
  var newNode = theNode.cloneNode(false);
  if(theNode.nodeType == 1)  // copy the "calculated" style
  {
    if(theNode.getAttribute('action_button'))
      return(null);
    if(theNode.currentStyle)
    {
      for(var attribName in theNode.currentStyle)
      {
        if(attribName=='toJSONString')continue;
        var attribValue = theNode.currentStyle[attribName];
        if ((attribValue != '') && (attribValue != 'undefined') && (attribValue != 'none') && (attribValue != 'normal') && (attribValue != 'auto'))
          newNode.style[attribName] = attribValue;
      }
    }
    else if (window.getComputedStyle)
    {
      var newStyles = window.getComputedStyle(theNode,null);
      for (var lcv=0;lcv < newStyles.length;lcv++)
      {
        var attribName = newStyles.item(lcv);
        var attribValue = newStyles.getPropertyValue(attribName);
        if (attribValue.indexOf('-moz') >= 0) {} else
        if ((attribValue != '') && (attribValue != 'undefined') && (attribValue != 'none') && (attribValue != 'normal') && (attribValue != 'auto'))
          newNode.style.setProperty(attribName,attribValue,null);
      }
    }
  }
  for(var lcv=0;lcv < theNode.childNodes.length;lcv++)
  {
    var cNode = duplicateNodeTreeEmbeddingStyles(theNode.childNodes[lcv]);
    if(cNode != null)
      newNode.appendChild(cNode);
  }
  return(newNode);
};

function duplicateNodeTreeEmbeddingStylesSubset(theNode)
{
  var newNode = theNode.cloneNode(false);
  if(theNode.nodeType == 1)  // copy the "calculated" style
  {
    if(theNode.getAttribute('action_button'))
      return(null);
    try { newNode.removeAttribute('class'); newNode.removeAttribute('className'); } catch (e) { }
    if(theNode.currentStyle)
    {
      var copyAttribs = Array('margin','borderColor','borderStyle','borderWidth','backgroundColor','color','fontStyle','fontFamily','fontSize','fontWeight','padding','width','height','textAlign','textDecoration','cursor','visibility');
      for(var lcv=0;lcv < copyAttribs.length;lcv++)
      {
        var attribName = copyAttribs[lcv];
        var attribValue = theNode.currentStyle.getAttribute(attribName);
        if ((attribValue != null) && (attribValue != '') && (attribValue != 'undefined') && (attribValue != 'none') && (attribValue != 'normal') && (attribValue != 'auto') && (attribValue != 'transparent') && (attribValue != 'visible') && (attribValue != 'inherit'))
        try{ newNode.style[attribName] = attribValue; } catch(e){}
      }
    }
    else if (window.getComputedStyle)
    {
      var copyAttribs = Array('margin','border-bottom-color','border-bottom-width','border-bottom-style','border-top-color','border-top-width','border-top-style','border-left-color','border-left-width','border-left-style','border-right-color','border-right-width','border-right-style','background-color','color','font-family','font-size','font-weight','padding','width','height','text-align','text-decoration','cursor','visibility');
      var newStyles = window.getComputedStyle(theNode,null);
      for (var lcv=0;lcv < copyAttribs.length;lcv++)
      {
        var attribName = copyAttribs[lcv];
        var attribValue = newStyles.getPropertyValue(attribName);
        if ((attribValue != null) && (attribValue != '') && (attribValue != 'undefined') && (attribValue != 'none') && (attribValue != 'normal') && (attribValue != 'auto') && (attribValue != 'transparent') && (attribValue != 'visible') && (attribValue != 'inherit'))
          newNode.style.setProperty(attribName,attribValue,null);
      }
    }
  }
  for(var lcv=0;lcv < theNode.childNodes.length;lcv++)
  {
    var cNode = duplicateNodeTreeEmbeddingStylesSubset(theNode.childNodes[lcv]);
    if(cNode != null)
      newNode.appendChild(cNode);
  }
  return(newNode);
};

document.addStylesheet = function (url)
{
  var callback=(arguments.length>1)?arguments[1]:null;
  var ele = document.createElement('LINK');
  ele.setAttribute('type','text/css');
  ele.setAttribute('href',url);
  ele.setAttribute('rel','stylesheet');
  ele.setAttribute('disabled','false');
  if(typeof(callback)=='function'){
    if(ele.readyState==null){
      ele.addEventListener("load",function(){callback(url)},false);
    }else{
      ele.onreadystatechange=function(){
        if((ele.readyState=='loaded')||(ele.readyState=='complete')){
          setTimeout("",0);
          callback(url);
        }
      }
    };
  };
  document.getElementsByTagName('head')[0].appendChild(ele);
  ele.disabled = false;  //IE fix
};

function cloneObject(originalObject)
{
  /* TODO: prevent recursion */
  /* TODO:  VERIFY TYPE CASTING */
  if (originalObject == null)
    newObject = null;
  else
  {
    var newObject = null;
    var objectType = typeof(originalObject);
    objectType = objectType.toLowerCase();
    if (objectType == "object")
    {
      var con = originalObject.constructor;
      if (con == Date)
        objectType = "date";
      else 
        if (con == Array)
          objectType = "array";
        else
          type="object";
    }
    switch (objectType)
    {
      case "object":
        newObject = new Object;
        for (var i in originalObject){
          if(i=='toJSONString')continue;
          try{
            newObject[i] = cloneObject(originalObject[i]);
          }
          catch(e){
            //probably tried to descend to a system object
            dprintf('Warning: attribute "'+i+'" could not be duplicated by cloneNode.',false,"logWarning");
            newObject[i]=null;
          }
        }
        break;
      case "array":
        newObject = new Array;
        for (var i=0; i<originalObject.length; i++)
          newObject[i] = cloneObject(originalObject[i]);
        break;
      default:
        newObject = originalObject;
    }
  }
  return newObject;
};

var CSSClass = {};  // Create our namespace object
// Return true if element e is a member of the class c; false otherwise
CSSClass.is = function(e, c) {
    if (typeof e == "string") e = document.getElementById(e); // element id

    // Before doing a regexp search, optimize for a couple of common cases.
    var classes = e.className;
    if (!classes) return false;    // Not a member of any classes
    if (classes == c) return true; // Member of just this one class

    // Otherwise, use a regular expression to search for c as a word by itself
    // \b in a regular expression requires a match at a word boundary.
    return e.className.search("\\b" + c + "\\b") != -1;
};

// Add class c to the className of element e if it is not already there.
CSSClass.add = function(e, c) {
    if (typeof e == "string") e = document.getElementById(e); // element id
    if (CSSClass.is(e, c)) return; // If already a member, do nothing
    if (e.className) c = " " + c;  // Whitespace separator, if needed
    e.className += c;              // Append the new class to the end
};

// Remove all occurrences (if any) of class c from the className of element e
CSSClass.remove = function(e, c) {
    if (typeof e == "string") e = document.getElementById(e); // element id
    // Search the className for all occurrences of c and replace with "".
    // \s* matches any number of whitespace characters.
    // "g" makes the regular expression match any number of occurrences
    e.className = e.className.replace(new RegExp("\\b"+ c+"\\b\\s*", "g"), "");
};

CSSClass.set=function(elementId,newClass)//explicitly set class of element, overriding all existing data
{
  var elementReference = ((typeof(elementId)=='object')?(elementId):(document.getElementById(elementId)));
  while((elementReference != null) && (elementReference.nodeName == '#text'))
     elementReference = elementReference.parentNode;
  if (elementReference != null)
    elementReference.className = newClass;
};

setClass=CSSClass.set;  //for backwards compatibility

function convertDistance(dist,srcUnit,destUnit){
	if (srcUnit == destUnit){
		return dist;
	}
	
	srcUnitID = convertUnitToID(srcUnit);
	destUnitID = convertUnitToID(destUnit);
	var resp = freeance_request(null,'UnitConv.Convert',srcUnitID,destUnitID,dist);
	
	if(resp.XMLRPC_FAULT){
		alert('Fault '+clientReply.XMLRPC_FAULT_CODE+': '+clientReply.XMLRPC_FAULT_MESSAGE);
		return dist;
	}
	
	return resp.data;
};

//for finding old format of units
function convertUnitToID(unitName){
	switch (unitName.toLowerCase()){
		case 'm':
			return 2;
		case 'km':
			return 12;
		case 'ft':
			return 3;
		case 'yd':
			return 40;
		case 'mi':
			return 11;
		case 'mm':
			return 105;
		case 'in':
			return 106;
		case 'cm':
			return 107;
		case 'pt':
		case 'point':
			return 108;
	}
	return unitName; //fallback for newer style
}

Freeance_Communication=function(){};
Freeance_Communication.javascript_load=function(scriptURL /*,callbackFunction*/){
  //dprintf('loadJavaScript('+scriptURL+')',true,'logNotice');
  if(document.jsload_setwait)document.jsload_setwait(true);
  var callback=(arguments.length>1)?arguments[1]:null;
  var ele=document.createElement('SCRIPT');
  if(ele.readyState==null){
    ele.addEventListener("load",function(e){
      if(document.jsload_setwait)document.jsload_setwait(false);
      if(typeof(callback)=='function')callback()
      },false);
  }else{
    ele.onreadystatechange=function(){
      if((ele.readyState=='loaded')||(ele.readyState=='complete')){
        if(document.jsload_setwait)document.jsload_setwait(false);
        setTimeout("",0);
        if(typeof(callback)=='function')callback();
      }
    }
  };
  ele.setAttribute('type','text/javascript');
  ele.setAttribute('language','JavaScript');
  ele.setAttribute('src',scriptURL);
  document.getElementsByTagName('head')[0].appendChild(ele);
  return true;
};
loadJavaScript=Freeance_Communication.javascript_load;

Freeance_Communication.xmlrpc_request = function(/*Callback,function_name,param[1],...param[n]*/)
{
  var Callback = arguments[0];
  var functionName = arguments[1];
  var returnValue = null;
  var thisRequest = new XMLRPCMessage(functionName);
  for (lcv = 2; lcv < arguments.length; lcv++)
    thisRequest.addParameter(arguments[lcv]);
  var thisRequestDoc = XmlDocument.create();
  thisRequestDoc.loadXML(thisRequest.xml());
  if (Callback)
    returnValue = XmlHttp.postAsync_(FREEANCE_XMLRPC_URL,thisRequestDoc,function(xmlrpc_response){Callback(getXMLRPCResponseObject(xmlrpc_response));});
  else
    returnValue = getXMLRPCResponseObject(XmlHttp.postSync(FREEANCE_XMLRPC_URL,thisRequestDoc));
  return returnValue;
};
freeance_request = Freeance_Communication.xmlrpc_request;

Freeance_Error = function(){};
Freeance_Error.is_error = function(data){
  if (data===null) return true;
  if (data===undefined) return true;
  if (data['XMLRPC_FAULT']) return true;
  if (data['FREEANCE_FAULT'])return true;
  if (data['GUILIB_FAULT'])return true;
  return false;
};
Freeance_Error.get_message=function(data){
  if (data===null) return 'Value is null';
  if (data===undefined) return 'Value is undefined';
  if (data['XMLRPC_FAULT']) return data['XMLRPC_FAULT_MESSAGE'];
  if (data['FREEANCE_FAULT']) return data['FREEANCE_FAULT_MESSAGE'];
  if (data['GUILIB_FAULT']) return data['GUILIB_FAULT_MESSAGE'];
  return null;
};
Freeance_Error.get_code=function(data){
  if (data===null) return -1001;
  if (data===undefined) return -1002;
  if (data['XMLRPC_FAULT']) return data['XMLRPC_FAULT_CODE'];
  if (data['FREEANCE_FAULT']) return data['FREEANCE_FAULT_CODE'];
  if (data['GUILIB_FAULT']) return data['GUILIB_FAULT_CODE'];
  return null;
};
Freeance_Error.xmldoc_is_valid=function(xmlDoc)
{ 
  try
  {
    if(xmlDoc == null) 
      return false;
    var xmlstr = (typeof(xmlDoc.xml)=='function')?xmlDoc.xml():xmlDoc.xml;
    if(xmlstr == '')
      return false;
    if(xmlDoc.documentElement.nodeName == 'parsererror')
      return false;
    return true;
  }
  catch(e)
  {
    return false;
  }
};

Freeance_Event = function(){};
Freeance_Event.add = function(ele,type,fcn)
{
  type=type.toLowerCase();
  var cap = (arguments.length>3)?arguments[3]:false;
  if (!ele.FREEANCE_EVENTS)
    ele.FREEANCE_EVENTS = [];
  ele.FREEANCE_EVENTS.push({evt:type,fcn:fcn});
  if(ele.addEventListener) 
    ele.addEventListener(type,fcn,cap);
  else 
    if(ele.attachEvent)
      ele.attachEvent('on'+type,fcn);
    else
      return {FREEANCE_FAULT:true,FREEANCE_FAULT_CODE:-1003,FREEANCE_FAULT_MESSAGE:'Browser does not support dynamic addition of events to elements'};
  return true;
};
Freeance_Event.remove = function(ele,type,fcn)
{
  type=type.toLowerCase();
  var cap = (arguments.length>3)?arguments[3]:false;
  if (ele.FREEANCE_EVENTS)
  {
    for (var i=0;i<ele.FREEANCE_EVENTS.length;i++)
      if (ele.FREEANCE_EVENTS[i])
        if((ele.FREEANCE_EVENTS[i]['evt']==type)&&(ele.FREEANCE_EVENTS[i]['fcn']==fcn))
          ele.FREEANCE_EVENTS[i] = null;
  }
  if(ele.removeEventListener) 
    ele.removeEventListener(type,fcn,cap);
  else 
    if(ele.detachEvent)
      ele.detachEvent('on'+type,fcn);
    else
      return {FREEANCE_FAULT:true,FREEANCE_FAULT_CODE:-1003,FREEANCE_FAULT_MESSAGE:'Browser does not support dynamic addition of events to elements'};
  return true;
};
Freeance_Event.remove_all = function(ele)
{
  if (ele.FREEANCE_EVENTS!=null)
  {
    for (var i=0;i<ele.FREEANCE_EVENTS.length;i++){
      if(ele.removeEventListener) 
        ele.removeEventListener(ele.FREEANCE_EVENTS[i]['evt'],ele.FREEANCE_EVENTS[i]['fcn'],ele.FREEANCE_EVENTS[i]['cap']);
      else 
        if(ele.detachEvent)
          ele.detachEvent('on'+ele.FREEANCE_EVENTS[i]['evt'],ele.FREEANCE_EVENTS[i]['fcn']);
        else
          return {FREEANCE_FAULT:true,FREEANCE_FAULT_CODE:-1003,FREEANCE_FAULT_MESSAGE:'Browser does not support dynamic addition of events to elements'};
    }
    ele.FREEANCE_EVENTS=null;
  }
  return true;
};

SQLWhereBuilder = new (function ()
{
	var $_this = this;
  this.noQuotes = ["",""];
  this.singleQuotes = ["'","'"];
  
  this._combine = function(field,operator,quotes,value)
  {
    if(quotes == this.singleQuotes)
      var str = '('+field+' '+operator+' '+quotes[0]+value.replace("'","''")+quotes[1]+')';
    else
      var str = '('+field+' '+operator+' '+quotes[0]+value+quotes[1]+')';
    return(str);
  };
  
  this.stmt_and = function(stmts)
  {
    return(stmts.join(' AND '));
  };
  this.stmt_or = function(stmts)
  {
    return(stmts.join(' OR '));
  };
  this.stmt_compare = function(field,operator,quotes,value)
  {
    if (typeof(quotes) == 'boolean')
      quotes = (quotes)?this.singleQuotes:this.noQuotes;
    if (typeof(value) != 'object')  // simple string,quotes,int|float|string
      return(this._combine(field,operator,quotes,value));
    var results = new Array();
    if (typeof(field) != 'object')  // version is string,qutoes,array
    {
      for(var lcv=0;lcv < value.length;lcv++)
        results.push(this._combine(field,operator,quotes,value[lcv]));
    }
    else  // must have parallel field/value arrays:  array,quotes,array
    {
      for(var lcv=0;lcv < field.length;lcv++)
        results.push(this._combine(field[lcv],operator,quotes,value[lcv]));
    }
    return(results);
  };
});}
/* FILE:FreeanceWeb/Common/lib/contrib/x/x.js */ if(!window.freeance_loaded_js['b547f427cdf2f9c4b700b97f544b29eb']){window.freeance_loaded_js['b547f427cdf2f9c4b700b97f544b29eb']=1;
/* x.js compiled from X 4.0 with XC 0.27b. Distributed by GNU LGPL. For copyrights, license, documentation and more visit Cross-Browser.com */
// globals, Copyright 2001-2005 Michael Foster (Cross-Browser.com)
// Part of X, a Cross-Browser Javascript Library, Distributed under the terms of the GNU LGPL

var xOp7Up,xOp6Dn,xIE4Up,xIE4,xIE5,xNN4,xUA=navigator.userAgent.toLowerCase();
if(window.opera){
  var i=xUA.indexOf('opera');
  if(i!=-1){
    var v=parseInt(xUA.charAt(i+6));
    xOp7Up=v>=7;
    xOp6Dn=v<7;
  }
}
else if(navigator.vendor!='KDE' && document.all && xUA.indexOf('msie')!=-1){
  xIE4Up=parseFloat(navigator.appVersion)>=4;
  xIE4=xUA.indexOf('msie 4')!=-1;
  xIE5=xUA.indexOf('msie 5')!=-1;
}
else if(document.layers){xNN4=true;}
xMac=xUA.indexOf('mac')!=-1;
// xAddEventListener, Copyright 2001-2005 Michael Foster (Cross-Browser.com)
// Part of X, a Cross-Browser Javascript Library, Distributed under the terms of the GNU LGPL
                                                      
function xAddEventListener(e,eT,eL,cap)
{
  if(!(e=xGetElementById(e))) return;
  eT=eT.toLowerCase();
  if((!xIE4Up && !xOp7Up) && e==window) {
    if(eT=='resize') { window.xPCW=xClientWidth(); window.xPCH=xClientHeight(); window.xREL=eL; xResizeEvent(); return; }
    if(eT=='scroll') { window.xPSL=xScrollLeft(); window.xPST=xScrollTop(); window.xSEL=eL; xScrollEvent(); return; }
  }
  var eh='e.on'+eT+'=eL';
  if(e.addEventListener)
  {
    //MTH: fix inappropriate lowercase conversion
    if(eT == 'dommousescroll')
      eT = 'DOMMouseScroll';
    e.addEventListener(eT,eL,cap);
  }
  else if(e.attachEvent) e.attachEvent('on'+eT,eL);
  else eval(eh);
}
// called only from the above
function xResizeEvent()
{
  if (window.xREL) setTimeout('xResizeEvent()', 250);
  var cw = xClientWidth(), ch = xClientHeight();
  if (window.xPCW != cw || window.xPCH != ch) { window.xPCW = cw; window.xPCH = ch; if (window.xREL) window.xREL(); }
}
function xScrollEvent()
{
  if (window.xSEL) setTimeout('xScrollEvent()', 250);
  var sl = xScrollLeft(), st = xScrollTop();
  if (window.xPSL != sl || window.xPST != st) { window.xPSL = sl; window.xPST = st; if (window.xSEL) window.xSEL(); }
}
// xAppendChild, Copyright 2001-2005 Michael Foster (Cross-Browser.com)
// Part of X, a Cross-Browser Javascript Library, Distributed under the terms of the GNU LGPL

function xAppendChild(oParent, oChild)
{
  if (oParent.appendChild) return oParent.appendChild(oChild);
  else return null;
}
// xBackground, Copyright 2001-2005 Michael Foster (Cross-Browser.com)
// Part of X, a Cross-Browser Javascript Library, Distributed under the terms of the GNU LGPL

function xBackground(e,c,i)
{
  if(!(e=xGetElementById(e))) return '';
  var bg='';
  if(e.style) {
    if(xStr(c)) {
      if(!xOp6Dn) e.style.backgroundColor=c;
      else e.style.background=c;
    }
    if(xStr(i)) e.style.backgroundImage=(i!='')? 'url('+i+')' : null;
    if(!xOp6Dn) bg=e.style.backgroundColor;
    else bg=e.style.background;
  }
  return bg;
}
// xBar, Copyright 2003,2004,2005 Michael Foster (Cross-Browser.com)
// Part of X, a Cross-Browser Javascript Library, Distributed under the terms of the GNU LGPL

// Bar-Graph Object

function xBar(dir,                // direction, 'ltr', 'rtl', 'ttb', or 'btt'
              conStyle, barStyle) // container and bar style class names
{
  //// Public Properties

  this.value = 0; // current value, read-only

  //// Public Methods

  // Update current value
  this.update = function(v)
  {
    if (v < 0) v = 0;
    else if (v > this.inMax) v = this.inMax;
    this.con.title = this.bar.title = this.value = v;
    switch(this.dir) {
      case 'ltr': // left to right
      v = this.scale(v, this.w);
      xLeft(this.bar, v - this.w);
      break;
      case 'rtl': // right to left
      v = this.scale(v, this.w);
      xLeft(this.bar, this.w - v);
      break;
      case 'btt': // bottom to top
      v = this.scale(v, this.h);
      xTop(this.bar, this.h - v);
      break;
      case 'ttb': // top to bottom
      v = this.scale(v, this.h);
      xTop(this.bar, v - this.h);
      break;
    }
  };

  // Change position and/or size
  this.paint = function(x, y, // container position
                        w, h) // container size
  {
    if (xNum(x)) this.x = x;
    if (xNum(y)) this.y = y;
    if (xNum(w)) this.w = w;
    if (xNum(h)) this.h = h;
    xResizeTo(this.con, this.w, this.h);
    xMoveTo(this.con, this.x, this.y);
    xResizeTo(this.bar, this.w, this.h);
    xMoveTo(this.bar, 0, 0);
  };

  // Change scale and/or start value
  this.reset = function(max, start) // non-scaled values
  {
    if (xNum(max)) this.inMax = max;
    if (xNum(start)) this.start = start;
    this.update(this.start);
  };

  //// Private Methods
  
  this.scale = function(v, outMax)
  {
    return Math.round(xLinearScale(v, 0, this.inMax, 0, outMax));
  };

  //// Private Properties

  this.dir = dir;
  this.x = 0;
  this.y = 0;
  this.w = 100;
  this.h = 100;
  this.inMax = 100;
  this.start = 0;
  this.conStyle = conStyle;
  this.barStyle = barStyle;

  //// Constructor

  // Create container
  this.con = document.createElement('DIV');
  this.con.className = this.conStyle;
  // Create bar
  this.bar = document.createElement('DIV');
  this.bar.className = this.barStyle;
  // Insert in object tree
  this.con.appendChild(this.bar);
  document.body.appendChild(this.con);

} // end xBar
// xCapitalize, Copyright 2001-2005 Michael Foster (Cross-Browser.com)
// Part of X, a Cross-Browser Javascript Library, Distributed under the terms of the GNU LGPL

// Capitalize the first letter of every word in str.

function xCapitalize(str)
{
  var i, c, wd, s='', cap = true;
  
  for (i = 0; i < str.length; ++i) {
    c = str.charAt(i);
    wd = isWordDelim(c);
    if (wd) {
      cap = true;
    }  
    if (cap && !wd) {
      c = c.toUpperCase();
      cap = false;
    }
    s += c;
  }
  return s;

  function isWordDelim(c)
  {
    // add other word delimiters as needed
    // (for example '-' and other punctuation)
    return c == ' ' || c == '\n' || c == '\t';
  }
}
// xCardinalPosition, Copyright 2004-2005 Michael Foster (Cross-Browser.com)
// Part of X, a Cross-Browser Javascript Library, Distributed under the terms of the GNU LGPL

function xCardinalPosition(e, cp, margin, outside)
{
  if(!(e=xGetElementById(e))) return;
  if (typeof(cp)!='string'){window.status='xCardinalPosition error: cp=' + cp + ', id=' + e.id; return;}
  var x=xLeft(e), y=xTop(e), w=xWidth(e), h=xHeight(e);
  var pw,ph,p = xParent(e);
  if (p == document || p.nodeName.toLowerCase() == 'html') {pw = xClientWidth(); ph = xClientHeight();}
  else {pw=xWidth(p); ph=xHeight(p);}
  var sx=xScrollLeft(p), sy=xScrollTop(p);
  var right=sx + pw, bottom=sy + ph;
  var cenLeft=sx + Math.floor((pw-w)/2), cenTop=sy + Math.floor((ph-h)/2);
  if (!margin) margin=0;
  else{
    if (outside) margin=-margin;
    sx +=margin; sy +=margin; right -=margin; bottom -=margin;
  }
  switch (cp.toLowerCase()){
    case 'n': x=cenLeft; if (outside) y=sy - h; else y=sy; break;
    case 'ne': if (outside){x=right; y=sy - h;}else{x=right - w; y=sy;}break;
    case 'e': y=cenTop; if (outside) x=right; else x=right - w; break;
    case 'se': if (outside){x=right; y=bottom;}else{x=right - w; y=bottom - h}break;
    case 's': x=cenLeft; if (outside) y=sy - h; else y=bottom - h; break;
    case 'sw': if (outside){x=sx - w; y=bottom;}else{x=sx; y=bottom - h;}break;
    case 'w': y=cenTop; if (outside) x=sx - w; else x=sx; break;
    case 'nw': if (outside){x=sx - w; y=sy - h;}else{x=sx; y=sy;}break;
    case 'cen': x=cenLeft; y=cenTop; break;
    case 'cenh': x=cenLeft; break;
    case 'cenv': y=cenTop; break;
  }
  var o = new Object();
  o.x = x; o.y = y;
  return o;
}
// xClientHeight, Copyright 2001-2005 Michael Foster (Cross-Browser.com)
// Part of X, a Cross-Browser Javascript Library, Distributed under the terms of the GNU LGPL

function xClientHeight()
{
  var h=0;
  if(xOp6Dn) h=window.innerHeight;
  else if(document.compatMode == 'CSS1Compat' && !window.opera && document.documentElement && document.documentElement.clientHeight)
    h=document.documentElement.clientHeight;
  else if(document.body && document.body.clientHeight)
    h=document.body.clientHeight;
  else if(xDef(window.innerWidth,window.innerHeight,document.width)) {
    h=window.innerHeight;
    if(document.width>window.innerWidth) h-=16;
  }
  if ((h < 20) && (xDef(window.innerHeight)))  // khtml can use this instead
    h = window.innerHeight;
  return h;
}
// xClientWidth, Copyright 2001-2005 Michael Foster (Cross-Browser.com)
// Part of X, a Cross-Browser Javascript Library, Distributed under the terms of the GNU LGPL

function xClientWidth()
{
  var w=0;
  if(xOp6Dn) w=window.innerWidth;
  else if(document.compatMode == 'CSS1Compat' && !window.opera && document.documentElement && document.documentElement.clientWidth)
    w=document.documentElement.clientWidth;
  else if(document.body && document.body.clientWidth)
    w=document.body.clientWidth;
  else if(xDef(window.innerWidth,window.innerHeight,document.height)) {
    w=window.innerWidth;
    if(document.height>window.innerHeight) w-=16;
  }
  return w;
}
// xClip, Copyright 2001-2005 Michael Foster (Cross-Browser.com)
// Part of X, a Cross-Browser Javascript Library, Distributed under the terms of the GNU LGPL

function xClip(e,t,r,b,l)
{
  if(!(e=xGetElementById(e))) return;
  if(e.style) {
    if (xNum(l)) e.style.clip='rect('+t+'px '+r+'px '+b+'px '+l+'px)';
    else e.style.clip='rect(0 '+parseInt(e.style.width)+'px '+parseInt(e.style.height)+'px 0)';
  }
}
// xCollapsible, Copyright 2005 Michael Foster (Cross-Browser.com)
// Part of X, a Cross-Browser Javascript Library, Distributed under the terms of the GNU LGPL

function xCollapsible(outerEle, bShow) // object prototype
{
  // Constructor

  var container = xGetElementById(outerEle);
  if (!container) {return null;}
  var isUL = container.nodeName.toUpperCase() == 'UL';
  var i, trg, aTgt = xGetElementsByTagName(isUL ? 'UL':'DIV', container);
  for (i = 0; i < aTgt.length; ++i) {
    trg = xPrevSib(aTgt[i]);
    if (trg && (isUL || trg.nodeName.charAt(0).toUpperCase() == 'H')) {
      aTgt[i].xTrgPtr = trg;
      aTgt[i].style.display = bShow ? 'block' : 'none';
      trg.style.cursor = 'pointer';
      trg.xTgtPtr = aTgt[i];
      trg.onclick = trg_onClick;
    }  
  }
  
  // Private

  function trg_onClick()
  {
    var tgt = this.xTgtPtr.style;
    if (tgt.display == 'none') {
      tgt.display = 'block';
    }  
    else {
      tgt.display = 'none';
    }
  }

  // Public

  this.displayAll = function(bShow)
  {
    for (var i = 0; i < aTgt.length; ++i) {
      if (aTgt[i].xTrgPtr) {
        xDisplay(aTgt[i], bShow ? "block":"none");
      }
    }
  };

  // The unload listener is for IE's circular reference memory leak bug.
  this.onUnload = function()
  {
    if (!xIE4Up || !container || !aTgt) {return;}
    for (i = 0; i < aTgt.length; ++i) {
      trg = aTgt[i].xTrgPtr;
      if (trg) {
        if (trg.xTgtPtr) {
          trg.xTgtPtr.TrgPtr = null;
          trg.xTgtPtr = null;
        }
        trg.onclick = null;
      }
    }
  };
}
// xColor, Copyright 2001-2005 Michael Foster (Cross-Browser.com)
// Part of X, a Cross-Browser Javascript Library, Distributed under the terms of the GNU LGPL

function xColor(e,s)
{
  if(!(e=xGetElementById(e))) return '';
  var c='';
  if(e.style && xDef(e.style.color)) {
    if(xStr(s)) e.style.color=s;
    c=e.style.color;
  }
  return c;
}
// xCreateElement, Copyright 2001-2005 Michael Foster (Cross-Browser.com)
// Part of X, a Cross-Browser Javascript Library, Distributed under the terms of the GNU LGPL

function xCreateElement(sTag)
{
  if (document.createElement) return document.createElement(sTag);
  else return null;
}
// xDef, Copyright 2001-2005 Michael Foster (Cross-Browser.com)
// Part of X, a Cross-Browser Javascript Library, Distributed under the terms of the GNU LGPL

function xDef()
{
  for(var i=0; i<arguments.length; ++i){if(typeof(arguments[i])=='undefined') return false;}
  return true;
}
// xDeg, Copyright 2001-2005 Michael Foster (Cross-Browser.com)
// Part of X, a Cross-Browser Javascript Library, Distributed under the terms of the GNU LGPL

function xDeg(rad)
{
  return rad * (180 / Math.PI);
}
// xDeleteCookie, Copyright 2001-2005 Michael Foster (Cross-Browser.com)
// Part of X, a Cross-Browser Javascript Library, Distributed under the terms of the GNU LGPL

function xDeleteCookie(name, path)
{
  if (xGetCookie(name)) {
    document.cookie = name + "=" +
                    "; path=" + ((!path) ? "/" : path) +
                    "; expires=" + new Date(0).toGMTString();
  }
}
// xDisableDrag, Copyright 2005 Michael Foster (Cross-Browser.com)
// Part of X, a Cross-Browser Javascript Library, Distributed under the terms of the GNU LGPL

function xDisableDrag(id, last)
{
  if (!window._xDrgMgr) return;
  var ele = xGetElementById(id);
  ele.xDraggable = false;
  ele.xODS = null;
  ele.xOD = null;
  ele.xODE = null;
  xRemoveEventListener(ele, 'mousedown', _xOMD, false);
  if (_xDrgMgr.mm && last) {
    _xDrgMgr.mm = false;
    xRemoveEventListener(document, 'mousemove', _xOMM, false);
  }
}
// xDisplay, Copyright 2003,2004,2005 Michael Foster (Cross-Browser.com)
// Part of X, a Cross-Browser Javascript Library, Distributed under the terms of the GNU LGPL

function xDisplay(e,s)
{
  if(!(e=xGetElementById(e))) return null;
  if(e.style && xDef(e.style.display)) {
    if (xStr(s)) e.style.display = s;
    return e.style.display;
  }
  return null;
}
// xEllipse, Copyright 2004,2005 Michael Foster (Cross-Browser.com)
// Part of X, a Cross-Browser Javascript Library, Distributed under the terms of the GNU LGPL

function xEllipse(e, xRadius, yRadius, radiusInc, totalTime, startAngle, stopAngle)
{
  if (!(e=xGetElementById(e))) return;
  if (!e.timeout) e.timeout = 25;
  e.xA = xRadius;
  e.yA = yRadius;
  e.radiusInc = radiusInc;
  e.slideTime = totalTime;
  startAngle *= (Math.PI / 180);
  stopAngle *= (Math.PI / 180);
  var startTime = (startAngle * e.slideTime) / (stopAngle - startAngle);
  e.stopTime = e.slideTime + startTime;
  e.B = (stopAngle - startAngle) / e.slideTime;
  e.xD = xLeft(e) - Math.round(e.xA * Math.cos(e.B * startTime)); // center point
  e.yD = xTop(e) - Math.round(e.yA * Math.sin(e.B * startTime)); 
  e.xTarget = Math.round(e.xA * Math.cos(e.B * e.stopTime) + e.xD); // end point
  e.yTarget = Math.round(e.yA * Math.sin(e.B * e.stopTime) + e.yD); 
  var d = new Date();
  e.C = d.getTime() - startTime;
  if (!e.moving) {e.stop=false; _xEllipse(e);}
}
function _xEllipse(e)
{
  if (!(e=xGetElementById(e))) return;
  var now, t, newY, newX;
  now = new Date();
  t = now.getTime() - e.C;
  if (e.stop) { e.moving = false; }
  else if (t < e.stopTime) {
    setTimeout("_xEllipse('"+e.id+"')", e.timeout);
    if (e.radiusInc) {
      e.xA += e.radiusInc;
      e.yA += e.radiusInc;
    }
    newX = Math.round(e.xA * Math.cos(e.B * t) + e.xD);
    newY = Math.round(e.yA * Math.sin(e.B * t) + e.yD);
    xMoveTo(e, newX, newY);
    e.moving = true;
  }  
  else {
    if (e.radiusInc) {
      e.xTarget = Math.round(e.xA * Math.cos(e.B * e.slideTime) + e.xD);
      e.yTarget = Math.round(e.yA * Math.sin(e.B * e.slideTime) + e.yD); 
    }
    xMoveTo(e, e.xTarget, e.yTarget);
    e.moving = false;
  }  
}
// xEnableDrag, Copyright 2002,2003,2004,2005 Michael Foster (Cross-Browser.com)
// Part of X, a Cross-Browser Javascript Library, Distributed under the terms of the GNU LGPL

//// Private Data
var _xDrgMgr = {ele:null, mm:false};
//// Public Functions
function xEnableDrag(id,fS,fD,fE)
{
  var ele = xGetElementById(id);
  ele.xDraggable = true;
  ele.xODS = fS;
  ele.xOD = fD;
  ele.xODE = fE;
  xAddEventListener(ele, 'mousedown', _xOMD, false);
  if (!_xDrgMgr.mm) {
    _xDrgMgr.mm = true;
    xAddEventListener(document, 'mousemove', _xOMM, false);
  }
}
//// Private Event Listeners
function _xOMD(e) // drag start
{
  var evt = new xEvent(e);
  var ele = evt.target;
  while(ele && !ele.xDraggable) {
    ele = xParent(ele);
  }
  if (ele) {
    xPreventDefault(e);
    ele.xDPX = evt.pageX;
    ele.xDPY = evt.pageY;
    _xDrgMgr.ele = ele;
    xAddEventListener(document, 'mouseup', _xOMU, false);
    if (ele.xODS) {
      ele.xODS(ele, evt.pageX, evt.pageY);
    }
  }
}
function _xOMM(e) // drag
{
  var evt = new xEvent(e);
  if (_xDrgMgr.ele) {
    xPreventDefault(e);
    var ele = _xDrgMgr.ele;
    var dx = evt.pageX - ele.xDPX;
    var dy = evt.pageY - ele.xDPY;
    ele.xDPX = evt.pageX;
    ele.xDPY = evt.pageY;
    if (ele.xOD) {
      ele.xOD(ele, dx, dy);
    }
    else {
      xMoveTo(ele, xLeft(ele) + dx, xTop(ele) + dy);
    }
  }  
}
function _xOMU(e) // drag end
{
  if (_xDrgMgr.ele) {
    xPreventDefault(e);
    xRemoveEventListener(document, 'mouseup', _xOMU, false);
    if (_xDrgMgr.ele.xODE) {
      var evt = new xEvent(e);
      _xDrgMgr.ele.xODE(_xDrgMgr.ele, evt.pageX, evt.pageY);
    }
    _xDrgMgr.ele = null;
  }  
}
// xEvalTextarea, Copyright 2001-2005 Michael Foster (Cross-Browser.com)
// Part of X, a Cross-Browser Javascript Library, Distributed under the terms of the GNU LGPL

function xEvalTextarea()
{
  var f = document.createElement('FORM');
  f.onsubmit = 'return false';
  var t = document.createElement('TEXTAREA');
  t.id='xDebugTA';
  t.name='xDebugTA';
  t.rows='20';
  t.cols='60';
  var b = document.createElement('INPUT');
  b.type = 'button';
  b.value = 'Evaluate';
  b.onclick = function() {eval(this.form.xDebugTA.value);};
  f.appendChild(t);
  f.appendChild(b);
  document.body.appendChild(f);
}
// xEvent, Copyright 2001-2005 Michael Foster (Cross-Browser.com)
// Part of X, a Cross-Browser Javascript Library, Distributed under the terms of the GNU LGPL

function xEvent(evt) // object prototype
{
  var e = evt || window.event;
  if(!e) return;
  if(e.type) this.type = e.type;
  if(e.target) this.target = e.target;
  else if(e.srcElement) this.target = e.srcElement;

  // Section B
  if (e.relatedTarget) this.relatedTarget = e.relatedTarget;
  else if (e.type == 'mouseover' && e.fromElement) this.relatedTarget = e.fromElement;
  else if (e.type == 'mouseout') this.relatedTarget = e.toElement;
  // End Section B

  if(xOp6Dn) { this.pageX = e.clientX; this.pageY = e.clientY; }
  else if(xDef(e.pageX,e.pageY)) { this.pageX = e.pageX; this.pageY = e.pageY; }
  else if(xDef(e.clientX,e.clientY)) { this.pageX = e.clientX + xScrollLeft(); this.pageY = e.clientY + xScrollTop(); }

  // Section A
  if (xDef(e.offsetX,e.offsetY)) {
    this.offsetX = e.offsetX;
    this.offsetY = e.offsetY;
  }
  else if (xDef(e.layerX,e.layerY)) {
    this.offsetX = e.layerX;
    this.offsetY = e.layerY;
  }
  else {
    this.offsetX = this.pageX - xPageX(this.target);
    this.offsetY = this.pageY - xPageY(this.target);
  }
  // End Section A
  
  if (e.keyCode) { this.keyCode = e.keyCode; } // for moz/fb, if keyCode==0 use which
  else if (xDef(e.which) && e.type.indexOf('key')!=-1) { this.keyCode = e.which; }

  this.shiftKey = e.shiftKey;
  this.ctrlKey = e.ctrlKey;
  this.altKey = e.altKey;
}

//  I need someone with IE/Mac to compare test snippets 1 and 2 in section A.
  
//  // Snippet 1
//  if(xDef(e.offsetX,e.offsetY)) {
//    this.offsetX = e.offsetX;
//    this.offsetY = e.offsetY;
//    if (xIE4Up && xMac) {
//      this.offsetX += xScrollLeft();
//      this.offsetY += xScrollTop();
//    }
//  }
//  else if (xDef(e.layerX,e.layerY)) {
//    this.offsetX = e.layerX;
//    this.offsetY = e.layerY;
//  }
//  else {
//    this.offsetX = this.pageX - xPageX(this.target);
//    this.offsetY = this.pageY - xPageY(this.target);
//  }

//  // Snippet 2
//  if (xDef(e.offsetX,e.offsetY) && !(xIE4Up && xMac)) {
//    this.offsetX = e.offsetX;
//    this.offsetY = e.offsetY;
//  }
//  else if (xDef(e.layerX,e.layerY)) {
//    this.offsetX = e.layerX;
//    this.offsetY = e.layerY;
//  }
//  else {
//    this.offsetX = this.pageX - xPageX(this.target);
//    this.offsetY = this.pageY - xPageY(this.target);
//  }

//  This was in section B:

//  if (e.relatedTarget) this.relatedTarget = e.relatedTarget;
//  else if (xIE4Up) {
//    if (e.type == 'mouseover') this.relatedTarget = e.fromElement;
//    else if (e.type == 'mouseout') this.relatedTarget = e.toElement;
//  }
//  changed to remove sniffer after discussion with Hallvord

// Possible optimization:

//  if (e.keyCode) { this.keyCode = e.keyCode; } // for moz/fb, if keyCode==0 use which
//  else if (xDef(e.which) && e.type.indexOf('key')!=-1) { this.keyCode = e.which; }
//  // replace the above 2 lines with the following?
//  // this.keyCode = e.keyCode || e.which || 0;
// xFenster, Copyright 2004-2005 Michael Foster (Cross-Browser.com)
// Part of X, a Cross-Browser Javascript Library, Distributed under the terms of the GNU LGPL

function xFenster(eleId, iniX, iniY, barId, resBtnId, maxBtnId) // object prototype
{
  // Private Properties
  var me = this;
  var ele = xGetElementById(eleId);
  var rBtn = xGetElementById(resBtnId);
  var mBtn = xGetElementById(maxBtnId);
  var x, y, w, h, maximized = false;
  // Public Methods
  this.onunload = function()
  {
    if (xIE4Up) { // clear cir refs
      xDisableDrag(barId);
      xDisableDrag(rBtn);
      mBtn.onclick = ele.onmousedown = null;
      me = ele = rBtn = mBtn = null;
    }
  }
  this.paint = function()
  {
    xMoveTo(rBtn, xWidth(ele) - xWidth(rBtn), xHeight(ele) - xHeight(rBtn));
    xMoveTo(mBtn, xWidth(ele) - xWidth(rBtn), 0);
  }
  // Private Event Listeners
  function barOnDrag(e, mdx, mdy)
  {
    xMoveTo(ele, xLeft(ele) + mdx, xTop(ele) + mdy);
  }
  function resOnDrag(e, mdx, mdy)
  {
    xResizeTo(ele, xWidth(ele) + mdx, xHeight(ele) + mdy);
    me.paint();
  }
  function fenOnMousedown()
  {
    xZIndex(ele, xFenster.z++);
  }
  function maxOnClick()
  {
    if (maximized) {
      maximized = false;
      xResizeTo(ele, w, h);
      xMoveTo(ele, x, y);
    }
    else {
      w = xWidth(ele);
      h = xHeight(ele);
      x = xLeft(ele);
      y = xTop(ele);
      xMoveTo(ele, xScrollLeft(), xScrollTop());
      maximized = true;
      xResizeTo(ele, xClientWidth(), xClientHeight());
    }
    me.paint();
  }
  // Constructor Code
  xFenster.z++;
  xMoveTo(ele, iniX, iniY);
  this.paint();
  xEnableDrag(barId, null, barOnDrag, null);
  xEnableDrag(rBtn, null, resOnDrag, null);
  mBtn.onclick = maxOnClick;
  ele.onmousedown = fenOnMousedown;
  xShow(ele);
} // end xFenster object prototype

xFenster.z = 0; // xFenster static property
// xFirstChild, Copyright 2001-2005 Michael Foster (Cross-Browser.com)
// Part of X, a Cross-Browser Javascript Library, Distributed under the terms of the GNU LGPL

function xFirstChild(e, t)
{
  var c = e ? e.firstChild : null;
  if (t) while (c && c.nodeName != t) { c = c.nextSibling; }
  else while (c && c.nodeType != 1) { c = c.nextSibling; }
  return c;
}
// xGetComputedStyle, Copyright 2001-2005 Michael Foster (Cross-Browser.com)
// Part of X, a Cross-Browser Javascript Library, Distributed under the terms of the GNU LGPL

function xGetComputedStyle(oEle, sProp, bInt)
{
  var s, p = 'undefined';
  var dv = document.defaultView;
  if(dv && dv.getComputedStyle){
    s = dv.getComputedStyle(oEle,'');
    if (s) p = s.getPropertyValue(sProp);
  }
  else if(oEle.currentStyle) {
    // convert css property name to object property name for IE
    var a = sProp.split('-');
    sProp = a[0];
    for (var i=1; i<a.length; ++i) {
      c = a[i].charAt(0);
      sProp += a[i].replace(c, c.toUpperCase());
    }   
    p = oEle.currentStyle[sProp];
  }
  else return null;
  return bInt ? (parseInt(p) || 0) : p;
}

// xGetCookie, Copyright 2001-2005 Michael Foster (Cross-Browser.com)
// Part of X, a Cross-Browser Javascript Library, Distributed under the terms of the GNU LGPL

function xGetCookie(name)
{
  var value=null, search=name+"=";
  if (document.cookie.length > 0) {
    var offset = document.cookie.indexOf(search);
    if (offset != -1) {
      offset += search.length;
      var end = document.cookie.indexOf(";", offset);
      if (end == -1) end = document.cookie.length;
      value = unescape(document.cookie.substring(offset, end));
    }
  }
  return value;
}
// xGetElementById, Copyright 2001-2005 Michael Foster (Cross-Browser.com)
// Part of X, a Cross-Browser Javascript Library, Distributed under the terms of the GNU LGPL

function xGetElementById(e)
{
  if(typeof(e)!='string') return e;
  if(document.getElementById) e=document.getElementById(e);
  else if(document.all) e=document.all[e];
  else e=null;
  return e;
}
// xGetElementsByAttribute, Copyright 2001-2005 Michael Foster (Cross-Browser.com)
// Part of X, a Cross-Browser Javascript Library, Distributed under the terms of the GNU LGPL

function xGetElementsByAttribute(sTag, sAtt, sRE, fn)
{
  var a, list, found = new Array(), re = new RegExp(sRE, 'i');
  list = xGetElementsByTagName(sTag);
  for (var i = 0; i < list.length; ++i) {
    a = list[i].getAttribute(sAtt);
    if (!a) {a = list[i][sAtt];}
    if (typeof(a)=='string' && a.search(re) != -1) {
      found[found.length] = list[i];
      if (fn) fn(list[i]);
    }
  }
  return found;
}
// xGetElementsByClassName, Copyright 2001-2005 Michael Foster (Cross-Browser.com)
// Part of X, a Cross-Browser Javascript Library, Distributed under the terms of the GNU LGPL

function xGetElementsByClassName(c,p,t,f)
{
  var found = new Array();
  var re = new RegExp('\\b'+c+'\\b', 'i');
  var list = xGetElementsByTagName(t, p);
  for (var i = 0; i < list.length; ++i) {
    if (list[i].className && list[i].className.search(re) != -1) {
      found[found.length] = list[i];
      if (f) f(list[i]);
    }
  }
  return found;
}
// xGetElementsByTagName, Copyright 2001-2005 Michael Foster (Cross-Browser.com)
// Part of X, a Cross-Browser Javascript Library, Distributed under the terms of the GNU LGPL

function xGetElementsByTagName(t,p)
{
  var list = null;
  t = t || '*';
  p = p || document;
  if (xIE4 || xIE5) {
    if (t == '*') list = p.all;
    else list = p.all.tags(t);
  }
  else if (p.getElementsByTagName) list = p.getElementsByTagName(t);
  return list || new Array();
}
// xGetElePropsArray, Copyright 2001-2005 Michael Foster (Cross-Browser.com)
// Part of X, a Cross-Browser Javascript Library, Distributed under the terms of the GNU LGPL

function xGetElePropsArray(ele, eleName)
{
  var u = 'undefined';
  var i = 0, a = new Array();
  
  nv('Element', eleName);
  nv('id', (xDef(ele.id) ? ele.id : u));
  nv('tagName', (xDef(ele.tagName) ? ele.tagName : u));

  nv('xWidth()', xWidth(ele));
  nv('style.width', (xDef(ele.style) && xDef(ele.style.width) ? ele.style.width : u));
  nv('offsetWidth', (xDef(ele.offsetWidth) ? ele.offsetWidth : u));
  nv('scrollWidth', (xDef(ele.offsetWidth) ? ele.offsetWidth : u));
  nv('clientWidth', (xDef(ele.clientWidth) ? ele.clientWidth : u));

  nv('xHeight()', xHeight(ele));
  nv('style.height', (xDef(ele.style) && xDef(ele.style.height) ? ele.style.height : u));
  nv('offsetHeight', (xDef(ele.offsetHeight) ? ele.offsetHeight : u));
  nv('scrollHeight', (xDef(ele.offsetHeight) ? ele.offsetHeight : u));
  nv('clientHeight', (xDef(ele.clientHeight) ? ele.clientHeight : u));

  nv('xLeft()', xLeft(ele));
  nv('style.left', (xDef(ele.style) && xDef(ele.style.left) ? ele.style.left : u));
  nv('offsetLeft', (xDef(ele.offsetLeft) ? ele.offsetLeft : u));
  nv('style.pixelLeft', (xDef(ele.style) && xDef(ele.style.pixelLeft) ? ele.style.pixelLeft : u));

  nv('xTop()', xTop(ele));
  nv('style.top', (xDef(ele.style) && xDef(ele.style.top) ? ele.style.top : u));
  nv('offsetTop', (xDef(ele.offsetTop) ? ele.offsetTop : u));
  nv('style.pixelTop', (xDef(ele.style) && xDef(ele.style.pixelTop) ? ele.style.pixelTop : u));

  nv('', '');
  nv('xGetComputedStyle()', '');

  nv('top');
  nv('right');
  nv('bottom');
  nv('left');

  nv('width');
  nv('height');

  nv('color');
  nv('background-color');
  nv('font-family');
  nv('font-size');
  nv('text-align');
  nv('line-height');
  nv('content');
  
  nv('float');
  nv('clear');

  nv('margin');
  nv('padding');
  nv('padding-top');
  nv('padding-right');
  nv('padding-bottom');
  nv('padding-left');

  nv('border-top-width');
  nv('border-right-width');
  nv('border-bottom-width');
  nv('border-left-width');

  nv('position');
  nv('overflow');
  nv('visibility');
  nv('display');
  nv('z-index');
  nv('clip');
  nv('cursor');

  return a;

  function nv(name, value)
  {
    a[i] = new Object();
    a[i].name = name;
    a[i].value = typeof(value)=='undefined' ? xGetComputedStyle(ele, name) : value;
    ++i;
  }
}
// xGetElePropsString, Copyright 2001-2005 Michael Foster (Cross-Browser.com)
// Part of X, a Cross-Browser Javascript Library, Distributed under the terms of the GNU LGPL

function xGetElePropsString(ele, eleName, newLine)
{
  var s = '', a = xGetElePropsArray(ele, eleName);
  for (var i = 0; i < a.length; ++i) {
    s += a[i].name + ' = ' + a[i].value + (newLine || '\n');
  }
  return s;
}
// xGetURLArguments, Copyright 2001-2005 Michael Foster (Cross-Browser.com)
// Part of X, a Cross-Browser Javascript Library, Distributed under the terms of the GNU LGPL

function xGetURLArguments()
{
  var idx = location.href.indexOf('?');
  var params = new Array();
  if (idx != -1) {
    var pairs = location.href.substring(idx+1, location.href.length).split('&');
    for (var i=0; i<pairs.length; i++) {
      nameVal = pairs[i].split('=');
      params[i] = nameVal[1];
      params[nameVal[0]] = nameVal[1];
    }
  }
  return params;
}
// xHasPoint, Copyright 2001-2005 Michael Foster (Cross-Browser.com)
// Part of X, a Cross-Browser Javascript Library, Distributed under the terms of the GNU LGPL

function xHasPoint(e,x,y,t,r,b,l)
{
  if (!xNum(t)){t=r=b=l=0;}
  else if (!xNum(r)){r=b=l=t;}
  else if (!xNum(b)){l=r; b=t;}
  var eX = xPageX(e), eY = xPageY(e);
  return (x >= eX + l && x <= eX + xWidth(e) - r &&
          y >= eY + t && y <= eY + xHeight(e) - b );
}
// xHeight, Copyright 2001-2005 Michael Foster (Cross-Browser.com)
// Part of X, a Cross-Browser Javascript Library, Distributed under the terms of the GNU LGPL

function xHeight(e,h)
{
  if(!(e=xGetElementById(e))) return 0;
  if (xNum(h)) {
    if (h<0) h = 0;
    else h=Math.round(h);
  }
  else h=-1;
  var css=xDef(e.style);
  if (e == document || e.tagName.toLowerCase() == 'html' || e.tagName.toLowerCase() == 'body') {
    h = xClientHeight();
  }
  else if(css && xDef(e.offsetHeight) && xStr(e.style.height)) {
    if(h>=0) {
      var pt=0,pb=0,bt=0,bb=0;
      if (document.compatMode=='CSS1Compat') {
        var gcs = xGetComputedStyle;
        pt=gcs(e,'padding-top',1);
        if (pt !== null) {
          pb=gcs(e,'padding-bottom',1);
          bt=gcs(e,'border-top-width',1);
          bb=gcs(e,'border-bottom-width',1);
        }
        // Should we try this as a last resort?
        // At this point getComputedStyle and currentStyle do not exist.
        else if(xDef(e.offsetHeight,e.style.height)){
          e.style.height=h+'px';
          pt=e.offsetHeight-h;
        }
      }
      h-=(pt+pb+bt+bb);
      if(isNaN(h)||h<0) return;
      else e.style.height=h+'px';
    }
    h=e.offsetHeight;
  }
  else if(css && xDef(e.style.pixelHeight)) {
    if(h>=0) e.style.pixelHeight=h;
    h=e.style.pixelHeight;
  }
  return h;
}
// xHex, Copyright 2001-2005 Michael Foster (Cross-Browser.com)
// Part of X, a Cross-Browser Javascript Library, Distributed under the terms of the GNU LGPL

function xHex(n, digits, prefix)
{
  var p = '', n = Math.ceil(n);
  if (prefix) p = prefix;
  n = n.toString(16);
  for (var i=0; i < digits - n.length; ++i) {
    p += '0';
  }
  return p + n;
}
// xHide, Copyright 2001-2005 Michael Foster (Cross-Browser.com)
// Part of X, a Cross-Browser Javascript Library, Distributed under the terms of the GNU LGPL

function xHide(e){return xVisibility(e,0);}
// xImgAsyncWait, Copyright 2001-2005 Michael Foster (Cross-Browser.com)
// Part of X, a Cross-Browser Javascript Library, Distributed under the terms of the GNU LGPL

function xImgAsyncWait(fnStatus, fnInit, fnError, sErrorImg, sAbortImg, imgArray)
{
  var i, imgs = imgArray || document.images;
  
  for (i = 0; i < imgs.length; ++i) {
    imgs[i].onload = imgOnLoad;
    imgs[i].onerror = imgOnError;
    imgs[i].onabort = imgOnAbort;
  }
  
  xIAW.fnStatus = fnStatus;
  xIAW.fnInit = fnInit;
  xIAW.fnError = fnError;
  xIAW.imgArray = imgArray;

  xIAW();

  function imgOnLoad()
  {
    this.wasLoaded = true;
  }
  function imgOnError()
  {
    if (sErrorImg && !this.wasError) {
      this.src = sErrorImg;
    }
    this.wasError = true;
  }
  function imgOnAbort()
  {
    if (sAbortImg && !this.wasAborted) {
      this.src = sAbortImg;
    }
    this.wasAborted = true;
  }
}
// end xImgAsyncWait()

// Don't call xIAW() directly. It is only called from xImgAsyncWait().

function xIAW()
{
  var me = arguments.callee;
  if (!me) {
    return; // I could have used a global object instead of callee
  }
  var i, imgs = me.imgArray ? me.imgArray : document.images;
  var c = 0, e = 0, a = 0, n = imgs.length;
  for (i = 0; i < n; ++i) {
    if (imgs[i].wasError) {
      ++e;
    }
    else if (imgs[i].wasAborted) {
      ++a;
    }
    else if (imgs[i].complete || imgs[i].wasLoaded) {
      ++c;
    }
  }
  if (me.fnStatus) {
    me.fnStatus(n, c, e, a);
  }
  if (c + e + a == n) {
    if ((e || a) && me.fnError) {
      me.fnError(n, c, e, a);
    }
    else if (me.fnInit) {
      me.fnInit();
    }
  }
  else setTimeout('xIAW()', 250);
}
// end xIAW()
// xImgRollSetup, Copyright 2002,2003,2004,2005 Michael Foster (Cross-Browser.com)
// Part of X, a Cross-Browser Javascript Library, Distributed under the terms of the GNU LGPL

function xImgRollSetup(p,s,x)
{
  var ele, id;
  for (var i=3; i<arguments.length; ++i) {
    id = arguments[i];
    if (ele = xGetElementById(id)) {
      ele.xIOU = p + id + x;
      ele.xIOO = new Image();
      ele.xIOO.src = p + id + s + x;
      ele.onmouseout = imgOnMouseout;
      ele.onmouseover = imgOnMouseover;
    }
  }
  function imgOnMouseout(e)
  {
    if (this.xIOU) {
      this.src = this.xIOU;
    }
  }
  function imgOnMouseover(e)
  {
    if (this.xIOO && this.xIOO.complete) {
      this.src = this.xIOO.src;
    }
  }
}
// xInclude, Copyright 2004,2005 Michael Foster (Cross-Browser.com)
// Part of X, a Cross-Browser Javascript Library, Distributed under the terms of the GNU LGPL

function xInclude(url1, url2, etc)
{
  if (document.getElementById || document.all || document.layers) { // minimum dhtml support required
    var h, f, i, j, a, n, inc;

    for (var i=0; i<arguments.length; ++i) { // loop thru all the url arguments

      h = ''; // html (script or link element) to be written into the document
      f = arguments[i].toLowerCase(); // f is current url in lowercase
      inc = false; // if true the file has already been included

      // Extract the filename from the url

      // Should I extract the file name? What if there are two files with the same name 
      // but in different directories? If I don't extract it what about: '../foo.js' and '../../foo.js' ?

      a = f.split('/');
      n = a[a.length-1]; // the file name

      // loop thru the list to see if this file has already been included
      for (j = 0; j < xIncludeList.length; ++j) {
        if (n == xIncludeList[j]) { // should I use '==' or a string cmp func?
          inc = true;
          break;
        }
      }

      if (!inc) { // if the file has not yet been included

        xIncludeList[xIncludeList.length] = n; // add it to the list of included files

        // is it a .js file?
        if (f.indexOf('.js') != -1) {
          if (xNN4) { // if nn4 use nn4 versions of certain lib files
            var c='x_core', e='x_event', d='x_dom', n='_n4';
            if (f.indexOf(c) != -1) { f = f.replace(c, c+n); }
            else if (f.indexOf(e) != -1) { f = f.replace(e, e+n); }
            else if (f.indexOf(d) != -1) { f = f.replace(d, d+n); }
          }
          h = "<script type='text/javascript' src='" + f + "'></script>";
        }

        // else is it a .css file?
        else if (f.indexOf('.css') != -1) { // CSS file
          h = "<link rel='stylesheet' type='text/css' href='" + f + "'>";
        }    
        
        // write the link or script element into the document
        if (h.length) { document.writeln(h); }

      } // end if (!inc)
    } // end outer for
    return true;
  } // end if (min dhtml support)
  return false;
}
// xInnerHtml, Copyright 2001-2005 Michael Foster (Cross-Browser.com)
// Part of X, a Cross-Browser Javascript Library, Distributed under the terms of the GNU LGPL

function xInnerHtml(e,h)
{
  if(!(e=xGetElementById(e)) || !xStr(e.innerHTML)) return null;
  var s = e.innerHTML;
  if (xStr(h)) {e.innerHTML = h;}
  return s;
}
// xIntersection, Copyright 2001-2005 Michael Foster (Cross-Browser.com)
// Part of X, a Cross-Browser Javascript Library, Distributed under the terms of the GNU LGPL

function xIntersection(e1, e2, o)
{
  var ix1, iy2, iw, ih, intersect = true;
  var e1x1 = xPageX(e1);
  var e1x2 = e1x1 + xWidth(e1);
  var e1y1 = xPageY(e1);
  var e1y2 = e1y1 + xHeight(e1);
  var e2x1 = xPageX(e2);
  var e2x2 = e2x1 + xWidth(e2);
  var e2y1 = xPageY(e2);
  var e2y2 = e2y1 + xHeight(e2);
  // horizontal
  if (e1x1 <= e2x1) {
    ix1 = e2x1;
    if (e1x2 < e2x1) intersect = false;
    else iw = Math.min(e1x2, e2x2) - e2x1;
  }
  else {
    ix1 = e1x1;
    if (e2x2 < e1x1) intersect = false;
    else iw = Math.min(e1x2, e2x2) - e1x1;
  }
  // vertical
  if (e1y2 >= e2y2) {
    iy2 = e2y2;
    if (e1y1 > e2y2) intersect = false;
    else ih = e2y2 - Math.max(e1y1, e2y1);
  }
  else {
    iy2 = e1y2;
    if (e2y1 > e1y2) intersect = false;
    else ih = e1y2 - Math.max(e1y1, e2y1);
  }
  // intersected rectangle
  if (intersect && typeof(o)=='object') {
    o.x = ix1;
    o.y = iy2 - ih;
    o.w = iw;
    o.h = ih;
  }
  return intersect;
}
// xLeft, Copyright 2001-2005 Michael Foster (Cross-Browser.com)
// Part of X, a Cross-Browser Javascript Library, Distributed under the terms of the GNU LGPL

function xLeft(e, iX)
{
  if(!(e=xGetElementById(e))) return 0;
  var css=xDef(e.style);
  if (css && xStr(e.style.left)) {
    if(xNum(iX)) e.style.left=iX+'px';
    else {
      iX=parseInt(e.style.left);
      if(isNaN(iX)) iX=0;
    }
  }
  else if(css && xDef(e.style.pixelLeft)) {
    if(xNum(iX)) e.style.pixelLeft=iX;
    else iX=e.style.pixelLeft;
  }
  return iX;
}
// xLinearScale, Copyright 2001-2005 Michael Foster (Cross-Browser.com)
// Part of X, a Cross-Browser Javascript Library, Distributed under the terms of the GNU LGPL

function xLinearScale(val,iL,iH,oL,oH)
{
  var m=(oH-oL)/(iH-iL);
  var b=oL-(iL*m);
  return m*val+b;
}
// xLoadScript, Copyright 2001-2005 Michael Foster (Cross-Browser.com)
// Part of X, a Cross-Browser Javascript Library, Distributed under the terms of the GNU LGPL

function xLoadScript(url)
{
  if (document.createElement && document.getElementsByTagName) {
    var s = document.createElement('script');
    var h = document.getElementsByTagName('head');
    if (s && h.length) {
      s.src = url;
      h[0].appendChild(s);
    }
  }
}
// xMenu1, Copyright 2001-2005 Michael Foster (Cross-Browser.com)
// Part of X, a Cross-Browser Javascript Library, Distributed under the terms of the GNU LGPL

function xMenu1(triggerId, menuId, mouseMargin, openEvent)
{
  var isOpen = false;
  var trg = xGetElementById(triggerId);
  var mnu = xGetElementById(menuId);
  if (trg && mnu) {
    xAddEventListener(trg, openEvent, onOpen, false);
  }
  function onOpen()
  {
    if (!isOpen) {
      xMoveTo(mnu, xPageX(trg), xPageY(trg) + xHeight(trg));
      xShow(mnu);
      xAddEventListener(document, 'mousemove', onMousemove, false);
      isOpen = true;
    }
  }
  function onMousemove(ev)
  {
    var e = new xEvent(ev);
    if (!xHasPoint(mnu, e.pageX, e.pageY, -mouseMargin) &&
        !xHasPoint(trg, e.pageX, e.pageY, -mouseMargin))
    {
      xHide(mnu);
      xRemoveEventListener(document, 'mousemove', onMousemove, false);
      isOpen = false;
    }
  }
} // end xMenu1
// xMenu1A, Copyright 2001-2005 Michael Foster (Cross-Browser.com)
// Part of X, a Cross-Browser Javascript Library, Distributed under the terms of the GNU LGPL

function xMenu1A(triggerId, menuId, mouseMargin, slideTime, openEvent)
{
  var isOpen = false;
  var trg = xGetElementById(triggerId);
  var mnu = xGetElementById(menuId);
  if (trg && mnu) {
    xHide(mnu);
    xAddEventListener(trg, openEvent, onOpen, false);
  }
  function onOpen()
  {
    if (!isOpen) {
      xMoveTo(mnu, xPageX(trg), xPageY(trg));
      xShow(mnu);
      xSlideTo(mnu, xPageX(trg), xPageY(trg) + xHeight(trg), slideTime);
      xAddEventListener(document, 'mousemove', onMousemove, false);
      isOpen = true;
    }
  }
  function onMousemove(ev)
  {
    var e = new xEvent(ev);
    if (!xHasPoint(mnu, e.pageX, e.pageY, -mouseMargin) &&
        !xHasPoint(trg, e.pageX, e.pageY, -mouseMargin))
    {
      xRemoveEventListener(document, 'mousemove', onMousemove, false);
      xSlideTo(mnu, xPageX(trg), xPageY(trg), slideTime);
      setTimeout("xHide('" + menuId + "')", slideTime);
      isOpen = false;
    }
  }
} // end xMenu1A
// xMenu1B, Copyright 2001-2005 Michael Foster (Cross-Browser.com)
// Part of X, a Cross-Browser Javascript Library, Distributed under the terms of the GNU LGPL

function xMenu1B(openTriggerId, closeTriggerId, menuId, slideTime, bOnClick)
{
  xMenu1B.instances[xMenu1B.instances.length] = this;
  var isOpen = false;
  var oTrg = xGetElementById(openTriggerId);
  var cTrg = xGetElementById(closeTriggerId);
  var mnu = xGetElementById(menuId);
  if (oTrg && cTrg && mnu) {
    xHide(mnu);
    if (bOnClick) oTrg.onclick = openOnEvent;
    else oTrg.onmouseover = openOnEvent;
    cTrg.onclick = closeOnClick;
  }
  function openOnEvent()
  {
    if (!isOpen) {
      for (var i = 0; i < xMenu1B.instances.length; ++i) {
        xMenu1B.instances[i].close();
      }
      xMoveTo(mnu, xPageX(oTrg), xPageY(oTrg));
      xShow(mnu);
      xSlideTo(mnu, xPageX(oTrg), xPageY(oTrg) + xHeight(oTrg), slideTime);
      isOpen = true;
    }
  }
  function closeOnClick()
  {
    if (isOpen) {
      xSlideTo(mnu, xPageX(oTrg), xPageY(oTrg), slideTime);
      setTimeout("xHide('" + menuId + "')", slideTime);
      isOpen = false;
    }
  }
  this.close = function()
  {
    closeOnClick();
  }
} // end xMenu1B

xMenu1B.instances = new Array(); // static member of xMenu1B
// xMenu5, Copyright 2004,2005 Michael Foster (Cross-Browser.com)
// Part of X, a Cross-Browser Javascript Library, Distributed under the terms of the GNU LGPL

function xMenu5(idUL, btnClass, idAutoOpen) // object prototype
{
  // Constructor

  var i, ul, btns, mnu = xGetElementById(idUL);
  btns = xGetElementsByClassName(btnClass, mnu, 'DIV');
  for (i = 0; i < btns.length; ++i) {
    ul = xNextSib(btns[i], 'UL');
    btns[i].xClpsTgt = ul;
    btns[i].onclick = btn_onClick;
    set_display(btns[i], 0);
  }
  if (idAutoOpen) {
    var e = xGetElementById(idAutoOpen);
    while (e && e != mnu) {
      if (e.xClpsTgt) set_display(e, 1);
      while (e && e != mnu && e.nodeName != 'LI') e = e.parentNode;
      e = e.parentNode; // UL
      while (e && !e.xClpsTgt) e = xPrevSib(e);
    }
  }

  // Private
  
  function btn_onClick()
  {
    var thisLi, fc, pUl;
    if (this.xClpsTgt.style.display == 'none') {
      set_display(this, 1);
      // get this label's parent LI
      var li = this.parentNode;
      thisLi = li;
      pUl = li.parentNode; // get this LI's parent UL
      li = xFirstChild(pUl); // get the UL's first LI child
      // close all labels' ULs on this level except for thisLI's label
      while (li) {
        if (li != thisLi) {
          fc = xFirstChild(li);
          if (fc && fc.xClpsTgt) {
            set_display(fc, 0);
          }
        }
        li = xNextSib(li);
      }
    }  
    else {
      set_display(this, 0);
    }
  }

  function set_display(ele, bBlock)
  {
    if (bBlock) {
      ele.xClpsTgt.style.display = 'block';
      ele.innerHTML = '-';
    }
    else {
      ele.xClpsTgt.style.display = 'none';
      ele.innerHTML = '+';
    }
  }

  // Public

  this.onUnload = function()
  {
    for (i = 0; i < btns.length; ++i) {
      btns[i].xClpsTgt = null;
      btns[i].onclick = null;
    }
  }
} // end xMenu5 prototype


// xMoveTo, Copyright 2001-2005 Michael Foster (Cross-Browser.com)
// Part of X, a Cross-Browser Javascript Library, Distributed under the terms of the GNU LGPL

function xMoveTo(e,x,y)
{
  xLeft(e,x);
  xTop(e,y);
}
// xName, Copyright 2001-2005 Michael Foster (Cross-Browser.com)
// Part of X, a Cross-Browser Javascript Library, Distributed under the terms of the GNU LGPL

function xName(e)
{
  if (!e) return e;
  else if (e.id && e.id != "") return e.id;
  else if (e.name && e.name != "") return e.name;
  else if (e.nodeName && e.nodeName != "") return e.nodeName;
  else if (e.tagName && e.tagName != "") return e.tagName;
  else return e;
}
// xNextSib, Copyright 2001-2005 Michael Foster (Cross-Browser.com)
// Part of X, a Cross-Browser Javascript Library, Distributed under the terms of the GNU LGPL

function xNextSib(e,t)
{
  var s = e ? e.nextSibling : null;
  if (t) while (s && s.nodeName != t) { s = s.nextSibling; }
  else while (s && s.nodeType != 1) { s = s.nextSibling; }
  return s;
}
// xNum, Copyright 2001-2005 Michael Foster (Cross-Browser.com)
// Part of X, a Cross-Browser Javascript Library, Distributed under the terms of the GNU LGPL

function xNum()
{
  for(var i=0; i<arguments.length; ++i){if(isNaN(arguments[i]) || typeof(arguments[i])!='number') return false;}
  return true;
}
// xOffsetLeft, Copyright 2001-2005 Michael Foster (Cross-Browser.com)
// Part of X, a Cross-Browser Javascript Library, Distributed under the terms of the GNU LGPL

function xOffsetLeft(e)
{
  if (!(e=xGetElementById(e))) return 0;
  if (xDef(e.offsetLeft)) return e.offsetLeft;
  else return 0;
}
// xOffsetTop, Copyright 2001-2005 Michael Foster (Cross-Browser.com)
// Part of X, a Cross-Browser Javascript Library, Distributed under the terms of the GNU LGPL

function xOffsetTop(e)
{
  if (!(e=xGetElementById(e))) return 0;
  if (xDef(e.offsetTop)) return e.offsetTop;
  else return 0;
}
// xPad, Copyright 2001-2005 Michael Foster (Cross-Browser.com)
// Part of X, a Cross-Browser Javascript Library, Distributed under the terms of the GNU LGPL

function xPad(s,len,c,left)
{
  if(typeof s != 'string') s=s+'';
  if(left) {for(var i=s.length; i<len; ++i) s=c+s;}
  else {for (var i=s.length; i<len; ++i) s+=c;}
  return s;
}
// xPageX, Copyright 2001-2005 Michael Foster (Cross-Browser.com)
// Part of X, a Cross-Browser Javascript Library, Distributed under the terms of the GNU LGPL

function xPageX(e)
{
  if (!(e=xGetElementById(e))) return 0;
  var x = 0;
  while (e) {
    if (xDef(e.offsetLeft)) x += e.offsetLeft;
    e = xDef(e.offsetParent) ? e.offsetParent : null;
  }
  return x;
}
// xPageY, Copyright 2001-2005 Michael Foster (Cross-Browser.com)
// Part of X, a Cross-Browser Javascript Library, Distributed under the terms of the GNU LGPL

function xPageY(e)
{
  if (!(e=xGetElementById(e))) return 0;
  var y = 0;
  while (e) {
    if (xDef(e.offsetTop)) y += e.offsetTop;
    e = xDef(e.offsetParent) ? e.offsetParent : null;
  }
//  if (xOp7Up) return y - document.body.offsetTop; // v3.14, temporary hack for opera bug 130324 (reported 1nov03)
  return y;
}
// xParaEq, Copyright 2004,2005 Michael Foster (Cross-Browser.com)
// Part of X, a Cross-Browser Javascript Library, Distributed under the terms of the GNU LGPL

// Animation with Parametric Equations

function xParaEq(e, xExpr, yExpr, totalTime)
{
  if (!(e=xGetElementById(e))) return;
  e.t = 0;
  e.tStep = .008;
  if (!e.timeout) e.timeout = 25;
  e.xExpr = xExpr;
  e.yExpr = yExpr;
  e.slideTime = totalTime;
  var d = new Date();
  e.C = d.getTime();
  if (!e.moving) {e.stop=false; _xParaEq(e);}
}
function _xParaEq(e)
{
  if (!(e=xGetElementById(e))) return;
  var now = new Date();
  var et = now.getTime() - e.C;
  e.t += e.tStep;
  t = e.t;
  if (e.stop) { e.moving = false; }
  else if (!e.slideTime || et < e.slideTime) {
    setTimeout("_xParaEq('"+e.id+"')", e.timeout);
    var p = xParent(e), centerX, centerY;
    centerX = (xWidth(p)/2)-(xWidth(e)/2);
    centerY = (xHeight(p)/2)-(xHeight(e)/2);
    e.xTarget = Math.round((eval(e.xExpr) * centerX) + centerX) + xScrollLeft(p);
    e.yTarget = Math.round((eval(e.yExpr) * centerY) + centerY) + xScrollTop(p);
    xMoveTo(e, e.xTarget, e.yTarget);
    e.moving = true;
  }  
  else {
    e.moving = false;
  }  
}
// xParent, Copyright 2001-2005 Michael Foster (Cross-Browser.com)
// Part of X, a Cross-Browser Javascript Library, Distributed under the terms of the GNU LGPL

function xParent(e, bNode)
{
  if (!(e=xGetElementById(e))) return null;
  var p=null;
  if (!bNode && xDef(e.offsetParent)) p=e.offsetParent;
  else if (xDef(e.parentNode)) p=e.parentNode;
  else if (xDef(e.parentElement)) p=e.parentElement;
  return p;
}
// xParentChain, Copyright 2001-2005 Michael Foster (Cross-Browser.com)
// Part of X, a Cross-Browser Javascript Library, Distributed under the terms of the GNU LGPL

function xParentChain(e,delim,bNode)
{
  if (!(e=xGetElementById(e))) return;
  var lim=100, s = "", d = delim || "\n";
  while(e) {
    s += xName(e) + ', ofsL:'+e.offsetLeft + ', ofsT:'+e.offsetTop + d;
    e = xParent(e,bNode);
    if (!lim--) break;
  }
  return s;
}
// xPopup, Copyright 2001-2005 Michael Foster (Cross-Browser.com)
// Part of X, a Cross-Browser Javascript Library, Distributed under the terms of the GNU LGPL

function xPopup(sTmrType, uTimeout, sPos1, sPos2, sPos3, sStyle, sId, sUrl)
{
  if (document.getElementById && document.createElement &&
      document.body && document.body.appendChild)
  { 
    // create popup element
    //var e = document.createElement('DIV');
    var e = document.createElement('IFRAME');
    this.ele = e;
    e.id = sId;
    e.style.position = 'absolute';
    e.className = sStyle;
    //e.innerHTML = sHtml;
    e.src = sUrl;
    document.body.appendChild(e);
    xShow(e);
    this.tmr = xTimer.set(sTmrType, this, sTmrType, uTimeout);
    // init
    this.open = false;
    this.margin = 10;
    this.pos1 = sPos1;
    this.pos2 = sPos2;
    this.pos3 = sPos3;
    this.slideTime = 500; // slide time in ms
    this.interval();
  } 
} // end xPopup
// methods
xPopup.prototype.show = function()
{
  this.interval();
};
xPopup.prototype.hide = function()
{
  this.timeout();
};
// timer event listeners
xPopup.prototype.timeout = function() // hide popup
{
  if (this.open) {
    var e = this.ele;
    var pos = xCardinalPosition(e, this.pos3, this.margin, true);
    xSlideTo(e, pos.x, pos.y, this.slideTime);
    setTimeout("xHide('" + e.id + "')", this.slideTime);
    this.open = false;
  }
};
xPopup.prototype.interval = function() // size, position and show popup
{
  if (!this.open) {
    var e = this.ele;
    var pos = xCardinalPosition(e, this.pos1, this.margin, true);
    xMoveTo(e, pos.x, pos.y);
    xShow(e);
    pos = xCardinalPosition(e, this.pos2, this.margin, false);
    xSlideTo(e, pos.x, pos.y, this.slideTime);
    this.open = true;
  }
};
// xPreventDefault, Copyright 2004,2005 Michael Foster (Cross-Browser.com)
// Part of X, a Cross-Browser Javascript Library, Distributed under the terms of the GNU LGPL

function xPreventDefault(e)
{
  if (e && e.preventDefault) e.preventDefault();
  else if (window.event) window.event.returnValue = false;
}
// xPrevSib, Copyright 2001-2005 Michael Foster (Cross-Browser.com)
// Part of X, a Cross-Browser Javascript Library, Distributed under the terms of the GNU LGPL

function xPrevSib(e,t)
{
  var s = e ? e.previousSibling : null;
  if (t) while(s && s.nodeName != t) {s=s.previousSibling;}
  else while(s && s.nodeType != 1) {s=s.previousSibling;}
  return s;
}
// xRad, Copyright 2001-2005 Michael Foster (Cross-Browser.com)
// Part of X, a Cross-Browser Javascript Library, Distributed under the terms of the GNU LGPL

function xRad(deg)
{
  return deg*(Math.PI/180);
}
// xRemoveEventListener, Copyright 2001-2005 Michael Foster (Cross-Browser.com)
// Part of X, a Cross-Browser Javascript Library, Distributed under the terms of the GNU LGPL

function xRemoveEventListener(e,eT,eL,cap)
{
  if(!(e=xGetElementById(e))) return;
  eT=eT.toLowerCase();
  if((!xIE4Up && !xOp7Up) && e==window) {
    if(eT=='resize') { window.xREL=null; return; }
    if(eT=='scroll') { window.xSEL=null; return; }
  }
  var eh='e.on'+eT+'=null';
  if(e.removeEventListener) e.removeEventListener(eT,eL,cap);
  else if(e.detachEvent) e.detachEvent('on'+eT,eL);
  else eval(eh);
}
// xResizeTo, Copyright 2001-2005 Michael Foster (Cross-Browser.com)
// Part of X, a Cross-Browser Javascript Library, Distributed under the terms of the GNU LGPL

function xResizeTo(e,w,h)
{
  xWidth(e,w);
  xHeight(e,h);
}
// xScrollLeft, Copyright 2001-2005 Michael Foster (Cross-Browser.com)
// Part of X, a Cross-Browser Javascript Library, Distributed under the terms of the GNU LGPL

function xScrollLeft(e, bWin)
{
  var offset=0;
  if (!xDef(e) || bWin || e == document || e.tagName.toLowerCase() == 'html' || e.tagName.toLowerCase() == 'body') {
    var w = window;
    if (bWin && e) w = e;
    if(w.document.documentElement && w.document.documentElement.scrollLeft) offset=w.document.documentElement.scrollLeft;
    else if(w.document.body && xDef(w.document.body.scrollLeft)) offset=w.document.body.scrollLeft;
  }
  else {
    e = xGetElementById(e);
    if (e && xNum(e.scrollLeft)) offset = e.scrollLeft;
  }
  return offset;
}
// xScrollTop, Copyright 2001-2005 Michael Foster (Cross-Browser.com)
// Part of X, a Cross-Browser Javascript Library, Distributed under the terms of the GNU LGPL

function xScrollTop(e, bWin)
{
  var offset=0;
  if (!xDef(e) || bWin || e == document || e.tagName.toLowerCase() == 'html' || e.tagName.toLowerCase() == 'body') {
    var w = window;
    if (bWin && e) w = e;
    if(w.document.documentElement && w.document.documentElement.scrollTop) offset=w.document.documentElement.scrollTop;
    else if(w.document.body && xDef(w.document.body.scrollTop)) offset=w.document.body.scrollTop;
  }
  else {
    e = xGetElementById(e);
    if (e && xNum(e.scrollTop)) offset = e.scrollTop;
  }
  return offset;
}
// xSelect, Copyright 2004-2005 Michael Foster (Cross-Browser.com)
// Part of X, a Cross-Browser Javascript Library, Distributed under the terms of the GNU LGPL

function xSelect(sId, fnSubOnChange)
{
  //// Properties
  
  this.ready = false;
  
  //// Constructor

  // Check for required browser objects
  var s0 = xGetElementById(sId);
  if (!s0 || !s0.firstChild || !s0.nodeName || !document.createElement || !s0.form || !s0.form.appendChild)
  {
    return;
  }
  
  // Create main category SELECT element
  var s1 = document.createElement('SELECT');
  s1.id = sId + '_main';
  s1.display = 'block'; // for opera bug?
  s1.style.position = 'absolute';
  s1.xSelObj = this;
  s1.xSelData = new Array();
  // append s1 to s0's form
  s0.form.appendChild(s1);

  // Iterate thru s0 and fill array.
  // For each OPTGROUP, a[og][0] == OPTGROUP label, and...
  // a[og][n] = innerHTML of OPTION n.
  var ig=0, io, op, og, a = s1.xSelData;
  og = s0.firstChild;
  while (og) {
    if (og.nodeName.toLowerCase() == 'optgroup') {
      io = 0;
      a[ig] = new Array();
      a[ig][io] = og.label;
      op = og.firstChild;
      while (op) {
        if (op.nodeName.toLowerCase() == 'option') {
          io++;
          a[ig][io] = op.innerHTML;
        }
        op = op.nextSibling;
      }
      ig++;
    }
    og = og.nextSibling;
  }

  // in s1 insert a new OPTION for each OPTGROUP in s0
  for (ig=0; ig<a.length; ++ig) {
    op = new Option(a[ig][0]);
    s1.options[ig] = op;
  }
  
  // Create sub-category SELECT element
  var s2 = document.createElement('SELECT');
  s2.id = sId + '_sub';
  s2.display = 'block'; // for opera bug?
  s2.style.position = 'absolute';
  s2.xSelMain = s1;
  s1.xSelSub = s2;
  // append s2 to s0's form
  s0.form.appendChild(s2);
  
  // Add event listeners
  s1.onchange = xSelectMain_OnChange;
  s2.onchange = fnSubOnChange;
  // Hide s0. Position and show s1 where s0 was.
  // Position and show s2 to the right of s1.
  xHide(s0);
//alert(s1.offsetParent.nodeName + '\n' + xPageX(s0) + ', ' + xPageY(s0) + '\n' + xOffsetLeft(s0) + ', ' + xOffsetTop(s0));//////////
  xMoveTo(s1, xOffsetLeft(s0), xOffsetTop(s0));
//  xMoveTo(s1, xOffsetLeft(s0), xPageY(s0));
//  xMoveTo(s1, s0.offsetLeft, xPageY(s0));
//  xMoveTo(s1, s0.offsetLeft, s0.offsetTop);
  xShow(s1);
  xMoveTo(s2, xOffsetLeft(s0) + xWidth(s1), xOffsetTop(s0));
//  xMoveTo(s2, s0.offsetLeft + xWidth(s1), xPageY(s0));
//  xMoveTo(s2, s0.offsetLeft + xWidth(s1), s0.offsetTop);
  xShow(s2);

  // Initialize s2
  s1.onchange();
  // Ready to rock!
  this.ready = true;
  
} // end xSelect object prototype

function xSelectMain_OnChange()
{
  var io, s2 = this.xSelSub;
  // clear existing
  for (io=0; io<s2.options.length; ++io) {
    s2.options[io] = null;
  }
  // insert new
  var a = this.xSelData, ig = this.selectedIndex;
  for (io=1; io<a[ig].length; ++io) {
    op = new Option(a[ig][io]);
    s2.options[io-1] = op;
  }
}
// xSetCookie, Copyright 2001-2005 Michael Foster (Cross-Browser.com)
// Part of X, a Cross-Browser Javascript Library, Distributed under the terms of the GNU LGPL

function xSetCookie(name, value, expire, path)
{
  document.cookie = name + "=" + escape(value) +
                    ((!expire) ? "" : ("; expires=" + expire.toGMTString())) +
                    "; path=" + ((!path) ? "/" : path);
}
// xSetIETitle, Copyright 2001-2005 Michael Foster (Cross-Browser.com)
// Part of X, a Cross-Browser Javascript Library, Distributed under the terms of the GNU LGPL

function xSetIETitle()
{
  if (xIE4Up) {
    var i = xUA.indexOf('msie') + 1;
    var v = xUA.substr(i + 4, 3);
    document.title = 'IE ' + v + ' - ' + document.title;
  }
}
// xShow, Copyright 2001-2005 Michael Foster (Cross-Browser.com)
// Part of X, a Cross-Browser Javascript Library, Distributed under the terms of the GNU LGPL

function xShow(e) {return xVisibility(e,1);}
// xSlideCornerTo, Copyright 2005 Michael Foster (Cross-Browser.com)
// Part of X, a Cross-Browser Javascript Library, Distributed under the terms of the GNU LGPL

function xSlideCornerTo(e, corner, targetX, targetY, totalTime)
{
  if (!(e=xGetElementById(e))) return;
  if (!e.timeout) e.timeout = 25;
  e.xT = targetX;
  e.yT = targetY;
  e.slideTime = totalTime;
  e.corner = corner.toLowerCase();
  e.stop = false;
  switch(e.corner) {
    case 'nw': e.xA = e.xT - xLeft(e); e.yA = e.yT - xTop(e); e.xD = xLeft(e); e.yD = xTop(e); break;
    case 'sw': e.xA = e.xT - xLeft(e); e.yA = e.yT - (xTop(e) + xHeight(e)); e.xD = xLeft(e); e.yD = xTop(e) + xHeight(e); break;
    case 'ne': e.xA = e.xT - (xLeft(e) + xWidth(e)); e.yA = e.yT - xTop(e); e.xD = xLeft(e) + xWidth(e); e.yD = xTop(e); break;
    case 'se': e.xA = e.xT - (xLeft(e) + xWidth(e)); e.yA = e.yT - (xTop(e) + xHeight(e)); e.xD = xLeft(e) + xWidth(e); e.yD = xTop(e) + xHeight(e); break;
    default: alert("xSlideCornerTo: Invalid corner"); return;
  }
  e.B = Math.PI / ( 2 * e.slideTime );
  var d = new Date();
  e.C = d.getTime();
  if (!e.moving) _xSlideCornerTo(e);
}

function _xSlideCornerTo(e)
{
  if (!(e=xGetElementById(e))) return;
  var now, seX, seY;
  now = new Date();
  t = now.getTime() - e.C;
  if (e.stop) { e.moving = false; e.stop = false; return; }
  else if (t < e.slideTime) {
    setTimeout("_xSlideCornerTo('"+e.id+"')", e.timeout);
    s = Math.sin( e.B * t );
    newX = Math.round(e.xA * s + e.xD);
    newY = Math.round(e.yA * s + e.yD);
  }
  else { newX = e.xT; newY = e.yT; }  
  seX = xLeft(e) + xWidth(e);
  seY = xTop(e) + xHeight(e);
  switch(e.corner) {
    case 'nw': xMoveTo(e, newX, newY); xResizeTo(e, seX - xLeft(e), seY - xTop(e)); break;
    case 'sw': if (e.xT != xLeft(e)) { xLeft(e, newX); xWidth(e, seX - xLeft(e)); } xHeight(e, newY - xTop(e)); break;
    case 'ne': xWidth(e, newX - xLeft(e)); if (e.yT != xTop(e)) { xTop(e, newY); xHeight(e, seY - xTop(e)); } break;
    case 'se': xWidth(e, newX - xLeft(e)); xHeight(e, newY - xTop(e)); break;
    default: e.stop = true;
  }
  //window.status = ('Target: ' + e.xT + ', ' + e.yT);//////debug///////
//  xClip(e, 'auto'); // ?????is this needed? it was used in the original CBE method?????
  e.moving = true;
  if (t >= e.slideTime) {
    e.moving = false;
  }
}
// xSlideTo, Copyright 2001-2005 Michael Foster (Cross-Browser.com)
// Part of X, a Cross-Browser Javascript Library, Distributed under the terms of the GNU LGPL

function xSlideTo(e, x, y, uTime)
{
  if (!(e=xGetElementById(e))) return;
  if (!e.timeout) e.timeout = 25;
  e.xTarget = x; e.yTarget = y; e.slideTime = uTime; e.stop = false;
  e.yA = e.yTarget - xTop(e); e.xA = e.xTarget - xLeft(e); // A = distance
  if (e.slideLinear) e.B = 1/e.slideTime;
  else e.B = Math.PI / (2 * e.slideTime); // B = period
  e.yD = xTop(e); e.xD = xLeft(e); // D = initial position
  var d = new Date(); e.C = d.getTime();
  if (!e.moving) _xSlideTo(e);
}
function _xSlideTo(e)
{
  if (!(e=xGetElementById(e))) return;
  var now, s, t, newY, newX;
  now = new Date();
  t = now.getTime() - e.C;
  if (e.stop) { e.moving = false; }
  else if (t < e.slideTime) {
    setTimeout("_xSlideTo('"+e.id+"')", e.timeout);
    if (e.slideLinear) s = e.B * t;
    else s = Math.sin(e.B * t);
    newX = Math.round(e.xA * s + e.xD);
    newY = Math.round(e.yA * s + e.yD);
    xMoveTo(e, newX, newY);
    e.moving = true;
  }  
  else {
    xMoveTo(e, e.xTarget, e.yTarget);
    e.moving = false;
  }  
}

// xStopPropagation, Copyright 2004,2005 Michael Foster (Cross-Browser.com)
// Part of X, a Cross-Browser Javascript Library, Distributed under the terms of the GNU LGPL

function xStopPropagation(evt)
{
  if (evt && evt.stopPropagation) evt.stopPropagation();
  else if (window.event) window.event.cancelBubble = true;
}
// xStr, Copyright 2001-2005 Michael Foster (Cross-Browser.com)
// Part of X, a Cross-Browser Javascript Library, Distributed under the terms of the GNU LGPL

function xStr(s)
{
  for(var i=0; i<arguments.length; ++i){if(typeof(arguments[i])!='string') return false;}
  return true;
}
// xTableCellVisibility, Copyright 2004,2005 Michael Foster (Cross-Browser.com)
// Part of X, a Cross-Browser Javascript Library, Distributed under the terms of the GNU LGPL

function xTableCellVisibility(bShow, sec, nRow, nCol)
{
  sec = xGetElementById(sec);
  if (sec && nRow < sec.rows.length && nCol < sec.rows[nRow].cells.length) {
    sec.rows[nRow].cells[nCol].style.visibility = bShow ? 'visible' : 'hidden';
  }
}
// xTableColDisplay, Copyright 2004-2005 Michael Foster (Cross-Browser.com)
// Part of X, a Cross-Browser Javascript Library, Distributed under the terms of the GNU LGPL

function xTableColDisplay(bShow, sec, nCol)
{
  var r;
  sec = xGetElementById(sec);
  if (sec && nCol < sec.rows[0].cells.length) {
    for (r = 0; r < sec.rows.length; ++r) {
      sec.rows[r].cells[nCol].style.display = bShow ? '' : 'none';
    }
  }
}
// xTableCursor, Copyright 2004,2005 Michael Foster (Cross-Browser.com)
// Part of X, a Cross-Browser Javascript Library, Distributed under the terms of the GNU LGPL

function xTableCursor(id, inh, def, hov, sel) // object prototype
{
  var tbl = xGetElementById(id);
  if (tbl) {
    xTableIterate(tbl, init);
  }
  function init(obj, isRow)
  {
    if (isRow) {
      obj.className = def;
      obj.onmouseover = trOver;
      obj.onmouseout = trOut;
    }
    else {
      obj.className = inh;
      obj.onmouseover = tdOver;
      obj.onmouseout = tdOut;
    }
  }
  this.unload = function() { xTableIterate(tbl, done); };
  function done(o) { o.onmouseover = o.onmouseout = null; }
  function trOver() { this.className = hov; }
  function trOut() { this.className = def; }
  function tdOver() { this.className = sel; }
  function tdOut() { this.className = inh; }
}
// xTableIterate, Copyright 2004,2005 Michael Foster (Cross-Browser.com)
// Part of X, a Cross-Browser Javascript Library, Distributed under the terms of the GNU LGPL

function xTableIterate(sec, fnCallback, data)
{
  var r, c;
  sec = xGetElementById(sec);
  if (!sec || !fnCallback) { return; }
  for (r = 0; r < sec.rows.length; ++r) {
    if (false == fnCallback(sec.rows[r], true, r, c, data)) { return; }
    for (c = 0; c < sec.rows[r].cells.length; ++c) {
      if (false == fnCallback(sec.rows[r].cells[c], false, r, c, data)) { return; }
    }
  }
}

// xTableRowDisplay, Copyright 2004,2005 Michael Foster (Cross-Browser.com)
// Part of X, a Cross-Browser Javascript Library, Distributed under the terms of the GNU LGPL

function xTableRowDisplay(bShow, sec, nRow)
{
  sec = xGetElementById(sec);
  if (sec && nRow < sec.rows.length) {
    sec.rows[nRow].style.display = bShow ? '' : 'none';
  }
}
// xTabPanelGroup, Copyright 2005 Michael Foster (Cross-Browser.com)
// Part of X, a Cross-Browser Javascript Library, Distributed under the terms of the GNU LGPL

function xTabPanelGroup(id, w, h, th, clsTP, clsTG, clsTD, clsTS) // object prototype
{
  // Private Methods

  function onClick() //r7
  {
    paint(this);
    return false;
  }
  function onFocus() //r7
  {
    paint(this);
  }
  function paint(tab)
  {
    tab.className = clsTS;
    xZIndex(tab, highZ++);
    xDisplay(panels[tab.xTabIndex], 'block'); //r6
  
    if (selectedIndex != tab.xTabIndex) {
      xDisplay(panels[selectedIndex], 'none'); //r6
      tabs[selectedIndex].className = clsTD;
  
      selectedIndex = tab.xTabIndex;
    }
  }

  // Public Methods

  this.select = function(n) //r7
  {
    if (n && n <= tabs.length) {
      var t = tabs[n-1];
      if (t.focus) t.focus();
      else t.onclick();
    }
  }

  this.onUnload = function()
  {
    if (xIE4Up) for (var i = 0; i < tabs.length; ++i) {tabs[i].onclick = null;}
  }

  // Constructor Code (note that all these vars are 'private')

  var panelGrp = xGetElementById(id);
  if (!panelGrp) { return null; }
  var panels = xGetElementsByClassName(clsTP, panelGrp);
  var tabs = xGetElementsByClassName(clsTD, panelGrp);
  var tabGrp = xGetElementsByClassName(clsTG, panelGrp);
  if (!panels || !tabs || !tabGrp || panels.length != tabs.length || tabGrp.length != 1) { return null; }
  var selectedIndex = 0, highZ, x = 0, i;
  xResizeTo(panelGrp, w, h);
  xResizeTo(tabGrp[0], w, th);
  xMoveTo(tabGrp[0], 0, 0);
  w -= 2; // remove border widths
  var tw = w / tabs.length;
  for (i = 0; i < tabs.length; ++i) {
    xResizeTo(tabs[i], tw, th); 
    xMoveTo(tabs[i], x, 0);
    x += tw;
    tabs[i].xTabIndex = i;
    tabs[i].onclick = onClick;
    tabs[i].onfocus = onFocus; //r7
    xDisplay(panels[i], 'none'); //r6
    xResizeTo(panels[i], w, h - th - 2); // -2 removes border widths
    xMoveTo(panels[i], 0, th);
  }
  highZ = i;
  tabs[0].onclick();
}
// xTimer, Copyright 2003-2005 Michael Foster (Cross-Browser.com)
// Part of X, a Cross-Browser Javascript Library, Distributed under the terms of the GNU LGPL

function xTimerMgr()
{
  this.timers = new Array();
}

// xTimerMgr Methods
xTimerMgr.prototype.set = function(type, obj, sMethod, uTime, data) // type: 'interval' or 'timeout'
{
  return (this.timers[this.timers.length] = new xTimerObj(type, obj, sMethod, uTime, data));
};
xTimerMgr.prototype.run = function()
{
  var i, t, d = new Date(), now = d.getTime();
  for (i = 0; i < this.timers.length; ++i) {
    t = this.timers[i];
    if (t && t.running) {
      t.elapsed = now - t.time0;
      if (t.elapsed >= t.preset) { // timer event on t
        t.obj[t.mthd](t); // pass listener this xTimerObj
        if (t.type.charAt(0) == 'i') { t.time0 = now; }
        else { t.stop(); }
      }  
    }
  }
};

// Object Prototype used only by xTimerMgr
function xTimerObj(type, obj, mthd, preset, data)
{
  // Public Properties
  this.data = data;
  // Read-only Properties
  this.type = type; // 'interval' or 'timeout'
  this.obj = obj;
  this.mthd = mthd; // string
  this.preset = preset;
  this.reset();
} // end xTimerObj constructor
// xTimerObj Methods
xTimerObj.prototype.stop = function() { this.running = false; };
xTimerObj.prototype.start = function() { this.running = true; }; // continue after a stop
xTimerObj.prototype.reset = function()
{
  var d = new Date();
  this.time0 = d.getTime();
  this.elapsed = 0;
  this.running = true;
};

var xTimer = new xTimerMgr(); // applications assume global name is 'xTimer'
setInterval('xTimer.run()', 250);
// xTooltipGroup, Copyright 2002,2003,2004,2005 Michael Foster (Cross-Browser.com)
// Part of X, a Cross-Browser Javascript Library, Distributed under the terms of the GNU LGPL

document.write("<style type='text/css'>#xTooltipElement{position:absolute;visibility:hidden;}</style>");
document.write("<div id='xTooltipElement'>xTooltipElement</div>");

var xttTrigger = null; // current trigger element

function xTooltipGroup(grpClassOrIdList, tipClass, origin, xOffset, yOffset, textList)
{

  //// Properties

  this.c = tipClass;
  this.o = origin;
  this.x = xOffset;
  this.y = yOffset;
  this.t = null; // tooltip element - all groups use the same element

  //// Constructor Code

  var i, tips;
  if (xStr(grpClassOrIdList)) {
    tips = xGetElementsByClassName(grpClassOrIdList);
    for (i = 0; i < tips.length; ++i) {
      tips[i].xTooltip = this;
    }
  }
  else {
    tips = new Array();
    for (i = 0; i < grpClassOrIdList.length; ++i) {
      tips[i] = xGetElementById(grpClassOrIdList[i]);
      if (!tips[i]) {
        alert('Element not found for id = ' + grpClassOrIdList[i]);
      }  
      else {
        tips[i].xTooltip = this;
        tips[i].xTooltipText = textList[i];
      }
    }
  }
  if (!this.t) { // only execute once
    this.t = xGetElementById('xTooltipElement');
    xAddEventListener(document, 'mousemove', this.docOnMousemove, false);
  }
} // end xTooltipGroup ctor

//// xTooltipGroup Methods

xTooltipGroup.prototype.show = function(trigEle, mx, my)
{
  if (xttTrigger != trigEle) { // if not active or moved to an adjacent trigger
    this.t.className = trigEle.xTooltip.c;
    this.t.innerHTML = trigEle.xTooltipText ? trigEle.xTooltipText : trigEle.title;
    xttTrigger = trigEle;
  }  
  var x, y;
  switch(this.o) {
    case 'right':
      x = xPageX(trigEle) + xWidth(trigEle);
      y = xPageY(trigEle);
      break;
    case 'top':
      x = xPageX(trigEle);
      y = xPageY(trigEle) - xHeight(trigEle);
      break;
    case 'mouse':
      x = mx;
      y = my;
      break;
  }
  xMoveTo(this.t, x + this.x, y + this.y);
  xShow(this.t);
};

xTooltipGroup.prototype.hide = function()
{
  xMoveTo(this.t, -1000, -1000);
  xttTrigger = null;
};

xTooltipGroup.prototype.docOnMousemove = function(oEvent)
{
  // this == document at runtime
  var o, e = new xEvent(oEvent);
  if (e.target && (o = e.target.xTooltip)) {
    o.show(e.target, e.pageX, e.pageY);
  }
  else if (xttTrigger) {
    xttTrigger.xTooltip.hide();
  }
};
// xTop, Copyright 2001-2005 Michael Foster (Cross-Browser.com)
// Part of X, a Cross-Browser Javascript Library, Distributed under the terms of the GNU LGPL

function xTop(e, iY)
{
  if(!(e=xGetElementById(e))) return 0;
  var css=xDef(e.style);
  if(css && xStr(e.style.top)) {
    if(xNum(iY)) e.style.top=iY+'px';
    else {
      iY=parseInt(e.style.top);
      if(isNaN(iY)) iY=0;
    }
  }
  else if(css && xDef(e.style.pixelTop)) {
    if(xNum(iY)) e.style.pixelTop=iY;
    else iY=e.style.pixelTop;
  }
  return iY;
}
// xTriStateImage, Copyright 2004,2005 Michael Foster (Cross-Browser.com)
// Part of X, a Cross-Browser Javascript Library, Distributed under the terms of the GNU LGPL

function xTriStateImage(idOut, urlOver, urlDown, fnUp) // Object Prototype
{
  var img;
  // Downgrade Detection
  if (typeof Image != 'undefined' && document.getElementById) {
    img = document.getElementById(idOut);
    if (img) {
      // Constructor Code
      var urlOut = img.src;
      var i = new Image();
      i.src = urlOver;
      i = new Image();
      i.src = urlDown;
      // Event Listeners (closure)
      img.onmouseover = function()
      {
        this.src = urlOver;
      };
      img.onmouseout = function()
      {
        this.src = urlOut;
      };
      img.onmousedown = function()
      {
        this.src = urlDown;
      };
      img.onmouseup = function()
      {
        this.src = urlOver;
        if (fnUp) {
          fnUp();
        }
      };
    }
  }
  // Destructor Method
  this.onunload = function()
  {
    if (xIE4Up && img) { // Remove any circular references for IE
      img.onmouseover = img.onmouseout = img.onmousedown = null;
      img = null;
    }
  };    
}
var xVersion = "4.0";// xVisibility, Copyright 2003-2005 Michael Foster (Cross-Browser.com)
// Part of X, a Cross-Browser Javascript Library, Distributed under the terms of the GNU LGPL

function xVisibility(e, bShow)
{
  if(!(e=xGetElementById(e))) return null;
  if(e.style && xDef(e.style.visibility)) {
    if (xDef(bShow)) e.style.visibility = bShow ? 'visible' : 'hidden';
    return e.style.visibility;
  }
  return null;
}

//function xVisibility(e,s)
//{
//  if(!(e=xGetElementById(e))) return null;
//  var v = 'visible', h = 'hidden';
//  if(e.style && xDef(e.style.visibility)) {
//    if (xDef(s)) {
//      // try to maintain backwards compatibility (???)
//      if (xStr(s)) e.style.visibility = s;
//      else e.style.visibility = s ? v : h;
//    }
//    return e.style.visibility;
//    // or...
//    // if (e.style.visibility.length) return e.style.visibility;
//    // else return xGetComputedStyle(e, 'visibility');
//  }
//  else if (xDef(e.visibility)) { // NN4
//    if (xDef(s)) {
//      // try to maintain backwards compatibility
//      if (xStr(s)) e.visibility = (s == v) ? 'show' : 'hide';
//      else e.visibility = s ? v : h;
//    }
//    return (e.visibility == 'show') ? v : h;
//  }
//  return null;
//}
// xWalkEleTree, Copyright 2005 Michael Foster (Cross-Browser.com)
// Part of X, a Cross-Browser Javascript Library, Distributed under the terms of the GNU LGPL

function xWalkEleTree(n,f,d,l,b)
{
  if (typeof l == 'undefined') l = 0;
  if (typeof b == 'undefined') b = 0;
  var v = f(n,l,b,d);
  if (!v) return 0;
  if (v == 1) {
    for (var c = n.firstChild; c; c = c.nextSibling) {
      if (c.nodeType == 1) {
        if (!l) ++b;
        if (!xWalkEleTree(c,f,d,l+1,b)) return 0;
      }
    }
  }
  return 1;
}
// xWalkTree, Copyright 2001-2005 Michael Foster (Cross-Browser.com)
// Part of X, a Cross-Browser Javascript Library, Distributed under the terms of the GNU LGPL

function xWalkTree(n, f)
{
  f(n);
  for (var c = n.firstChild; c; c = c.nextSibling) {
    if (c.nodeType == 1) xWalkTree(c, f);
  }
}

// original implementation:
// function xWalkTree(oNode, fnVisit)
// {
//   if (oNode) {
//     if (oNode.nodeType == 1) {fnVisit(oNode);}
//     for (var c = oNode.firstChild; c; c = c.nextSibling) {
//       xWalkTree(c, fnVisit);
//     }
//   }
// }
// xWidth, Copyright 2001-2005 Michael Foster (Cross-Browser.com)
// Part of X, a Cross-Browser Javascript Library, Distributed under the terms of the GNU LGPL

function xWidth(e,w)
{
  if(!(e=xGetElementById(e))) return 0;
  if (xNum(w)) {
    if (w<0) w = 0;
    else w=Math.round(w);
  }
  else w=-1;
  var css=xDef(e.style);
  if (e == document || e.tagName.toLowerCase() == 'html' || e.tagName.toLowerCase() == 'body') {
    w = xClientWidth();
  }
  else if(css && xDef(e.offsetWidth) && xStr(e.style.width)) {
    if(w>=0) {
      var pl=0,pr=0,bl=0,br=0;
      if (document.compatMode=='CSS1Compat') {
        var gcs = xGetComputedStyle;
        pl=gcs(e,'padding-left',1);
        if (pl !== null) {
          pr=gcs(e,'padding-right',1);
          bl=gcs(e,'border-left-width',1);
          br=gcs(e,'border-right-width',1);
        }
        // Should we try this as a last resort?
        // At this point getComputedStyle and currentStyle do not exist.
        else if(xDef(e.offsetWidth,e.style.width)){
          e.style.width=w+'px';
          pl=e.offsetWidth-w;
        }
      }
      w-=(pl+pr+bl+br);
      if(isNaN(w)||w<0) return;
      else e.style.width=w+'px';
    }
    w=e.offsetWidth;
  }
  else if(css && xDef(e.style.pixelWidth)) {
    if(w>=0) e.style.pixelWidth=w;
    w=e.style.pixelWidth;
  }
  return w;
}
// xWinClass, Copyright 2003-2005 Michael Foster (Cross-Browser.com)
// Part of X, a Cross-Browser Javascript Library, Distributed under the terms of the GNU LGPL

// xWinClass Object Prototype

function xWinClass(clsName, winName, w, h, x, y, loc, men, res, scr, sta, too)
{
  var thisObj = this;
  var e='',c=',',xf='left=',yf='top='; this.n = name;
  if (document.layers) {xf='screenX='; yf='screenY=';}
  this.f = (w?'width='+w+c:e)+(h?'height='+h+c:e)+(x>=0?xf+x+c:e)+
    (y>=0?yf+y+c:e)+'location='+loc+',menubar='+men+',resizable='+res+
    ',scrollbars='+scr+',status='+sta+',toolbar='+too;
  this.opened = function() {return this.w && !this.w.closed;};
  this.close = function() {if(this.opened()) this.w.close();};
  this.focus = function() {if(this.opened()) this.w.focus();};
  this.load = function(sUrl) {
    if (this.opened()) this.w.location.href = sUrl;
    else this.w = window.open(sUrl,this.n,this.f);
    this.focus();
    return false;
  };
  // Closures
  // this == <A> element reference, thisObj == xWinClass object reference
  function onClick() {return thisObj.load(this.href);}
  // '*' works with any element, not just A
  xGetElementsByClassName(clsName, document, '*', bindOnClick);
  function bindOnClick(e) {e.onclick = onClick;}
}
// xWindow, Copyright 2001-2005 Michael Foster (Cross-Browser.com)
// Part of X, a Cross-Browser Javascript Library, Distributed under the terms of the GNU LGPL

function xWindow(name, w, h, x, y, loc, men, res, scr, sta, too)
{
  var e='',c=',',xf='left=',yf='top='; this.n = name;
  if (document.layers) {xf='screenX='; yf='screenY=';}
  this.f = (w?'width='+w+c:e)+(h?'height='+h+c:e)+(x>=0?xf+x+c:e)+
    (y>=0?yf+y+c:e)+'location='+loc+',menubar='+men+',resizable='+res+
    ',scrollbars='+scr+',status='+sta+',toolbar='+too;
  this.opened = function() {return this.w && !this.w.closed;};
  this.close = function() {if(this.opened()) this.w.close();};
  this.focus = function() {if(this.opened()) this.w.focus();};
  this.load = function(sUrl) {
    if (this.opened()) this.w.location.href = sUrl;
    else this.w = window.open(sUrl,this.n,this.f);
    this.focus();
    return false;
  };
}

// Previous implementation:
// function xWindow(name, w, h, x, y, loc, men, res, scr, sta, too)
// {
//   var f = '';
//   if (w && h) {
//     if (document.layers) f = 'screenX=' + x + ',screenY=' + y;
//     else f = 'left=' + x + ',top=' + y;
//     f += ',width=' + w + ',height=' + h + ',';
//   }
//   f += ('location='+loc+',menubar='+men+',resizable='+res
//     +',scrollbars='+scr+',status='+sta+',toolbar='+too);
//   this.features = f;
//   this.name = name;
//   this.load = function(sUrl) {
//     if (this.wnd && !this.wnd.closed) this.wnd.location.href = sUrl;
//     else this.wnd = window.open(sUrl, this.name, this.features);
//     this.wnd.focus();
//     return false;
//   }
// }
// xWinOpen, Copyright 2003-2005 Michael Foster (Cross-Browser.com)
// Part of X, a Cross-Browser Javascript Library, Distributed under the terms of the GNU LGPL

// A simple alternative to xWindow.

var xChildWindow = null;
function xWinOpen(sUrl)
{
  var features = "left=0,top=0,width=600,height=500,location=0,menubar=0," +
    "resizable=1,scrollbars=1,status=0,toolbar=0";
  if (xChildWindow && !xChildWindow.closed) {xChildWindow.location.href  = sUrl;}
  else {xChildWindow = window.open(sUrl, "myWinName", features);}
  xChildWindow.focus();
  return false;
}
// xWinScrollTo, Copyright 2003-2005 Michael Foster (Cross-Browser.com)
// Part of X, a Cross-Browser Javascript Library, Distributed under the terms of the GNU LGPL

var xWinScrollWin = null;
function xWinScrollTo(win,x,y,uTime) {
  var e = win;
  if (!e.timeout) e.timeout = 25;
  var st = xScrollTop(e, 1);
  var sl = xScrollLeft(e, 1);
  e.xTarget = x; e.yTarget = y; e.slideTime = uTime; e.stop = false;
  e.yA = e.yTarget - st;
  e.xA = e.xTarget - sl; // A = distance
  e.B = Math.PI / (2 * e.slideTime); // B = period
  e.yD = st;
  e.xD = sl; // D = initial position
  var d = new Date(); e.C = d.getTime();
  if (!e.moving) {
    xWinScrollWin = e;
    _xWinScrollTo();
  }
}
function _xWinScrollTo() {
  var e = xWinScrollWin || window;
  var now, s, t, newY, newX;
  now = new Date();
  t = now.getTime() - e.C;
  if (e.stop) { e.moving = false; }
  else if (t < e.slideTime) {
    setTimeout("_xWinScrollTo()", e.timeout);
    s = Math.sin(e.B * t);
    newX = Math.round(e.xA * s + e.xD);
    newY = Math.round(e.yA * s + e.yD);
    e.scrollTo(newX, newY);
    e.moving = true;
  }  
  else {
    e.scrollTo(e.xTarget, e.yTarget);
    xWinScrollWin = null;
    e.moving = false;
  }  
}
// xZIndex, Copyright 2001-2005 Michael Foster (Cross-Browser.com)
// Part of X, a Cross-Browser Javascript Library, Distributed under the terms of the GNU LGPL

function xZIndex(e,uZ)
{
  if(!(e=xGetElementById(e))) return 0;
  if(e.style && xDef(e.style.zIndex)) {
    if(xNum(uZ)) e.style.zIndex=uZ;
    uZ=parseInt(e.style.zIndex);
  }
  return uZ;
}}
/* FILE:FreeanceWeb/Common/lib/TemplateLibraryJIT.js */ if(!window.freeance_loaded_js['613b222fc97209d9b8e3eb21bb844945']){window.freeance_loaded_js['613b222fc97209d9b8e3eb21bb844945']=1;
function TemplateWidget()
{
  /* Internal Variables */
  this.imethod = "var html = new Array();";  // "var html = '';"
  this.smethod = "html.push(";  // "html += ";
  this.emethod = ");\n";  // ";\n";
  this.cmethod = "return(html.join(''));\n";  // "return(html);\n"
  this.badAttributeCharacters = Array();
  
  /************************************************************/
  this.escapeDoubleQuotes = function(str)
  {
    //var safe1 = String.replaceStr(str,'"','\\"',false);
    return(str.replace(/\"/g,'\\"'));
  };
  /************************************************************/
  this.modifyBadAttributeCharacters = function(theHTML)
  {
    for(var lcv=0;lcv < this.badAttributeCharacters.length;lcv++)
      theHTML = String.replaceStr(theHTML,this.badAttributeCharacters[lcv][0],this.badAttributeCharacters[lcv][1],false);
    return(theHTML);
  };
  /************************************************************/
  this.rebuildNode = function(node)
  {
    var nodeStrObj = {
      start: '<'+node.nodeName,
      template: Array()
    };
    var attribStr = '';
    for(var key=0;key < node.attributes.length;key++)
    {
      if (node.attributes[key].specified)
      {
        var attribName = node.attributes[key].name;
        var attribValue = node.attributes[key].value;
        if (attribName.substr(0,9) != 'template_')
          attribStr += ' '+attribName+'="'+attribValue+'"';
        else
          nodeStrObj.template[attribName] = attribValue;
      }
    }
    nodeStrObj.start += this.escapeDoubleQuotes(attribStr) + '>';
    nodeStrObj.end = '</'+node.nodeName+'>';
    return(nodeStrObj);
  };
  /************************************************************/
  this.templateToJS = function(theHTML)
  {
    var thedoc = XmlDocument.create();
    theHTML = ['<span>',this.modifyBadAttributeCharacters(theHTML.replace(/\\/g,'\\\\').replace(/\n/g,'\\n')),'</span>'].join('');
    thedoc.loadXML(theHTML);
    node = thedoc.documentElement;
    var srcCode = this.imethod+"\n"+this.process(node);
    var JSObj = {
      html: theHTML,
      srcCode: srcCode,
      toEval: "JSObj.run = function(data){ "+srcCode+"\n"+this.cmethod+" }"
    };
    try{
      eval(JSObj.toEval); 
    }
    catch(e)
    {
      var errstr = '';
      e.sourceHTML = JSObj.html;
      var xmlstr = (typeof(thedoc.xml)=='function')?thedoc.xml():thedoc.xml;
      e.postHTML = xmlstr;
      JSObj.errstr = 'Invalid Template: '+e.message+' on line '+e.lineNumber+'\n~~~~~~~~~~~~~~~~~~~~~~~~~\nPost HTML: '+e.postHTML+'\n~~~~~~~~~~~~~~~~~~~~~~~~~\nSource HTML: '+e.sourceHTML;
      JSObj.run = function(data){ return('<textarea height="100%" width="100%" style="width:100%;height:100%">'+JSObj.errstr+'\n~~~~~~~~~~~~~~~~~~~~~~~~~\nCode:\n'+JSObj.srcCode+'</textarea>'); }  // return to this line eventually after debugging
    }
    return(JSObj);
  };
  /************************************************************/
  this.process = function(node,dataprefix,nestlevel,parentLoop)
  {
/*
      case 'dboption': this.renderDBOption(elem,data); break;  // should add arraypos implementation
 ** visibility
 ** tooltip
 ** postexec
*/
    if (typeof(dataprefix) == 'undefined')
      dataprefix = '';
    if (typeof(nestlevel) == 'undefined')
      nestlevel = 0;
    if (typeof(parentLoop) == 'undefined')
      parentLoop = '';
    var loopnumber = 0;
    var srcCode = [];
    if (node == null) return('');
    var okToPreProcess = true;
    var okToDescend = true;
    var okToPostProcess = true;
    var smethod = this.smethod;
    var emethod = this.emethod;
    switch (node.nodeType)
    {
      case 1: // element
        var rebuild = this.rebuildNode(node);
        if ((typeof rebuild.template['template_enabled'] != 'undefined') && (rebuild.template['template_enabled'].toUpperCase() == 'Y'))
        {
          switch(rebuild.template['template_type'].toLowerCase())
          {
            case 'dbvalue':
                okToPreProcess = okToDescend = false;
                srcCode.push(
                  smethod,'"',rebuild.start.substr(0,rebuild.start.length-1),
                  ' datavalue=\\"','"',this.emethod,
                  smethod,'(data',dataprefix,'["',rebuild.template['template_value_field'],
                  '"])?document._JITT_.decodeHTMLEntities(data',dataprefix,'["',
                  rebuild.template['template_value_field'],'"]):""',emethod,  // may need to have quick function to check if not missing or blank what to do, i.e. put in a &nbsp;
                  smethod,'"\\">"',emethod,
                  smethod,'(data',dataprefix,
                  '["',rebuild.template['template_value_field'],'"])?data',
                  dataprefix,'["',rebuild.template['template_value_field'],
                  '"]:"&nbsp;"',emethod  // may need to have quick function to check if not missing or blank what to do, i.e. put in a &nbsp;
                );
                break;
            case 'block':
                dataprefix += '["'+rebuild.template['template_value_field']+'"]';
                srcCode.push('if (typeof(data',dataprefix,')==\'undefined\') data',dataprefix,"=Array();\n");
                break;
            case 'repeatblock':
                okToPreProcess = okToDescend = okToPostProcess = false;
                if (rebuild.template['template_value_field'])
                  dataprefix += '["'+rebuild.template['template_value_field']+'"]';
                var loopname = 'loop'+nestlevel+'_'+loopnumber;
                srcCode.push('for(var ',loopname,' in data',dataprefix,')\n',
                  '{\n',
                  'if(',loopname,'==\'toJSONString\'){continue;}',
                  smethod,' "',rebuild.start,'"',emethod
                );
                loopnumber++;
                dataprefix += '['+loopname+']';
                parentLoop = loopname;
                for(var ilv=0;ilv < node.childNodes.length;ilv++)
                  srcCode.push(this.process(node.childNodes[ilv],dataprefix,++nestlevel,parentLoop));
                srcCode.push(smethod,' "',rebuild.end,'"',emethod,'}\n');
                break;
             case 'rownum':
                var offset = 0;
                if (rebuild.template['template_startwith'])
                  offset = parseInt(rebuild.template['template_startwith']);
                srcCode.push(smethod);
                if (offset > 0)
                  srcCode.push(offset,'+');
                else if (offset < 0)
                  srcCode.push(offset);
                srcCode.push('parseInt(',parentLoop,')',emethod);
                break;
             case 'date':
                okToDescend = false;
                var format = (rebuild.template['template_format']?rebuild.template['template_format']:"");
                srcCode.push(smethod,'document._JITT_.buildDate(null,"',format,'")',emethod);
                break;
             case 'dbdate':
                okToDescend = false;
                var field = rebuild.template['template_value_field']?rebuild.template['template_value_field']:"";
                if (field != "")
                  srcCode.push(smethod,'document._JITT_.buildDate(',
				  '(data',dataprefix,'["',rebuild.template['template_value_field'],'"])?data',dataprefix,'["',rebuild.template['template_value_field'],'"]:"",',
                  (rebuild.template['template_format']?('"'+rebuild.template['template_format']+'"'):'""'),',',
				  (rebuild.template['template_offset']?('"'+rebuild.template['template_offset']+'"'):'""'),
                    ')',emethod);
                else
                  srcCode.push(smethod,"&nbsp;",emethod);
                break;
             case 'time':
                okToDescend = false;
                srcCode.push(smethod,'document._JITT_.buildTime(null,"',
                  (rebuild.template['template_format']?rebuild.template['template_format']:""),
                  '")',emethod);
                break;
             case 'dbtime':
                okToDescend = false;
                var field = rebuild.template['template_value_field']?rebuild.template['template_value_field']:"";
                if (field != "")
                  srcCode.push(smethod,
                    'document._JITT_.buildTime((data',
                      dataprefix,'["',rebuild.template['template_value_field'],'"])?data',
                      dataprefix,'["',rebuild.template['template_value_field'],'"]:"",',
                      (rebuild.template['template_format']?('"'+rebuild.template['template_format']+'"'):'""'),')',emethod);
                else
                  srcCode.push(smethod,"&nbsp;",emethod);
                break;
            case 'anchor':
                okToPreProcess = okToDescend = false;
                srcCode.push(smethod,'"',rebuild.start.substr(0,rebuild.start.length-1),
                  ' href=\\"','"',emethod,
                  smethod,'"',rebuild.template['template_beforeurl'],'"',emethod,
                  smethod,'(data',dataprefix,'["',rebuild.template['template_urlfield'],
                    '"])?document._JITT_.decodeHTMLEntities(data',dataprefix,'["',rebuild.template['template_urlfield'],'"]):""',emethod,
                  smethod,'"',rebuild.template['template_afterurl'],'"',emethod,
                  smethod,'"\\">"',emethod,
                  smethod,'"',rebuild.template['template_beforelabel'],'"',emethod,
                  smethod,'(data',dataprefix,'["',rebuild.template['template_labelfield'],'"])?data',
                  dataprefix,'["',rebuild.template['template_labelfield'],'"]:""',emethod,
                  smethod,'"',rebuild.template['template_afterlabel'],'"',emethod
                );
                break;
            case 'dbimage':
                okToPreProcess = okToDescend = false;
                srcCode.push(smethod,'"',rebuild.start.substr(0,rebuild.start.length-1),
                  ' src=\\"','"',emethod,
                  smethod,'"',rebuild.template['template_beforeurl'],'"',emethod,
                  smethod,'(data',dataprefix,'["',rebuild.template['template_urlfield'],
                  '"])?document._JITT_.decodeHTMLEntities(data',dataprefix,'["',rebuild.template['template_urlfield'],'"]):""',emethod,
                  smethod,'"',rebuild.template['template_afterurl'],'"',emethod,
                  smethod,'"\\""',emethod,
                  smethod,'" alt=\\"','"',emethod,
                  smethod,'"',rebuild.template['template_beforealt'],'"',emethod,
                  smethod,'(data',dataprefix,'["',rebuild.template['template_altfield'],'"])?data',
                  dataprefix,'["',rebuild.template['template_altfield'],'"]:""',emethod,
                  smethod,'"',rebuild.template['template_afteralt'],'"',emethod,
                  smethod,'"\\""',emethod,
                  smethod,'" title=\\"','"',emethod,
                  smethod,'"',rebuild.template['template_beforealt'],'"',emethod,
                  smethod,'(data',dataprefix,'["',rebuild.template['template_altfield'],'"])?data',dataprefix,
                  '["',rebuild.template['template_altfield'],'"]:""',emethod,
                  smethod,'"',rebuild.template['template_afteralt'],'"',emethod,
                  smethod,'"\\">"',emethod
                );
                break;
            case 'maplink':
                okToPreProcess = okToDescend = false;
                srcCode.push(smethod,'"',rebuild.start.substr(0,rebuild.start.length-1),
                  ' datavalue=\\"','"',emethod,  // TODO:  Detect if key field is not present, substitute value field in that case.
                  smethod,'(data',dataprefix,'["',rebuild.template['template_key_field'],'"])?document._JITT_.decodeHTMLEntities(data',
                  dataprefix,'["',rebuild.template['template_key_field'],'"]):""',emethod, // may need to have quick function to check if not missing or blank what to do, i.e. put in a &nbsp;
                  smethod,'"\\">"',emethod,
                  smethod,'(data',dataprefix,'["',rebuild.template['template_display_field']?rebuild.template['template_display_field']:rebuild.template['template_value_field'],'"])?data',
                  dataprefix,'["',
                  rebuild.template['template_display_field']?rebuild.template['template_display_field']:rebuild.template['template_value_field'],'"]:"&nbsp;"',emethod
                );  // may need to have quick function to check if not missing or blank what to do, i.e. put in a &nbsp;
                break;
            case 'path':
                okToPreProcess = okToDescend = false;
                srcCode.push('html.push("',rebuild.start.substr(0,rebuild.start.length-1),' FREEANCE_TYPE=\\"path\\" pathvalue=\\"",');
                srcCode.push('(data[1][0]["',rebuild.template['template_path_field'],'"])?document._JITT_.decodeHTMLEntities(data[1][0]["',rebuild.template['template_path_field'],'"]):" ",');
                srcCode.push('"\\">',rebuild.template['template_text'],'");\n');
                break;
            case 'follow':
                okToPreProcess = okToDescend = false;
                srcCode.push('html.push("',rebuild.start.substr(0,rebuild.start.length-1),' FREEANCE_TYPE=\\"chase\\" chasevalue=\\"",');
                srcCode.push('(data[1][0]["',rebuild.template['template_chase_field'],'"])?document._JITT_.decodeHTMLEntities(data[1][0]["',rebuild.template['template_chase_field'],'"]):" ",');
                srcCode.push('"\\">',rebuild.template['template_text'],'");\n');
                break;
          }
        }
        if (okToPreProcess)
          if (rebuild.start)
              srcCode.unshift(smethod,'"',rebuild.start,'"',emethod);
        if (okToDescend)
        {
          for(var ilv=0;ilv < node.childNodes.length;ilv++)
            srcCode.push(this.process(node.childNodes[ilv],dataprefix,++nestlevel,parentLoop));
        }
        if (okToPostProcess)
          if (rebuild.end)
            srcCode.push(smethod,'"',rebuild.end,'"',emethod);
        break;
      case 3:
      case 4:
        okToPreProcess = okToDescend = okToPostProcess = false;
        srcCode.push(smethod,'"',this.escapeDoubleQuotes(node.nodeValue),'"',emethod);
        break;
    }
    return(srcCode.join(''));
  };
  /************************************************************/
  this.renderFromHTMLElement = function(sourceElement,targetElement,data)
  {
    targetElement.innerHTML = this.templateToJS(sourceElement.innerHTML).run(data);
  };
  /************************************************************/
  this.renderFromHTMLString = function(sourcehtml,targetElement,data)
  {
    targetElement.innerHTML = this.templateToJS(sourcehtml).run(data);
  };
  /************************************************************/
  // for date/dbdate
  this.badAttributeCharacters.push(
    ['<YYYY>','&lt;YYYY&gt;'],
    ['<YY>','&lt;YY&gt;'],['<MMM>','&lt;MMM&gt;'],['<MM>','&lt;MM&gt;'],['<M>','&lt;M&gt;'],['<DDD>','&lt;DDD&gt;'],['<DD>','&lt;DD&gt;'],
    ['<D>','&lt;D&gt;'],
    ['<HH>','&lt;HH&gt;'],
    ['<hh>','&lt;hh&gt;'],
    ['<H>','&lt;H&gt;'],
    ['<h>','&lt;h&gt;'],
    ['<mm>','&lt;mm&gt;'],
    ['<ss>','&lt;ss&gt;'],
    ['<ampm>','&lt;ampm&gt;'],
    ['<AMPM>','&lt;AMPM&gt;']
  );
};
/************************************************************/
/* JITT's inline accessory functions */
/************************************************************/
document._JITT_ = {
twoDigitStr: function(value)
{
  var str = new String(value);
  if (value < 10)
    str = '0'+str;
  return(str);
},
buildDate: function(datestr,format,offset)
{
  if (datestr == "") return('&nbsp;');
  if (!document._JITT_.jitstore)
  {
    if ((document.babelfish) && (document.babelfish.getActiveLanguage() != 'EN'))
    {
      document._JITT_.jitstore={
        FullMonths: Array(document.babelfish.translateWord('January'),document.babelfish.translateWord('February'),document.babelfish.translateWord('March'),document.babelfish.translateWord('April'),document.babelfish.translateWord('May'),document.babelfish.translateWord('June'),document.babelfish.translateWord('July'),document.babelfish.translateWord('August'),document.babelfish.translateWord('September'),document.babelfish.translateWord('October'),document.babelfish.translateWord('November'),document.babelfish.translateWord('December')),
        ShortMonths: Array(document.babelfish.translateWord('Jan'),document.babelfish.translateWord('Feb'),document.babelfish.translateWord('Mar'),document.babelfish.translateWord('Apr'),document.babelfish.translateWord('May'),document.babelfish.translateWord('Jun'),document.babelfish.translateWord('Jul'),document.babelfish.translateWord('Aug'),document.babelfish.translateWord('Sep'),document.babelfish.translateWord('Oct'),document.babelfish.translateWord('Nov'),document.babelfish.translateWord('Dec')),
        FullDOW: Array(document.babelfish.translateWord('Sunday'),document.babelfish.translateWord('Monday'),document.babelfish.translateWord('Tuesday'),document.babelfish.translateWord('Wednesday'),document.babelfish.translateWord('Thursday'),document.babelfish.translateWord('Friday'),document.babelfish.translateWord('Saturday')),
        ShortDOW: Array(document.babelfish.translateWord('Sun'),document.babelfish.translateWord('Mon'),document.babelfish.translateWord('Tue'),document.babelfish.translateWord('Wed'),document.babelfish.translateWord('Thu'),document.babelfish.translateWord('Fri'),document.babelfish.translateWord('Sat'))
      };
    }
    else
    {
      document._JITT_.jitstore={
        FullMonths: ['January','February','March','April','May','June','July','August','September','October','November','December'],
        ShortMonths: ['Jan','Feb','Mar','Apr','May','Jun','Jul','Aug','Sep','Oct','Nov','Dec'],
        FullDOW: ['Sunday','Monday','Tuesday','Wednesday','Thursday','Friday','Saturday'],
        ShortDOW: ['Sun','Mon','Tue','Wed','Thu','Fri','Sat']
      }
    }
  };
  if (format == '')
    format = '<M> <DD>, <YYYY>';  // something goofed... set default
  var thedate = (datestr == null)?(new Date()):(new Date(parseInt(datestr)));
  if(offset == '' || offset == 'undefined')
    offset = '0';
  thedate.setHours(thedate.getHours() + parseInt(offset));
  var year = thedate.getYear();
  if (year < 1900)
    year += 1900;
  var shortyear = year % 100;
  return (format.replace(/<YYYY>/g,year).replace(/<YY>/g,document._JITT_.twoDigitStr(shortyear)).replace(/<MMM>/g,document._JITT_.jitstore.ShortMonths[thedate.getMonth()]).replace(/<MM>/g,document._JITT_.twoDigitStr(thedate.getMonth()+1)).replace(/<M>/g,document._JITT_.jitstore.FullMonths[thedate.getMonth()]).replace(/<DDD>/g,document._JITT_.jitstore.ShortDOW[thedate.getDay()]).replace(/<DD>/g,document._JITT_.twoDigitStr(thedate.getDate())).replace(/<D>/g,document._JITT_.jitstore.FullDOW[thedate.getDay()]));  
},
buildTime: function(timestr,format)
{
  if (timestr == "") return('&nbsp;');
  if (!document._JITT_.jitstore)
  {
    document._JITT_.jitstore = new Object();
  }
  if ((!document._JITT_.jitstore.am)||(!document._JITT_.jitstore.pm))
  {
    if ((document.babelfish) && (document.babelfish.getActiveLanguage() != 'EN'))
    {
      document._JITT_.jitstore.am = document.babelfish.translateWord('am');
      document._JITT_.jitstore.pm = document.babelfish.translateWord('pm');
    }
    else
    {
      document._JITT_.jitstore.am = 'am';
      document._JITT_.jitstore.pm = 'pm';
    }
  }
  if (format == '')
    format = '<h>:<mm><ampm>';  // something goofed... set default
  var timenow = (timestr == null)?(new Date()):(new Date(parseInt(timestr)));
  var ampm = (timenow.getHours() <= 11)?document._JITT_.jitstore.am:document._JITT_.jitstore.pm;
  var ampmhours = timenow.getHours() % 12;
  if (ampmhours == 0)
    ampmhours = 12; // midnight
  format.replace('<HH>',document._JITT_.twoDigitStr(timenow.getHours())).replace(/<hh>/,document._JITT_.twoDigitStr(ampmhours)).replace(/<H>/,timenow.getHours()).replace(/<h>/,ampmhours).replace(/<mm>/,document._JITT_.twoDigitStr(timenow.getMinutes())).replace(/<ss>/,document._JITT_.twoDigitStr(timenow.getSeconds())).replace(/<ampm>/,ampm).replace(/<AMPM>/,ampm.toUpperCase());
  return(format);
},
decodeHTMLEntities: function(orig)
{
  /* &copy; 	&reg; 	&bull; */
  return orig.toString().replace(/&amp;/g,'&').replace(/&nbsp;/g,' ').replace(/&gt;/g,'>').replace(/&lt;/g,'<').replace(/&quot;/g,'&');
}
};}
/* FILE:FreeanceWeb/Common/lib/contrib/wz_jsgraphics.js */ if(!window.freeance_loaded_js['ce7a8000506bb70376d47e34424e6b6f']){window.freeance_loaded_js['ce7a8000506bb70376d47e34424e6b6f']=1;
/* This notice must be untouched at all times.

wz_jsgraphics.js    v. 3.05
The latest version is available at
http://www.walterzorn.com
or http://www.devira.com
or http://www.walterzorn.de

Copyright (c) 2002-2009 Walter Zorn. All rights reserved.
Created 3. 11. 2002 by Walter Zorn (Web: http://www.walterzorn.com )
Last modified: 2. 2. 2009

Performance optimizations for Internet Explorer
by Thomas Frank and John Holdsworth.
fillPolygon method implemented by Matthieu Haller.

High Performance JavaScript Graphics Library.
Provides methods
- to draw lines, rectangles, ellipses, polygons
	with specifiable line thickness,
- to fill rectangles, polygons, ellipses and arcs
- to draw text.
NOTE: Operations, functions and branching have rather been optimized
to efficiency and speed than to shortness of source code.

LICENSE: LGPL

This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License (LGPL) as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.

This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
Lesser General Public License for more details.

You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA,
or see http://www.gnu.org/copyleft/lesser.html
*/


var jg_ok, jg_ie, jg_fast, jg_dom, jg_moz;


function _chkDHTM(wnd, x, i)
// Under XUL, owner of 'document' must be specified explicitly
{
	x = wnd.document.body || null;
	jg_ie = x && typeof x.insertAdjacentHTML != "undefined" && wnd.document.createElement;
	jg_dom = (x && !jg_ie &&
		typeof x.appendChild != "undefined" &&
		typeof wnd.document.createRange != "undefined" &&
		typeof (i = wnd.document.createRange()).setStartBefore != "undefined" &&
		typeof i.createContextualFragment != "undefined");
	jg_fast = jg_ie && wnd.document.all && !wnd.opera;
	jg_moz = jg_dom && typeof x.style.MozOpacity != "undefined";
	jg_ok = !!(jg_ie || jg_dom);
}

function _pntCnvDom()
{
	var x = this.wnd.document.createRange();
	x.setStartBefore(this.cnv);
	x = x.createContextualFragment(jg_fast? this._htmRpc() : this.htm);
	if(this.cnv) this.cnv.appendChild(x);
	this.htm = "";
}

function _pntCnvIe()
{
	if(this.cnv) this.cnv.insertAdjacentHTML("BeforeEnd", jg_fast? this._htmRpc() : this.htm);
	this.htm = "";
}

function _pntDoc()
{
	this.wnd.document.write(jg_fast? this._htmRpc() : this.htm);
	this.htm = '';
}

function _pntN()
{
	;
}

function _mkDiv(x, y, w, h)
{
	this.htm += '<div style="position:absolute;'+
		'left:' + x + 'px;'+
		'top:' + y + 'px;'+
		'width:' + w + 'px;'+
		'height:' + h + 'px;'+
		'clip:rect(0,'+w+'px,'+h+'px,0);'+
		'background-color:' + this.color +
		(!jg_moz? ';overflow:hidden' : '')+
		';"><\/div>';
}

function _mkDivIe(x, y, w, h)
{
	this.htm += '%%'+this.color+';'+x+';'+y+';'+w+';'+h+';';
}

function _mkDivPrt(x, y, w, h)
{
	this.htm += '<div style="position:absolute;'+
		'border-left:' + w + 'px solid ' + this.color + ';'+
		'left:' + x + 'px;'+
		'top:' + y + 'px;'+
		'width:0px;'+
		'height:' + h + 'px;'+
		'clip:rect(0,'+w+'px,'+h+'px,0);'+
		'background-color:' + this.color +
		(!jg_moz? ';overflow:hidden' : '')+
		';"><\/div>';
}

var _regex =  /%%([^;]+);([^;]+);([^;]+);([^;]+);([^;]+);/g;
function _htmRpc()
{
	return this.htm.replace(
		_regex,
		'<div style="overflow:hidden;position:absolute;background-color:'+
		'$1;left:$2px;top:$3px;width:$4px;height:$5px"></div>\n');
}

function _htmPrtRpc()
{
	return this.htm.replace(
		_regex,
		'<div style="overflow:hidden;position:absolute;background-color:'+
		'$1;left:$2px;top:$3px;width:$4px;height:$5px;border-left:$4px solid $1"></div>\n');
}

function _mkLin(x1, y1, x2, y2)
{
	if(x1 > x2)
	{
		var _x2 = x2;
		var _y2 = y2;
		x2 = x1;
		y2 = y1;
		x1 = _x2;
		y1 = _y2;
	}
	var dx = x2-x1, dy = Math.abs(y2-y1),
	x = x1, y = y1,
	yIncr = (y1 > y2)? -1 : 1;

	if(dx >= dy)
	{
		var pr = dy<<1,
		pru = pr - (dx<<1),
		p = pr-dx,
		ox = x;
		while(dx > 0)
		{--dx;
			++x;
			if(p > 0)
			{
				this._mkDiv(ox, y, x-ox, 1);
				y += yIncr;
				p += pru;
				ox = x;
			}
			else p += pr;
		}
		this._mkDiv(ox, y, x2-ox+1, 1);
	}

	else
	{
		var pr = dx<<1,
		pru = pr - (dy<<1),
		p = pr-dy,
		oy = y;
		if(y2 <= y1)
		{
			while(dy > 0)
			{--dy;
				if(p > 0)
				{
					this._mkDiv(x++, y, 1, oy-y+1);
					y += yIncr;
					p += pru;
					oy = y;
				}
				else
				{
					y += yIncr;
					p += pr;
				}
			}
			this._mkDiv(x2, y2, 1, oy-y2+1);
		}
		else
		{
			while(dy > 0)
			{--dy;
				y += yIncr;
				if(p > 0)
				{
					this._mkDiv(x++, oy, 1, y-oy);
					p += pru;
					oy = y;
				}
				else p += pr;
			}
			this._mkDiv(x2, oy, 1, y2-oy+1);
		}
	}
}

function _mkLin2D(x1, y1, x2, y2)
{
	if(x1 > x2)
	{
		var _x2 = x2;
		var _y2 = y2;
		x2 = x1;
		y2 = y1;
		x1 = _x2;
		y1 = _y2;
	}
	var dx = x2-x1, dy = Math.abs(y2-y1),
	x = x1, y = y1,
	yIncr = (y1 > y2)? -1 : 1;

	var s = this.stroke;
	if(dx >= dy)
	{
		if(dx > 0 && s-3 > 0)
		{
			var _s = (s*dx*Math.sqrt(1+dy*dy/(dx*dx))-dx-(s>>1)*dy) / dx;
			_s = (!(s-4)? Math.ceil(_s) : Math.round(_s)) + 1;
		}
		else var _s = s;
		var ad = Math.ceil(s/2);

		var pr = dy<<1,
		pru = pr - (dx<<1),
		p = pr-dx,
		ox = x;
		while(dx > 0)
		{--dx;
			++x;
			if(p > 0)
			{
				this._mkDiv(ox, y, x-ox+ad, _s);
				y += yIncr;
				p += pru;
				ox = x;
			}
			else p += pr;
		}
		this._mkDiv(ox, y, x2-ox+ad+1, _s);
	}

	else
	{
		if(s-3 > 0)
		{
			var _s = (s*dy*Math.sqrt(1+dx*dx/(dy*dy))-(s>>1)*dx-dy) / dy;
			_s = (!(s-4)? Math.ceil(_s) : Math.round(_s)) + 1;
		}
		else var _s = s;
		var ad = Math.round(s/2);

		var pr = dx<<1,
		pru = pr - (dy<<1),
		p = pr-dy,
		oy = y;
		if(y2 <= y1)
		{
			++ad;
			while(dy > 0)
			{--dy;
				if(p > 0)
				{
					this._mkDiv(x++, y, _s, oy-y+ad);
					y += yIncr;
					p += pru;
					oy = y;
				}
				else
				{
					y += yIncr;
					p += pr;
				}
			}
			this._mkDiv(x2, y2, _s, oy-y2+ad);
		}
		else
		{
			while(dy > 0)
			{--dy;
				y += yIncr;
				if(p > 0)
				{
					this._mkDiv(x++, oy, _s, y-oy+ad);
					p += pru;
					oy = y;
				}
				else p += pr;
			}
			this._mkDiv(x2, oy, _s, y2-oy+ad+1);
		}
	}
}

function _mkLinDott(x1, y1, x2, y2)
{
	if(x1 > x2)
	{
		var _x2 = x2;
		var _y2 = y2;
		x2 = x1;
		y2 = y1;
		x1 = _x2;
		y1 = _y2;
	}
	var dx = x2-x1, dy = Math.abs(y2-y1),
	x = x1, y = y1,
	yIncr = (y1 > y2)? -1 : 1,
	drw = true;
	if(dx >= dy)
	{
		var pr = dy<<1,
		pru = pr - (dx<<1),
		p = pr-dx;
		while(dx > 0)
		{--dx;
			if(drw) this._mkDiv(x, y, 1, 1);
			drw = !drw;
			if(p > 0)
			{
				y += yIncr;
				p += pru;
			}
			else p += pr;
			++x;
		}
	}
	else
	{
		var pr = dx<<1,
		pru = pr - (dy<<1),
		p = pr-dy;
		while(dy > 0)
		{--dy;
			if(drw) this._mkDiv(x, y, 1, 1);
			drw = !drw;
			y += yIncr;
			if(p > 0)
			{
				++x;
				p += pru;
			}
			else p += pr;
		}
	}
	if(drw) this._mkDiv(x, y, 1, 1);
}

function _mkOv(left, top, width, height)
{
	var a = (++width)>>1, b = (++height)>>1,
	wod = width&1, hod = height&1,
	cx = left+a, cy = top+b,
	x = 0, y = b,
	ox = 0, oy = b,
	aa2 = (a*a)<<1, aa4 = aa2<<1, bb2 = (b*b)<<1, bb4 = bb2<<1,
	st = (aa2>>1)*(1-(b<<1)) + bb2,
	tt = (bb2>>1) - aa2*((b<<1)-1),
	w, h;
	while(y > 0)
	{
		if(st < 0)
		{
			st += bb2*((x<<1)+3);
			tt += bb4*(++x);
		}
		else if(tt < 0)
		{
			st += bb2*((x<<1)+3) - aa4*(y-1);
			tt += bb4*(++x) - aa2*(((y--)<<1)-3);
			w = x-ox;
			h = oy-y;
			if((w&2) && (h&2))
			{
				this._mkOvQds(cx, cy, x-2, y+2, 1, 1, wod, hod);
				this._mkOvQds(cx, cy, x-1, y+1, 1, 1, wod, hod);
			}
			else this._mkOvQds(cx, cy, x-1, oy, w, h, wod, hod);
			ox = x;
			oy = y;
		}
		else
		{
			tt -= aa2*((y<<1)-3);
			st -= aa4*(--y);
		}
	}
	w = a-ox+1;
	h = (oy<<1)+hod;
	y = cy-oy;
	this._mkDiv(cx-a, y, w, h);
	this._mkDiv(cx+ox+wod-1, y, w, h);
}

function _mkOv2D(left, top, width, height)
{
	var s = this.stroke;
	width += s+1;
	height += s+1;
	var a = width>>1, b = height>>1,
	wod = width&1, hod = height&1,
	cx = left+a, cy = top+b,
	x = 0, y = b,
	aa2 = (a*a)<<1, aa4 = aa2<<1, bb2 = (b*b)<<1, bb4 = bb2<<1,
	st = (aa2>>1)*(1-(b<<1)) + bb2,
	tt = (bb2>>1) - aa2*((b<<1)-1);

	if(s-4 < 0 && (!(s-2) || width-51 > 0 && height-51 > 0))
	{
		var ox = 0, oy = b,
		w, h,
		pxw;
		while(y > 0)
		{
			if(st < 0)
			{
				st += bb2*((x<<1)+3);
				tt += bb4*(++x);
			}
			else if(tt < 0)
			{
				st += bb2*((x<<1)+3) - aa4*(y-1);
				tt += bb4*(++x) - aa2*(((y--)<<1)-3);
				w = x-ox;
				h = oy-y;

				if(w-1)
				{
					pxw = w+1+(s&1);
					h = s;
				}
				else if(h-1)
				{
					pxw = s;
					h += 1+(s&1);
				}
				else pxw = h = s;
				this._mkOvQds(cx, cy, x-1, oy, pxw, h, wod, hod);
				ox = x;
				oy = y;
			}
			else
			{
				tt -= aa2*((y<<1)-3);
				st -= aa4*(--y);
			}
		}
		this._mkDiv(cx-a, cy-oy, s, (oy<<1)+hod);
		this._mkDiv(cx+a+wod-s, cy-oy, s, (oy<<1)+hod);
	}

	else
	{
		var _a = (width-(s<<1))>>1,
		_b = (height-(s<<1))>>1,
		_x = 0, _y = _b,
		_aa2 = (_a*_a)<<1, _aa4 = _aa2<<1, _bb2 = (_b*_b)<<1, _bb4 = _bb2<<1,
		_st = (_aa2>>1)*(1-(_b<<1)) + _bb2,
		_tt = (_bb2>>1) - _aa2*((_b<<1)-1),

		pxl = new Array(),
		pxt = new Array(),
		_pxb = new Array();
		pxl[0] = 0;
		pxt[0] = b;
		_pxb[0] = _b-1;
		while(y > 0)
		{
			if(st < 0)
			{
				pxl[pxl.length] = x;
				pxt[pxt.length] = y;
				st += bb2*((x<<1)+3);
				tt += bb4*(++x);
			}
			else if(tt < 0)
			{
				pxl[pxl.length] = x;
				st += bb2*((x<<1)+3) - aa4*(y-1);
				tt += bb4*(++x) - aa2*(((y--)<<1)-3);
				pxt[pxt.length] = y;
			}
			else
			{
				tt -= aa2*((y<<1)-3);
				st -= aa4*(--y);
			}

			if(_y > 0)
			{
				if(_st < 0)
				{
					_st += _bb2*((_x<<1)+3);
					_tt += _bb4*(++_x);
					_pxb[_pxb.length] = _y-1;
				}
				else if(_tt < 0)
				{
					_st += _bb2*((_x<<1)+3) - _aa4*(_y-1);
					_tt += _bb4*(++_x) - _aa2*(((_y--)<<1)-3);
					_pxb[_pxb.length] = _y-1;
				}
				else
				{
					_tt -= _aa2*((_y<<1)-3);
					_st -= _aa4*(--_y);
					_pxb[_pxb.length-1]--;
				}
			}
		}

		var ox = -wod, oy = b,
		_oy = _pxb[0],
		l = pxl.length,
		w, h;
		for(var i = 0; i < l; i++)
		{
			if(typeof _pxb[i] != "undefined")
			{
				if(_pxb[i] < _oy || pxt[i] < oy)
				{
					x = pxl[i];
					this._mkOvQds(cx, cy, x, oy, x-ox, oy-_oy, wod, hod);
					ox = x;
					oy = pxt[i];
					_oy = _pxb[i];
				}
			}
			else
			{
				x = pxl[i];
				this._mkDiv(cx-x, cy-oy, 1, (oy<<1)+hod);
				this._mkDiv(cx+ox+wod, cy-oy, 1, (oy<<1)+hod);
				ox = x;
				oy = pxt[i];
			}
		}
		this._mkDiv(cx-a, cy-oy, 1, (oy<<1)+hod);
		this._mkDiv(cx+ox+wod, cy-oy, 1, (oy<<1)+hod);
	}
}

function _mkOvDott(left, top, width, height)
{
	var a = (++width)>>1, b = (++height)>>1,
	wod = width&1, hod = height&1, hodu = hod^1,
	cx = left+a, cy = top+b,
	x = 0, y = b,
	aa2 = (a*a)<<1, aa4 = aa2<<1, bb2 = (b*b)<<1, bb4 = bb2<<1,
	st = (aa2>>1)*(1-(b<<1)) + bb2,
	tt = (bb2>>1) - aa2*((b<<1)-1),
	drw = true;
	while(y > 0)
	{
		if(st < 0)
		{
			st += bb2*((x<<1)+3);
			tt += bb4*(++x);
		}
		else if(tt < 0)
		{
			st += bb2*((x<<1)+3) - aa4*(y-1);
			tt += bb4*(++x) - aa2*(((y--)<<1)-3);
		}
		else
		{
			tt -= aa2*((y<<1)-3);
			st -= aa4*(--y);
		}
		if(drw && y >= hodu) this._mkOvQds(cx, cy, x, y, 1, 1, wod, hod);
		drw = !drw;
	}
}

function _mkRect(x, y, w, h)
{
	var s = this.stroke;
	this._mkDiv(x, y, w, s);
	this._mkDiv(x+w, y, s, h);
	this._mkDiv(x, y+h, w+s, s);
	this._mkDiv(x, y+s, s, h-s);
}

function _mkRectDott(x, y, w, h)
{
	this.drawLine(x, y, x+w, y);
	this.drawLine(x+w, y, x+w, y+h);
	this.drawLine(x, y+h, x+w, y+h);
	this.drawLine(x, y, x, y+h);
}

function jsgFont()
{
	this.PLAIN = 'font-weight:normal;';
	this.BOLD = 'font-weight:bold;';
	this.ITALIC = 'font-style:italic;';
	this.ITALIC_BOLD = this.ITALIC + this.BOLD;
	this.BOLD_ITALIC = this.ITALIC_BOLD;
}
var Font = new jsgFont();

function jsgStroke()
{
	this.DOTTED = -1;
}
var Stroke = new jsgStroke();

function jsGraphics(cnv, wnd)
{
	this.setColor = function(x)
	{
		this.color = x.toLowerCase();
	};

	this.setStroke = function(x)
	{
		this.stroke = x;
		if(!(x+1))
		{
			this.drawLine = _mkLinDott;
			this._mkOv = _mkOvDott;
			this.drawRect = _mkRectDott;
		}
		else if(x-1 > 0)
		{
			this.drawLine = _mkLin2D;
			this._mkOv = _mkOv2D;
			this.drawRect = _mkRect;
		}
		else
		{
			this.drawLine = _mkLin;
			this._mkOv = _mkOv;
			this.drawRect = _mkRect;
		}
	};

	this.setPrintable = function(arg)
	{
		this.printable = arg;
		if(jg_fast)
		{
			this._mkDiv = _mkDivIe;
			this._htmRpc = arg? _htmPrtRpc : _htmRpc;
		}
		else this._mkDiv = arg? _mkDivPrt : _mkDiv;
	};

	this.setFont = function(fam, sz, sty)
	{
		this.ftFam = fam;
		this.ftSz = sz;
		this.ftSty = sty || Font.PLAIN;
	};

	this.drawPolyline = this.drawPolyLine = function(x, y)
	{
		for (var i=x.length - 1; i;)
		{--i;
			this.drawLine(x[i], y[i], x[i+1], y[i+1]);
		}
	};

	this.fillRect = function(x, y, w, h)
	{
		this._mkDiv(x, y, w, h);
	};

	this.drawPolygon = function(x, y)
	{
		this.drawPolyline(x, y);
		this.drawLine(x[x.length-1], y[x.length-1], x[0], y[0]);
	};

	this.drawEllipse = this.drawOval = function(x, y, w, h)
	{
		this._mkOv(x, y, w, h);
	};

	this.fillEllipse = this.fillOval = function(left, top, w, h)
	{
		var a = w>>1, b = h>>1,
		wod = w&1, hod = h&1,
		cx = left+a, cy = top+b,
		x = 0, y = b, oy = b,
		aa2 = (a*a)<<1, aa4 = aa2<<1, bb2 = (b*b)<<1, bb4 = bb2<<1,
		st = (aa2>>1)*(1-(b<<1)) + bb2,
		tt = (bb2>>1) - aa2*((b<<1)-1),
		xl, dw, dh;
		if(w) while(y > 0)
		{
			if(st < 0)
			{
				st += bb2*((x<<1)+3);
				tt += bb4*(++x);
			}
			else if(tt < 0)
			{
				st += bb2*((x<<1)+3) - aa4*(y-1);
				xl = cx-x;
				dw = (x<<1)+wod;
				tt += bb4*(++x) - aa2*(((y--)<<1)-3);
				dh = oy-y;
				this._mkDiv(xl, cy-oy, dw, dh);
				this._mkDiv(xl, cy+y+hod, dw, dh);
				oy = y;
			}
			else
			{
				tt -= aa2*((y<<1)-3);
				st -= aa4*(--y);
			}
		}
		this._mkDiv(cx-a, cy-oy, w, (oy<<1)+hod);
	};

	this.fillArc = function(iL, iT, iW, iH, fAngA, fAngZ)
	{
		var a = iW>>1, b = iH>>1,
		iOdds = (iW&1) | ((iH&1) << 16),
		cx = iL+a, cy = iT+b,
		x = 0, y = b, ox = x, oy = y,
		aa2 = (a*a)<<1, aa4 = aa2<<1, bb2 = (b*b)<<1, bb4 = bb2<<1,
		st = (aa2>>1)*(1-(b<<1)) + bb2,
		tt = (bb2>>1) - aa2*((b<<1)-1),
		// Vars for radial boundary lines
		xEndA, yEndA, xEndZ, yEndZ,
		iSects = (1 << (Math.floor((fAngA %= 360.0)/180.0) << 3))
				| (2 << (Math.floor((fAngZ %= 360.0)/180.0) << 3))
				| ((fAngA >= fAngZ) << 16),
		aBndA = new Array(b+1), aBndZ = new Array(b+1);
		
		// Set up radial boundary lines
		fAngA *= Math.PI/180.0;
		fAngZ *= Math.PI/180.0;
		xEndA = cx+Math.round(a*Math.cos(fAngA));
		yEndA = cy+Math.round(-b*Math.sin(fAngA));
		_mkLinVirt(aBndA, cx, cy, xEndA, yEndA);
		xEndZ = cx+Math.round(a*Math.cos(fAngZ));
		yEndZ = cy+Math.round(-b*Math.sin(fAngZ));
		_mkLinVirt(aBndZ, cx, cy, xEndZ, yEndZ);

		while(y > 0)
		{
			if(st < 0) // Advance x
			{
				st += bb2*((x<<1)+3);
				tt += bb4*(++x);
			}
			else if(tt < 0) // Advance x and y
			{
				st += bb2*((x<<1)+3) - aa4*(y-1);
				ox = x;
				tt += bb4*(++x) - aa2*(((y--)<<1)-3);
				this._mkArcDiv(ox, y, oy, cx, cy, iOdds, aBndA, aBndZ, iSects);
				oy = y;
			}
			else // Advance y
			{
				tt -= aa2*((y<<1)-3);
				st -= aa4*(--y);
				if(y && (aBndA[y] != aBndA[y-1] || aBndZ[y] != aBndZ[y-1]))
				{
					this._mkArcDiv(x, y, oy, cx, cy, iOdds, aBndA, aBndZ, iSects);
					ox = x;
					oy = y;
				}
			}
		}
		this._mkArcDiv(x, 0, oy, cx, cy, iOdds, aBndA, aBndZ, iSects);
		if(iOdds >> 16) // Odd height
		{
			if(iSects >> 16) // Start-angle > end-angle
			{
				var xl = (yEndA <= cy || yEndZ > cy)? (cx - x) : cx;
				this._mkDiv(xl, cy, x + cx - xl + (iOdds & 0xffff), 1);
			}
			else if((iSects & 0x01) && yEndZ > cy)
				this._mkDiv(cx - x, cy, x, 1);
		}
	};

/* fillPolygon method, implemented by Matthieu Haller.
This javascript function is an adaptation of the gdImageFilledPolygon for Walter Zorn lib.
C source of GD 1.8.4 found at http://www.boutell.com/gd/

THANKS to Kirsten Schulz for the polygon fixes!

The intersection finding technique of this code could be improved
by remembering the previous intertersection, and by using the slope.
That could help to adjust intersections to produce a nice
interior_extrema. */
	this.fillPolygon = function(array_x, array_y)
	{
		var i;
		var y;
		var miny, maxy;
		var x1, y1;
		var x2, y2;
		var ind1, ind2;
		var ints;

		var n = array_x.length;
		if(!n) return;

		miny = array_y[0];
		maxy = array_y[0];
		for(i = 1; i < n; i++)
		{
			if(array_y[i] < miny)
				miny = array_y[i];

			if(array_y[i] > maxy)
				maxy = array_y[i];
		}
		for(y = miny; y <= maxy; y++)
		{
			var polyInts = new Array();
			ints = 0;
			for(i = 0; i < n; i++)
			{
				if(!i)
				{
					ind1 = n-1;
					ind2 = 0;
				}
				else
				{
					ind1 = i-1;
					ind2 = i;
				}
				y1 = array_y[ind1];
				y2 = array_y[ind2];
				if(y1 < y2)
				{
					x1 = array_x[ind1];
					x2 = array_x[ind2];
				}
				else if(y1 > y2)
				{
					y2 = array_y[ind1];
					y1 = array_y[ind2];
					x2 = array_x[ind1];
					x1 = array_x[ind2];
				}
				else continue;

				 //  Modified 11. 2. 2004 Walter Zorn
				if((y >= y1) && (y < y2))
					polyInts[ints++] = Math.round((y-y1) * (x2-x1) / (y2-y1) + x1);

				else if((y == maxy) && (y > y1) && (y <= y2))
					polyInts[ints++] = Math.round((y-y1) * (x2-x1) / (y2-y1) + x1);
			}
			polyInts.sort(_CompInt);
			for(i = 0; i < ints; i+=2)
				this._mkDiv(polyInts[i], y, polyInts[i+1]-polyInts[i]+1, 1);
		}
	};

	this.drawString = function(txt, x, y)
	{
		this.htm += '<div style="position:absolute;white-space:nowrap;'+
			'left:' + x + 'px;'+
			'top:' + y + 'px;'+
			'font-family:' +  this.ftFam + ';'+
			'font-size:' + this.ftSz + ';'+
			'color:' + this.color + ';' + this.ftSty + '">'+
			txt +
			'<\/div>';
	};

/* drawStringRect() added by Rick Blommers.
Allows to specify the size of the text rectangle and to align the
text both horizontally (e.g. right) and vertically within that rectangle */
	this.drawStringRect = function(txt, x, y, width, halign)
	{
		this.htm += '<div style="position:absolute;overflow:hidden;'+
			'left:' + x + 'px;'+
			'top:' + y + 'px;'+
			'width:'+width +'px;'+
			'text-align:'+halign+';'+
			'font-family:' +  this.ftFam + ';'+
			'font-size:' + this.ftSz + ';'+
			'color:' + this.color + ';' + this.ftSty + '">'+
			txt +
			'<\/div>';
	};

	this.drawImage = function(imgSrc, x, y, w, h, a)
	{
		this.htm += '<div style="position:absolute;'+
			'left:' + x + 'px;'+
			'top:' + y + 'px;'+
			// w (width) and h (height) arguments are now optional.
			// Added by Mahmut Keygubatli, 14.1.2008
			(w? ('width:' +  w + 'px;') : '') +
			(h? ('height:' + h + 'px;'):'')+'">'+
			'<img src="' + imgSrc +'"'+ (w ? (' width="' + w + '"'):'')+ (h ? (' height="' + h + '"'):'') + (a? (' '+a) : '') + '>'+
			'<\/div>';
	};

	this.clear = function()
	{
		this.htm = "";
		if(this.cnv) this.cnv.innerHTML = "";
	};

	this._mkOvQds = function(cx, cy, x, y, w, h, wod, hod)
	{
		var xl = cx - x, xr = cx + x + wod - w, yt = cy - y, yb = cy + y + hod - h;
		if(xr > xl+w)
		{
			this._mkDiv(xr, yt, w, h);
			this._mkDiv(xr, yb, w, h);
		}
		else
			w = xr - xl + w;
		this._mkDiv(xl, yt, w, h);
		this._mkDiv(xl, yb, w, h);
	};
	
	this._mkArcDiv = function(x, y, oy, cx, cy, iOdds, aBndA, aBndZ, iSects)
	{
		var xrDef = cx + x + (iOdds & 0xffff), y2, h = oy - y, xl, xr, w;

		if(!h) h = 1;
		x = cx - x;

		if(iSects & 0xff0000) // Start-angle > end-angle
		{
			y2 = cy - y - h;
			if(iSects & 0x00ff)
			{
				if(iSects & 0x02)
				{
					xl = Math.max(x, aBndZ[y]);
					w = xrDef - xl;
					if(w > 0) this._mkDiv(xl, y2, w, h);
				}
				if(iSects & 0x01)
				{
					xr = Math.min(xrDef, aBndA[y]);
					w = xr - x;
					if(w > 0) this._mkDiv(x, y2, w, h);
				}
			}
			else
				this._mkDiv(x, y2, xrDef - x, h);
			y2 = cy + y + (iOdds >> 16);
			if(iSects & 0xff00)
			{
				if(iSects & 0x0100)
				{
					xl = Math.max(x, aBndA[y]);
					w = xrDef - xl;
					if(w > 0) this._mkDiv(xl, y2, w, h);
				}
				if(iSects & 0x0200)
				{
					xr = Math.min(xrDef, aBndZ[y]);
					w = xr - x;
					if(w > 0) this._mkDiv(x, y2, w, h);
				}
			}
			else
				this._mkDiv(x, y2, xrDef - x, h);
		}
		else
		{
			if(iSects & 0x00ff)
			{
				if(iSects & 0x02)
					xl = Math.max(x, aBndZ[y]);
				else
					xl = x;
				if(iSects & 0x01)
					xr = Math.min(xrDef, aBndA[y]);
				else
					xr = xrDef;
				y2 = cy - y - h;
				w = xr - xl;
				if(w > 0) this._mkDiv(xl, y2, w, h);
			}
			if(iSects & 0xff00)
			{
				if(iSects & 0x0100)
					xl = Math.max(x, aBndA[y]);
				else
					xl = x;
				if(iSects & 0x0200)
					xr = Math.min(xrDef, aBndZ[y]);
				else
					xr = xrDef;
				y2 = cy + y + (iOdds >> 16);
				w = xr - xl;
				if(w > 0) this._mkDiv(xl, y2, w, h);
			}
		}
	};

	this.setStroke(1);
	this.setFont("verdana,geneva,helvetica,sans-serif", "12px", Font.PLAIN);
	this.color = "#000000";
	this.htm = "";
	this.wnd = wnd || window;

	if(!jg_ok) _chkDHTM(this.wnd);
	if(jg_ok)
	{
		if(cnv)
		{
			if(typeof(cnv) == "string")
				this.cont = document.all? (this.wnd.document.all[cnv] || null)
					: document.getElementById? (this.wnd.document.getElementById(cnv) || null)
					: null;
			else if(cnv == window.document)
				this.cont = document.getElementsByTagName("body")[0];
			// If cnv is a direct reference to a canvas DOM node
			// (option suggested by Andreas Luleich)
			else this.cont = cnv;
			// Create new canvas inside container DIV. Thus the drawing and clearing
			// methods won't interfere with the container's inner html.
			// Solution suggested by Vladimir.
			this.cnv = this.wnd.document.createElement("div");
			this.cnv.style.fontSize=0;
			this.cont.appendChild(this.cnv);
			this.paint = jg_dom? _pntCnvDom : _pntCnvIe;
		}
		else
			this.paint = _pntDoc;
	}
	else
		this.paint = _pntN;

	this.setPrintable(false);
}

function _mkLinVirt(aLin, x1, y1, x2, y2)
{
	var dx = Math.abs(x2-x1), dy = Math.abs(y2-y1),
	x = x1, y = y1,
	xIncr = (x1 > x2)? -1 : 1,
	yIncr = (y1 > y2)? -1 : 1,
	p,
	i = 0;
	if(dx >= dy)
	{
		var pr = dy<<1,
		pru = pr - (dx<<1);
		p = pr-dx;
		while(dx > 0)
		{--dx;
			if(p > 0)    //  Increment y
			{
				aLin[i++] = x;
				y += yIncr;
				p += pru;
			}
			else p += pr;
			x += xIncr;
		}
	}
	else
	{
		var pr = dx<<1,
		pru = pr - (dy<<1);
		p = pr-dy;
		while(dy > 0)
		{--dy;
			y += yIncr;
			aLin[i++] = x;
			if(p > 0)    //  Increment x
			{
				x += xIncr;
				p += pru;
			}
			else p += pr;
		}
	}
	for(var len = aLin.length, i = len-i; i;)
		aLin[len-(i--)] = x;
};

function _CompInt(x, y)
{
	return(x - y);
}}
/* FILE:FreeanceWeb/Common/lib/XML/XMLParser.js */ if(!window.freeance_loaded_js['61ea00013512eb88332e6c9a371d15c5']){window.freeance_loaded_js['61ea00013512eb88332e6c9a371d15c5']=1;
//XMLParser.js
//Base xml parser object.
//includes some utility functions.
function XMLParser(newXmlDoc)
{
  return this.init(newXmlDoc);
};

XMLParser.prototype.init = function (newXmlDoc)
{
  this.xmlDoc = newXmlDoc||null;   // XmlDocument
  if (this.xmlDoc == null)
    return (this);
};

XMLParser.prototype.setDocumentByDoc = function(newXmlDoc)
{
  if (!newXmlDoc) 
    return null;
  else
    this.xmlDoc = newXmlDoc;
};

XMLParser.prototype.setDocumentByStr = function(XMLParserStr)
{
  if (!XMLParserStr) 
    return;
  if (this.xmlDoc == null)
    this.xmlDoc = XmlDocument.create();
  this.xmlDoc.loadXML(XMLParserStr);
};

/**********************************************************
              Generic data handling
***********************************************************/
XMLParser.decodeSTRING = function(theNode)
{
  if(theNode)
    if (theNode.childNodes.length > 0) // has textNode
      return (theNode.childNodes[0].nodeValue);
  return ('');
};
XMLParser.prototype.decodeSTRING = XMLParser.decodeSTRING;
XMLParser.prototype.decodeINT = XMLParser.decodeINT = function(theNode) // leaf node
{ 
  var theSTRING = XMLParser.decodeSTRING(theNode);
  return (parseInt(theSTRING,10));
};

XMLParser.prototype.decodeBOOLEAN = XMLParser.decodeBOOLEAN = function(theNode)
{
  var theSTRING = this.decodeSTRING(theNode);
  return (parseInt(theSTRING) == 1);
};

XMLParser.prototype.decodeDOUBLE = XMLParser.decodeDOUBLE = function(theNode)
{
  var theSTRING = this.decodeSTRING(theNode);
  return (parseFloat(theSTRING));
};

XMLParser.prototype.decodeDATETIME = function(theNode) {};
XMLParser.prototype.decodeBASE64 = function(theNode) {};

/**********************************************************
                  Helper Functions
***********************************************************/

XMLParser.prototype.getNextChildNodeIndex = 
XMLParser.prototype.__helper__getNextElementChildNode = 
XMLParser.getNextElementChildNode = function(aNode,firstpos)
{
  var foundpos = -1;
  for (var lcv=firstpos;(lcv < aNode.childNodes.length) && (foundpos == -1); lcv++)
    if (aNode.childNodes[lcv].nodeType == 1)
      foundpos = lcv;
  return (foundpos);
};

XMLParser.prototype.getNextNamedChildNodeIndex = 
XMLParser.prototype.getNextElementNamedChildNode = 
XMLParser.prototype.__helper__getNextElementNamedChildNode = 
XMLParser.getNextElementNamedChildNode = function(aNode,firstpos,nodeName)
{
  for (var lcv=firstpos;lcv < aNode.childNodes.length; lcv++)
    if ((aNode.childNodes[lcv].nodeType == 1) && (aNode.childNodes[lcv].nodeName == nodeName))
      return(lcv);
  return (-1);
};

XMLParser.prototype.getRemainingNamedChildNodes =
XMLParser.prototype.__helper__getRemainingNextElementNamedChildNodes =
XMLParser.getRemainingNextElementNamedChildNodes = function(aNode,firstpos,nodeName)
{
  var nodeCollection = new Array();
  for (var lcv=firstpos;lcv < aNode.childNodes.length; lcv++)
    if ((aNode.childNodes[lcv].nodeType == 1) && (aNode.childNodes[lcv].nodeName == nodeName))
      nodeCollection[nodeCollection.length] = aNode.childNodes[lcv];
  return (nodeCollection);
};}
/* FILE:FreeanceWeb/Client/PublicKiosk1/lib/XML/FreeanceXMLParser.js */ if(!window.freeance_loaded_js['b542428ceaab47c3b6b41bbf609fc991']){window.freeance_loaded_js['b542428ceaab47c3b6b41bbf609fc991']=1;
/**************************************************
FreeanceXMLParser.js
  XML parser for the freeance configuration libraries
  extends the base xml parser, adding appropriate
  functions for dealing with the possible freeance
  extensions and core modules.
-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
Dependancies:
  XMLParser-base.js
  Util.js
  X.js

**************************************************/

FreeanceXMLParser = function(newID)
{
  if (arguments.length > 0)
    this.init(newID);
};
FreeanceXMLParser.prototype = new XMLParser();
FreeanceXMLParser.prototype.constructor = FreeanceXMLParser;
FreeanceXMLParser.superclass = XMLParser.prototype;

FreeanceXMLParser.prototype.init = function(newID)
{
  FreeanceXMLParser.superclass.init.call(this, newID);  //call parent's init function
};

FreeanceXMLParser.prototype.getObject = function(objectName)
{
  //this overrides the default parser's getObject function
  if (this.xmlDoc == null)
    return null;
  if (arguments.length > 0)
  {
    switch (arguments[0])
    {
      case 'applicationConfig':
        return (this.parseApplicationConfig(this.xmlDoc.getElementsByTagName("applicationConfig").item(0)));
        break;
      case 'mapConfig':
        return (this.parseMapConfig(this.xmlDoc.getElementsByTagName("map").item(0)));
        break;
      case 'templateConfig':
        return (this.parseTemplateConfig(this.xmlDoc.getElementsByTagName("templates").item(0)));
        break;
      case 'extensionConfig':
        return(this.parseExtensionConfig(this.xmlDoc.getElementsByTagName('extensionConfig').item(0)));
        break;
      case 'queryConfig':
        return (this.parseQueryConfig(this.xmlDoc.getElementsByTagName("queryConfig").item(0)));
        break;
      case 'measureConfig':
        return (this.parseMeasureConfig(this.xmlDoc.getElementsByTagName(arguments[0]).item(0)));
        break;
      case 'emailConfig':
        return (this.parseEMailConfig(this.xmlDoc.getElementsByTagName(arguments[0]).item(0)));
        break;
      default:
        return (this.getObjectRecurse(this.xmlDoc.getElementsByTagName("value").item(0)));
    }
  }
  else
    return (this.getObjectRecurse(this.xmlDoc.getElementsByTagName("value").item(0)));
    //here we assume that they incorrectly declared the parser...
};

FreeanceXMLParser.prototype.getObjectRecurse = function()
{
  //first argument is the starting node. 
  //additional parameters may be required for certain node types; these vary
  
  
  //dprintf('FreeanceXMLParser.getObjectRecurse;executing native code for '+arguments[0].nodeName,false);
  var theNode = arguments[0];
  var returnValue = null;
  var i = 0;
  if (this.xmlDoc == null) 
    return null;
  else      
    switch (theNode.nodeName)
    {
      case 'left':
      case 'top':
      case 'zpos':
      case 'width':
      case 'height':
      case 'visibility':
      case 'style':
      case 'label':
      case 'imageName':
      case 'partOfExtension':
      case 'tooltip':
      case 'onTooltip':
      case 'offTooltip':
      case 'buttonState':
      case 'useRollover':
      case 'enableDrag':
      case 'groupName':
      case 'imageSource':
      case 'scaleImage':
      case 'orientation':
      case 'caption':
      case 'setActive':
      case 'useScroll':
      case 'pageType':
      case 'usePageControl':
      case 'color':
      case 'font':
      case 'fontSize': 
      case 'valueFontSize':
      case 'cellSpacing':
        if (this.__helper__getNextElementNamedChildNode(theNode,0,"value")!= -1)
          return (this.getObjectRecurse(theNode.childNodes[this.__helper__getNextElementNamedChildNode(theNode,0,"value")]));
        else
        {
          return null;
        }
        break;
      default:
      {
        dprintf('FreeanceXMLParser.getObjectRecurse; unknown node type: '+theNode.nodeName,false);
        //dprintf('FreeanceXMLParser.getObjectRecurse; executing parent class code for '+arguments[0].nodeName,false);
        return FreeanceXMLParser.superclass.getObjectRecurse.call(this, arguments[0]);
        break;
      }
    }
  return returnValue;
};

FreeanceXMLParser.prototype.parseApplicationConfig = function(appNode)
{
  var appConfig = new Array;
  appConfig.id = this.decodeSTRING(appNode.childNodes[this.__helper__getNextElementNamedChildNode(appNode,0,"applicationId")]);
  appConfig.organization = this.decodeSTRING(appNode.childNodes[this.__helper__getNextElementNamedChildNode(appNode,0,"organization")]);
  appConfig.title = this.decodeSTRING(appNode.childNodes[this.__helper__getNextElementNamedChildNode(appNode,0,"title")]);
  appConfig.clientType = this.decodeSTRING(appNode.childNodes[this.__helper__getNextElementNamedChildNode(appNode,0,"clientType")]);
  if (this.__helper__getNextElementNamedChildNode(appNode,0,"stylesheet") != -1)
    appConfig.stylesheet = this.decodeSTRING(appNode.childNodes[this.__helper__getNextElementNamedChildNode(appNode,0,"stylesheet")]);
  else
    appConfig.stylesheet = 'default';
  appConfig.administrator = this.decodeSTRING(appNode.childNodes[this.__helper__getNextElementNamedChildNode(appNode,0,"administrator")]);
  appConfig.adminEmail = this.decodeSTRING(appNode.childNodes[this.__helper__getNextElementNamedChildNode(appNode,0,"adminEmail")]);
  var mapUnitIndex = this.__helper__getNextElementNamedChildNode(appNode,0,"mapUnits");
  appConfig.mapUnits = ((mapUnitIndex > -1)?(this.decodeSTRING(appNode.childNodes[mapUnitIndex])):('FT'));
  var vmapHeightIndex = this.__helper__getNextElementNamedChildNode(appNode,0,"vmapHeight");
  appConfig.vmapHeight = ((vmapHeightIndex > -1)?(this.decodeINT(appNode.childNodes[vmapHeightIndex])):(100));
  var customLayoutIndex = this.__helper__getNextElementNamedChildNode(appNode,0,"customOptions");
  appConfig.customOptions = ((customLayoutIndex!=-1)?(this.parseApplicationCustomOptions(appNode.childNodes[customLayoutIndex])):(null));
  OBJECT_MANAGER.setGuiValue("ApplicationConfig", appConfig);
  return appConfig;
};

FreeanceXMLParser.prototype.parseApplicationCustomOptions = function (customNode)
{
  //get values for page customization....
  var customConfig = new Object;
  var nodeIndex = this.__helper__getNextElementNamedChildNode(customNode,0,"pageHeaderHeight");
  customConfig.pageHeaderHeight = (nodeIndex==-1)?(70):(this.decodeINT(customNode.childNodes[nodeIndex]));
  nodeIndex = this.__helper__getNextElementNamedChildNode(customNode,0,"leftPanelDisplay");
  customConfig.leftPanelDisplay = (nodeIndex==-1)?(true):(this.decodeINT(customNode.childNodes[nodeIndex])==1);
  nodeIndex = this.__helper__getNextElementNamedChildNode(customNode,0,"legendDisplay");
  customConfig.legendDisplay = (nodeIndex==-1)?(true):(this.decodeINT(customNode.childNodes[nodeIndex])==1);
  nodeIndex = this.__helper__getNextElementNamedChildNode(customNode,0,"legendEnable");
  customConfig.legendEnable = (nodeIndex==-1)?(true):(this.decodeINT(customNode.childNodes[nodeIndex])==1);
  nodeIndex = this.__helper__getNextElementNamedChildNode(customNode,0,"layerDisplay");
  customConfig.layerDisplay = (nodeIndex==-1)?(false):(this.decodeINT(customNode.childNodes[nodeIndex])==1);
  nodeIndex = this.__helper__getNextElementNamedChildNode(customNode,0,"layerEnable");
  customConfig.layerEnable = (nodeIndex==-1)?(true):(this.decodeINT(customNode.childNodes[nodeIndex])==1);
  nodeIndex = this.__helper__getNextElementNamedChildNode(customNode,0,"resultPanelHeight");
  customConfig.resultPanelHeight = (nodeIndex==-1)?(50):(this.decodeINT(customNode.childNodes[nodeIndex]));
  nodeIndex = this.__helper__getNextElementNamedChildNode(customNode,0,"customPanelPosition");
  customConfig.customPanelPosition = (nodeIndex==-1)?(0):(this.decodeINT(customNode.childNodes[nodeIndex]));
  nodeIndex = this.__helper__getNextElementNamedChildNode(customNode,0,"customPanelTitle");
  customConfig.customPanelTitle = (nodeIndex==-1)?('Site Instructions'):(this.decodeSTRING(customNode.childNodes[nodeIndex]));
  nodeIndex = this.__helper__getNextElementNamedChildNode(customNode,0,"customLegendURL");
  customConfig.customLegendURL = (nodeIndex==-1)?(''):(this.decodeSTRING(customNode.childNodes[nodeIndex]));
  customConfig.showDisclaimer = (customNode.getElementsByTagName('showDisclaimer')[0])?(this.decodeSTRING(customNode.getElementsByTagName('showDisclaimer')[0]) == 'true'):(false),
  customConfig.disclaimerText = (customNode.getElementsByTagName('disclaimerText')[0])?(this.decodeSTRING(customNode.getElementsByTagName('disclaimerText')[0])):(''),
  customConfig.disclaimerURL = (customNode.getElementsByTagName('disclaimerURL')[0])?(this.decodeSTRING(customNode.getElementsByTagName('disclaimerURL')[0])):('')
  return customConfig;
};

FreeanceXMLParser.prototype.parseMapConfig = function(mapNode)
{
  var mapConfig = new Object();
  mapConfig['id'] = mapNode.getAttribute("id");
  mapConfig["resourceId"] = this.decodeSTRING(mapNode.childNodes[this.__helper__getNextElementNamedChildNode(mapNode,0,"resourceId")]);
  mapConfig["imsHostname"] = this.decodeSTRING(mapNode.childNodes[this.__helper__getNextElementNamedChildNode(mapNode,0,"imsHostname")]);
  mapConfig["previousStates"] = this.decodeINT(mapNode.childNodes[this.__helper__getNextElementNamedChildNode(mapNode,0,"previousStates")]);
  if (this.__helper__getNextElementNamedChildNode(mapNode,0,"vicinityMap")!=-1)
    mapConfig['vmap'] = this.parseVMapConfig(mapNode.childNodes[this.__helper__getNextElementNamedChildNode(mapNode,0,"vicinityMap")]);
  if (this.__helper__getNextElementNamedChildNode(mapNode,0,"themeDefinitions")!=-1)
    mapConfig['themes'] = this.parseThemeDefinitions(mapNode.childNodes[this.__helper__getNextElementNamedChildNode(mapNode,0,"themeDefinitions")]);
  mapConfig["activeTheme"] = this.decodeSTRING(mapNode.childNodes[this.__helper__getNextElementNamedChildNode(mapNode,0,"activeTheme")]);
  mapConfig['themeGroups'] = this.parseThemeGroups(mapNode);

  var legendAttributeIndex = this.__helper__getNextElementNamedChildNode(mapNode,0,"legendAttributes");
  var legendIndex = this.__helper__getNextElementNamedChildNode(mapNode,0,"legend");
  mapConfig['legendAttributes'] = this.parseLegendAttributes(mapNode.childNodes[(legendAttributeIndex>-1)?legendAttributeIndex:legendIndex]);

  //Configure the printing system
  var printNodes = mapNode.getElementsByTagName("pdfPrintConfig");
  mapConfig.printConfig = (printNodes.length)?this.parsePdfPrintConfig(printNodes[0]):{templates: new Array,defaultTemplate: -1};
  
  var projectionId = 0;
  var projectionIdx = this.__helper__getNextElementNamedChildNode(mapNode,0,'projectionId');
  if(projectionIdx!=-1)
	projectionId=(mapNode.childNodes[projectionIdx].getAttribute('value')!=null)?(parseInt(mapNode.childNodes[projectionIdx].getAttribute('value'))):(this.decodeINT(mapNode.childNodes[projectionIdx]));
  
  mapConfig.projectionId = projectionId;
  
  mapConfig['coordZoomToTolerance'] = (mapNode.getElementsByTagName('coordZoomToTolerance')[0])?(parseInt(mapNode.getElementsByTagName('coordZoomToTolerance')[0].getAttribute('value'))):(500);    //Configure the CSV export system
  if (this.__helper__getNextElementNamedChildNode(mapNode,0,"exportConfig")!=-1)
    mapConfig['exportConfig'] = this.parseMapExportConfig(mapNode.childNodes[this.__helper__getNextElementNamedChildNode(mapNode,0,"exportConfig")]);
  if (this.__helper__getNextElementNamedChildNode(mapNode,0,"scalebar")!=-1)
  {
    var scalebarConfigNode = mapNode.childNodes[this.__helper__getNextElementNamedChildNode(mapNode,0,"scalebar")];
    mapConfig['scalebarConfig'] = this.parseScalebarConfig(scalebarConfigNode);
  }
  else
  {
    mapConfig['scalebarConfig'] = null;
  }
  //Capture any geocode extension data
  if (this.__helper__getNextElementNamedChildNode(mapNode,0,"geocodeConfig")!=-1)
  {
    try{
      mapConfig['geocodeConfig'] = this.parseGeocodeConfig(mapNode.childNodes[this.__helper__getNextElementNamedChildNode(mapNode,0,"geocodeConfig")]);
    }
    catch(e)
    {
      alert('Initialization Error:\nGeocode configuration is present but the extension could not be loaded.');
    }
  }

  //Capture any directmapping extension data
  try
  {
    if (this.__helper__getNextElementNamedChildNode(mapNode,0,"directMappingConfig")!=-1)
      mapConfig['directMappingConfig'] = this.parseDirectMappingConfig(mapNode.childNodes[this.__helper__getNextElementNamedChildNode(mapNode,0,"directMappingConfig")]);
  }
  catch(e)
  {
    //A direct mapping configuration is present but the direct mapping extension has not been loaded.
    //this can happen in some circumstances so let the error go, it won't hurt anything.
    dprintf('Warning: Freeance Direct is configured but not installed.');
  }
  
  //parse map schemes
  if (this.__helper__getNextElementNamedChildNode(mapNode,0,"mapSchemeDefinitions")!=-1)
  {
    var mapSchemeConfigNode = mapNode.childNodes[this.__helper__getNextElementNamedChildNode(mapNode,0,"mapSchemeDefinitions")];
    mapConfig['mapSchemeConfig'] = this.parseMapSchemeConfig(mapSchemeConfigNode);
  }
  else
  {
    mapConfig['mapSchemeConfig'] = null;
  }
  var seamlessPanIdx=this.__helper__getNextElementNamedChildNode(mapNode,0,"seamlessPan");
  var seamlessPan = false;
  if(seamlessPanIdx!=-1)
    seamlessPan=(mapNode.childNodes[seamlessPanIdx].getAttribute('enabled')=='true');
  mapConfig.seamlessPan = seamlessPan;
  
  
  OBJECT_MANAGER.setGuiValue(mapConfig['id'], mapConfig);
  return mapConfig;
};

FreeanceXMLParser.prototype.parseMapSchemeConfig = function (mapSchemeConfigNode)
{
  var mapSchemeTags = this.__helper__getRemainingNextElementNamedChildNodes(mapSchemeConfigNode,0,"mapScheme");
  var defaultMapSchemeNode = mapSchemeConfigNode.childNodes[this.__helper__getNextElementNamedChildNode(mapSchemeConfigNode,0,"defaultScheme")];
  var mapSchemes = new Array;
  if (mapSchemeTags.length > 0)
  {
    for (var i = 0; i<mapSchemeTags.length; i++)
    {
      var currentMapSchemeId = parseInt(mapSchemeTags[i].getAttribute('id'));
      if(mapSchemeTags[i].getAttribute('link')){
        mapSchemes.push({
          id: currentMapSchemeId,
          name: this.decodeSTRING(mapSchemeTags[i].childNodes[this.__helper__getNextElementNamedChildNode(mapSchemeTags[i],0,"schemeName")]),
          link: mapSchemeTags[i].getAttribute('link'),
          clientType: mapSchemeTags[i].getAttribute('clientType')
        });
      }
      else if(mapSchemeTags[i].getAttribute('extLink')){
        mapSchemes.push({
          id: currentMapSchemeId,
          name: this.decodeSTRING(mapSchemeTags[i].childNodes[this.__helper__getNextElementNamedChildNode(mapSchemeTags[i],0,"schemeName")]),
          extLink: mapSchemeTags[i].getAttribute('extLink')
        });
      }
      else{
        var themes = new Object;
        var themeTags = this.__helper__getRemainingNextElementNamedChildNodes(mapSchemeTags[i],0,"theme");
        for (var currentTheme = 0; currentTheme < themeTags.length; currentTheme++)
        {
          themeId = themeTags[currentTheme].getAttribute('id');
          themes[themeId] = {
            id: themeId,
            display: parseInt(themeTags[currentTheme].getAttribute('display')),
            legend: themeTags[currentTheme].getAttribute('legend')
          }
        };
        var layerControl = null;
        var layerControlNode = mapSchemeTags[i].getElementsByTagName('layerControl')[0];
        if(layerControlNode){
          var config = [];
          for (var j=0;j<layerControlNode.childNodes.length;j++)
          if (layerControlNode.childNodes[j].nodeName=='groupItem')
            config.push(this.parseThemeGroupItem(layerControlNode.childNodes[j]));
          layerControl = config;
        }
        var hiddenQueryNodes = mapSchemeTags[i].getElementsByTagName('hiddenQuery');
        var hiddenQueries = {};
        for(var j = 0; j < hiddenQueryNodes.length; j++){
          hiddenQueries[hiddenQueryNodes[j].getAttribute('id')] = true;
        }
        var mapTool = null;
        if(mapSchemeTags[i].getElementsByTagName('mapTool')[0]){
          mapTool = mapSchemeTags[i].getElementsByTagName('mapTool')[0].getAttribute('name');
        }
        mapSchemes.push({
          id: currentMapSchemeId,
          name: this.decodeSTRING(mapSchemeTags[i].childNodes[this.__helper__getNextElementNamedChildNode(mapSchemeTags[i],0,"schemeName")]),
          themes: themes,
          layerControl: layerControl,
          hiddenQueries: hiddenQueries,
          mapTool: mapTool
        });
      }
    }
  };
  return {
    mapSchemes: mapSchemes,
    defaultMapScheme: (this.decodeSTRING(defaultMapSchemeNode) != '')? parseInt(this.decodeSTRING(defaultMapSchemeNode)) : 0
  };
};

FreeanceXMLParser.prototype.parseThemeGroups = function(mapNode)
{
  var config = [];
  //determine type of layer control to use
  var themeGroupDefinitionNodes = mapNode.getElementsByTagName("themeGroupDefinitions");
  var layerControlNodes = mapNode.getElementsByTagName("layerControl");
  if (themeGroupDefinitionNodes.length>0) //pre-4.2 format, map to new structure
  {
    config = this.parseOldThemeGroups(themeGroupDefinitionNodes[0]);
  }
  else
  {
    //top-level is an implicit group
    for (var i=0;i<layerControlNodes[0].childNodes.length;i++)
      if (layerControlNodes[0].childNodes[i].nodeName=='groupItem')
        config.push(this.parseThemeGroupItem(layerControlNodes[0].childNodes[i]));
  }
  return config;
};


FreeanceXMLParser.prototype.parseThemeGroupItem = function(groupItemNode){
  var config = {
    type:groupItemNode.getAttribute('type'),
    name:groupItemNode.getAttribute('name'),
    layerid:groupItemNode.getAttribute('layerid'),
    toggle:groupItemNode.getAttribute('toggle')=='on',
    children:[]
  };
  if(config.type=='group' || config.type=='radio_group')
    for(var i=0;i<groupItemNode.childNodes.length;i++)
      if(groupItemNode.childNodes[i].nodeName=='groupItem')
        config.children.push(this.parseThemeGroupItem(groupItemNode.childNodes[i]));
  return config;
};


FreeanceXMLParser.prototype.parseOldThemeGroups = function(parentNode)
{
  dprintf('loading pre-4.2 style theme groups');
  var config = [];
  var childconfig = [];
  var groupMemberNodes = null;
  var groupNodes = parentNode.getElementsByTagName('themeGroup');
  if (groupNodes.length==1) //treat as single group with label
  {
    config.push({
      type: 'label',
      name: this.decodeSTRING(groupNodes[0].getElementsByTagName('themeGroupName')[0]),
      toggle: false
    });
    groupMemberNodes = groupNodes[0].getElementsByTagName('themeGroupMember');
    for (var i=0;i<groupMemberNodes.length;i++){
      config.push({
        type:'layer',
        layerid:this.decodeSTRING(groupMemberNodes[i]),
        toggle:true
      });
    }
  }
  else
  {
    for (var i=0;i<groupNodes.length;i++){
      childconfig = [];
      groupMemberNodes = groupNodes[i].getElementsByTagName('themeGroupMember');
      for (var j=0;j<groupMemberNodes.length;j++){
        childconfig.push({
          type:'layer',
          layerid:this.decodeSTRING(groupMemberNodes[j]),
          name:'',
          toggle:true,
          children:[]
        });
      }
      config.push({
        type: 'group',
        name: this.decodeSTRING(groupNodes[i].getElementsByTagName('themeGroupName')[0]),
        layerid:'',
        toggle: false,
        children: childconfig
      });
    }
  }
  return config;  
};


FreeanceXMLParser.prototype.parseScalebarConfig = function(newNode)
{
  var scalebarConfig = new Array();
  for (var levelIndex = this.__helper__getNextElementNamedChildNode(newNode,0,"level");levelIndex!=-1;levelIndex=this.__helper__getNextElementNamedChildNode(newNode,levelIndex+1,"level"))
  {
    var levelNode = newNode.childNodes[levelIndex];
    scalebarConfig.push([
      parseInt(levelNode.getAttribute('topUnit')),
      parseFloat(levelNode.getAttribute('topLength')),
      parseInt(levelNode.getAttribute('bottomUnit')),
      parseFloat(levelNode.getAttribute('bottomLength')),
      parseFloat(levelNode.getAttribute('mapWidth'))
    ]);
  }
  return scalebarConfig;
};

FreeanceXMLParser.prototype.parseVMapConfig = function(vmapNode)
{
  return {
    id: vmapNode.getAttribute("id"),
    resourceId: this.decodeSTRING(vmapNode.childNodes[this.__helper__getNextElementNamedChildNode(vmapNode,0,"resourceId")]),
    slaveType: this.decodeSTRING(vmapNode.childNodes[this.__helper__getNextElementNamedChildNode(vmapNode,0,"slaveType")]),
    boundBoxPercentMin: this.decodeDOUBLE(vmapNode.childNodes[this.__helper__getNextElementNamedChildNode(vmapNode,0,"boundBoxPercentMin")]),
    styleSheet: this.decodeSTRING(vmapNode.childNodes[this.__helper__getNextElementNamedChildNode(vmapNode,0,"styleSheet")])
  };
};

FreeanceXMLParser.prototype.parseTemplateConfig = function(templateRootNode)
{
  var templates = new Object();
  var htmlString = '';
  for (var templateIndex = this.__helper__getNextElementNamedChildNode(templateRootNode,0,"template");templateIndex!=-1;templateIndex=this.__helper__getNextElementNamedChildNode(templateRootNode,templateIndex+1,"template"))
  {
    for (var lcv=0;lcv < templateRootNode.childNodes[templateIndex].childNodes.length;lcv++)
    {
      if (templateRootNode.childNodes[templateIndex].childNodes.item(lcv).nodeType == 4)
        htmlString = templateRootNode.childNodes[templateIndex].childNodes.item(lcv).nodeValue;
    }
    templates[templateRootNode.childNodes[templateIndex].getAttribute("id")] = htmlString;
  }
  OBJECT_MANAGER.setGuiValue('templates', templates);
  return templates;
};

FreeanceXMLParser.prototype.parseExtensionConfig = function(extensionConfigNode)
{
  var extensions = new Object();
  var extensionNodes = extensionConfigNode.getElementsByTagName('extension');
  for(var lcv=0; lcv < extensionNodes.length;lcv++)
  {
    var extension = extensionNodes[lcv];
    var name = extension.getAttribute('name');
    var enabled = extension.getAttribute('enabled');
    extensions[name] = new Object();
    extensions[name].enabled = (enabled == 'true'); //?true:false;
    if (extensions[name].enabled)
    {
      var forceLoad = extension.getAttribute('forceLoad');
      extensions[name].forceLoad = ((typeof(forceLoad)=='string')?((forceLoad == 'true')?true:false):(false));
    }
    extensions[name].loaded = false;
  }
  OBJECT_MANAGER.setGuiValue('extensions',extensions);
  return(extensions);
};

FreeanceXMLParser.prototype.parseThemeDefinitions = function (newNode)
{
  var themeDefinitions = new Array();
  for (themeIndex=this.__helper__getNextElementNamedChildNode(newNode,0,"theme");themeIndex!=-1;themeIndex=this.__helper__getNextElementNamedChildNode(newNode,themeIndex+1,"theme"))
  {
    themeDefinitions[newNode.childNodes[themeIndex].getAttribute("id")] = this.parseTheme(newNode.childNodes[themeIndex]);
  }
  return themeDefinitions;
};

FreeanceXMLParser.prototype.parseTheme = function (themeNode)
{
  var themeAttributes = new Array();
  var themeFieldsNodes = themeNode.getElementsByTagName('themeFields');
  themeAttributes["id"] = themeNode.getAttribute("id");
  themeAttributes["hideTheme"] = themeNode.getAttribute("hideTheme");
  if (themeAttributes["hideTheme"] == null)
    themeAttributes["hideTheme"] = false;
  else
    themeAttributes["hideTheme"] = themeAttributes["hideTheme"] == 'true';
  
  themeAttributes["themeName"] = escapeHTML(this.decodeSTRING(themeNode.childNodes[this.__helper__getNextElementNamedChildNode(themeNode,0,"themeName")]));
  if (this.__helper__getNextElementNamedChildNode(themeNode,0,"selectOptions")!=-1)
    themeAttributes["selectOptions"] = this.parseThemeSelectOptions(themeNode.childNodes[this.__helper__getNextElementNamedChildNode(themeNode,0,"selectOptions")]);
  else
    themeAttributes["selectOptions"] = null;
  if (this.__helper__getNextElementNamedChildNode(themeNode,0,"bufferOptions")!=-1)
    themeAttributes["bufferOptions"] = this.parseThemeBufferOptions(themeNode.childNodes[this.__helper__getNextElementNamedChildNode(themeNode,0,"bufferOptions")]);
  else
    themeAttributes["bufferOptions"] = null;
  themeAttributes["themeFields"] = themeFieldsNodes.length?(this.decodeSTRING(themeFieldsNodes[0])).parseJSON():{};
  themeAttributes["visibility"] = false;
  return themeAttributes;
};

FreeanceXMLParser.prototype.parseThemeSelectOptions = function(newNode)
{
  var selectAttributes = {
    styleSheet: this.decodeSTRING(newNode.childNodes[this.__helper__getNextElementNamedChildNode(newNode,0,"styleSheet")]),
    fieldList: this.decodeSTRING(newNode.childNodes[this.__helper__getNextElementNamedChildNode(newNode,0,"fieldList")]),
    limit: this.decodeINT(newNode.childNodes[this.__helper__getNextElementNamedChildNode(newNode,0,"limit")]),
    tolerance: this.decodeDOUBLE(newNode.childNodes[this.__helper__getNextElementNamedChildNode(newNode,0,"tolerance")]),
    idField: this.decodeSTRING(newNode.childNodes[this.__helper__getNextElementNamedChildNode(newNode,0,"idField")]),
    keyField: this.decodeSTRING(newNode.childNodes[this.__helper__getNextElementNamedChildNode(newNode,0,"keyField")])
  };
  var keyFieldTypeIndex = this.__helper__getNextElementNamedChildNode(newNode,0,"keyFieldType");
  selectAttributes["keyFieldType"] = ((keyFieldTypeIndex!=-1)?(this.decodeINT(newNode.childNodes[keyFieldTypeIndex])):(12));
  var zoomExtentRatioIndex = this.__helper__getNextElementNamedChildNode(newNode,0,"zoomExtentRatio");
  if (zoomExtentRatioIndex == -1)
    selectAttributes["zoomExtentRatio"] = 1.2;
  else
    selectAttributes["zoomExtentRatio"] = this.decodeDOUBLE(newNode.childNodes[zoomExtentRatioIndex]);
  selectAttributes["resultTemplate"] = this.decodeSTRING(newNode.childNodes[this.__helper__getNextElementNamedChildNode(newNode,0,"resultTemplate")]);
  var sqlParamsIndex = this.__helper__getNextElementNamedChildNode(newNode,0,"sqlParams");
  if (sqlParamsIndex > -1)
    selectAttributes["sqlParams"] = this.parseChainedQuerySqlParams(newNode.childNodes[sqlParamsIndex]);
  else
    selectAttributes["sqlParams"] = null;
  return selectAttributes;
};

FreeanceXMLParser.prototype.parseChainedQuerySqlParams = function(sqlParamsNode)
{
  var sqlParams = new Array();
  var sqlParamNodeList = sqlParamsNode.getElementsByTagName('sqlParam');
  var numQueries = 0;
  for(var lcv=0;lcv < sqlParamNodeList.length;lcv++)
  {
    numQueries++;
    var theNode = sqlParamNodeList[lcv];
    sqlParams[lcv] = new Object;
    sqlParams[lcv]["pdqIdentifier"] = this.decodeSTRING(theNode.childNodes[this.__helper__getNextElementNamedChildNode(theNode,0,"pdqIdentifier")]);
    sqlParams[lcv]["fieldList"] = new Array();
    var fieldListNode = theNode.childNodes[this.__helper__getNextElementNamedChildNode(theNode,0,"fieldList")];
    var fieldNodeList = fieldListNode.getElementsByTagName('field');
    for(var fieldIndex=0;fieldIndex < fieldNodeList.length;fieldIndex++)
    {
      var fieldListIndex = sqlParams[lcv]["fieldList"].length;
      sqlParams[lcv]["fieldList"][fieldListIndex] = new Object();
      sqlParams[lcv]["fieldList"][fieldListIndex]["fieldName"] = this.decodeSTRING(fieldNodeList[fieldIndex].getElementsByTagName("fieldName")[0]);
      sqlParams[lcv]["fieldList"][fieldListIndex]["pdqFieldName"] = this.decodeSTRING(fieldNodeList[fieldIndex].getElementsByTagName("pdqFieldName")[0]);
    }
    if (this.__helper__getNextElementNamedChildNode(theNode,0,"queryType") > -1)
    {
      sqlParams[lcv]["queryType"] = this.decodeSTRING(theNode.childNodes[this.__helper__getNextElementNamedChildNode(theNode,0,"queryType")]);
      sqlParams[lcv]["numRows"]   = this.decodeINT(theNode.childNodes[this.__helper__getNextElementNamedChildNode(theNode,0,"numRows")]);
      sqlParams[lcv]["startAt"] = this.decodeINT(theNode.childNodes[this.__helper__getNextElementNamedChildNode(theNode,0,"startAt")]);
    }
    else  // do not want.  use full select instead
    {
      sqlParams[lcv]["queryType"] = '';
      sqlParams[lcv]["numRows"] = 0;
      sqlParams[lcv]["startAt"] = 0;
    }
  }
  if (numQueries == 0)
    sqlParams = null;
  return(sqlParams);
};

FreeanceXMLParser.prototype.parseThemeBufferOptions = function(newNode)
{
  var bufferAttributes = {
    styleSheet: this.decodeSTRING(newNode.childNodes[this.__helper__getNextElementNamedChildNode(newNode,0,"styleSheet")]),
    areaStyleSheet: this.decodeSTRING(newNode.childNodes[this.__helper__getNextElementNamedChildNode(newNode,0,"areaStyleSheet")]),
    fieldList: this.decodeSTRING(newNode.childNodes[this.__helper__getNextElementNamedChildNode(newNode,0,"fieldList")]),
    limit: this.decodeINT(newNode.childNodes[this.__helper__getNextElementNamedChildNode(newNode,0,"limit")]),
    resultTemplate: this.decodeSTRING(newNode.childNodes[this.__helper__getNextElementNamedChildNode(newNode,0,"resultTemplate")]),
    invalidTemplate: this.decodeSTRING(newNode.childNodes[this.__helper__getNextElementNamedChildNode(newNode,0,"invalidTemplate")]),
    maxSelect: this.decodeINT(newNode.childNodes[this.__helper__getNextElementNamedChildNode(newNode,0,"maxSelect")])
  };
  var sqlParamsIndex = this.__helper__getNextElementNamedChildNode(newNode,0,"sqlParams");
  if (sqlParamsIndex > -1)
    bufferAttributes["sqlParams"] = this.parseChainedQuerySqlParams(newNode.childNodes[sqlParamsIndex]);
  else
    bufferAttributes["sqlParams"] = null;
  if (this.__helper__getNextElementNamedChildNode(newNode,0,"filterQueries") != -1)
  {
    var queryListNode = newNode.childNodes[this.__helper__getNextElementNamedChildNode(newNode,0,"filterQueries")];
    bufferAttributes["filterQueries"] = new Object;
    for (var queryIndex = this.__helper__getNextElementNamedChildNode(queryListNode,0,"query");queryIndex!=-1;queryIndex=this.__helper__getNextElementNamedChildNode(queryListNode,queryIndex+1,"query"))
    {
      bufferAttributes["filterQueries"][this.decodeSTRING(queryListNode.childNodes[queryIndex])] = null;
    }
  }
  else
    bufferAttributes["filterQueries"] = null;
  if (this.__helper__getNextElementNamedChildNode(newNode,0,"export_csv")!=-1)
  {
    if (!bufferAttributes["export"])
      bufferAttributes["export"] = new Object;
    bufferAttributes["export"].csv = new Object;
    if(this.decodeSTRING(newNode.childNodes[this.__helper__getNextElementNamedChildNode(newNode,0,"export_csv")]) == 'true')
    {
      bufferAttributes["export"].csv.enabled = true;
      bufferAttributes["export"].csv.delim = this.decodeSTRING(newNode.childNodes[this.__helper__getNextElementNamedChildNode(newNode,0,"export_csv_delim")]);
      if(this.decodeSTRING(newNode.childNodes[this.__helper__getNextElementNamedChildNode(newNode,0,"export_csv_includefieldnames")])=='true')
        bufferAttributes["export"].csv.includeFieldNames = true;
      else
        bufferAttributes["export"].csv.includeFieldNames = false;
    }
    else
      bufferAttributes["export"].csv.enabled = false;
  }
  return bufferAttributes;
};

FreeanceXMLParser.prototype.parseLegendAttributes = function (newNode)
{
  return (newNode.nodeName=='legendAttributes')?{
    width: this.decodeINT(newNode.getElementsByTagName('width')[0].getElementsByTagName('int')[0]),
    height: this.decodeINT(newNode.getElementsByTagName('height')[0].getElementsByTagName('int')[0]),
    color: this.decodeSTRING(newNode.getElementsByTagName('color')[0].getElementsByTagName('string')[0]),
    font: this.decodeSTRING(newNode.getElementsByTagName('font')[0].getElementsByTagName('string')[0]),
    fontSize: this.decodeINT(newNode.getElementsByTagName('fontSize')[0].getElementsByTagName('int')[0]),
    valueFontSize: this.decodeINT(newNode.getElementsByTagName('valueFontSize')[0].getElementsByTagName('int')[0]),
    cellSpacing: this.decodeINT(newNode.getElementsByTagName('cellSpacing')[0].getElementsByTagName('int')[0])
  }:{
    width: newNode.getAttribute('width'),
    height: parseInt(newNode.getAttribute('height')),
    color: newNode.getAttribute('color'),
    font: newNode.getAttribute('font'),
    fontSize: newNode.getAttribute('fontSize'),
    valueFontSize: parseInt(newNode.getAttribute('valueFontSize')),
    cellSpacing: parseInt(newNode.getAttribute('cellSpacing'))
  };
};


FreeanceXMLParser.prototype.parseMapExportConfig = function(newNode)
{
  var exportConfig = new Object;
  exportConfig.enabled = newNode.getAttribute('enabled');
  return exportConfig;
};

FreeanceXMLParser.prototype.parsePdfPrintConfig = function (newNode)
{
  var printConfig = {
    templates: [],
    defaultTemplate: parseInt(newNode.getAttribute('defaultTemplate'))
  };
  var templateNodes = newNode.getElementsByTagName('template');
  for(var i=0;i<templateNodes.length;i++)
  {
    var inputNodes = templateNodes[i].getElementsByTagName('userinput');
    var userinput = [];
    for (var j=0;j<inputNodes.length;j++)
      userinput.push({
          id:inputNodes[j].getAttribute('id'),
          description:inputNodes[j].getAttribute('description'),
          maxlength:parseInt(inputNodes[j].getAttribute('maxlength'))
      });
    printConfig.templates.push({
      displayName: this.decodeSTRING(templateNodes[i].getElementsByTagName("displayname")[0]),
      templateName: this.decodeSTRING(templateNodes[i].getElementsByTagName("templatename")[0]),
      orientation: templateNodes[i].getAttribute('orientation'),
      unit: templateNodes[i].getAttribute('unit'),
      width: parseFloat(templateNodes[i].getAttribute('width')),
      height: parseFloat(templateNodes[i].getAttribute('height')),
      mapwidth: parseFloat(templateNodes[i].getAttribute('mapwidth')),
      mapheight: parseFloat(templateNodes[i].getAttribute('mapheight')),
      userinput: userinput
    });
  }
  if ((printConfig.templates.length > 0)&&(printConfig.defaultTemplate==-1))
    printConfig.defaultTemplate = 0;
  if (printConfig.templates.length==0)
    printConfig.defaultTemplate = -1;
  printConfig.activeTemplate = printConfig.defaultTemplate;
  return printConfig;
};

FreeanceXMLParser.prototype.parseQueryConfig = function(queryRootNode)
{
  var queries = new Object();
  var htmlString = '';
  for (var queryIndex = this.__helper__getNextElementNamedChildNode(queryRootNode,0,"definedQuery");queryIndex!=-1;queryIndex=this.__helper__getNextElementNamedChildNode(queryRootNode,queryIndex+1,"definedQuery"))
  {
    var currentQuery = queryRootNode.childNodes[queryIndex];
    queries[currentQuery.getAttribute("id")] = this.parseDefinedQuery(currentQuery);
  }
  OBJECT_MANAGER.setGuiValue('queries', queries);
  return queries;
};

FreeanceXMLParser.prototype.parseDefinedQuery = function(queryNode)
{
  var requestNode = queryNode.getElementsByTagName('request')[0];
  var fieldsNode = queryNode.getElementsByTagName('fieldList')[0];
  var exportNode = queryNode.getElementsByTagName('exportQuery')[0];
  var templateNode = queryNode.getElementsByTagName('resultTemplates')[0];
  var fieldList = this.parseQueryFields(fieldsNode);
  var exportConfig = (!exportNode)?({
      csv:{
        enabled: false,
        delim:',',
        includeFieldNames:true
      },
      xml:{
        enabled: false
      }
    }):({
      csv:{
        enabled: (this.decodeSTRING(exportNode.getElementsByTagName('export_csv')[0])=='true'),
        delim:this.decodeSTRING(exportNode.getElementsByTagName('export_csv_delim')[0]),
        includeFieldNames:(this.decodeSTRING(exportNode.getElementsByTagName('export_csv_includefieldnames')[0])=='true')
      },
      xml:{
        enabled: (this.decodeSTRING(exportNode.getElementsByTagName('export_xml')[0])=='true')
    }
  });
  
  var displayIndex = this.getNextElementNamedChildNode(queryNode,0,"display");
  var dbtypeindex = this.getNextElementNamedChildNode(requestNode,0,"dbtype");
  var config = {
    id: queryNode.getAttribute('id'),
    display: (displayIndex>-1)?(this.decodeSTRING(queryNode.childNodes[displayIndex])=='true'):true,
    title: this.decodeSTRING(queryNode.getElementsByTagName('title')[0]),
    description: this.decodeSTRING(queryNode.getElementsByTagName('description')[0]),
    HTMLForm: this.decodeSTRING(queryNode.getElementsByTagName('HTMLForm')[0]),
    fieldList:fieldList,
    request:{
      dbtype: (dbtypeindex>-1)?(this.decodeSTRING(requestNode.childNodes[dbtypeindex])):'',
      requestMethod: this.decodeSTRING(requestNode.childNodes[this.getNextElementNamedChildNode(requestNode,0,"requestMethod")]),
      pdqIdentifier: this.decodeSTRING(requestNode.childNodes[this.getNextElementNamedChildNode(requestNode,0,"pdqIdentifier")])
    },
    export_:exportConfig,
    templates:{
      validTemplate:this.decodeSTRING(templateNode.getElementsByTagName('validTemplate')[0]),
      invalidTemplate:this.decodeSTRING(templateNode.getElementsByTagName('invalidTemplate')[0]),
      emptyTemplate:this.decodeSTRING(templateNode.getElementsByTagName('emptyTemplate')[0]),
      pageRows:this.decodeINT(templateNode.getElementsByTagName('pageRows')[0])
    },
    suggestConfig:[],
    zoomto:{
      enabled: false,
      queryfield:'',
      layerfield:'',
      layerfieldtype:12,
      layerid:'',
      stylesheet:''      
    }
  };
  var zoomto = null;
  var zoomtoNode = null;
  for (var i=0;i<queryNode.childNodes.length;i++)
    if(queryNode.childNodes[i].nodeName=='zoomto')
      zoomtoNode = queryNode.childNodes[i];
  
  if(zoomtoNode){
    config["zoomto"]={
      enabled: true,
      queryfield:zoomtoNode.getAttribute("queryfield"),
      layerfield:zoomtoNode.getAttribute("layerfield"),
      layerfieldtype:parseInt(zoomtoNode.getAttribute("layerfieldtype")),
      layerid:zoomtoNode.getAttribute("layerid"),
      stylesheet:zoomtoNode.getAttribute("stylesheet"),
		auto:(zoomtoNode.getAttribute("auto") == "true"),
		autoMaplink:(zoomtoNode.getAttribute("autoMaplink") == "true"),
		maplinkLayer:zoomtoNode.getAttribute("maplinkLayer")
    }
  };
  var suggestNodeIndex = this.getNextElementNamedChildNode(queryNode,0,"suggestConfig");
  if (suggestNodeIndex!=-1)
  {
    var suggestConfigNode = queryNode.childNodes[suggestNodeIndex];
    var suggestNodes = suggestConfigNode.getElementsByTagName('suggestInput');
    for (var i=0;i<suggestNodes.length;i++)
    {
      config.suggestConfig.push({
        pdqfield: suggestNodes[i].getAttribute('pdqfield'),
        elementId: suggestNodes[i].getAttribute('elementId'),
        resultElementId: suggestNodes[i].getAttribute('resultElementId'),
        timeout: parseInt(suggestNodes[i].getAttribute('timeout')),
        dbid: suggestNodes[i].getAttribute('dbid'),
        tablename: suggestNodes[i].getAttribute('tablename'),
        fieldname: suggestNodes[i].getAttribute('fieldname'),
        resultlimit: parseInt(suggestNodes[i].getAttribute('resultlimit'))
      });
    }
  };
  return config;  
};

FreeanceXMLParser.prototype.parseQueryFields = function(fieldsNode)
{
  var fieldsConfig = new Array();
  for (var fieldIndex=this.__helper__getNextElementChildNode(fieldsNode,0);fieldIndex!=-1;fieldIndex=this.__helper__getNextElementChildNode(fieldsNode,fieldIndex+1))
  {
    var currentNode = fieldsNode.childNodes[fieldIndex];
    var newField = {
      fieldType: currentNode.nodeName,
      caption: '',
      fieldName: '',
      width: 0,
      defaultValue: '',
      initialValue: '',
      optionList: [],
      dynamicList:{
        dbid: '',
        table:'',
        valuefield: '',
        labelfield: '',
        whereclause:'',
        limit:10
      }
    };
    for (var i=0;i<currentNode.childNodes.length;i++){
      var fieldOptionNode=currentNode.childNodes[i];
      switch(fieldOptionNode.nodeName){
        case 'caption':
        case 'fieldName':
        case 'defaultValue':
        case 'initialValue':
          newField[fieldOptionNode.nodeName]=this.decodeSTRING(fieldOptionNode);
          break;
        case 'width':
          newField['width']=this.decodeINT(fieldOptionNode);
          break;
        case 'optionList':
          newField['optionList'] = this.parseOptionList(fieldOptionNode);
          break;
        case 'dynamicList':
          newField['dynamicList']['dbid']=fieldOptionNode.getAttribute('dbid');
          newField['dynamicList']['table']=fieldOptionNode.getAttribute('table');
          newField['dynamicList']['valuefield']=fieldOptionNode.getAttribute('valuefield');
          newField['dynamicList']['labelfield']=fieldOptionNode.getAttribute('labelfield');
          newField['dynamicList']['whereclause']=fieldOptionNode.getAttribute('whereclause');
          newField['dynamicList']['limit']=parseInt(fieldOptionNode.getAttribute('limit'));
          break;
      };
    }
    fieldsConfig.push(newField);
  }
  return fieldsConfig;
};

FreeanceXMLParser.prototype.parseOptionList = function(listParentNode)
{
  var optionList = new Array;
  for (var optionIndex=this.__helper__getNextElementChildNode(listParentNode,0);optionIndex!=-1;optionIndex=this.__helper__getNextElementChildNode(listParentNode,optionIndex+1))
  {
    var currentNode = listParentNode.childNodes[optionIndex];
    switch (currentNode.nodeName)
    {
      case 'option':
        optionList.push({
          type: 'option',
          value: currentNode.getAttribute("value"),
          label: currentNode.getAttribute("label")
        });
        break;
      case 'optgroup':
        optionList.push({
          type: 'optgroup',
          label: currentNode.getAttribute("label"),
          value: this.parseOptionList(currentNode)
        });
        break;
      default:
        break;
    }
  }
  return optionList;
};


FreeanceXMLParser.prototype.parseMeasureConfig = function(configNode)
{
  var config = null;
  if (configNode != null)
  {
    config = {
      distanceMeasureUnits: this.decodeSTRING(configNode.childNodes[this.__helper__getNextElementNamedChildNode(configNode,0,'distanceMeasureUnits')]),
      distanceColor: this.decodeSTRING(configNode.childNodes[this.__helper__getNextElementNamedChildNode(configNode,0,'distanceColor')]),
      distanceThickness: this.decodeSTRING(configNode.childNodes[this.__helper__getNextElementNamedChildNode(configNode,0,'distanceThickness')])
    }
  }
  OBJECT_MANAGER.setGuiValue('MeasureConfig',config);
  return (config);
};}
/* FILE:FreeanceWeb/Common/lib/XML/XMLPostRequest.js */ if(!window.freeance_loaded_js['1526d47063cf263b6ca5528b7fe8cd6b']){window.freeance_loaded_js['1526d47063cf263b6ca5528b7fe8cd6b']=1;
/******************************************************************
-------DEPRECATED
******************************************************************/

function makeTextSyncPostRequest(/*URL,functionName,params....*/)
{
  var URL = arguments[0];
  var functionName = arguments[1];
  dprintf('<span class="logWarning">DEPRECATED FUNCTION CALL</span><BR>-------<BR>makeTextSyncPostRequest('+URL+','+functionName+'...)',true);

  var argstr = '';
  for (var argpos=2;argpos<arguments.length;argpos++)
    argstr+=','+arguments[argpos];  
  dprintf('<span class="logWarning">DEPRECATED FUNCTION CALL</span><BR>-------<BR>makeTextSyncPostRequest('+URL+','+functionName+argstr+')',true);

  
  var thisRequest = new XMLRPCMessage(functionName);
  for (lcv = 2; lcv < arguments.length; lcv++)
    thisRequest.addParameter(arguments[lcv]);
  var thisRequestDoc = XmlDocument.create();
  thisRequestDoc.loadXML(thisRequest.xml());
  
  var serverReply = XmlHttp.postTextSync(URL,thisRequestDoc);
  return (serverReply);
};

/******************************************************************/

function makeSyncPostRequest(/*URL,functionName,params....*/)
{
  var URL = arguments[0];
  var functionName = arguments[1];
  
  
  var argstr = '';
  for (var argpos=2;argpos<arguments.length;argpos++)
    argstr+=','+arguments[argpos];  
  dprintf('<span class="logWarning">DEPRECATED FUNCTION CALL</span><BR>-------<BR>makeSyncPostRequest('+URL+','+functionName+argstr+')',true);
  
  var thisRequest = new XMLRPCMessage(functionName);
  for (lcv = 2; lcv < arguments.length; lcv++)
    thisRequest.addParameter(arguments[lcv]);
  var thisRequestDoc = XmlDocument.create();
  thisRequestDoc.loadXML(thisRequest.xml());
  
  var serverReplyDoc = XmlHttp.postSync(URL,thisRequestDoc);
  return serverReplyDoc;
};

/*******************************************************************/

function makeASyncPostRequest(/*Callback,request_type,URL,functionName,params....*/)
{
  //9-09-02:  modified to accept a request-type parameter
  var Callback = arguments[0];
  var request_type = arguments[1];
  var URL = arguments[2];
  var functionName = arguments[3];

  var argstr = '';
  for (var argpos=4;argpos<arguments.length;argpos++)
    argstr+=','+arguments[argpos];
  dprintf('<span class="logWarning">DEPRECATED FUNCTION CALL</span><BR>-------<BR>makeASyncPostRequest('+URL+','+request_type+','+functionName+argstr+')',true);
  
  var thisRequest = new XMLRPCMessage(functionName);
  for (lcv = 4; lcv < arguments.length; lcv++)
    thisRequest.addParameter(arguments[lcv]);
  var thisRequestDoc = XmlDocument.create();
  thisRequestDoc.loadXML(thisRequest.xml());
  XmlHttp.postAsync(URL,thisRequestDoc,Callback,request_type);
  return(thisRequestDoc);
};

function makeASyncPostRequest_(/*Callback,request_type,URL,functionName,params....*/)
{
  //9-09-02:  modified to accept a request-type parameter
  var Callback = arguments[0];
  var URL = arguments[1];
  var functionName = arguments[2];
  var argstr = '';
  for (var argpos=3;argpos<arguments.length;argpos++)
    argstr+=','+arguments[argpos];
  dprintf('<span class="logWarning">DEPRECATED FUNCTION CALL</span><BR>-------<BR>makeASyncPostRequest('+URL+','+functionName+argstr+')',true);
  
  var thisRequest = new XMLRPCMessage(functionName);
  for (lcv = 3; lcv < arguments.length; lcv++)
    thisRequest.addParameter(arguments[lcv]);
  var thisRequestDoc = XmlDocument.create();
  thisRequestDoc.loadXML(thisRequest.xml());
  XmlHttp.postAsync_(URL,thisRequestDoc,Callback);
  return(thisRequestDoc);
};


/******************************************************************/

function validateXMLDoc(xmlDoc)
{ 
  dprintf('<span class="logWarning">DEPRECATED FUNCTION CALL</span><BR>-------<BR>validateXMLDoc('+xmlDoc+')',true);
  try
  {
    if(xmlDoc == null) 
      return false;
    var xmlstr = (typeof(xmlDoc.xml)=='function')?xmlDoc.xml():xmlDoc.xml;
    if(xmlstr == '')
      return false;
    if(xmlDoc.documentElement.nodeName == 'parsererror')
      return false;
    return true;
  }
  catch(e)
  {
    return false;
  }
};}
/* FILE:FreeanceWeb/Common/lib/XML/XMLRPC_Message.js */ if(!window.freeance_loaded_js['885aca9f74987530f9be7a13e170c1e4']){window.freeance_loaded_js['885aca9f74987530f9be7a13e170c1e4']=1;
/*

xmlrpc.js beta version 1
Tool for creating XML-RPC formatted requests in JavaScript

Copyright 2001 Scott Andrew LePera
scott@scottandrew.com
http://www.scottandrew.com/xml-rpc

License: 
You are granted the right to use and/or redistribute this 
code only if this license and the copyright notice are included 
and you accept that no warranty of any kind is made or implied 
by the author.

*/

function XMLRPCMessage(methodname){
  this.method = methodname||"system.listMethods";
  this.params = [];
  return this;
};

XMLRPCMessage.prototype.setMethod = function(methodName){
  if (!methodName) return;
  this.method = methodName;
};

XMLRPCMessage.escapeXML = function(srcString)
{
  return srcString.replace(/&/g,'&amp;').replace(/</g,'&lt;').replace(/>/g,'&gt;').replace(/"/g,'&quot;');
};

XMLRPCMessage.prototype.replaceStr = function(orig,lookfor,replacewith,ignorecase)  // JPW::Jan 6, 2003
  {
    var str = new String();
    str += orig;
    var type = 'g';
    if (ignorecase) 
      type += 'i';
    var re = new RegExp (lookfor, type);
    return(str.replace(re,replacewith));
  };

XMLRPCMessage.prototype.addParameter = function(data){
  if (arguments.length==0) return;
  var type = typeof(data);
  type = type.toLowerCase();
  this.params[this.params.length] = data;
};

XMLRPCMessage.prototype.xml = function(){

  var method = this.method;
  // assemble the XML message header
  var xml = "";
  xml += "<?xml version=\"1.0\"?>\n";
  xml += "<methodCall>\n";
  xml += "<methodName>" + method+ "</methodName>\n";
  xml += "<params>\n";
  // do individual parameters
  for (var i = 0; i < this.params.length; i++){
    var data = this.params[i];
    var paramXML=XMLRPCMessage.getParamXML(XMLRPCMessage.dataTypeOf(data),data);
    if (paramXML!=null)
    {
      xml += "<param>\n";
      xml += "<value>" + paramXML + "</value>\n";
      xml += "</param>\n";
    }
    else
      alert('Warning:\nAn error occurred when building a request to send to the server\nAttempted to add an undefined value as a parameter.\nSome data may be lost.');
  }
  xml += "</params>\n";
  xml += "</methodCall>";
  return xml; // for now
};

XMLRPCMessage.dataTypeOf = function (o){
  // identifies the data type
  var type = typeof(o);
  type = type.toLowerCase();
  switch(type){
    case "number":
      if (Math.round(o) == o) type = "i4";
      else type = "double";
      break;
    case "object":
      try {
        var con = o.constructor;
        if (con == Date) type = "date";
        else if (con == Array) type = "array";
        else type = "struct";
      }
      catch(e)
      { type = "struct" }
      break;
  }
  return type;
};

XMLRPCMessage.doValueXML = function(type,data){
  var xml=null;
  switch (type)
  {
    case 'string':
      data = this.escapeXML(data);
      break;
    case 'undefined':
      data=null;
      break;
    default:
      break;
  }
  if (data!=null)
    xml = "<" + type + ">" + data + "</" + type + ">";
  return xml;
};

XMLRPCMessage.doBooleanXML = function(data){
  var value = (data==true)?1:0;
  var xml = "<boolean>" + value + "</boolean>";
  return xml;
};

XMLRPCMessage.doDateXML = function(data){
  var xml = "<dateTime.iso8601>";
  xml += dateToISO8601(data);
  xml += "</dateTime.iso8601>";
  return xml;
};

XMLRPCMessage.doArrayXML = function(data){
  var xml = "<array><data>\n";
  for (var i = 0; i < data.length; i++){
    var paramXML=XMLRPCMessage.getParamXML(XMLRPCMessage.dataTypeOf(data[i]),data[i]);
    //if an element has been deleted from an array it will leave a null entry.
    // warn the user and keep going.
    if (paramXML!=null)
      xml += "<value>" + paramXML + "</value>\n";
    /*
    else
      alert('Warning:\nAn error occurred when building a request to send to the server\nAttempted to add an undefined index to an Array.\nSome data may be lost.');
    */
  }
  xml += "</data></array>\n";
  return xml;
};

XMLRPCMessage.doStructXML = function(data){
  var xml = "<struct>\n";
  for (var i in data){
    if(i=='toJSONString')continue;
    var paramXML=XMLRPCMessage.getParamXML(XMLRPCMessage.dataTypeOf(data[i]),data[i]);
    if (paramXML!=null){
      xml += "<member>\n";
      xml += "<name>" + this.escapeXML(i) + "</name>\n";
      xml += "<value>" + paramXML + "</value>\n";
      xml += "</member>\n";
    }
    else{
      alert('Warning:\nAn error occurred when building a request to send to the server\nAttempted to add an undefined member to a Struct.\nSome data may be lost.');      
    }
  }
  xml += "</struct>\n";
  return xml;
};

XMLRPCMessage.getParamXML = function(type,data){
  var xml;
  switch (type){
    case "date":
      xml = XMLRPCMessage.doDateXML(data);
      break;
    case "array":
      xml = XMLRPCMessage.doArrayXML(data);
      break;
    case "struct":
      xml = XMLRPCMessage.doStructXML(data);
      break;
	  case "boolean":
      xml = XMLRPCMessage.doBooleanXML(data);
      break;
    default:
      xml = XMLRPCMessage.doValueXML(type,data);
      break;
  }
  return xml;
};

function dateToISO8601(date){
  // wow I hate working with the Date object
  var year = new String(date.getYear());
  var month = leadingZero(new String(date.getMonth()));
  var day = leadingZero(new String(date.getDate()));
  var time = leadingZero(new String(date.getHours())) + ":" + leadingZero(new String(date.getMinutes())) + ":" + leadingZero(new String(date.getSeconds()));

  var converted = year+month+day+"T"+time;
  return converted;
};

function leadingZero(n){
  // pads a single number with a leading zero. Heh.
  if (n.length==1) n = "0" + n;
  return n;
};}
/* FILE:FreeanceWeb/Common/lib/XML/XMLRPC_Reply.js */ if(!window.freeance_loaded_js['aa366632a9bef563eb91d6714ca12e91']){window.freeance_loaded_js['aa366632a9bef563eb91d6714ca12e91']=1;
function XMLRPCResponse(xmlResponseDoc)
{
  this.xmlDoc = xmlResponseDoc||null;   // XmlDocument
  if (this.xmlDoc == null)
    return (this);
};
XMLRPCResponse.prototype.setResponseByDoc = function(xmlResponseDoc)
{
  if (!xmlResponseDoc) return;
  this.xmlDoc = xmlResponseDoc;
};
XMLRPCResponse.prototype.setResponseByStr = function(xmlResponseStr)
{
  if (!xmlResponseStr) return;
  if (this.xmlDoc == null)
    this.xmlDoc = XmlDocument.create();
  this.xmlDoc.loadXML(xmlResponseStr);
};
XMLRPCResponse.prototype.isFault = function()
{
  if (this.xmlDoc == null) return true;
  try
  {
    var fNode = (this.xmlDoc.documentElement.childNodes.item(0).nodeType == 1)?this.xmlDoc.documentElement.childNodes.item(0):this.xmlDoc.documentElement.childNodes.item(1);
    return(fNode.nodeName == 'fault');
  }
  catch(e){ return(true); }
};
XMLRPCResponse.prototype.getFaultCode = function()
{
  if (this.xmlDoc == null) return (-1);
  if (!this.isFault()) return (-1);
  var members = this.xmlDoc.getElementsByTagName("member");
  for (var lcv = 0;lcv < members.length; lcv++)
  {
    var nameElem = members[lcv].getElementsByTagName("name").item(0);
    if ((nameElem == null) || (nameElem.childNodes.length == 0))  // should never happen
      return (-1);
    var nameStrNode = nameElem.childNodes.item(0);  // grab the text node
    if (nameStrNode.nodeValue == 'faultCode')
    {
      var codeNode = members[lcv].getElementsByTagName("int").item(0);  // node holding the value
      if ((codeNode == null) || (codeNode.childNodes.length == 0)) // should never happen
        return (-1);
      return (codeNode.childNodes.item(0).nodeValue);
    }
  }
  return (-1);
};
XMLRPCResponse.prototype.getFaultString = function()
{
  if (this.xmlDoc == null) return ("");
  if (!this.isFault()) return ("");
  var members = this.xmlDoc.getElementsByTagName("member");
  for (var lcv = 0;lcv < members.length; lcv++)
  {
    var nameElem = members[lcv].getElementsByTagName("name").item(0);
    if ((nameElem == null) || (nameElem.childNodes.length == 0))  // should never happen
      return ("");
    var nameStrNode = nameElem.childNodes.item(0);  // grab the text node
    if (nameStrNode.nodeValue == 'faultString')
    {
      var codeNode = members[lcv].getElementsByTagName("string").item(0);  // node holding the value
      if ((codeNode == null) || (codeNode.childNodes.length == 0)) // should never happen
        return ("");
      return (codeNode.childNodes.item(0).nodeValue);
    }
  }
  return ("");
};
XMLRPCResponse.prototype.getObject = function()
{
  if (this.xmlDoc == null) return null;
  return (this.getObjectRecurse(this.xmlDoc.getElementsByTagName("value").item(0)));
};
XMLRPCResponse.prototype.getObjectRecurse = function(theNode)
{
  if (this.xmlDoc == null) return null;
  if (theNode == null) return null;  
  switch (theNode.nodeName)
  {
    case 'value': // loop thru all tags on this level
      return(this.getObjectRecurse(theNode.childNodes[0])); break;
    case 'string': return(this.decodeSTRING(theNode)); break;
    case 'i4':
    case 'int': return(this.decodeINT(theNode)); break;
    case 'boolean': return(this.decodeBOOLEAN(theNode)); break;
    case 'double': return(this.decodeDOUBLE(theNode)); break;
    case 'dateTime.iso8601': return(this.decodeDATETIME(theNode)); break;
    case 'base64': return(this.decodeBASE64(theNode)); break;
    case 'array': return(this.decodeARRAY(theNode)); break;
    case 'struct': return(this.decodeSTRUCT(theNode)); break;
    default: alert('unknown node type: '+theNode.nodeName); break;
  }
};
XMLRPCResponse.prototype.unescapeHTML = function(newString)
{
  return newString.replace(/&lt;/g,'<').replace(/&gt;/g,'>').replace(/&quot;/g,'"').replace(/&amp;/g,'&');
};
XMLRPCResponse.prototype.decodeSTRING = function(theNode)
{
  if (theNode.childNodes.length > 0) // has textNode
  {
    try{
    if (!xIE4Up)
      theNode.normalize();
    }catch(e)
    {
      try{
      if (!is.ie)
        theNode.normalize();
      }catch(e){}      
    }
    return (this.unescapeHTML(theNode.childNodes[0].nodeValue));
  }
  else return ('');
};
XMLRPCResponse.prototype.decodeINT = function(theNode) // leaf node
{
  var theSTRING = this.decodeSTRING(theNode);
  return (parseInt(theSTRING));
};
XMLRPCResponse.prototype.decodeBOOLEAN = function(theNode)
{
  var theSTRING = this.decodeSTRING(theNode);
  return (theSTRING == '1');
};
XMLRPCResponse.prototype.decodeDOUBLE = function(theNode)
{
  var theSTRING = this.decodeSTRING(theNode);
  return (parseFloat(theSTRING));
};
XMLRPCResponse.prototype.decodeDATETIME = function(theNode) {};
XMLRPCResponse.prototype.decodeBASE64 = function(theNode) {};
XMLRPCResponse.prototype.decodeSTRUCT = function(theNode)
{
  var thisStruct = new Object();
  for (var lcv = 0; lcv < theNode.childNodes.length; lcv++)
  {
    var memberNode = theNode.childNodes[lcv];
    if (memberNode.nodeName == "member")
    {
      var valueNameNode = memberNode.getElementsByTagName("name").item(0);
      var valueNameStr = this.decodeSTRING(valueNameNode);
      thisStruct[valueNameStr] = this.getObjectRecurse(memberNode.getElementsByTagName("value").item(0));
    }
  }
  return (thisStruct);
};
XMLRPCResponse.prototype.__helper__getNextElementChildNode = function(aNode,firstpos)
{
  var foundpos = -1;
  for (var lcv=firstpos;(lcv < aNode.childNodes.length) && (foundpos == -1); lcv++)  
    if (aNode.childNodes[lcv].nodeType == 1)
      foundpos = lcv;
  return (foundpos);
};
XMLRPCResponse.prototype.__helper__getNextElementNamedChildNode = function(aNode,firstpos,nodeName)
{
  for (var lcv=firstpos;lcv < aNode.childNodes.length; lcv++)
    if ((aNode.childNodes[lcv].nodeType == 1) && (aNode.childNodes[lcv].nodeName == nodeName))
      return(lcv);
  return (-1);
};
XMLRPCResponse.prototype.decodeARRAY = function(theNode)
{
  var thisArray = new Array();
  var thisArrayPos = 0;

  var dataNode = theNode.childNodes[this.__helper__getNextElementNamedChildNode(theNode,0,"data")];
  var valueNodePos = 0;
  while (valueNodePos >= 0)
  {
    valueNodePos = this.__helper__getNextElementNamedChildNode(dataNode,valueNodePos,"value");
    if (valueNodePos >= 0)
    {
      valueNode = dataNode.childNodes[valueNodePos];
      thisArray[thisArrayPos] = this.getObjectRecurse(valueNode.firstChild);
      thisArrayPos++;
    }
    if (valueNodePos >= 0) valueNodePos++;
  }
  return (thisArray);
};
/*********************************************************/
function getXMLRPCResponseObject(serverReplyDoc)
{
  //returns a valid object or null
  var clientReply = null;
  var response={data:null,'XMLRPC_FAULT':false,'XMLRPC_FAULT_CODE':null,'XMLRPC_FAULT_MESSAGE':''};
  var validDoc = (serverReplyDoc != null);
  //begin error checks
  if (validDoc)
  {
    var xmlstr = (typeof(serverReplyDoc.xml)=='function')?serverReplyDoc.xml():serverReplyDoc.xml;
    validDoc = (xmlstr != '');
  }
  if (validDoc){
    if (serverReplyDoc.documentElement.nodeName == 'parsererror')
    {
      validDoc = false;
      response.XMLRPC_FAULT_MESSAGE = 'A response was received from the server but could not be processed - the format was invalid.';
    }
  }
  if (validDoc)
  {
    clientReply = new XMLRPCResponse();
    clientReply.setResponseByDoc(serverReplyDoc);
    if (clientReply.isFault())
    {
      response.XMLRPC_FAULT = true;
      response.XMLRPC_FAULT_CODE = clientReply.getFaultCode();
      response.XMLRPC_FAULT_MESSAGE = clientReply.getFaultString();
    }
    else
    {
      response.data = clientReply.getObject(); 
    }
  }
  else
  {
    response.XMLRPC_FAULT = true;
    response.XMLRPC_FAULT_CODE = -1;
    if (response.XMLRPC_FAULT_MESSAGE=='')
      response.XMLRPC_FAULT_MESSAGE = 'An invalid response was received from the server.\n';
    return response;
  }
  return response;
};}
/* FILE:FreeanceWeb/Common/lib/GuiLib/ObjectManager.js */ if(!window.freeance_loaded_js['bc8201f922e10563872a0962bba58598']){window.freeance_loaded_js['bc8201f922e10563872a0962bba58598']=1;
//ObjectManager.js
//this object attempts to connect messages spawned by GUIWidgets to their appropriate functions.
//basically it maintains a list of element names, with a series of pointers to their associated objects.
//The prototype GUIWidget object needs to register its elements when they are created.
//There should only be one of these per application.  With this in mind, it will always be named OBJECT_MANAGER.

//New for version 3:  
//      extension manager.  Will have all widget and control types registered
//      also will handle bindings between xml parser functions and the corresponding objects

//<objectName>.js
//
//------------------------------------------
//Dependancies:
//  

ObjectManager = function( )
{
  this.messageBindings = new Array();  //links an object id to the object itself
  this.objectList = new Array();       //struct with attribute names of an object name; value of attribute is pointer to object
  this.objectIndex = new Array();      //Lookup table for objects

  this.valueList = new Array();
  this.valueIndex = new Array();

  this.controlList = new Array();
  this.controlIndex = new Array();

  this.extensions = new Object();
  /**********************************************
   new code to support object type registration
  **********************************************/
  this.widgetRegistry = new Object();
  this.controlRegistry = new Object();
};

OBJECT_MANAGER = new ObjectManager();   //global variable


/*************************************************

  Registration functions for individual objects, 
  widget types, control types.

*************************************************/


ObjectManager.prototype.registerObject = function(objectName, objectPointer)
{
  //alert("In registerObject, the object name is "+objectName + " and the new messageBinding index is "+messageBindings.length);
  var objectID = this.messageBindings.length;
  this.messageBindings[this.messageBindings.length] = new Array(objectName, objectPointer);
  this.objectList[objectName] = objectPointer;
  this.objectIndex[this.objectIndex.length] = objectName;
  return objectID;
};

ObjectManager.prototype.registerWidget = function (widgetType, prototype)
{
  this.widgetsRegistry[widgetType] = prototype;
};

ObjectManager.prototype.registerExtension = function (extensionId, setActiveState)
{
  this.extensions[extensionId] = setActiveState;
};


/**************************************************

  Event handling functions

*************************************************/


ObjectManager.prototype.processEvent = function(e)
{
  var evt = new xEvent(e);
  //dprintf('In object manager, processing an event of type '+evt.type+' for entity number '+parseInt(evt.target.objectManagerId));
  if (!isNaN(parseInt(evt.target.objectManagerId)))
  {
    switch (evt.type)
    {
      case 'click':
	      this.messageBindings[parseInt(evt.target.objectManagerId)][1].clickCallback(evt);
	      break;
      case 'mousedown':
        this.messageBindings[parseInt(evt.target.objectManagerId)][1].mouseDownCallback(evt);
        break;
      case 'mouseup':
        this.messageBindings[parseInt(evt.target.objectManagerId)][1].mouseUpCallback(evt);
        break;
      case 'mousemove':
        this.messageBindings[parseInt(evt.target.objectManagerId)][1].mouseMoveCallback(evt);
        break;
      case 'mouseover':
        this.messageBindings[parseInt(evt.target.objectManagerId)][1].mouseOverCallback(evt);
        break;
      case 'mouseout':
        this.messageBindings[parseInt(evt.target.objectManagerId)][1].mouseOutCallback(evt);
        break;
      case 'keypress':
        this.messageBindings[parseInt(evt.target.objectManagerId)][1].keyPressCallback(evt);
        break;
      case 'keyup':
        this.messageBindings[parseInt(evt.target.objectManagerId)][1].keyUpCallback(evt);
        break;
      case 'keydown':
        this.messageBindings[parseInt(evt.target.objectManagerId)][1].keyDownCallback(evt);
        break;
      case 'drag':
        this.messageBindings[parseInt(evt.target.objectManagerId)][1].dragCallback(evt);
        break;
      case 'dragStart':
        this.messageBindings[parseInt(evt.target.objectManagerId)][1].dragStartCallback(evt);
        break;
      case 'dragEnd':
        this.messageBindings[parseInt(evt.target.objectManagerId)][1].dragEndCallback(evt);
        break;
      case 'change':
        this.messageBindings[parseInt(evt.target.objectManagerId)][1].changeCallback(evt);
        break;
      case 'focus':
        this.messageBindings[parseInt(evt.target.objectManagerId)][1].focusCallback(evt);
        break;
      default:
        //alert(evt.type);
        break;
    }
  }
};

ObjectManager.prototype.setGuiValue = function(valueName, newValue)
{
  this.valueList[valueName] = newValue;
  this.valueIndex[this.valueIndex.length] = valueName;
  return this.valueList[valueName];
};

ObjectManager.prototype.getGuiValue = function(valueName)
{
  switch (valueName)
  {
    case '_PAGEWIDTH_':
      return xClientWidth();
      break;
    case '_PAGEHEIGHT_':
      return xClientHeight();
      break;
    default:
      return this.valueList[valueName];
      break;
  }
};


ObjectManager.prototype.addControl = function(controlPointer,controlType, controlId)
{
  /**
    TODO:  REWRITE!
    INSTEAD OF A SWITCH STATEMENT, CHECK THE CONTROL REGISTRY
    Only registered controls can be used, otherwise a warning will be given.
    This helps to force all controls to follow the proper structure...
  **/
  switch (controlType)
  {
    case 'layerControl':
    case 'radioButtonGroup':
    case 'map':
    case 'labelControl':
    case 'queryControl':
    case 'selectionControl':
      this.controlList[controlId] = new Array(controlPointer, controlType);
      this.controlIndex[this.controlIndex.length] = new Array(controlId, controlType);
      break;
    default:
      alert('Object Manager Error:\nUnknown control type "'+controlType+'"\nControl id = "'+controlId+'"');
      break;
  }
};

ObjectManager.prototype.getControl = function(controlId)
{
  if (this.controlList[controlId])
    return this.controlList[controlId][0];
  else
    return null;
};


ObjectManager.prototype.extensionIsRegistered = function (extensionId)
{
  if (this.extensions[extensionId])
    return true;
  else
    return false;
};

ObjectManager.prototype.getWidgetAttribute = function(widgetName, attributeName)
{
  var widget = this.objectList[widgetName];
  switch (attributeName)
  {
    case 'width':
      return widget.width();
      break;
    case 'height':
      return widget.height();
      break;
    case 'left':
    case 'xpos':
      return widget.left();
      break;
    case 'top':
    case 'ypos':
      return widget.top();
      break;
    case 'right':
      return widget.left()+widget.width();
      break;
    case 'bottom':
      return widget.top()+widget.height();
      break;
    case 'zpos':
      return widget.zIndex;
      break;
    default:
      return null;
  }
};

function EVENT_LISTENER(e)
{
  //global convienance function to communicate with object manager
  //also a nice place for monitoring events during a debug session
  //catches event message and moves it along to the object manager
  //This function is called for every event that is attached to a widget
  /*evt = e;
    dprintf('Event Details:<br>Target Element:  '+evt.target+'<br>'+
          'GUILib target:  '+parseInt(evt.target.objectManagerId)+':  '+this.objectIndex[parseInt(evt.target.objectManagerId)]+'<br>'+
          'event type:  '+evt.type+'<br>'+
          'page coordinates:  ('+evt.pageX+','+evt.pageY+')<br>'+
          'relative coordinates:  ('+evt.offsetX+','+evt.offsetY+')<br>'+
          'corrected coordinates for image buttons:  ('+(evt.offsetX+xLeft(evt.target))+','+evt.offsetY+')<br>'+
          'key code:  '+evt.keyCode
         );
    */      
  
  OBJECT_MANAGER.processEvent(e);
};

/**************************************************

      Debug / documentation functions

**************************************************/

ObjectManager.prototype.listGuiValues = function()
{
  listString = '<table border = "1"><tr><td colspan = "3" align="center">GUI values:</td></tr>';
  listString = listString+'<tr><td>Index</td><td>Name</td><td>Value</td></tr>';
  for (i=0; i<this.valueIndex.length; i++)
  {
    listString = listString+'<tr><td>'+i+'</td><td>'+this.valueIndex[i]+'</td><td>'+this.valueList[this.valueIndex[i]]+'</td></tr>';
  }
  listString = listString + '</table>';
  return (listString);
};

ObjectManager.prototype.listGuiWidgets = function()
{
  listString = '<table border = "1"><tr><td colspan="2" align="center">GUI Widgets:</td></tr>';
  listString = listString+'<tr><td>Index</td><td>Name</td></tr>';
  for (i=0; i<this.objectIndex.length; i++)
  {
    listString = listString+'<tr><td>'+i+'</td><td>'+this.objectIndex[i]+'</td></tr>';
  }
  listString = listString + '</table>';
  return (listString);
};

ObjectManager.prototype.listGuiControls = function()
{
  listString = '<table border = "1"><tr><td colspan = "3" align="center">GUI Controls:</td></tr>';
  listString = listString+'<tr><td>Index</td><td>Name</td><td>Type</td></tr>';
  for (i=0; i<this.controlIndex.length; i++)
  {
    listString = listString+'<tr><td>'+i+'</td><td>'+this.controlIndex[i][0]+'</td><td>'+this.controlIndex[i][1]+'</td></tr>';
  } 
  listString = listString + '</table>';
  return (listString);
};

/**************************************************

  Add utility functions to the document object

**************************************************/

document.getWidgetById = function (objectName)
{
  return (OBJECT_MANAGER.objectList[objectName]);
};

document.getGuiValue = function (valueName)
{
  return OBJECT_MANAGER.getGuiValue(valueName);
};

document.getGuiControl = function (valueName)
{
  return OBJECT_MANAGER.getControl(valueName);
};


/*************************************************
      Deprecated Methods
*************************************************/

document.getGuiWidgetById = function (objectName)
{
  alert('Warning:  getGuiWidgetById has been deprecated.\nUse getWidgetById instead');  
  return document.getWidgetById(objectName);
};

document.getGuiValueById = function (valueName)
{
  alert('Warning:  document.getGuiValueById has been deprecated.\nUse getGuiValue instead');
  return document.getGuiValue(valueName);
};}
/* FILE:FreeanceWeb/Common/lib/GuiLib/GuiWidget.js */ if(!window.freeance_loaded_js['d01d22db9f2d191971bbf8f6f1ab8d64']){window.freeance_loaded_js['d01d22db9f2d191971bbf8f6f1ab8d64']=1;
/**GuiWidget.js
  The GuiWidget is the base element of the gui library.  Based on a DIV, various extensions are made to handle
  size, position and events throughg a single interface.  Also included is the ability to generate a set of widgets
  from a specification file written in an XML language, eliminating the need for complex JavaScript coding in a given
  application
  
  Dependancies:
    x.js  -  can be obtained from cross-browser.com.  handles differences between browser implementations of html
    XMLParser-base,js - defines XMLParser object and helper functions.
**/


GuiWidget = function(newID, newParent, newXPosition, newYPosition, newZIndex, newWidth, newHeight, newVisibility, newClass)
{
  if (arguments.length > 0)
  {
    this.widgetType = 'GuiWidget';
    this.init(newID, newParent, newXPosition, newYPosition, newZIndex, newWidth, newHeight, newVisibility, newClass);
  }
};

GuiWidget_onLoad = function()
{
  GuiWidget.ToolTip = document.createElement("DIV");  //ToolTip is a static property of the GuiWidget class to ensure that only one is created.
  document.getElementsByTagName("body").item(0).appendChild(GuiWidget.ToolTip);            //child of the document object.
  xHide(GuiWidget.ToolTip);
};

GuiWidget.prototype.init = function(newID, newParent, newXPosition, newYPosition, newZIndex, newWidth, newHeight, newVisibility, newClass)
{
  this.id = newID;
  this.parentElement = newParent;
  this.xPosition = parseInt(newXPosition);
  this.yPosition = parseInt(newYPosition);
  this.zIndex = parseInt(newZIndex);
  this.visibility = false;
  
  this.element = document.createElement("DIV");
  this.element.objectManagerId = OBJECT_MANAGER.registerObject(this.id, this);
  if (this.parentElement == null)
  {
    document.getElementsByTagName("body").item(0).appendChild(this.element); 
  }
  else
  {
  	this.parentElement.appendChild(this.element);
  }
  this.setClass(newClass);
  this.element.id = this.id;

  this.moveTo(newXPosition, newYPosition);
  xZIndex(this.element,newZIndex);
  this.resizeTo(newWidth,newHeight);
  this.setVisibility(newVisibility);
};

/*******************************************/

GuiWidget.prototype.setVisibility = function(newVisibility)
{
  this.visibility = newVisibility;
  return (newVisibility)?this.show():this.hide();
};

/*******************************************/

GuiWidget.prototype.show = function()
{
  this.visibility = true;
  if (this.element)
    this.element.style.visibility= 'inherit';
  return true;
};

/*******************************************/

GuiWidget.prototype.hide = function()
{
  this.visibility = false;
  this.element.style.visibility='hidden';
  xHide(this.element);
  return true;
};

/*******************************************/

GuiWidget.prototype.width = function()
{
  if (arguments.length > 0)
    return xResizeTo(this.element, parseInt(arguments[0]), xHeight(this.element));
  return xWidth(this.element);
};

/*******************************************/

GuiWidget.prototype.height = function()
{
  if (arguments.length > 0)
  {
    return xHeight(this.element,arguments[0]);
  }
  return xHeight(this.element);
};

/*******************************************/

GuiWidget.prototype.left = function()
{
  if (arguments.length > 0)
    return xLeft(this.element,arguments[0]);
  else
    return xLeft(this.element);
};

/*******************************************/

GuiWidget.prototype.top = function()
{
  if (arguments.length > 0)
    return xTop(this.element,arguments[0]);
  else
    return xTop(this.element);
};

/*******************************************/

GuiWidget.prototype.resizeTo = function (newWidth, newHeight)
{
  xResizeTo(this.element,newWidth, newHeight);
  if (this.resizeEvent)
    this.resizeEvent(newWidth, newHeight);
};

GuiWidget.prototype.moveTo = function (newXPosition, newYPosition)
{
  this.xPosition = parseInt(newXPosition);
  this.yPosition = parseInt(newYPosition);
  xMoveTo(this.element, this.xPosition, this.yPosition);
  if (this.moveEvent)
    this.moveEvent(newXPosition, newYPosition);
};

GuiWidget.prototype.setClass = function (newClass)
{
  this.element.setAttribute((xIE4Up?("className"):("class")),(((newClass == '')||(newClass == null))?(this.widgetType):(newClass)));
};

GuiWidget.prototype.innerHtml = function (newString)
{
  this.element.innerHTML = newString;
};

/****************************************************************/
/* Event Callback Functions                                     */
/* Calls the appropriate functions if they exist.               */
/****************************************************************/

GuiWidget.prototype.mouseOverCallback = function(e)
{
  if (this.mouseOver)
    this.mouseOver(e);
  if (this.layoutMouseOverEvent)
    this.layoutMouseOverEvent(e);
  if (this.mouseOverEvent)
    this.mouseOverEvent(e);
};

/*******************************************/

GuiWidget.prototype.clickCallback = function(e)
{
  if (this.click)
    this.click(e);
  if (this.layoutMouseClickEvent)
    this.layoutMouseClickEvent(e);
  if (this.clickEvent)
    this.clickEvent(e);
};

/*******************************************/

GuiWidget.prototype.mouseOutCallback = function(e)
{
  if (this.mouseOut)
    this.mouseOut(e);
  if (this.layoutMouseOutEvent)
    this.layoutMouseOutEvent(e);
  if (this.mouseOutEvent)
    this.mouseOutEvent(e);
};

/*******************************************/

GuiWidget.prototype.mouseDownCallback = function(e)
{
  if (this.mouseDown)
    this.mouseDown(e);
  if (this.layoutMouseDownEvent)
    this.layoutMouseDownEvent(e);
  if (this.mouseDownEvent)
    this.mouseDownEvent(e);
};

/*******************************************/

GuiWidget.prototype.mouseMoveCallback = function(e)
{
  xMoveTo(GuiWidget.ToolTip,e.clientX, e.clientY);
  if (this.mouseMove)
    this.mouseMove(e);
  if (this.layoutMouseMoveEvent)
    this.layoutMouseMoveEvent(e);
  if (this.mouseMoveEvent)
    this.mouseMoveEvent(e);
};

/*******************************************/

GuiWidget.prototype.mouseUpCallback = function(e)
{
  if (this.mouseUp)
    this.mouseUp(e);
  if (this.layoutMouseUpEvent)
    this.layoutMouseUpEvent(e);
  if (this.mouseUpEvent)
    this.mouseUpEvent(e);
};

GuiWidget.showTooltip = function(e, tooltipText)
{
  if (document.babelfish)
    tooltipText = document.babelfish.translateWord(tooltipText);
  xMoveTo(GuiWidget.ToolTip,e.pageX+GuiWidget.tooltipOffset[0], e.pageY+GuiWidget.tooltipOffset[1]);
  xZIndex(GuiWidget.ToolTip,255);
  GuiWidget.ToolTip.innerHTML = tooltipText;
  if (xIE4Up)
    GuiWidget.ToolTip.setAttribute("className", "GuiToolTip");
  else
    GuiWidget.ToolTip.setAttribute("class", "GuiToolTip");
  xShow(GuiWidget.ToolTip);
};

GuiWidget.hideTooltip = function()
{
  xHide(GuiWidget.ToolTip);
};}
/* FILE:FreeanceWeb/Common/lib/GuiLib/Button.js */ if(!window.freeance_loaded_js['3a6341f0c1663d34db49e07a6e212857']){window.freeance_loaded_js['3a6341f0c1663d34db49e07a6e212857']=1;
//Button.js
//A generic, labelless button. 

Button = function(newID, newParent, newXPosition, newYPosition, newZIndex, newWidth, newHeight, newVisibility)
{
  if (arguments.length > 0)
    this.init(newID, newParent, newXPosition, newYPosition, newZIndex, newWidth, newHeight, newVisibility);
};

Button.prototype = new GuiWidget();
Button.prototype.constructor = Button;
Button.superclass = GuiWidget.prototype;

Button.prototype.init = function(newID, newParent, newXPosition, newYPosition, newZIndex, newWidth, newHeight, newVisibility)
{
  Button.superclass.init.call(this, newID, newParent, newXPosition, newYPosition, newZIndex, newWidth, newHeight, newVisibility);
  xAddEventListener(this.element,'click', EVENT_LISTENER, false);
  xAddEventListener(this.element,'mouseover', EVENT_LISTENER, false);
  xAddEventListener(this.element,'mousedown', EVENT_LISTENER, false);
  xAddEventListener(this.element,'mouseup', EVENT_LISTENER, false);
  xAddEventListener(this.element,'mouseout', EVENT_LISTENER, false);
  this.setClass('GuiButton');
};

Button.prototype.mouseOver = function(e)
{
  this.setClass('GuiButtonHover');
};
 
Button.prototype.mouseOut = function(e)
{
  this.setClass('GuiButton');
};

Button.prototype.mouseUp = function(e)
{
  this.setClass('GuiButtonHover');
};

Button.prototype.mouseDown = function(e)
{
  this.setClass('GuiButtonDown');
};

Button.prototype.click = function(e)
{
  this.setClass('GuiButtonHover');
};}
/* FILE:FreeanceWeb/Common/lib/GuiLib/ImagePanel.js */ if(!window.freeance_loaded_js['b7321994be56ccc724785a237196f3d3']){window.freeance_loaded_js['b7321994be56ccc724785a237196f3d3']=1;
//ImagePanel.js
ImagePanel = function(newID, newParent, newXPosition, newYPosition, newZIndex, newWidth, newHeight, newVisibility, newImageSource, newScaleImage, newImageWidth, newImageHeight)
{
  if (arguments.length > 0)
    this.init(newID, newParent, newXPosition, newYPosition, newZIndex, newWidth, newHeight, newVisibility, newImageSource, newScaleImage, newImageWidth, newImageHeight);
};

ImagePanel.prototype = new GuiWidget();
ImagePanel.prototype.constructor = ImagePanel;
ImagePanel.superclass = GuiWidget.prototype;

ImagePanel.prototype.init = function(newID, newParent, newXPosition, newYPosition, newZIndex, newWidth, newHeight, newVisibility, newImageSource, newScaleImage, newImageWidth, newImageHeight)
{
  ImagePanel.superclass.init.call(this, newID, newParent, newXPosition, newYPosition, newZIndex, newWidth, newHeight, newVisibility);
  this.setClass("GuiImagePanel");
  this.imageNode = document.createElement("IMG");
  this.imageNode.objectManagerId = this.element.objectManagerId;
  this.imageNode.src = newImageSource;
  this.imageWidth = newImageWidth;
  this.imageHeight = newImageHeight;
  this.scaleImage = newScaleImage;
  this.element.appendChild(this.imageNode);
  this.imageNode.setAttribute((xIE4Up?("className"):("class")),"GuiImagePanel");
  
  if (this.scaleImage)
  {
    xHeight(this.imageNode,this.height());
    xWidth(this.imageNode,this.width());
    xMoveTo(this.imageNode,0,0);    
  }
  else
  {
    this.centerImage(); 
  }
  this.imageNode.imagePanelObject = this;
  xAddEventListener(this.element,'click',     EVENT_LISTENER, false);
  xAddEventListener(this.element,'mouseover', EVENT_LISTENER, false);
  xAddEventListener(this.element,'mousedown', EVENT_LISTENER, false);
  xAddEventListener(this.element,'mouseup',   EVENT_LISTENER, false);
  xAddEventListener(this.element,'mouseout',  EVENT_LISTENER, false);
  xAddEventListener(this.element,'mousemove', EVENT_LISTENER, false);
};

ImagePanel.prototype.centerImage = function()
{
  if ((this.imageWidth != null) && (this.imageHeight != null))
    xMoveTo(this.imageNode,(xWidth(this.element)/2-(this.imageWidth/2)), xHeight(this.element)/2-(this.imageHeight)/2);
  else
    xMoveTo(this.imageNode,(xWidth(this.element)/2-(xWidth(this.imageNode)/2)), xHeight(this.element)/2-(xHeight(this.imageNode)/2));
};

ImagePanel.prototype.show = function()
{
  xShow(this.element);
  xShow(this.imageNode);
  this.centerImage();
};

ImagePanel.prototype.hide = function()
{
  xHide(this.element);
  xHide(this.imageNode);
  this.centerImage();
};}
/* FILE:FreeanceWeb/Common/lib/GuiLib/ImageButton.js */ if(!window.freeance_loaded_js['937792cdf4ab44c9d4ebf999ed24dfb7']){window.freeance_loaded_js['937792cdf4ab44c9d4ebf999ed24dfb7']=1;
//ImageButton.js
//a clickable button using a set of images.
//assumes the image names are based on a standard naming convention
// ex:  button.png
//      buttonHover.png
//      buttonDown.png
//onclickFunction is a function executed when the button is clicked;
//  including any parameters required.
//------------------------------------------
//Dependancies:
//  ImageButton.js-|->Button.js->GuiWidget.js-><CBE libraries>

ImageButton = function(newID, newParent, newXPosition, newYPosition, newZIndex, newWidth, newHeight, imgYOffset, newVisibility, newimageName, newTooltip)
{
  if (arguments.length > 0)
    this.init(newID, newParent, newXPosition, newYPosition, newZIndex, newWidth, newHeight, imgYOffset, newVisibility, newimageName, newTooltip);
};
ImageButton.prototype = new Button();
ImageButton.prototype.constructor = ImageButton;
ImageButton.superclass = Button.prototype;

ImageButton.prototype.init = function(newID, newParent, newXPosition, newYPosition, newZIndex, newWidth, newHeight, imgYOffset, newVisibility, newImageName, newTooltip)
{
  ImageButton.superclass.init.call(this, newID, newParent, newXPosition, newYPosition, newZIndex, newWidth, newHeight, newVisibility);
  this.imageName = newImageName;
  this.tooltip = newTooltip;
  this.buttonImage = new Image;
  this.buttonImage.src = GuiWidget.THEME_PATH+'/'+GuiWidget.THEME+'/images/'+this.imageName;
  this.tooltip=newTooltip;
  
  this.imageNode = document.createElement("IMG");
  this.imageNode.src = this.buttonImage.src;
  this.imageNode.objectManagerId = this.element.objectManagerId;
  if (xIE4Up)
  {
    xWidth(this.imageNode,newWidth * 3);
    xHeight(this.imageNode,newHeight * 15);
  }
  this.element.appendChild(this.imageNode);

  this.setClass('GuiImageButton');
  this.imageNode.setAttribute(((xIE4Up)?("className"):('class')), "GuiImageButtonImage");
  xTop(this.imageNode,0-imgYOffset);
};

ImageButton.prototype.mouseOver = function(e)
{
  xLeft(this.imageNode,0 - this.width());
  this.setClass('GuiImageButtonHover');
  if (this.tooltip != '')
    GuiWidget.showTooltip(e, this.tooltip);
};

ImageButton.prototype.mouseOut = function(e)
{
  xLeft(this.imageNode,0);
  this.setClass('GuiImageButton');
  GuiWidget.hideTooltip();
};

ImageButton.prototype.mouseUp = function(e)
{
  xLeft(this.imageNode,0 - this.width());
  this.setClass('GuiImageButtonHover');
  GuiWidget.hideTooltip();
};

ImageButton.prototype.mouseDown = function(e)
{
  xLeft(this.imageNode,0 - this.width()*2);
  this.setClass('GuiImageButtonDown');
  GuiWidget.hideTooltip();
};

ImageButton.prototype.click = function(e)
{
  xLeft(this.imageNode,0 - this.width());
  this.setClass('GuiImageButtonHover');
  GuiWidget.hideTooltip();
};}
/* FILE:FreeanceWeb/Common/lib/GuiLib/LinearGradient.js */ if(!window.freeance_loaded_js['81b3cf097aa4903213a583558e59cfd0']){window.freeance_loaded_js['81b3cf097aa4903213a583558e59cfd0']=1;
function linearGradient(color1, color2, numSteps)
{
  var result = new Array();
  var c1 = new Array(parseInt("0x"+color1.substr(1,2)), parseInt("0x"+color1.substr(3,2)), parseInt("0x"+color1.substr(5,2)));
  var c2 = new Array(parseInt("0x"+color2.substr(1,2)), parseInt("0x"+color2.substr(3,2)), parseInt("0x"+color2.substr(5,2)));
  var dC = new Array((c2[0]-c1[0])/numSteps, (c2[1]-c1[1])/numSteps, (c2[2]-c1[2]));

  for (i=0; i<numSteps; i++)
  {
    var R = Math.round(dC[0]*i+c1[0]);
    R=(R>0xff)?0xff:R;
	R=(R<0)?0:R;
    R=R.toString(16);
    var G = Math.round(dC[1]*i+c1[1]);
    G=(G>0xff)?0xff:G;
	G=(G<0)?0:G;
    G=G.toString(16);
    var B = Math.round(dC[2]*i+c1[2]);
    B=(B>0xff)?0xff:B;
	B=(B<0)?0:B;
    B=B.toString(16);
    result[i] = "#"+((R.length==1)?("0"+R):R)+((G.length==1)?("0"+G):G)+((B.length==1)?("0"+B):B);    
  }
  return result;
};}
/* FILE:FreeanceWeb/Common/lib/GuiLib/RadioButton.js */ if(!window.freeance_loaded_js['c17d98eb6a71f471b0158e03c3d89b21']){window.freeance_loaded_js['c17d98eb6a71f471b0158e03c3d89b21']=1;
//RadioButton.js
//a clickable button which is a member of a group of "Radio Buttons".
//The button may have two states - 'on' and 'off'.
//  Only one button out of a group may be 'on' at any given time.  This requires 
//  that the radio button be associated with a group at initialization time.
//  The default state for all radio buttons is off, represented by the "normal" 
//  graphic and the radioButtonOff style in the theme stylesheet.  After the 
//  necessary buttons have been created in the document, then a particular button 
//  can be set active either directly through code, through a call to the radio 
//  button group object specifying the index of the button to set active, or with 
//  a mouse click on the radio button itself.
//The user-specified functions are 'clickOn', called when the button's state
//  changes to true (on); and 'clickOff', which is called when the button's 
//  state changes to false (off)
//------------------------------------------
//Dependancies:
//  RadioButton.js-> |->ImageButton.js|->Button.js->GuiWidget.js-><CBE libraries>
//                   |                |->overlib.js
//                   |->RadioButtonGroup.js



RadioButton = function(newID, newParent, newXPosition, newYPosition, newZIndex, newWidth, newHeight, imgYOffset, newVisibility, newImageRoot, newTooltip, newGroup, newGroupId)
{
  if (arguments.length > 0)
    this.init(newID, newParent, newXPosition, newYPosition, newZIndex, newWidth, newHeight, imgYOffset, newVisibility, newImageRoot, newTooltip,newGroup, newGroupId);
};
RadioButton.prototype = new ImageButton();
RadioButton.prototype.constructor = RadioButton;
RadioButton.superclass = ImageButton.prototype;

RadioButton.prototype.init = function(newID, newParent, newXPosition, newYPosition, newZIndex, newWidth, newHeight, imgYOffset, newVisibility, newImageRoot, newTooltip,newGroup, newGroupId)
{
  RadioButton.superclass.init.call(this, newID, newParent, newXPosition, newYPosition, newZIndex, newWidth, newHeight, imgYOffset, newVisibility, newImageRoot, newTooltip);
  
  if (newGroupId)
    this.group = OBJECT_MANAGER.getControl(newGroupId);
  else
    this.group = newGroup;
  this.groupIndex = this.group.addButton(this);
  this.active = false;
};

RadioButton.prototype.setGroup = function(newGroup)
{
  this.group = newGroup;
  this.groupIndex = newGroup.addButton(this);
};

RadioButton.prototype.isActive = function()
{
  return this.active; 
};

RadioButton.prototype.setActive = function()
{
  //should only be called from RadioButtonGroup!
  this.active = true;
  xLeft(this.imageNode,0 - this.width()*2);
};

RadioButton.prototype.setInactive = function()
{
  //should only be called from RadioButtonGroup!
  this.active = false;
  xLeft(this.imageNode,0);
  if (this.setInactiveEvent)
    this.setInactiveEvent();
};

RadioButton.prototype.click = function(e)
{
  this.group.setActiveButton(this.groupIndex);
  this.active = true;
  xLeft(this.imageNode,0-this.width());
  this.setClass('GuiImageButtonHover');
  GuiWidget.hideTooltip();
};

RadioButton.prototype.mouseOver = function(e)
{
  xLeft(this.imageNode,0-this.width());
  this.setClass('GuiImageButtonHover');
  if (this.tooltip != '')
    GuiWidget.showTooltip(e,this.tooltip);
};

RadioButton.prototype.mouseOut = function(e)
{
  xLeft(this.imageNode,this.active?(0-this.width()*2):0);
  this.setClass('GuiImageButton');
  GuiWidget.hideTooltip();
};

RadioButton.prototype.mouseUp = function(e)
{
  xLeft(this.imageNode,0-this.width());
  this.setClass('GuiImageButtonHover');
  GuiWidget.hideTooltip();
};

RadioButton.prototype.mouseDown = function(e)
{
  xLeft(this.imageNode,0-this.width()*2);
  this.setClass('GuiImageButtonDown');
  GuiWidget.hideTooltip();
};}
/* FILE:FreeanceWeb/Common/lib/GuiLib/RadioButtonGroup2.js */ if(!window.freeance_loaded_js['1742d5e92a5b86eda43bbb23aa658ec3']){window.freeance_loaded_js['1742d5e92a5b86eda43bbb23aa658ec3']=1;
//RadioButtonGroup.js
//Control structure for radio buttons
//
//Contains an array of radio button objects.  Each radio button in the group
//  has a pointer to the group, and is aware of its index in the array.
//Communication between the group and the buttons is two-directional.  When
//  a button is clicked, it calls the setActive function in the group, with
//  the button's index passed as a parameter.  This information is then used
//  to set the currently active button to its 'inactive' state and to update
//  the active button index in the group.
//The active button is initialized to -1 (an invalid index) since the radio buttons
//  default to an inactive state.
//
//------------------------------------------
//No Dependancies.

RadioButtonGroup = function(newId)
{
  if (arguments.length > 0)
    this.init(newId);
};

RadioButtonGroup.prototype.init = function(newId)
{
  this.buttons = new Array();
  this.buttonLookup={};
  this.activeButton = -1;
  this.id = newId;
  
  //this can probably be removed
  OBJECT_MANAGER.addControl(this,'radioButtonGroup', newId);
};
  
RadioButtonGroup.prototype.setActiveButton = function(buttonIndex)
{
  if (this.activeButton != -1)
  {
    if (this.buttons[this.activeButton].setInactive)
      this.buttons[this.activeButton].setInactive();
    else
      this.buttons[this.activeButton].checked = false;
  }
  
  
  if (typeof(buttonIndex)=='string')
    buttonIndex=this.buttonLookup[buttonIndex];
  if(buttonIndex==null)
    buttonIndex=-1;
  this.activeButton = buttonIndex;
  if (buttonIndex != -1)
  {
    if (this.buttons[buttonIndex].setActive)
      this.buttons[buttonIndex].setActive();
    else
      this.buttons[buttonIndex].checked = true;
  }
};

RadioButtonGroup.prototype.getActiveButton = function()
{
  if (this.activeButton != -1)
    return(this.buttons[this.activeButton]);
  else
    return(null);
};

RadioButtonGroup.prototype.addButton = function(button)
{
  this.buttonLookup[button.id]=this.buttons.length;
  this.buttons.push(button);
  return this.buttonLookup[button.id];
};}
/* FILE:FreeanceWeb/Common/lib/GuiLib/ToolBar2.js */ if(!window.freeance_loaded_js['5e9be6961fa906604d781c4bd77cf420']){window.freeance_loaded_js['5e9be6961fa906604d781c4bd77cf420']=1;
//ToolBar.js
//A button panel is used to dynamically control the placement of a series of image
//buttons.  Generally speakinig, these buttons should be of equal size.  They will be
//tiled either horizontally or vertically depending on the value of the alignment property of the class.
//------------------------------------------
//Dependancies:
//  x                    radioButtonGroup
//  |--guiWidget         |
//    |--button          |
//      |--imageButton   |
//      |--radioButton-- |
//      |--toggleButton


ToolBar = function(newID, parentElement, xPosition, yPosition, zIndex, width, height, visibility, styleClass, alignment)
{
  this.widgetType = 'ToolBar';
  this.init(newID,parentElement, xPosition, yPosition, zIndex, width, height, visibility, styleClass,alignment);
};
ToolBar.prototype = new GuiWidget();
ToolBar.prototype.constructor = ToolBar;
ToolBar.superclass = GuiWidget.prototype;

ToolBar.prototype.init = function(newID,parentElement, xPosition, yPosition, zIndex, width, height, visibility, styleClass,alignment)
{
  ToolBar.superclass.init.call(this, newID,parentElement, xPosition, yPosition, zIndex, width, height, visibility, styleClass);  //call parent's init function
  this.alignment = alignment;
  this.buttonObjects = [];//array of button objects; a string value names a divider
  this.buttonLookup = {};
};

ToolBar.prototype.getButton = function(buttonid)
{
  if(this.buttonLookup[buttonid]!=null)
    return this.buttonObjects[this.buttonLookup[buttonid]];
  else
    return null;
};

ToolBar.prototype.showButton = function(buttonid)
{
  if(this.buttonLookup[buttonid]!=null)
  {
    this.buttonObjects[this.buttonLookup[buttonid]].show();
    this.updateButtons();
    return true;
  }
  else return false;
};

ToolBar.prototype.hideButton = function(buttonid)
{
  if(this.buttonLookup[buttonid]!=null)
  {
    this.buttonObjects[this.buttonLookup[buttonid]].hide();
    this.updateButtons();
    return true;
  }
  else return false;
};

ToolBar.prototype.addButton = function (newButtonId, newButtonType, insertionType, insertionReference)
{
  //arguments list varies by button type; will be same as constructor for that particular button, however the parentElement and z-index is not set
  //insertionType determines whether the button should be positioned first, last, before a specific button or after a specific button.
  //insertionReference is used for the before, after and fixed options
  //  if a string, looks up the element to use for positioning
  //  if a number, this is the new button index
  var newButtonObjects = [];
  var newButton = null;
  var errorcode=null;
  var errormessage=null;
  var referenceIdx = -1; //index of insertion reference button

  if (((insertionType==ToolBar.ADD_BUTTON_BEFORE)||(insertionType==ToolBar.ADD_BUTTON_AFTER))&&typeof(insertionReference=='string'))
  {
    //find index of reference element
    if (this.buttonLookup[insertionReference]!=null)
      referenceIdx=this.buttonLookup[insertionReference];
  };

  //Declare the button; position at 0,0 - the updateFormat function will set positions.
  switch (newButtonType)
  {
    case ToolBar.BUTTON_IMAGE:
      //function parameters:  id,type,width,height,visibility,imageName,tooltip
      newButton = new ImageButton(newButtonId, this.element, 0, 0, 0, arguments[4], arguments[5], arguments[6], arguments[7],arguments[8],arguments[9] );    
      break;
    case ToolBar.BUTTON_RADIO:
      newButton = new RadioButton(newButtonId, this.element, 0, 0, 0, arguments[4], arguments[5], arguments[6], arguments[7], arguments[8], arguments[9], arguments[10],arguments[11]);
      break;
    default:
      errorcode="0";
      errormessage='toolbar.addButton:  unknown button type \''+newButtonType+'\'';
      break;
  };
  if (newButton){
    //put button at correct position in toolbar
    switch(insertionType){
      case ToolBar.ADD_BUTTON_LAST:
        this.buttonObjects.push(newButton);
        break;
      case ToolBar.ADD_BUTTON_FIRST:
        newButtonObjects.push(newButton);
        this.buttonObjects = newButtonObjects.concat(this.buttonObjects);
        break;
      case ToolBar.ADD_BUTTON_BEFORE:
        if(referenceIdx==-1)
          this.buttonObjects.push(newButton);
        else
        {
          if (referenceIdx==0){
            newButtonObjects.push(newButton);
            this.buttonObjects = newButtonObjects.concat(this.buttonObjects);
          }
          else
          {
            this.buttonObjects = this.buttonObjects.slice(0,referenceIdx).concat(newButton,this.buttonObjects.slice(referenceIdx+1,this.buttonObjects.length));
          }
        };
        break;
      case ToolBar.ADD_BUTTON_LAST:
        if(referenceIdx==-1)
          this.buttonObjects.push(newButton);
        break;
      case ToolBar.ADD_BUTTON_FIXED:
        break;
    };
    //rebuild lookup table
    for (var i=0;i<this.buttonObjects.length;i++)
    {
      this.buttonLookup[(typeof(this.buttonObjects[i])=='string')?this.buttonObjects[i]:this.buttonObjects[i].id]=i;
    };
    this.updateButtons();
    returnvalue=newButton;
  }
  else
    returnvalue={GUILIB_FAULT:true,GUILIB_FAULT_CODE:errorcode,GUILIB_FAULT_MESSAGE:errormessage};
  return returnvalue;
};

ToolBar.prototype.removeButton = function(buttonid)
{
  var buttonobj = null;
  var buttonindex = -1;
  var newbuttons = [];
  if(this.buttonLookup[buttonid]){
    buttonindex = this.buttonLookup[buttonid];
    buttonobj = this.buttonObjects[buttonindex];
    delete this.buttonLookup[buttonid];
    for (var i=0;i<this.buttonObjects.length;i++)
      if(i!=buttonindex)
        newbuttons.push(this.buttonObjects[i]);
    this.buttonObjects = newbuttons;
    if(typeof(buttonobj)!='string')
      if(buttonobj.parentElement = this.element)
        this.element.removeChild(buttonobj.element);
    this.updateButtons();
  };
  return buttonobj;
};

ToolBar.prototype.updateButtons=function(){
  //TODO: ADD REMAINING FORMAT OPTIONS 
  var offset=0;
  for(var i=0;i<this.buttonObjects.length;i++)
  {
    if(typeof(this.buttonObjects[i])!='string')
    {
      if (this.buttonObjects[i].visibility)
        switch(this.alignment){
          case ToolBar.ALIGN_VERTICAL:
            this.buttonObjects[i].moveTo(0,offset);
            offset+=this.buttonObjects[i].height();
            break;
          case ToolBar.ALIGN_HORIZONTAL:
            this.buttonObjects[i].moveTo(offset,0);
            offset+=this.buttonObjects[i].width();
            break;
        };
    };
  };
};

ToolBar.prototype.addDivider = function (newDividerId,insertionType,insertionReference)
{
  //TODO:  ADD DIVIDER CODE
};

//POSITION CONSTANTS
ToolBar.ADD_BUTTON_LAST=0;
ToolBar.ADD_BUTTON_FIRST=1;
ToolBar.ADD_BUTTON_BEFORE=2;
ToolBar.ADD_BUTTON_AFTER=3;
ToolBar.ADD_BUTTON_FIXED=4;

//ALIGNMENT CONSTANTS
ToolBar.ALIGN_VERTICAL=0;
ToolBar.ALIGN_HORIZONTAL=1;
ToolBar.ALIGN_VERTICAL_BOTTOM=2;
ToolBar.ALIGN_HORIZONTAL_RIGHT=1;
ToolBar.ALIGN_VERTICAL_CENTER=2;
ToolBar.ALIGN_HORIZONTAL_CENTER=1;

//BUTTON TYPE CONSTANTS
ToolBar.BUTTON_IMAGE=0;
ToolBar.BUTTON_RADIO=1;}
/* FILE:FreeanceWeb/Client/PublicKiosk1/lib/MapLib/Map.js */ if(!window.freeance_loaded_js['802a1157339ecae4651a3cf75f9d0ff4']){window.freeance_loaded_js['802a1157339ecae4651a3cf75f9d0ff4']=1;
//Map.js

Map = function (newId)
{
  OBJECT_MANAGER.addControl(this,'map', newId);
  $_this = this;
  this.id        = newId;
  this.config = null;
  this.mapNumber = 0;
  this.clientVersion = null;
  this.serverVersion = null;

  //interface objects directly controlled by the map object
  this.mapImage       = null;
  this.mapLoadImage = null;
  this.vmapPresent = false;
  this.vmapImage     = null;
  this.mapLoadImage = null;
  this.legendImage = null;
  this.customLegendImage = null;  //will be a string if a custom legend image should be used.
  
  //Ancillary controls
  this.bookmarkControl = null;
  this.markupControl = null;
  this.layerControl = null;
  this.bufferControl = null;
  this.themeControl = null;
  this.selectionControl = null;
  this.coordConvControl = null;
  this.measureControl = null;
  this.geocodeControl = null;
  this.zoomBar = null;
  this.scaleBar = null;

  this.extensionMapClickHandlers = new Array();  // JPW
  
  //session specific data
  this.sessionID = null;
  this.extent    = new Array;        //extent of main map
  this.dragExtent = Array(0,0,0,0);  //drag extent tracker
  this.vmapExtent    = new Array;    //extent of vicinity map
  this.bookmarks = new Array();      //contains bookmarks for current session
  this.bookmark_redrawmaps = true;    //???
  this.legendVisible = null;          //is the legend currently displayed?
  this.legendSync    = false;         //does the legend match the current map display?
  this.numWaitingRequests = 0;        //counter for load image
  this.printOptions = null;
  this.zoomFactor = 1.5;
  this.initialExtent = null;
  this.activeMapScheme = null;
  this.firstLoad = true;
  this.dragTileCounter = 0;
  this.dragTileSessionId = null;
  this.configDocNode = null;          //document node containing config data
this.eventCallbacks = {
  layerChange: [],
  imageChange: [],
  tileLoadStart: [],
  tileLoadFinish: []
};

this.setConfig = function(newConfig)
{
  this.config = newConfig;
  if (this.layerControl)
    this.layerControl.draw();
  this.selectionsExist = false;
  var selectionCount = 0;
  this.buffersExist = false;
  var bufferCount = 0;
  this.selectableThemes = new Array();
  this.bufferableThemes = new Array();
  for (var currentTheme in this.config.themes)
  {
    if(currentTheme=='toJSONString')continue;
    if (this.config.themes[currentTheme].selectOptions != null)
    {
      this.selectionsExist = true;
      this.selectableThemes[this.selectableThemes.length] = currentTheme;
      selectionCount++;
    }
    if (this.config.themes[currentTheme].bufferOptions != null)
    {
      this.bufferableThemes[this.bufferableThemes.length] = currentTheme;
      this.buffersExist = true;
      bufferCount++;
    }
  }
  
  this.vmapPresent = (this.config["vmap"]["resourceId"] != '');
  //Check for existence of ancillary controls and initialize
  if (this.selectionControl)
    this.selectionControl.initialize();
  if (this.bufferControl)
    this.bufferControl.initialize(this.bufferableThemes);
  if (this.coordConvControl)
    this.coordConvControl.draw();
  if (this.measureControl)
    this.measureControl.initialize();
  if (this.geocodeControl)
    this.geocodeControl.initialize();
};

this.initialize = function(sessionID)
{
  //arguments[1] = scheme id (if present)
  var useMapScheme = false;
  if (arguments.length > 0)
    if (arguments[1] != null)
      useMapScheme = true;
  var map0 = Array(this.config["resourceId"], this.config["previousStates"],this.mapImage.width(),this.mapImage.height(),false);
  if (this.vmapImage != null)
  {
    var map1 = Array(this.config["vmap"]["resourceId"],0,this.vmapImage.width(),this.vmapImage.height(),true,0,this.config["vmap"]["slaveType"],this.config["vmap"]["boundBoxPercentMin"],this.config["vmap"]["styleSheet"]);
    var map_args = Array(map0,map1);
  }
  else
  {
    var map_args = Array(map0);
  }
  if (this.scalebar != null)
    this.scalebar.initialize();
  this.setWaiting(true);
  if (useMapScheme&&(this.config.mapSchemeConfig.mapSchemes.length>0))
  {    
    var mapSchemes = this.config.mapSchemeConfig.mapSchemes;
    var schemeId = arguments[1];
    this.activeMapScheme = schemeId;
    var scheme=mapSchemes[schemeId];
    var themeArray = new Array();
    var themes = scheme.themes;
    for (var currentTheme in themes)
    {
      if(currentTheme=='toJSONString')continue;
      var theme=themes[currentTheme];
      themeArray.push([theme.id,(theme.display==1),theme.legend]);
    };
    if(scheme.layerControl){
      document.layerControl.config = scheme.layerControl;
    }
    else{
      document.layerControl.config = document.mapObject.config.themeGroups;
    }
    document.layerControl.drawPanel()
    makeASyncPostRequest(this, 'Initialize_withScheme', XMLRPC_URL, 'GIS.Session.initialize.with.preset.scheme', sessionID, map_args, themeArray);
    document.mapSchemeControl.setInactive(0);
    document.mapSchemeControl.setActive(schemeId);
  }
  else
    makeASyncPostRequest(this, 'Initialize', XMLRPC_URL,'GIS.Session.initialize',sessionID,map_args);
};

this.setMapLoadImage = function(newImagePanel)
{
  this.mapLoadImage = newImagePanel;
};

this.setMapImage = function(newMapImage)
{
  this.mapImage = newMapImage;
};

this.setVmapLoadImage = function(newImagePanel)
{
  this.vmapLoadImage = newImagePanel;
};

this.setVmapImage = function(newMapImage)
{
  this.vmapImage = newMapImage;
};

this.setLegendImage = function(newLegendImage, newLegendVisibility)
{
  this.legendImage = newLegendImage;
  this.legendVisible = newLegendVisibility;   //initial visibility of legend; will it be displayed when the page loads?
  this.legendSync    = false;
};

this.setWaiting = function(state)
{
  if (state)
  {
    if (this.mapImage != null)
      this.mapImage.setWaiting(true);
    if (this.vmapImage != null)
      this.vmapImage.setWaiting(true);
    this.numWaitingRequests++;
  }
  else
  {
    this.numWaitingRequests--;
    if (this.numWaitingRequests <= 0)
    {
      if (this.mapImage != null)
        this.mapImage.setWaiting(false);
      if (this.vmapImage != null)
        this.vmapImage.setWaiting(false);
    }
  }
  if(this.numWaitingRequests < 0) this.numWaitingRequests = 0; 
};

this.getMapDimensions = function()
{
  if (this.vmapImage != null)
    return Array(Array(this.mapImage.width(),this.mapImage.height()),Array(this.vmapImage.imageNode.cbe.width(),this.vmapImage.imageNode.cbe.height()));    
  else
    return Array(Array(this.mapImage.width(),this.mapImage.height()))
};

this.loadLegend = function()
{
  if (this.customLegendImage!=null)
    this.legendImage.src = this.customLegendImage;
  else{
      makeASyncPostRequest(this,'Legend',XMLRPC_URL,'GIS.Legend.getImage',this.sessionID,0,this.config["legendAttributes"]["width"],this.config["legendAttributes"]["height"],this.config["legendAttributes"]["color"],this.config["legendAttributes"]["font"],this.config["legendAttributes"]["fontSize"],this.config["legendAttributes"]["valueFontSize"],this.config["legendAttributes"]["cellSpacing"]);
  }
};

this.loadLegendSync = function()
{
  if (this.customLegendImage!=null)
    this.legendImage.src = this.customLegendImage;
  else{
    var oldURL = this.legendImage.src; 
    this.setWaiting(true);
    var xmlrpcResponse = makeSyncPostRequest(XMLRPC_URL,'GIS.Legend.getImage',this.sessionID,0,this.config["legendAttributes"]["width"],this.config["legendAttributes"]["height"],this.config["legendAttributes"]["color"],this.config["legendAttributes"]["font"],this.config["legendAttributes"]["fontSize"],this.config["legendAttributes"]["valueFontSize"],this.config["legendAttributes"]["cellSpacing"]);
    var result = getXMLRPCResponseObject(xmlrpcResponse);
    var data = result.data;
    if(data != null)
    {
		if(typeof(data) == "object" && data['inFreeance'] == true){
			this.legendImage.src = data['url'];
		}
		else{
			this.legendImage.src = this.correctURL(data);
		}
      //xMoveTo(this.legendImage,0,0);
      this.legendSync = true;
    }
    else
      dprintf('Communication Error:  Unable to load legend image');
    this.setWaiting(false);
  }
};

this.mouseMove = function(xPos,yPos,width,height,XPercent,YPercent,clickMode)
{
  switch (clickMode)
  {
    case 'MeasureDistance':
      this.setWaiting(false);
      var mapImageX = this.mapImage.left();
      var mapImageY = this.mapImage.top();
      var measurePointX = mapImageX + xPos;
      var measurePointY = mapImageY + yPos;
      var mapX = (XPercent * (this.extent[3]-this.extent[2])) + this.extent[2];  // XP * ExtentWidth + Left
      var mapY = (YPercent * (this.extent[1]-this.extent[0])) + this.extent[0];  // YP * ExtentHeight + Bottom
      if (this.measureControl != null)
      {
	  	this.measureControl.prevMapY = yPos;
		this.measureControl.prevMapX = xPos;
		window.setTimeout(function(){
			if($_this.measureControl.liveUpdate && $_this.measureControl.prevMapY == yPos && $_this.measureControl.prevMapX == xPos){
				var extent = $_this.extent;
				var coord={x:(XPercent * (extent[3]-extent[2])) + extent[2],y:(YPercent * (extent[1]-extent[0])) + extent[0]};
				$_this.measureControl.distanceCalculate(coord);
				$_this.measureControl.areaCalculate(coord);
			}
		},75);
      }
      else
        alert('Application Error\n'+this.id+'.click('+xPos+','+yPos+','+width+','+height+','+XPercent+','+YPercent+','+clickMode+')\nAttempting to process a measure point, but there is no measure control defined for the map object');
      break;
  }
}


this.click = function(xPos,yPos,width,height,XPercent,YPercent,clickMode)
{
  if ((clickMode != 'ZoomBox')&&(clickMode != 'MeasureDistance'))
    this.setWaiting(true);
  switch (clickMode)
  {
    case 'MeasureDistance':  // ADDED-BY: JPW
      //this.setWaiting(false);
      var measurePointX = xPos;
      var measurePointY = yPos;
      var mapX = (XPercent * (this.extent[3]-this.extent[2])) + this.extent[2];  // XP * ExtentWidth + Left
      var mapY = (YPercent * (this.extent[1]-this.extent[0])) + this.extent[0];  // YP * ExtentHeight + Bottom
      if (this.measureControl != null)
      {
        this.measureControl.distanceAddPoint(mapX,mapY);
        this.measureControl.distanceAddPointImage(measurePointX,measurePointY,xZIndex(this.mapImage.eventHandlerNode)+1);
        this.measureControl.distanceCalculate();
        this.measureControl.areaCalculate();
      }
      else
        alert('Application Error\n'+this.id+'.click('+xPos+','+yPos+','+width+','+height+','+XPercent+','+YPercent+','+clickMode+')\nAttempting to process a measure point, but there is no measure control defined for the map object');
      break;
    case 'ZoomIn':
      makeASyncPostRequest(this,clickMode,XMLRPC_URL,'GIS.Zoom.in.byPercent',this.sessionID,0,this.mapImage.width(),this.mapImage.height(),1.5,XPercent,YPercent);
      this.legendSync = false;
      break;
    case 'ZoomOut':
      makeASyncPostRequest(this,clickMode,XMLRPC_URL,'GIS.Zoom.out.byPercent',this.sessionID,0,this.mapImage.width(),this.mapImage.height(),1.5,XPercent,YPercent);
      this.legendSync = false;
      break;
    case 'Center':
      makeASyncPostRequest(this,clickMode,XMLRPC_URL,'GIS.Center.byPercent',this.sessionID,0,this.mapImage.width(),this.mapImage.height(),XPercent,YPercent);
      break;
    case 'Select':
      /** Select across all selectable themes **/
      var currentTheme = '';
      if (document.queryControl)
        document.queryControl.clearResults();
      document.getElementById('textResultTabContainer').innerHTML = '';
      this.clearAllBuffers();
      this.clearAllGeocodePoints();
      this.clearAllSelections();
      for (var currentThemeIndex = 0; currentThemeIndex < this.selectableThemes.length; currentThemeIndex++)
      {
        currentTheme = this.selectableThemes[currentThemeIndex];
        //this.clearThemeSelectionsSync(currentTheme);
        if (this.config.themes[currentTheme].visibility && (this.config.themes[currentTheme].selectOptions != null)&&this.selectionsExist)   //only process if the theme is displayed and configured for selection
        {
          var activeThemeTolerance=-1;  // use the server-side default for this theme
          var activeThemeName = currentTheme;
          var GIS_stylesheet = this.config.themes[currentTheme].selectOptions.styleSheet;
          var fieldsList = this.config.themes[currentTheme].selectOptions.fieldList;
          var activeThemeMaxSelectCount = this.config.themes[currentTheme].selectOptions.limit;
          var requestDetails = new Object;
          requestDetails["request"] = 'newSelection';
          requestDetails["themeId"] = currentTheme;
          requestDetails["deselect"] = false;
          if(this.config.themes[currentTheme].selectOptions.sqlParams)
          {
            var configSQLParams = this.config.themes[currentTheme].selectOptions.sqlParams;
            var sqlParams = Array();
            for(var pos=0;pos < configSQLParams.length;pos++)
            {
              sqlParams[pos] = Array();
              sqlParams[pos][0] = configSQLParams[pos].pdqIdentifier;
              var fieldPairs = Array();
              var limits = Array();
              for(var lcv=0;lcv < configSQLParams[pos].fieldList.length;lcv++)
              {
                fieldPairs[lcv] = Array();
                fieldPairs[lcv][0] = configSQLParams[pos].fieldList[lcv].fieldName;
                fieldPairs[lcv][1] = configSQLParams[pos].fieldList[lcv].pdqFieldName;
              }
              sqlParams[pos][1] = fieldPairs;
              if (configSQLParams[pos].queryType != '')
              {
                limits[0] = configSQLParams[pos].queryType;
                limits[1] = configSQLParams[pos].numRows;
                limits[2] = configSQLParams[pos].startAt;
                sqlParams[pos][2] = limits;
              }
            }
            xypoints = Array(Array(XPercent,YPercent));
            coordsinpercent = true;
            makeASyncPostRequest(this.selectionControl,requestDetails,XMLRPC_URL,'GIS.Selection.entity.byPoint',this.sessionID,0,this.mapImage.width(),this.mapImage.height(),xypoints,coordsinpercent,activeThemeName,activeThemeTolerance,fieldsList,false,GIS_stylesheet,1,sqlParams);
          }
          else
          {
            xypoints = Array(Array(XPercent,YPercent));
            coordsinpercent = true;
            makeASyncPostRequest(this.selectionControl,requestDetails,XMLRPC_URL,'GIS.Selection.entity.byPoint',this.sessionID,0,this.mapImage.width(),this.mapImage.height(),xypoints,coordsinpercent,activeThemeName,activeThemeTolerance,fieldsList,false,GIS_stylesheet,1);
          }
          this.redraw();
        }
        else
        {
          this.setWaiting(false);
        }
      }
      break;
      default:  // JPW
        if (this.extensionMapClickHandlers[clickMode])
        {
          this.setWaiting(false);
          this.extensionMapClickHandlers[clickMode](xPos,yPos,width,height,XPercent,YPercent,clickMode);
        }
        break;
  }
  return;
};

this.bufferOnCenter = function(bufferTheme, bufferDistance, MaxBufferCount)
{
  //this.setWaiting(true);
  document.getElementById('textResultTabContainer').innerHTML = '';
  this.clearAllBuffers();
  this.clearAllSelections();
  this.clearAllGeocodePoints();
  this.setWaiting(true);
  var GIS_stylesheet = this.config.themes[bufferTheme].bufferOptions.styleSheet;
  var GIS_areaStylesheet = this.config.themes[bufferTheme].bufferOptions.areaStyleSheet;
  var bufferFieldList = this.config.themes[bufferTheme].bufferOptions.fieldList;
  var clearFirst = true;
  if (bufferDistance == 0) bufferDistance = 0.1;
  if (MaxBufferCount == 0) MaxBufferCount = ((this.config.themes[bufferTheme].bufferOptions.maxSelect>0)?(this.config.themes[bufferTheme].bufferOptions.maxSelect):(1));
  var bufferSQLparams = this.bufferControl.getSQLParams();
  if(this.config.themes[bufferTheme].bufferOptions.sqlParams != null)
  {
    var configSQLParams = this.config.themes[bufferTheme].bufferOptions.sqlParams;
    var sqlParams = Array();
    for(var pos=0;pos < configSQLParams.length;pos++)
    {
      sqlParams[pos] = Array();
      sqlParams[pos][0] = configSQLParams[pos].pdqIdentifier;
      var fieldPairs = Array();
      var limits = Array();
      for(var lcv=0;lcv < configSQLParams[pos].fieldList.length;lcv++)
      {
        fieldPairs[lcv] = Array();
        fieldPairs[lcv][0] = configSQLParams[pos].fieldList[lcv].fieldName;
        fieldPairs[lcv][1] = configSQLParams[pos].fieldList[lcv].pdqFieldName;
      }
      sqlParams[pos][1] = fieldPairs;
      if (configSQLParams[pos].queryType != '')
      {
        limits[0] = configSQLParams[pos].queryType;
        limits[1] = configSQLParams[pos].numRows;
        limits[2] = configSQLParams[pos].startAt;
       sqlParams[pos][2] = limits;
      }
    }
  }
  else
    var sqlParams = new Array();
  var stylesheet=(GIS_areaStylesheet)?[GIS_stylesheet,GIS_areaStylesheet]:GIS_stylesheet;
  makeASyncPostRequest(this.bufferControl,Array('BufferXY',bufferTheme),XMLRPC_URL,'GIS.Buffer.at.XY',this.sessionID,0,this.mapImage.width(),this.mapImage.height(),0.5,0.5,true,bufferTheme,bufferDistance,bufferFieldList,true,stylesheet,MaxBufferCount,sqlParams);
};

this.bufferOnSelection = function(newSelectionHandle, newSourceTheme, newTargetTheme, newDistance, newSQLParams, newBufferSQLParams, newClearFirst)
{
  if (newSQLParams == null)
  {
    var bufferSQLparams = this.bufferControl.getSQLParams();
    if(this.config.themes[newTargetTheme].bufferOptions.sqlParams != null)
    {
      var configSQLParams = this.config.themes[newTargetTheme].bufferOptions.sqlParams;
      var sqlParams = Array();
      for(var pos=0;pos < configSQLParams.length;pos++)
      {
        sqlParams[pos] = Array();
        sqlParams[pos][0] = configSQLParams[pos].pdqIdentifier;
        var fieldPairs = Array();
        var limits = Array();
        for(var lcv=0;lcv < configSQLParams[pos].fieldList.length;lcv++)
        {
          fieldPairs[lcv] = Array();
          fieldPairs[lcv][0] = configSQLParams[pos].fieldList[lcv].fieldName;
          fieldPairs[lcv][1] = configSQLParams[pos].fieldList[lcv].pdqFieldName;
        }
        sqlParams[pos][1] = fieldPairs;
        if (configSQLParams[pos].queryType != '')
        {
          limits[0] = configSQLParams[pos].queryType;
          limits[1] = configSQLParams[pos].numRows;
          limits[2] = configSQLParams[pos].startAt;
         sqlParams[pos][2] = limits;
        }
      }
    }
    else
      var sqlParams = new Array();    
  }
  
  var bufferThemeParams = this.config.themes[newTargetTheme].bufferOptions;
  var GIS_stylesheet = this.config.themes[newTargetTheme].bufferOptions.styleSheet;
  var bufferFieldList = this.config.themes[newTargetTheme].bufferOptions.fieldList;
  var MaxBufferCount = this.config.themes[newTargetTheme].bufferOptions.maxSelect;
  var MapWidth = this.mapImage.width();
  var MapHeight = this.mapImage.height();

  this.setWaiting(true);
  if (bufferSQLparams == null)
    makeASyncPostRequest(this.bufferControl,Array('BufferOnSelection',newTargetTheme),XMLRPC_URL,'GIS.Buffer.on.Selection',this.sessionID,0,MapWidth,MapHeight,newSelectionHandle,newSourceTheme,newTargetTheme,newDistance,bufferFieldList,newClearFirst,GIS_stylesheet,MaxBufferCount,sqlParams);
  else
    makeASyncPostRequest(this.bufferControl,Array('BufferOnSelection',newTargetTheme),XMLRPC_URL,'GIS.Buffer.on.Selection',this.sessionID,0,MapWidth,MapHeight,newSelectionHandle,newSourceTheme,newTargetTheme,newDistance,bufferFieldList,newClearFirst,GIS_stylesheet,MaxBufferCount,sqlParams,newBufferSQLParams);
};

this.centerOnPoint = function(newMapX,newMapY)
{
  //accepts a new x,y coordinate pair in the current map units
  this.setWaiting(true);
  makeASyncPostRequest(this,'CenterOnPoint',XMLRPC_URL,'GIS.Center.onPoint',this.sessionID,0,this.mapImage.width(),this.mapImage.height(),newMapX,newMapY);
};

this.clickVmap = function (xPosition,yPosition,imageWidth, imageHeight)  // ASYNC
{
  var XPercent = xPosition / imageWidth;
  var YPercent = 1.0 - (yPosition / imageHeight);
  var mapX = (XPercent * (this.vmapExtent[3]-this.vmapExtent[2])) + this.vmapExtent[2];  // XP * ExtentWidth + Left
  var mapY = (YPercent * (this.vmapExtent[1]-this.vmapExtent[0])) + this.vmapExtent[0];  // YP * ExtentHeight + Bottom
  this.setWaiting(true);
  makeASyncPostRequest(this,'CenterOnPoint',XMLRPC_URL,'GIS.Center.onPoint',this.sessionID,0,this.mapImage.width(),this.mapImage.height(),mapX,mapY);
};

this.pan = function(DirStr)
{
  this.setWaiting(true);
  var mapData = makeASyncPostRequest(this,'Pan',XMLRPC_URL,'GIS.Pan.byDirection',this.sessionID,0,this.mapImage.width(),this.mapImage.height(),DirStr,0.4);
};

this.zoomInitialExtent = function()
{
  this.setWaiting(true);
  this.legendSync = false;
  makeASyncPostRequest(this,'ZoomInitialExtent',XMLRPC_URL,'GIS.Zoom.to.initialExtent',this.sessionID,0,this.mapImage.width(),this.mapImage.height());
};

this.zoomFullExtent = function()
{
  this.setWaiting(true);
  this.legendSync = false;
  makeASyncPostRequest(this,'ZoomInitialExtent',XMLRPC_URL,'GIS.Zoom.to.fullExtent',this.sessionID,0,this.mapImage.width(),this.mapImage.height());
};

this.zoomPresetExtent = function(newPresetName)
{
  this.setWaiting(true);
  this.legendSync = false;
  makeASyncPostRequest(this,'ZoomPresetExtent',XMLRPC_URL,'GIS.Zoom.to.presetExtent',this.sessionID,0,this.mapImage.width(),this.mapImage.height(),newPresetName);
};

this.zoomIn = function()
{
  this.setWaiting(true);
  this.legendSync = false;
  makeASyncPostRequest(this,'ZoomIn',XMLRPC_URL,'GIS.Zoom.in',this.sessionID,0,this.mapImage.width(),this.mapImage.height(),this.zoomFactor);
};

this.zoomOut = function()
{
  this.setWaiting(true);
  this.legendSync = false;
  makeASyncPostRequest(this,'ZoomOut',XMLRPC_URL,'GIS.Zoom.out',this.sessionID,0,this.mapImage.width(),this.mapImage.height(),this.zoomFactor);
};

this.zoomTo = function(themeIndex, SQLstr, select)
{
  //Zooms to an entity on a theme, with the option to select the object.
  //themeIndex is the index of the theme to perform the zoom on
  //SQLstr is a query string used to identify the unique object
  //select is a boolean indicating whether or not to select the object if it is found
  //
  if (select)
  {
    if (document.queryControl)
      document.queryControl.clearResults();
    document.getElementById('textResultTabContainer').innerHTML = '';
    this.clearAllBuffers();
    this.clearAllGeocodePoints();
    this.clearAllSelections();
  }
  this.setWaiting(true);
  this.legendSync = false;
  if (!this.selectionsExist)
    select = false;
  var GIS_stylesheet = this.config.themes[themeIndex].selectOptions.styleSheet;
  if (select)
  {
	var requestDetails = {
		request: 'newSelection',
		themeId: themeIndex,
		deselect: false
	};
    if(this.config.themes[themeIndex].selectOptions.sqlParams != null)
    {
      var configSQLParams = this.config.themes[themeIndex].selectOptions.sqlParams;
      var sqlParams = Array();
      for(var pos=0;pos < configSQLParams.length;pos++)
      {
        sqlParams[pos] = Array();
        sqlParams[pos][0] = configSQLParams[pos].pdqIdentifier;
        var fieldPairs = Array();
        var limits = Array();
        for(var lcv=0;lcv < configSQLParams[pos].fieldList.length;lcv++)
        {
          fieldPairs[lcv] = Array();
          fieldPairs[lcv][0] = configSQLParams[pos].fieldList[lcv].fieldName;
          fieldPairs[lcv][1] = configSQLParams[pos].fieldList[lcv].pdqFieldName;
        }
        sqlParams[pos][1] = fieldPairs;
        if (configSQLParams[pos].queryType != '')
        {
          limits[0] = configSQLParams[pos].queryType;
          limits[1] = configSQLParams[pos].numRows;
          limits[2] = configSQLParams[pos].startAt;
          sqlParams[pos][2] = limits;
        }
      }
      makeASyncPostRequest(this.selectionControl,requestDetails,XMLRPC_URL,'GIS.Zoom.to.entities',this.sessionID,0,this.mapImage.width(),this.mapImage.height(),themeIndex,this.config.themes[themeIndex].selectOptions.fieldList,SQLstr,this.config.themes[themeIndex].selectOptions.zoomExtentRatio,1,select,select,false,GIS_stylesheet,sqlParams);
    }
    else
    {
      makeASyncPostRequest(this.selectionControl,requestDetails,XMLRPC_URL,'GIS.Zoom.to.entities',this.sessionID,0,this.mapImage.width(),this.mapImage.height(),themeIndex,this.config.themes[themeIndex].selectOptions.fieldList,SQLstr,this.config.themes[themeIndex].selectOptions.zoomExtentRatio,1,select,select,false,GIS_stylesheet);
    }
  }
  else
  {
    makeASyncPostRequest(this,'zoomTo',XMLRPC_URL,'GIS.Zoom.to.entities',this.sessionID,0,this.mapImage.width(),this.mapImage.height(),themeIndex,this.config.themes[themeIndex].selectOptions.fieldList,SQLstr,this.config.themes[themeIndex].selectOptions.zoomExtentRatio,1,select,select,false,GIS_stylesheet);
  }
  scrollToTopOfScreen();
};

this.zoomTo_ = function(layerid,attrib,fieldtype,value,select)
{
	console.log('zoomTo_('+layerid+','+attrib+','+fieldtype+','+value+','+select+')');
	//same effect as zoomTo, but without a specified where clause
	// attrib is map attribute to match
	// fieldtype(string) is type of attribute.  use null to detect from configruation
	// value is the value to match against attrib
	if(!this.config["themes"][layerid])
		alert("Unable to execute zoom-to command - layer \""+layerid+"\" not found");
	else{
		if(this.config["themes"][layerid]["themeFields"]){  //only exists if layer is selectable
			if(!this.config["themes"][layerid]["themeFields"][attrib])
				alert("Unable to execute zoom-to command - layer \""+layerid+"\" does not have the attribute \""+attrib+"\"");
			else{
				if(!fieldtype){
					fieldtype=this.config["themes"][layerid]["themeFields"][attrib]["type"];
				}
			}
		}
		var quote=this.useSQLQuotes(fieldtype);
		console.log('field type detected as "'+fieldtype+'"; quote = '+quote);
		var sqlWhere = SQLWhereBuilder.stmt_compare(attrib,'=',(quote)?SQLWhereBuilder.singleQuotes:SQLWhereBuilder.noQuotes,value);
		this.zoomTo(layerid,sqlWhere,select);
	}
};

this.useSQLQuotes = function(fieldtype){
	return ((fieldtype=='String')||(fieldtype=='Date')||(fieldtype=='Character'));
};

this.zoomToExtent = function(newExtent)
{
  this.setWaiting(true);
  this.legendSync = false;
  makeASyncPostRequest(this,'ZoomToExtent',XMLRPC_URL,'GIS.Zoom.to.extent',this.sessionID,0,this.mapImage.width(),this.mapImage.height(),newExtent);
};

this.newWindowExtent = function(url)
{
  window.open(url+"&CMD=EXTENT&B="+this.extent[0]+"&T="+this.extent[1]+"&L="+this.extent[2]+"&R="+this.extent[3]);
}

this.refresh = function()
{
  this.setWaiting(true);
  makeASyncPostRequest(this,'MapRedraw',XMLRPC_URL,'GIS.Map.redraw',this.sessionID,0,this.mapImage.width(),this.mapImage.height());
};

this.redraw = function()
{
  this.setWaiting(true);
  makeASyncPostRequest(this,'MapRedraw',XMLRPC_URL,'GIS.Map.redraw',this.sessionID,0,this.mapImage.width(),this.mapImage.height());
};

this.zoomToPrevious = function()
{
  this.setWaiting(true);
  this.legendSync = false;
  makeASyncPostRequest(this,'ZoomPrevious',XMLRPC_URL,'GIS.Zoom.to.previousExtent',this.sessionID,0,this.mapImage.width(),this.mapImage.height());
};

this.zoomToWindow = function(bottom,top,left,right)
{
  this.setWaiting(true);
  this.legendSync = false;
  makeASyncPostRequest(this,'ZoomWindow',XMLRPC_URL,'GIS.Zoom.to.windowPercent',this.sessionID,0,this.mapImage.width(),this.mapImage.height(),bottom,top,left,right);
};

this.zoombar = function (ratio,divnum,numdivs)
{
  this.setWaiting(true);
  this.legendSync = false;
  makeASyncPostRequest(this,'ZoomBar',XMLRPC_URL,'GIS.Zoom.by.bar',this.sessionID,0,this.mapImage.width(),this.mapImage.height(),ratio,divnum,numdivs);
};

this.setThemes = function(newThemeList)
{
  for (i=0; i<newThemeList.length; i++)
  {
    this.themeLookup[newThemeList[i][0]] = i;
    this.themes[i] = new Array(newThemeList[i], "off");
  }
};

this.getThemeByName = function(newThemeName)
{
  return this.themes[this.themeLookup[newThemeName]];
};

this.setActiveTheme = function(newActiveTheme)
{
  this.config.activeTheme = newActiveTheme;
  if (this.layerControl)
    this.layerControl.update();
};

this.getBookmarkList = function ()
{
  //does not set the load image since it does not interfere with map operations
  if (this.bookmarkControl!=null)
    makeASyncPostRequest(this,'getBookmarkList',XMLRPC_URL,'GIS.Geobookmark.get.list',this.sessionID);
};

this.addBookmark = function (name)
{
  if (name != '')
    makeASyncPostRequest(this,'addBookmark',XMLRPC_URL,'GIS.Geobookmark.add.state',this.sessionID,0,name,false,false);
};

this.gotoBookmark = function (bookmarkIndex)
{
  var name = this.bookmarks[bookmarkIndex];  
  this.setWaiting(true);
  this.legendSync = false;
  makeASyncPostRequest(this,'gotoBookmark',XMLRPC_URL,'GIS.Geobookmark.restore.state',this.sessionID,0,name,this.bookmark_redrawmaps,true,true,true,false);
};

this.removeBookmark = function(bookmarkIndex)
{
  var name = this.bookmarks[bookmarkIndex];  
  this.setWaiting(true);
  makeASyncPostRequest(this,'removeBookmark',XMLRPC_URL,'GIS.Geobookmark.remove.state',this.sessionID,name);
};

this.loadThemes = function()
{
  this.setWaiting(true);
  makeASyncPostRequest(this,'getThemes',XMLRPC_URL,'GIS.Themes.getList',this.sessionID,0);
};

this.setThemeState = function(themeName, visible)
{
  var themeArray = [[themeName,visible]];
  this.config["themes"][themeName]["visibility"] = visible;
  this.legendSync = false;
  if (this.activeMapScheme!=null)
    this.config.mapSchemeConfig.mapSchemes[this.activeMapScheme].themes[themeName].display=(visible?1:0);
  makeASyncPostRequest(this, 'setThemes', XMLRPC_URL, 'GIS.Themes.setList', this.sessionID, 0, themeArray);
};

this.setThemesState = function(themeArray)
{
	for(var i = 0; i < themeArray.length; i++){
		this.config["themes"][themeArray[i][0]]["visibility"] = themeArray[i][1];
	}
	this.legendSync = false;
	makeASyncPostRequest(this, 'setThemes', XMLRPC_URL, 'GIS.Themes.setList', this.sessionID, 0, themeArray);
};

this.setMapScheme = function(schemeId)
{
  var themeArray = [];
  var themes = this.config.mapSchemeConfig.mapSchemes[parseInt(schemeId)].themes;
  for (var cT in themes){
    var currentTheme = themes[cT];
    if(currentTheme!='toJSONString' && cT != 'toJSONString'){
      themeArray.push([currentTheme.id,(currentTheme.display==1),currentTheme.legend]);
	}
  }
  this.setWaiting(true);
  this.legendSync = false;
	if(this.config.mapSchemeConfig.mapSchemes[schemeId].layerControl){
		document.layerControl.config = this.config.mapSchemeConfig.mapSchemes[schemeId].layerControl;
	}
	else{
		document.layerControl.config = document.mapObject.config.themeGroups;
	}
	document.layerControl.drawPanel()
  this.activeMapScheme=parseInt(schemeId);
  document.queryControl.drawFormPanel(this.config.mapSchemeConfig.mapSchemes[schemeId].hiddenQueries);
	if(this.config.mapSchemeConfig.mapSchemes[schemeId].mapTool){
		if(document.mapToolbar.getButton(this.config.mapSchemeConfig.mapSchemes[schemeId].mapTool+'Button') && document.mapToolbar.getButton(this.config.mapSchemeConfig.mapSchemes[schemeId].mapTool+'Button').clickEvent){
			document.mapToolbar.getButton(this.config.mapSchemeConfig.mapSchemes[schemeId].mapTool+'Button').clickEvent();
			document.mapToolbar.mapCursorRadioButtonGroup.setActiveButton(this.config.mapSchemeConfig.mapSchemes[schemeId].mapTool+'Button');
		}
	}
  makeASyncPostRequest(this, 'setMapScheme', XMLRPC_URL, 'GIS.Themes.setScheme', this.sessionID, 0, themeArray);
};

this.clearSelection = function(themeIndex, selectionHandle)
{
  this.setWaiting(true);
  makeASyncPostRequest(this.selectionControl,{request:  'clearSelection',themeIndex:themeIndex,handle: selectionHandle},XMLRPC_URL,'GIS.Selection.clear.EntityFromTheme',this.sessionID,0,themeIndex, selectionHandle, this.mapImage.width(),this.mapImage.height());
};

this.clearDuplicateSelection = function(themeIndex, selectionHandle)
{
  this.setWaiting(true);
  makeASyncPostRequest(this.selectionControl,{request: 'clearDuplicateSelection',themeIndex: themeIndex,handle: selectionHandle},XMLRPC_URL,'GIS.Selection.clear.EntityFromTheme',this.sessionID,0,themeIndex, selectionHandle, this.mapImage.width(),this.mapImage.height());
};

this.clearThemeSelections = function(themeIndex)
{
  this.setWaiting(true);
  this.selectionControl.selections[themeIndex].panel.innerHTML = '';
  makeASyncPostRequest(this.selectionControl,{request: 'clearTheme',themeIndex: themeIndex},XMLRPC_URL,'GIS.Selection.clear.AllFromTheme',this.sessionID,0,themeIndex);
};

this.clearAllSelections = function()
{
  //since only one feature on each layer can be selected at any given time, the selection handles do not need tracked. 
  if (this.selectionControl != null)
  {
    this.setWaiting(true);
    for (var themeIndex in this.selectionControl.selections){
      if(themeIndex=='toJSONString')continue;
      this.selectionControl.selections[themeIndex].panel.innerHTML = '';
      this.selectionControl.selections[themeIndex].panel.style.display = 'none';
    }
    var xmlrpcResponse = makeSyncPostRequest(XMLRPC_URL,'GIS.Selection.clear.AllThemes',this.sessionID,0);
    var mapData = getXMLRPCResponseObject(xmlrpcResponse);
    this.setWaiting(false);
  }
};

this.clearThemeSelectionsSync = function(themeIndex)
{
  this.setWaiting(true);
  var xmlrpcResponse = makeSyncPostRequest(XMLRPC_URL,'GIS.Selection.clear.AllFromTheme',this.sessionID,0,themeIndex);
  var mapData = getXMLRPCResponseObject(xmlrpcResponse);
  this.selectionControl.selections[themeIndex].panel.innerHTML = '';
  this.setWaiting(false);
};
this.clearSyncSelection = function(themeIndex, selectionHandle)
{
  this.setWaiting(true);
  var xmlrpcResponse = makeSyncPostRequest(XMLRPC_URL,'GIS.Selection.clear.EntityFromTheme',this.sessionID,0,this.themes[themeIndex][0][0], selectionHandle, this.mapImage.width(),this.mapImage.height());
  var mapData = getXMLRPCResponseObject(xmlrpcResponse);
  this.selectionControl.selections[themeIndex].panel.innerHTML = '';
  this.setWaiting(false);
};


this.clearThemeBuffer = function(themeName,bufferHandle)
{
  this.setWaiting(true);
  makeASyncPostRequest(this.bufferControl,Array('clearThemeBuffer',themeName,bufferHandle),XMLRPC_URL,'GIS.Buffer.clear.FromTheme',this.sessionID,0,themeName, bufferHandle, this.mapImage.width(),this.mapImage.height());
};

this.clearAllBuffers = function()
{
  if (this.bufferControl){
    if (this.bufferControl.hasBufferedResults()){
      this.setWaiting(true);
      var xmlrpcResponse = makeSyncPostRequest(XMLRPC_URL,'GIS.Buffer.clear.AllThemes',this.sessionID,0);
      var mapData = getXMLRPCResponseObject(xmlrpcResponse);
      if (this.bufferControl)
        this.bufferControl.clearAllBuffers();
      this.setWaiting(false);
    }
  }
};

this.clearAllGeocodePoints = function()
{
  if (this.geocodeControl!=null)
    this.geocodeControl.clearMarkup();
};

this.callback = function(serverReplyDoc, pendingOperation)
{
  var clearMeasurePoints = false;
  if (!validateXMLDoc(serverReplyDoc))
  {
    this.setWaiting(false);
    this.refresh();
    return null;
  }

  var clientReply = new XMLRPCResponse();
  //clientReply.setResponseByStr(serverReplyDoc.xml);
  clientReply.setResponseByDoc(serverReplyDoc);

  if(clientReply.isFault())
  {
    var data = null;
  }
  else
    var data = clientReply.getObject();

  if((data != null))
  {
    switch (pendingOperation)
    {
      case 'CoordConvSP2LatLon':
        if (this.coordConvControl)
          this.coordConvControl.callback(data,pendingOperation);
        break;
      case 'Initialize_withScheme':
      case 'Initialize':
        _MAP_INITIALIZED = true;
        this.extent = data[0][1];
        if (this.firstLoad)
        {
          this.firstLoad = false;
          this.initialExtent = cloneObject(data[0][1]);
        }
        if (this.mapImage != null)
        {
          this.setWaiting(true);
          this.mapImage.imageNode.mapObject = this;
          this.setMapImage(data[0][0]);
        }
        if (this.vmapImage != null)
        {
          this.setWaiting(true);
          this.vmapImage.imageNode.mapObject = this;
          this.vmapImage.imageNode.src = this.correctURL(data[1][0]);
        }
        this.vmapExtent = data[1][1];
        this.sessionID = data[data.length-1];
        document.setSessionID(this.sessionID);
        this.extent = data[0][1];
        this.loadThemes();
        this.loadLegend();
        this.getBookmarkList();
        if (this.labelControl != null)
          this.labelControl.initialize();
        if (this.selectionControl != null)
        {
          this.selectionControl.initialize();
        }
        if (this.zoomBar)
          this.zoomBar.initialize();
        runCMDs();
        if(this.config.mapSchemeConfig && this.config.mapSchemeConfig.mapSchemes && this.config.mapSchemeConfig.mapSchemes.length > 0 && document.queryControl){
          document.queryControl.drawFormPanel(this.config.mapSchemeConfig.mapSchemes[this.activeMapScheme].hiddenQueries);
        }
        break;
      case 'getThemes':
        for (i = 0; i < data.length; i++){
          try{
            this.config["themes"][data[i][0]]["visibility"] = data[i][1];
          }
          catch(e)
          {
            alert('Warning:\nUnable to set the visibility for map layer "'+data[i][0]+'"\nThere may be a mismatch between the client configuration and the map resource.');
          }
        }
        if (this.layerControl)
          this.layerControl.update();
        break;
      case 'setThemes':
        break;
      case 'setMapScheme':
        this.loadThemes();
        this.redraw();
        break;
      case 'Legend':
        this.setWaiting(true);
        if (this.legendImage != null){
          if(typeof(data) == "object" && data['inFreeance'] == true){
            this.legendImage.src = data['url'];
          }
          else{
            this.legendImage.src = this.correctURL(data);
          }
        }
        this.legendSync = true;
        break;
      case 'LoadLayers':
        break;
      case 'getBookmarkList':
        if (this.bookmarkControl)
          this.bookmarkControl.callback(data,'getBookmarkList');
        break;
      case 'addBookmark':
        if (this.bookmarkControl)
          this.bookmarkControl.callback(data,'addBookmark');
        this.getBookmarkList();
        break;
      case 'removeBookmark':
        if (this.bookmarkControl)
          this.bookmarkControl.callback(data,'removeBookmark');
        this.getBookmarkList();
        break;
      case 'gotoBookmark':
        if (this.mapImage != null)
        {
          this.setWaiting(true);
          this.setMapImage(data[0][1]);
        }
        if (this.vmapImage != null)
        {
          this.setWaiting(true);
          this.vmapImage.imageNode.src = this.correctURL(data[1][1]);
        }
        this.extent = data[0][2];
        this.loadThemes();
        if (this.legendVisible)
          this.loadLegend();
        clearMeasurePoints = true;
        break;
      case 'Select':
        break;
      case 'dEmail':
        break;
      case 'BufferXY':
        this.extent = data[0][0][2];
        if (this.mapImage != null){
          this.setWaiting(true);
          this.setMapImage(data[0][0][1]);
        }
        if (this.vmapImage != null){
          this.setWaiting(true);
          this.vmapImage.imageNode.src = this.correctURL(data[0][1][1]);
        }
        break;
      case 'zoomTo':
        if (this.mapImage != null){
          this.setWaiting(true);
          this.setMapImage(data[0][0][1]);
        }
        if (this.vmapImage != null){
          this.setWaiting(true);
          this.vmapImage.imageNode.src = this.correctURL(data[0][1][1]);
        }
        if (this.legendVisible)
          this.loadLegend;
        this.extent = data[0][0][2];
        clearMeasurePoints = true;
        break;
      case 'getPrintImage':
        this.printMap(data);
        break;
      case 'getExportedMap':
        this.downloadExportedMap(data);
        break;
      default:
        this.extent = data[0][2];
        if (this.mapImage != null){
          this.setMapImage(data[0][1]);
          this.setWaiting(true);
        }
        if (this.vmapImage != null){
          this.setWaiting(true);
          this.vmapImage.imageNode.src = this.correctURL(data[1][1]);
        }
        if (!this.legendSync)
        {
          this.loadLegend();
        }
        clearMeasurePoints = true;
        break;
    }
  }
  else
  {
    switch(parseInt(clientReply.getFaultCode()))
    {
      case 1018: // No Buffer elements found
        break;
      default:
        dprintf('A Server Error occurred in a Map request.\n\nOperation:  '+pendingOperation+'\nFault Code: '+clientReply.getFaultCode()+'\nError Message:\n'+clientReply.getFaultString());
    }
  }
  if ((this.measureControl != null) && clearMeasurePoints)
  {
    this.measureControl.distanceReset();
  }
  if ((this.zoomBar!=null)&&(this.zoomBar.initialized))
    this.zoomBar.highlightNearestDiv();
  if (this.scalebar)
    this.scalebar.drawScalebar();
  this.setWaiting(false);
};

this.checkImage = function(image){
  if(image.complete){
    $_this.setWaiting(false);
  }
  else{
    setTimeout(function(){$_this.checkImage(image)},50)
  }
}

this.setMapImage = function(imgURL)
{
  //set image to correct path and load tiles (if used)
  this.mapImage.imageNode.src = this.correctURL(imgURL);
  this.checkImage(this.mapImage.imageNode);
  if (this.config.seamlessPan)
  {
    var extentsMatch = true;
    for (var i=0;((i<this.extent.length)&&extentsMatch);i++)
      extentsMatch = (this.extent[i]==this.dragExtent[i]);
    if (!extentsMatch){  //only draw tiles if the extent changed.
      this.mapImage.clearDragTiles();
      this.dragExtent = cloneObject(this.extent);
      var $_this = this;
      var extentHeight = this.extent[1]-this.extent[0];
      var extentWidth = this.extent[3]-this.extent[2];
      var minLeft = this.extent[2]-extentWidth;
      var minBottom = this.extent[0]-extentHeight;
      var maxTop = this.extent[1]+extentHeight;
      var maxRight = this.extent[3]+extentWidth;
      var newExtents = [
        [this.extent[1],maxTop,minLeft,this.extent[2]],
        [this.extent[1],maxTop,this.extent[2],this.extent[3]],
        [this.extent[1],maxTop,this.extent[3],maxRight],
        [this.extent[0],this.extent[1],minLeft,this.extent[2]],
        [this.extent[0],this.extent[1],this.extent[2],this.extent[3]],
        [this.extent[0],this.extent[1],this.extent[3],maxRight],
        [minBottom,this.extent[0],minLeft,this.extent[2]],
        [minBottom,this.extent[0],this.extent[2],this.extent[3]],
        [minBottom,this.extent[0],this.extent[3],maxRight]
      ];
      var $_tileCounter = ++this.dragTileCounter;
      if (this.dragTileSessionId)
        this.mapTile_initializeCallback({data:[this.dragTileSessionId]},newExtents,$_tileCounter);
      else
        freeance_request(function(result){$_this.mapTile_initializeCallback(result,newExtents,$_tileCounter)},'GIS.Session.initialize','',Array(Array(this.config["resourceId"],1,1,1,false)));
    }
  }
};

this.mapTile_initializeCallback = function(result,newExtents,dragTileCounter)
{
  var $_this = this;
  if (this.dragTileCounter==dragTileCounter)
  {
    var $_sessionId = result['data'][result['data'].length-1];
    this.dragTileSessionId = $_sessionId;
    var themeArray = [];      //array of theme information to pass to server
    for (var i in this.config['themes']){
      if(i=='toJSONString')continue;
      themeArray.push([i,this.config['themes'][i]['visibility']]);
    }
    freeance_request(function(result){$_this.mapTile_setThemesCallback(result,newExtents,dragTileCounter,$_sessionId)},'GIS.Themes.setList', $_sessionId, 0, themeArray);
  }
  else
    dprintf('map tile request '+dragTileCounter+' cancelled');
};

this.mapTile_setThemesCallback = function(result,newExtents,dragTileCounter,sessionId)
{
  if (this.dragTileCounter==dragTileCounter)
  {
    var width = this.mapImage.width();
    var height = this.mapImage.height();
    for (var tileIndex=0;tileIndex<9;tileIndex++)
      if (tileIndex!=4) //skip center
        this.mapTile_makeImageRequest(newExtents[tileIndex],dragTileCounter,sessionId,tileIndex,width,height);
  }
  else
    dprintf('map tile request '+dragTileCounter+'['+tileIndex+'] cancelled');
};

this.mapTile_makeImageRequest = function(extent,dragTileCounter,sessionId,tileIndex,width,height)
{
  var $_this = this;
  freeance_request(function(result){$_this.mapTile_imageCallback(result,dragTileCounter,tileIndex);},'GIS.Zoom.to.extent',sessionId,0,width,height,extent);  
};

this.mapTile_imageCallback = function(result,dragTileCounter,tileIndex)
{
  if (this.dragTileCounter==dragTileCounter)
  {
    this.mapImage.dragTiles[tileIndex].setAttribute('src',this.correctURL(result['data'][0][1]));
  }
  else
    dprintf('map tile request '+dragTileCounter+'['+tileIndex+'] cancelled');

};

this.imageLoadCallback = function()
{
  this.mapObject.setWaiting(false);
};

this.selectionCallback = function (data)
{
  var returnValue;
  if (data)
  {
    this.mapImage.imageNode.src = this.correctURL(data[0][1]);
    if (this.vmapImage != null)
      this.vmapImage.imageNode.src = this.correctURL(data[1][1]);
    this.extent = data[0][2];
    returnValue = true;
  }
  else
    returnValue = null;
  this.setWaiting(false);
  if (data != null)
    if (this.onSelect)
      this.onSelect();
  return returnValue;
};

this.correctURL = function (newURL)
{
	return '../../'+((this.config["imsHostname"]!='')?(newURL.replace(/\/\/(?:\w|\.)+\//,'//'+this.config["imsHostname"]+'/')):(newURL));
};

this.exportMap = function()
{
  this.setWaiting(true);
  makeASyncPostRequest(this,'getExportedMap',XMLRPC_URL,'ArcIMS.Map.export',this.sessionID,0,this.mapImage.width(),this.mapImage.height());
};
this.downloadExportedMap = function(url)
{
  url = this.correctURL(url);
  downloadFile(url);
};

this.print = function()
{
  //arguments[0] = array of name,value pairs for placeholder variables
  //arguments[1] = callback fcn
  //arguments[2] = extent array
  var extent = [];
  var scale_config = [];
  if(arguments.length>2) extent = arguments[2];
  if(arguments.length>3) scale_config = arguments[3];
  if(arguments.length>4) attributeData = arguments[4];
  var placeholderVariables = new Array();
  if (this.config.printConfig.defaultTemplate == -1)
  {
    alert('Freeance Internal Error:  Unable to Print.\nReason:  No print configurations have been defined.');
  }
  else
  {
    this.loadLegendSync();
    this.setWaiting(true);
    placeholderVariables[0] = Array('legendImage',this.legendImage.src);
    if (this.vmapImage!=null)
      placeholderVariables[1] = Array('vmapImage',this.vmapImage.imageNode.src);
    else
      placeholderVariables[1] = Array('vmapImage',GuiWidget.THEME_PATH+'/'+GuiWidget.THEME+'/images/blank.gif');
    if (arguments.length > 0){
      for (var i=0;i<arguments[0].length;i++)  //process placeholders
      {
        placeholderVariables.push([arguments[0][i][0],arguments[0][i][1]]);
      }
    }
    freeance_request(arguments[1],'PDFPrint.Template.Map',this.config.printConfig.templates[this.config.printConfig.activeTemplate].templateName,placeholderVariables,document.sessionID,0,document.mapObject.mapImage.width(),document.mapObject.mapImage.height(),5,extent,scale_config,attributeData);
  }
};
};}
/* FILE:FreeanceWeb/Client/PublicKiosk1/lib/MapLib/MapImage.js */ if(!window.freeance_loaded_js['ddf64bf17740c9853248fa8b9a69e469']){window.freeance_loaded_js['ddf64bf17740c9853248fa8b9a69e469']=1;
//MapImage.js
//displays and handles navigation for a map object
//requires the zoom box class to function properly
_MapLoadImageWidth = 90;
_MapLoadImageHeight = 36;
  
MapImage = function(newID, newParent, newXPosition, newYPosition, newZIndex, newWidth, newHeight, newVisibility, newMapObject, newMapType)
{
  var $_this = this;
  this.id = newID;
  this.map = newMapObject;
  this.mapType = newMapType;  //valid types are 'MASTER','SLAVE'
  this.zoomWindowDelta = new Array(0,0);
  this.zoomBoxMargin = 0;
  this.zoomBoxClipLeft = 0;
  this.zoomBoxClipRight = 0;
  this.zoomBoxClipTop = 0;
  this.zoomBoxClipBottom = 0;  
  this.dragEnabled = false;
  this.currentCursor = 'MapImageWait';
  this.loadImage = null;
  this.waiting = false;
  this.parentElement = newParent;
  this.zoomBoxPending = false;
  this.mouseDownPosition = Array(0,0);  
  this.dragPending = false;
  this.cursorPos_old = [-1,-1];
  this.cursorPos = [-1,-1];
  this.eventCallbacks = {
    resize:Array(),
    click:Array(),
    mouseOver:Array(),
    mouseOut:Array(),
    mouseUp:Array(),
    mouseDown:Array(),
    mouseMove:Array(),
    dragStart:Array(),
    drag:Array(),
    dragEnd:Array()
  };
  
  this.registerEventCallback = function(eventType,callback)
  {
    if (this.eventCallbacks[eventType]!=null)  //empty array can eval to false
      this.eventCallbacks[eventType].push(callback);
    return this.eventCallbacks[eventType].length-1;
  };
  this.unregisterEventCallback = function(eventType,index)
  {
    if (this.eventCallbacks[eventType]!=null)  //empty array can eval to false
      this.eventCallbacks[eventType][index]=null;
  };
/*******************************************/
this.setMapObject = function(newMapObject){this.map = newMapObject;};
this.setMapImage = function(newImagePath)
{
  //parameter is the url for the new map image.
  this.imageNode.src = newImagePath;
  this.dragTiles[4].src = newImagePath;
  this.positionDragTiles();  
};

/*******************************************/
this.setMouseMode = function(newMode)
{
  //valid modes are:  select, zoomIn, zoomOut, center,
  this.mouseMode = newMode;
  switch (newMode)
  {
    case 'DragMap':
      this.currentCursor = 'MapImageDrag';
      this.eventHandlerNode.setAttribute((xIE4Up?("className"):("class")),'MapImageDrag');
      break;
    case 'ZoomIn':
    case 'ZoomOut':
    case 'ZoomWindow':
    case 'CoordConvSP2LatLon':
    case 'MeasureDistance':
    case 'Markup':
      this.currentCursor = 'MapImageZoom';
      this.eventHandlerNode.setAttribute((xIE4Up?("className"):("class")),'MapImageZoom');
      this.dragEnabled = false;
      break;
    case 'Center':
      this.currentCursor = 'MapImageCenter';
      this.eventHandlerNode.setAttribute((xIE4Up?("className"):("class")),'MapImageCenter');
      break;
    case 'Select':
    case 'SelectWindow':
    case 'BufferXY':
      this.currentCursor = 'MapImageSelect';
      this.eventHandlerNode.setAttribute((xIE4Up?("className"):("class")),'MapImageSelect');
      break;
    default:
      this.dragEnabled = false;
      break;
  }
};

this.setWaiting = function (newState)
{
  //shows or hides the loading image.
  if (newState)
  {
    if (this.mapType == 'MASTER')
      xShow(this.loadImage);
  }
  else
  {
    if (this.mapType == 'MASTER')
      xHide(this.loadImage);
    xMoveTo(this.imageNode,0,0);
    xShow(this.imageNode);
  }
  this.waiting = newState;
  this.eventHandlerNode.setAttribute((xIE4Up?("className"):("class")),((newState)?('MapImageWait'):(this.currentCursor)));
};

/*******************************************/
this.show = function(){xShow(this.element);};
this.hide = function(){xHide(this.element);};
/*******************************************/
this.left = function(){return ((arguments.length > 0)?(xLeft(this.element, arguments[0])):(xLeft(this.element)));};
this.top = function(){return ((arguments.length > 0)?(xTop(this.element, arguments[0])):(xTop(this.imageNode)));};
this.moveTo = function(newXPosition, newYPosition){xMoveTo(this.element,newXPosition, newYPosition);};
/*******************************************/
this.width = function()
{
  if (arguments.length > 0)
  {
    var width = arguments[0];
    var height = this.height();
    this.resizeTo(width,height);
  }
  return xWidth(this.imageNode);
};
this.height = function()
{
  if (arguments.length > 0)
  {
    var width = this.width();
    var height = arguments[0];
    this.resizeTo(width,height);
  }
  return xHeight(this.imageNode);
};
this.resizeTo = function(newWidth, newHeight)
{
  var centerX = Math.floor(0.5*newWidth);
  var centerY = Math.floor(0.5*newHeight);
  
  xResizeTo(this.element, newWidth, newHeight);
  xResizeTo(this.drawPlaneNode, newWidth, newHeight);
  if (this.measureCanvas)
  {
    xResizeTo(this.measureCanvas, newWidth, newHeight);
    this.measureCanvas.width = newWidth;
    this.measureCanvas.height = newHeight;
  }
  xResizeTo(this.rasterDrawPlaneNode, newWidth, newHeight);
  xResizeTo(this.customDrawPlaneNode, newWidth, newHeight);
  xResizeTo(this.zoomWindowNode, newWidth, newHeight);
  xResizeTo(this.eventHandlerNode, newWidth, newHeight);
  xResizeTo(this.imageNode, newWidth, newHeight);
  xMoveTo(this.bufferTargetNode,centerX-25,centerY-25);    
  xMoveTo(this.zoomInTargetNode,centerX-25,centerY-25);    
  xMoveTo(this.zoomOutTargetNode,centerX-25,centerY-25);    
  if ((this.mapType == 'MASTER')&&(this.loadImage != null))
    xMoveTo(this.loadImage,centerX,centerY);
  this.positionDragTiles(newWidth,newHeight);
  for (var i=0;i<this.eventCallbacks['resize'].length;i++)
    if (this.eventCallbacks['resize'][i])
      this.eventCallbacks['resize'][i](newWidth,newHeight);
};

/****************************************************************/
/* Event Callback Functions                                     */
/****************************************************************/
this.clickCallback = function(e)
{
  //pass x position, yposition, width, height and click mode to the map object
  var X = e.offsetX;
  var Y = e.offsetY;
  this.cursorPos_old = this.cursorPos;
  this.cursorPos = [X,Y];
  this.dragPending = false;
  if ((X == this.mouseDownPosition[0]) && (Y == this.mouseDownPosition[1]))
  {
    if (this.mapType == 'SLAVE')
      return this.processSlaveMapClick(X,Y);
    else
    {
      var MapWidth = this.width();
      var MapHeight = this.height();
      var XPercent = X / MapWidth;
      var YPercent = 1.0 -(Y / MapHeight);
      switch (this.mouseMode)
      {
        case 'SelectWindow':
          this.map.click(X,Y,MapWidth,MapHeight,XPercent,YPercent,'Select');
          break;
        case 'ZoomWindow':
          this.map.click(X,Y,MapWidth,MapHeight,XPercent,YPercent,'ZoomIn');
          break;
        case 'DragMap':
          this.map.click(X,Y,MapWidth,MapHeight,XPercent,YPercent,'Center');
          break;
        default:
          this.map.click(X,Y,MapWidth,MapHeight,XPercent,YPercent,this.mouseMode);
          break;
      }
    }
  }
  for (var i=0;i<this.eventCallbacks['click'].length;i++)
    if (this.eventCallbacks['click'][i])
      this.eventCallbacks['click'][i](e);
};

this.processSlaveMapClick = function (newX,newY)
{
  //newX,newY are the local coordinates on the image that were clicked.
  //can calculate the new position based on this and the map extent... 
  var XPercent = newX / this.width();
  var YPercent = 1.0 - (newY / this.height());
  var mapX = (XPercent * (this.map.vmapExtent[3]-this.map.vmapExtent[2])) + this.map.vmapExtent[2];  // XP * ExtentWidth + Left
  var mapY = (YPercent * (this.map.vmapExtent[1]-this.map.vmapExtent[0])) + this.map.vmapExtent[0];  // YP * ExtentHeight + Bottom
  return this.map.centerOnPoint(mapX,mapY);  
};

this.mouseMoveCallback = function(e)
{
  //pass x position, yposition, width, height and click mode to the map object
  var X = e.offsetX;
  var Y = e.offsetY;
  if ((X==this.cursorPos[0])&&(Y==this.cursorPos[1])){return false;};
  this.cursorPos_old = this.cursorPos;
  this.cursorPos = [X,Y];

  if (this.mapType != 'SLAVE')
  {
    var MapWidth = this.width();
    var MapHeight = this.height();
    var XPercent = X / MapWidth;
    var YPercent = 1.0 -(Y / MapHeight);
    switch (this.mouseMode)
    {
      default:
        this.map.mouseMove(X,Y,MapWidth,MapHeight,XPercent,YPercent,this.mouseMode);
        break;
    }
  }
  for (var i=0;i<this.eventCallbacks['mouseMove'].length;i++)
    if (this.eventCallbacks['mouseMove'][i])
      this.eventCallbacks['mouseMove'][i](e);
};

$_this.mouseWheelCallback = function(e){
  var xe = new xEvent(e);
  var X = xe.offsetX;
  var Y = xe.offsetY;
  $_this.cursorPos = [X,Y];
  $_this.dragPending = false;
  var MapWidth = $_this.width();
  var MapHeight = $_this.height();
  var XPercent = X / MapWidth;
  var YPercent = 1.0 -(Y / MapHeight);
  if(e.wheelDelta < 0){
    $_this.map.click(X,Y,MapWidth,MapHeight,XPercent,YPercent,'ZoomOut');
  }
  else{
    $_this.map.click(X,Y,MapWidth,MapHeight,XPercent,YPercent,'ZoomIn');
  }
  if(e.stopPropagation)
    e.stopPropagation();
  if(e.preventDefault)
    e.preventDefault();
  e.cancelBubble = true;
  e.cancel = true;
  e.returnValue = false;
  return false;
};

$_this.keyDownCallback = function(e){
  var xe = new xEvent(e);
  if(xe.target.tagName != 'INPUT' && xe.target.tagName != 'TEXTAREA'){
    var X = xe.offsetX;
    var Y = xe.offsetY;
    $_this.cursorPos = [X,Y];
    $_this.dragPending = false;
    var MapWidth = $_this.width();
    var MapHeight = $_this.height();
    var XPercent = X / MapWidth;
    var YPercent = 1.0 -(Y / MapHeight);

    switch(e.keyCode){
      case 33: //page up
      case 105: //9
        $_this.map.click(X,Y,MapWidth,MapHeight,0.75,0.75,'Center');
        break;
      case 34: //page down
      case 99: //3
        $_this.map.click(X,Y,MapWidth,MapHeight,0.75,0.25,'Center');
        break;
      case 35: //end
      case 97: //1
        $_this.map.click(X,Y,MapWidth,MapHeight,0.25,0.25,'Center');
        break;
      case 36: //home
      case 103: //7
        $_this.map.click(X,Y,MapWidth,MapHeight,0.25,0.75,'Center');
        break;
      case 37: //left
      case 100: //4
        $_this.map.click(X,Y,MapWidth,MapHeight,0.25,0.5,'Center');
        break;
      case 38: //up
      case 104: //8
        $_this.map.click(X,Y,MapWidth,MapHeight,0.5,0.75,'Center');
        break;
      case 39: //right
      case 102: //6
        $_this.map.click(X,Y,MapWidth,MapHeight,0.75,0.5,'Center');
        break;
      case 40: //down
      case 98: //2
        $_this.map.click(X,Y,MapWidth,MapHeight,0.5,0.25,'Center');
        break;
      case 45: //insert
      case 96: //0
        $_this.map.click(X,Y,MapWidth,MapHeight,0.5,0.5,'ZoomOut');
        break;
      case 46: //delete
      case 101: //5
      case 110: //.
        $_this.map.click(X,Y,MapWidth,MapHeight,0.5,0.5,'ZoomIn');
        break;
    }
  }
};

$_this.mouseScrollCallback = function(e){
  var xe = new xEvent(e);
  var X = xe.offsetX;
  var Y = xe.offsetY;
  $_this.cursorPos = [X,Y];
  $_this.dragPending = false;
  var MapWidth = $_this.width();
  var MapHeight = $_this.height();
  var XPercent = X / MapWidth;
  var YPercent = 1.0 -(Y / MapHeight);
  if(e.detail > 0){
    $_this.map.click(X,Y,MapWidth,MapHeight,XPercent,YPercent,'ZoomOut');
  }
  else{
    $_this.map.click(X,Y,MapWidth,MapHeight,XPercent,YPercent,'ZoomIn');
  }
  if(e.stopPropagation)
    e.stopPropagation();
  if(e.preventDefault)
    e.preventDefault();
  e.cancelBubble = true;
  e.cancel = true;
  e.returnValue = false;
  return false;
};

this.processMapDrag = function (dX,dY)
{
  //newX,newY are the local coordinates on the image that were clicked.
  //can calculate the new position based on this and the map extent... 
  this.dragEnabled = false;
  var MapWidth = this.width();
  var MapHeight = this.height();
  var X = (MapWidth*0.5-dX);
  var Y = (MapHeight*0.5-dY);
  var XPercent = X / MapWidth;
  var YPercent = 1.0 -(Y / MapHeight);
  return this.map.click(X,Y,MapWidth,MapHeight,XPercent,YPercent,'Center');  
};

/*******************************************/
this.mouseOverCallback = function(e)
{
  this.cursorPos_old = this.cursorPos;
  this.cursorPos = [-1,-1];
  for (var i=0;i<this.eventCallbacks['mouseOver'].length;i++)
    if (this.eventCallbacks['mouseOver'][i])
      this.eventCallbacks['mouseOver'][i](e);
};

this.mouseOutCallback = function(e)
{
   this.cursorPos_old = this.cursorPos;
   this.cursorPos = [-1,-1];
   //the cursor has moved out of the active map surface.  Abort zoom windows and drag-pans.
   if ((this.mouseMode == 'DragMap')&&this.dragEnabled)
   {
     this.imageNode.src = this.dragTiles[4].src;
     this.positionDragTiles();
   };
   this.dragEnabled = false;
   if (!((e.pageX > xPageX(this.imageNode)) &&
        (e.pageX < (xPageX(this.imageNode)+xWidth(this.imageNode))) &&
        (e.pageY > xPageY(this.imageNode) &&
        (e.pageY < (xPageY(this.imageNode)+xHeight(this.imageNode))))
       ))
      this.zoomBox.setInactive(e.offsetX, e.offsetY);
  for (var i=0;i<this.eventCallbacks['mouseOut'].length;i++)
    if (this.eventCallbacks['mouseOut'][i])
      this.eventCallbacks['mouseOut'][i](e);
};
/*******************************************/
this.mouseUpCallback = function(e){
  this.cursorPos_old = this.cursorPos;
  this.cursorPos = [e.offsetX,e.offsetY];
  for (var i=0;i<this.eventCallbacks['mouseUp'].length;i++)
    if (this.eventCallbacks['mouseUp'][i])
      this.eventCallbacks['mouseUp'][i](e);
};
/*******************************************/
this.mouseDownCallback = function(e){
  this.cursorPos_old = this.cursorPos;
  this.cursorPos = [e.offsetX,e.offsetY];
  this.mouseDownPosition = Array(e.offsetX,e.offsetY);
  for (var i=0;i<this.eventCallbacks['mouseDown'].length;i++)
    if (this.eventCallbacks['mouseDown'][i])
      this.eventCallbacks['mouseDown'][i](e);
};
/*******************************************/
this.dragStartCallback = function(element,xPos,yPos)
{
  switch (this.mouseMode)
  {
    case 'ZoomWindow':
    case 'SelectWindow':
      this.zoomBoxPending = true;
      this.zoomWindowDelta = Array(0,0);
      break;
    case 'DragMap':
      this.dragPending = true;
      this.element.appendChild(this.dragPlaneNode);
      this.positionDragTiles();
      this.dragPendingPosition = new Array(this.mouseDownPosition[0], this.mouseDownPosition[1]);
      this.dragDelta = Array(0,0);
      this.dragTiles[4].src = this.imageNode.src;
      this.imageNode.src = GuiWidget.THEME_PATH+'/'+GuiWidget.THEME+'/images/blank.gif';
      break;
    default:
      break;
  }
  this.dragEnabled = true;
  document.mouseUpCallbackObject = this;
  for (var i=0;i<this.eventCallbacks['dragStart'].length;i++)
    if (this.eventCallbacks['dragStart'][i])
      this.eventCallbacks['dragStart'][i](xPos,yPos);
};

/*******************************************/
this.dragCallback = function(dx,dy)
{
  //if either the zoom window or map drag functions are active, 
  //update the coordinates of either the zoom window or the map image.
  if (this.zoomBoxPending)
  {
    this.zoomBox.setActive(this.mouseDownPosition[0], this.mouseDownPosition[1]);
    this.zoomBoxPending = false;
  }
  if (((this.mouseMode == 'ZoomWindow') || (this.mouseMode == 'SelectWindow')) && (this.zoomBox.isActive) && (this.dragEnabled))
  {
    this.zoomWindowDelta[0] += dx;
    this.zoomWindowDelta[1] += dy;
    this.zoomBox.update(this.mouseDownPosition[0]+this.zoomWindowDelta[0], this.mouseDownPosition[1]+this.zoomWindowDelta[1]);
  }
  if (this.dragPending)
  {
    this.dragStart = Array(this.mouseDownPosition[0], this.mouseDownPosition[1]);
    this.dragPending = false;
  }
  if ((this.mouseMode == 'DragMap') && this.dragEnabled)
  {
    this.dragDelta[0]+=dx;
    this.dragDelta[1]+=dy;
    xMoveTo(this.dragPlaneNode,this.dragDelta[0]-this.width(),this.dragDelta[1]-this.height());
  }
  for (var i=0;i<this.eventCallbacks['drag'].length;i++)
    if (this.eventCallbacks['drag'][i])
      this.eventCallbacks['drag'][i](dx,dy);
};

/*******************************************/
this.dragEndCallback = function(evt, xPos, yPos)
{
  //execute the appropriate functions based on the current map mode.
  if (((this.mouseMode == 'ZoomWindow')||(this.mouseMode == 'SelectWindow'))&&(this.dragEnabled) &&(Math.abs(this.zoomWindowDelta[0])>0) &&(Math.abs(this.zoomWindowDelta[1])>0))
  {
    this.zoomBox.setInactive();
    this.dragEnabled = false;
    this.submitZoomWindow();
  }
  else
    if ((this.mouseMode == 'DragMap')&&(this.dragEnabled))
    {
      this.processMapDrag(this.dragDelta[0],this.dragDelta[1]);
    }
  for (var i=0;i<this.eventCallbacks['dragEnd'].length;i++)
    if (this.eventCallbacks['dragEnd'][i])
      this.eventCallbacks['dragEnd'][i](xPos,yPos);
    
};

this.submitZoomWindow = function()
{
  var MapWidth = this.width();
  var MapHeight = this.height();
  var x1 = this.mouseDownPosition[0];
  var y1 = this.mouseDownPosition[1];
  var x2 = this.mouseDownPosition[0]+this.zoomWindowDelta[0];
  var y2 = this.mouseDownPosition[1]+this.zoomWindowDelta[1];
  
  if(x1 < x2)
  {
    var left = x1;
    var right = x2;
  }
  else
  {
    var left = x2;
    var right = x1;
  } 
  if(y1 < y2)  // use reverse direction since web is flipped from gis
  {
    var top = y1;
    var bottom = y2;
  }
  else
  {
    var top = y2;
    var bottom = y1;
  }
  switch (this.mapType)
  {
    case 'MASTER':
      var the_bottom = 1.0 -(bottom / MapHeight);
      var the_top    = 1.0 -(top / MapHeight);
      var the_left   = left / MapWidth;
      var the_right  = right / MapWidth;
      
      switch (this.mouseMode)
      {
        case 'SelectWindow':
          this.map.selectByWindow(the_bottom,the_top,the_left,the_right);
          break;
        case 'ZoomWindow':
          this.map.zoomToWindow(the_bottom,the_top,the_left,the_right);
          break;
      }
      break;
    case 'SLAVE':
      var x1Percent = left / MapWidth;
      var x2Percent = right / MapWidth;
      var y1Percent = 1.0 - (top / MapHeight);
      var y2Percent = 1.0 - (bottom / MapHeight);
      var mapX1 = (x1Percent * (this.map.vmapExtent[3]-this.map.vmapExtent[2])) + this.map.vmapExtent[2];
      var mapX2 = (x2Percent * (this.map.vmapExtent[3]-this.map.vmapExtent[2])) + this.map.vmapExtent[2];
      var mapY1 = (y1Percent * (this.map.vmapExtent[1]-this.map.vmapExtent[0])) + this.map.vmapExtent[0];
      var mapY2 = (y2Percent * (this.map.vmapExtent[1]-this.map.vmapExtent[0])) + this.map.vmapExtent[0];
      this.map.zoomToExtent(Array(mapY2,mapY1,mapX1,mapX2));    
      break;
  }
};

this.showBufferTarget = function(){this.bufferTargetNode.style.display = 'block';};
this.hideBufferTarget = function(){this.bufferTargetNode.style.display = 'none';};
this.showZoomInTarget = function(){this.zoomInTargetNode.style.display = 'block';};
this.hideZoomInTarget = function(){this.zoomInTargetNode.style.display = 'none';};
this.showZoomOutTarget = function(){this.zoomOutTargetNode.style.display = 'block';};
this.hideZoomOutTarget = function(){this.zoomOutTargetNode.style.display = 'none';};
this.showCompass = function(){this.compassNode.style.display = 'block';};
this.hideCompass = function(){this.compassNode.style.display = 'none';};  

this.clearDragTiles = function()
{
  for (var i=0;i<this.dragTiles.length;i++)
    this.dragTiles[i].src = GuiWidget.THEME_PATH+'/'+GuiWidget.THEME+'/images/blank.gif';
};

this.positionDragTiles = function()
{
  var width = (arguments.length>0)?arguments[0]:this.width();
  var height = (arguments.length>1)?arguments[1]:this.height();
  xLeft(this.dragPlaneNode,-width);
  xTop(this.dragPlaneNode,-height);
  xWidth(this.dragPlaneNode,width*3);
  xHeight(this.dragPlaneNode,height*3);
  var currentTile = null;
  for (var x=0;x<3;x++)
  {
    for (var y=0;y<3;y++)
    {
      currentTile = this.dragTiles[x+y*3];
      xLeft(currentTile,x*width);
      xTop(currentTile,y*height);
      xWidth(currentTile,width);
      xHeight(currentTile,height);
    }
  }
};


/*******************************************************************************
**  INITIALIZATION CODE
*********************************/
  this.element = document.createElement("DIV");
  this.element.id = this.id;
  this.element.objectManagerId = OBJECT_MANAGER.registerObject(this.id, this);
  if (this.parentElement == null)
    document.getElementsByTagName("body").item(0).appendChild(this.element); 
  else
  	this.parentElement.appendChild(this.element);
  xLeft(this.element,newXPosition);
  xTop(this.element, newYPosition);
  xZIndex(this.element,newZIndex);
  xWidth(this.element,newWidth);
  xHeight(this.element,newHeight);
  if (newVisibility)
    xShow(this.element);
  else
    xHide(this.element);
  this.imageNode = document.createElement("IMG");
  this.dragPlaneNode = document.createElement("DIV");
  this.dragPlaneNode.setAttribute('id','dragPlaneNode');
  this.dragTiles = Array();
  for (var i=0;i<9;i++){
    this.dragTiles.push(document.createElement("IMG"));
    this.dragTiles[i].setAttribute((xIE4Up?("className"):("class")),'MapImage');
    this.dragTiles[i].setAttribute('id','MapImage.dragTiles['+i+']');
    this.dragTiles[i].src = GuiWidget.THEME_PATH+'/'+GuiWidget.THEME+'/images/blank.gif';
    this.dragPlaneNode.appendChild(this.dragTiles[i]);
  }
  this.clearDragTiles();  
  this.drawPlaneNode = document.createElement("DIV");
  try{
    var canvasElement = document.createElement("CANVAS");
    this.element.appendChild(canvasElement);
    if (typeof(G_vmlCanvasManager) != "undefined") {
      canvasElement = G_vmlCanvasManager.initElement(canvasElement);
    }
    this.measureCanvas = canvasElement;
    this.measureCanvas.getContext("2d");
  }catch(e)
  {
    //alert('canvas could not be initialized\n'+describeObject('',e,'\n'));
    this.measureCanvas = null;
  }
  this.customDrawPlaneNode = document.createElement("DIV");
  this.rasterDrawPlaneNode = document.createElement("DIV");
  this.eventHandlerNode = document.createElement("IMG");
  this.zoomWindowNode = document.createElement("DIV");
  
  this.bufferTargetNode = document.createElement('DIV');
  this.bufferTargetIMG = document.createElement("IMG");
  this.bufferTargetNode.appendChild(this.bufferTargetIMG);
  
  this.zoomInTargetNode = document.createElement('DIV');
  this.zoomInTargetIMG = document.createElement("IMG");
  this.zoomInTargetNode.appendChild(this.zoomInTargetIMG);
  
  this.zoomOutTargetNode = document.createElement('DIV');
  this.zoomOutTargetIMG = document.createElement("IMG");
  this.zoomOutTargetNode.appendChild(this.zoomOutTargetIMG);
  
  this.compassNode = document.createElement(((xIE4Up)?('DIV'):('IMG')));
  this.productLogoNode = document.createElement(((xIE4Up)?('DIV'):('IMG')));
  this.loadImage = document.createElement('IMG'); //animated gif

  //assemble the main object
  this.element.appendChild(this.imageNode);
  this.element.appendChild(this.drawPlaneNode);
  this.element.appendChild(this.customDrawPlaneNode);
  this.element.appendChild(this.rasterDrawPlaneNode);
  this.element.appendChild(this.eventHandlerNode);
  this.element.appendChild(this.zoomWindowNode);
  
  //Assemble map overlay images
  this.rasterDrawPlaneNode.appendChild(this.loadImage);
  this.rasterDrawPlaneNode.appendChild(this.bufferTargetNode);
  this.rasterDrawPlaneNode.appendChild(this.zoomInTargetNode);
  this.rasterDrawPlaneNode.appendChild(this.zoomOutTargetNode);
  this.rasterDrawPlaneNode.appendChild(this.compassNode);
  this.rasterDrawPlaneNode.appendChild(this.productLogoNode);
  this.rasterDrawPlaneNode.style.overflow = 'hidden';
  this.rasterDrawPlaneNode.style.width = 50;
  this.rasterDrawPlaneNode.style.height = 50;
  
  this.eventHandlerNode.src = GuiWidget.THEME_PATH+'/'+GuiWidget.THEME+'/images/blank.gif';
  this.resizeTo(newWidth, newHeight);
  
  //set load image attributes
  var centerX = Math.floor(0.5*newWidth);
  var centerY = Math.floor(0.5*newHeight);
  this.loadImage.id = this.id+'.loadImage';
  this.loadImage.src = GuiWidget.THEME_PATH+'/'+GuiWidget.THEME+'/images/mapLoad.gif';
  this.loadImage.style.position = 'absolute';
  this.loadImage.style.width = _MapLoadImageWidth;
  this.loadImage.style.height = _MapLoadImageHeight;
  xMoveTo(this.loadImage,centerX-0.5*_MapLoadImageWidth,centerY-0.5*_MapLoadImageHeight);
  this.loadImage.style.display = ((this.mapType == 'MASTER')?('block'):('none'));
  
  //set map overlay attributes
  this.bufferTargetNode.style.position = this.zoomInTargetNode.style.position = this.zoomOutTargetNode.style.position = this.compassNode.style.position = 'absolute';
  
  this.bufferTargetNode.style.display=this.zoomInTargetNode.style.display=this.zoomOutTargetNode.style.display = 'none';
  this.compassNode.style.display = 'none';
  this.compassNode.style.width = 50;
  this.compassNode.style.height = 200;
  this.compassNode.style.top = -145;
  this.compassNode.style.right = 5;
  this.productLogoNode.style.position = 'absolute';
  this.productLogoNode.style.display = ((this.mapType=='MASTER')?('block'):('none'));
  if (xIE4Up)
  {
    this.productLogoNode.style.width = _MapProductLogoWidth;
    this.productLogoNode.style.height = _MapProductLogoHeight;
  }
  this.productLogoNode.style.right = 5;
  this.productLogoNode.style.bottom = 5;


  //fix internet explorer 6 problem with 24-bit png map overlays
  if (xIE4Up) //fix png
  {
    this.bufferTargetIMG.style.filter = 'progid:DXImageTransform.Microsoft.AlphaImageLoader(src=\''+GuiWidget.THEME_PATH+'/'+GuiWidget.THEME+'/images/target.png'+'\', sizingMethod=\'image\')';
    this.zoomInTargetIMG.style.filter = 'progid:DXImageTransform.Microsoft.AlphaImageLoader(src=\''+GuiWidget.THEME_PATH+'/'+GuiWidget.THEME+'/images/target.png'+'\', sizingMethod=\'image\')';
    this.zoomOutTargetIMG.style.filter = 'progid:DXImageTransform.Microsoft.AlphaImageLoader(src=\''+GuiWidget.THEME_PATH+'/'+GuiWidget.THEME+'/images/target.png'+'\', sizingMethod=\'image\')';
    this.compassNode.style.filter = 'progid:DXImageTransform.Microsoft.AlphaImageLoader(src=\''+GuiWidget.THEME_PATH+'/'+GuiWidget.THEME+'/images/target.png'+'\', sizingMethod=\'image\')';
    this.productLogoNode.style.filter = 'progid:DXImageTransform.Microsoft.AlphaImageLoader(src=\''+GuiWidget.THEME_PATH+'/'+GuiWidget.THEME+'/images/mapProductLogo.png'+'\', sizingMethod=\'image\')';
	this.bufferTargetIMG.src = GuiWidget.THEME_PATH+'/'+GuiWidget.THEME+'/images/blank.gif';
    this.zoomInTargetIMG.src = GuiWidget.THEME_PATH+'/'+GuiWidget.THEME+'/images/blank.gif';
    this.zoomOutTargetIMG.src = GuiWidget.THEME_PATH+'/'+GuiWidget.THEME+'/images/blank.gif';
    this.compassNode.src = GuiWidget.THEME_PATH+'/'+GuiWidget.THEME+'/images/blank.gif';
    this.productLogoNode.src = GuiWidget.THEME_PATH+'/'+GuiWidget.THEME+'/images/mapProductLogo.png';
  }
  else
  {
    this.bufferTargetIMG.src = GuiWidget.THEME_PATH+'/'+GuiWidget.THEME+'/images/target.png';
    this.zoomInTargetIMG.src = GuiWidget.THEME_PATH+'/'+GuiWidget.THEME+'/images/target.png';
    this.zoomOutTargetIMG.src = GuiWidget.THEME_PATH+'/'+GuiWidget.THEME+'/images/target.png';
    this.compassNode.src = GuiWidget.THEME_PATH+'/'+GuiWidget.THEME+'/images/target.png';
    this.productLogoNode.src = GuiWidget.THEME_PATH+'/'+GuiWidget.THEME+'/images/mapProductLogo.png';
  }
  this.eventHandlerNode.mapImageObject = this;
  
  this.imageNode.setAttribute((xIE4Up?("className"):("class")),'MapImage');
  this.dragPlaneNode.setAttribute((xIE4Up?("className"):("class")),'MapImage');
  this.drawPlaneNode.setAttribute((xIE4Up?("className"):("class")),'MapImage');
  if (this.measureCanvas)
    this.measureCanvas.setAttribute((xIE4Up?("className"):("class")),'MapImage');
  this.rasterDrawPlaneNode.setAttribute((xIE4Up?("className"):("class")),'MapImage');
  this.customDrawPlaneNode.setAttribute((xIE4Up?("className"):("class")),'MapImage');
  this.zoomWindowNode.setAttribute((xIE4Up?("className"):("class")),'MapImage');
  this.eventHandlerNode.setAttribute((xIE4Up?("className"):("class")),'MapImage');
  
  this.imageNode.id = this.id+'.imageNode';
  this.drawPlaneNode.id = this.id+'.drawPlaneNode';
  this.rasterDrawPlaneNode.id = this.id+'.rasterDrawPlaneNode';
  this.eventHandlerNode.id = this.id+'.eventHandlerNode';
  this.bufferTargetNode.id = this.id+'.bufferTargetImage';
  this.zoomInTargetNode.id = this.id+'.zoomInTargetImage';
  this.zoomOutTargetNode.id = this.id+'.zoomOutTargetImage';
  this.productLogoNode.id = this.id+'.productLogoImage';
  
  this.imageNode.style.position = this.dragPlaneNode.style.position = this.drawPlaneNode.style.position = this.rasterDrawPlaneNode.style.position = this.customDrawPlaneNode.style.position = 'absolute';
  this.zoomInTargetIMG.style.top = -100;
  this.zoomOutTargetIMG.style.top = -50;
  this.bufferTargetIMG.style.top = 0;
  this.zoomInTargetIMG.style.position = this.bufferTargetIMG.style.position = this.zoomOutTargetIMG.style.position = 'relative';
  this.zoomInTargetIMG.style.width = this.bufferTargetIMG.style.width = this.zoomOutTargetIMG.style.width = 50;
  this.zoomInTargetIMG.style.height = this.bufferTargetIMG.style.height = this.zoomOutTargetIMG.style.height = 200;
  this.zoomInTargetNode.style.overflow = this.bufferTargetNode.style.overflow = this.zoomOutTargetNode.style.overflow  = 'hidden';
  this.zoomInTargetNode.style.height = this.bufferTargetNode.style.height = this.zoomOutTargetNode.style.height = 50;
  
  this.imageNode.id = this.id+'.imageNode';
  this.drawPlaneNode.id = this.id+'.drawPlaneNode';
  this.rasterDrawPlaneNode.id = this.id+'.rasterDrawPlaneNode';
  this.eventHandlerNode.id = this.id+'.eventHandlerNode';
  this.bufferTargetNode.id = this.id+'.bufferTargetImage';
  this.zoomInTargetNode.id = this.id+'.zoomInTargetImage';
  this.zoomOutTargetNode.id = this.id+'.zoomOutTargetImage';
  this.productLogoNode.id = this.id+'.productLogoImage';
  
  if (this.measureCanvas)
    this.measureCanvas.style.position = 'absolute';
  xZIndex(this.dragPlaneNode,0);
  xZIndex(this.imageNode,1);
  xZIndex(this.drawPlaneNode,2); 
  xZIndex(this.customDrawPlaneNode,3); 
  xZIndex(this.rasterDrawPlaneNode,4); 
  xZIndex(this.zoomWindowNode,5); 
  if (this.measureCanvas)
    xZIndex(this.measureCanvas,6); 
  xZIndex(this.eventHandlerNode,7);
  
  xMoveTo(this.imageNode, 0,0);
  //xMoveTo(this.dragPlaneNode, -newWidth,-newHeight);
  xMoveTo(this.drawPlaneNode, 0,0);
  xMoveTo(this.rasterDrawPlaneNode, 0,0);
  xMoveTo(this.zoomWindowNode, 0,0);
  if (this.measureCanvas)
    xMoveTo(this.measureCanvas, 0,0);
  xMoveTo(this.eventHandlerNode, 0,0);
  var targetX = centerX-25; 
  var targetY = centerY-25;
  xMoveTo(this.bufferTargetNode,targetX,targetY);
  xMoveTo(this.zoomInTargetNode,targetX,targetY);
  xMoveTo(this.zoomOutTargetNode,targetX,targetY);
  
  //The zoom window
  this.zoomBox = new ZoomBox(this.id+".zoomWindow", this.zoomWindowNode, 0, 0, this);
  
  //set up event listeners
  this.eventHandlerNode.mapImage = this;
  xAddEventListener(this.eventHandlerNode, 'click', function(e){$_this.clickCallback(new xEvent(e));}, false);
  xAddEventListener(this.eventHandlerNode, 'mouseover', function(e){$_this.mouseOverCallback(new xEvent(e));}, false);
  xAddEventListener(this.eventHandlerNode, 'mouseout', function(e){$_this.mouseOutCallback(new xEvent(e));}, false);
  xAddEventListener(this.eventHandlerNode, 'mouseup', function(e){$_this.mouseUpCallback(new xEvent(e));}, false);
  xAddEventListener(this.eventHandlerNode, 'mousedown', function(e){$_this.mouseDownCallback(new xEvent(e));}, false);
  xAddEventListener(this.eventHandlerNode, 'mousemove', function(e){$_this.mouseMoveCallback(new xEvent(e));}, false);
  if(this.mapType == 'MASTER'){
    xAddEventListener(this.eventHandlerNode, 'mousewheel', $_this.mouseWheelCallback, false);
    xAddEventListener(this.eventHandlerNode, 'DOMMouseScroll', $_this.mouseScrollCallback, false);
    xAddEventListener(document, 'keydown', $_this.keyDownCallback, true);
  }
  xEnableDrag(this.eventHandlerNode,
    function(element,dx,dy){$_this.dragStartCallback(dx,dy);},
    function(element,dx,dy){$_this.dragCallback(dx,dy);},
    function(element,dx,dy){$_this.dragEndCallback(dx,dy);}
  );
  setClass(this.element,'MapImageContainer');
  //force set vicinity maps to zoom window mode.  if the user clicks the map, will recenter at current zoom extent
  if (this.mapType == 'SLAVE')
    this.setMouseMode('ZoomWindow');
};}
/* FILE:FreeanceWeb/Client/PublicKiosk1/lib/MapLib/ZoomBar.js */ if(!window.freeance_loaded_js['2f91c28280cf481fb8796cde9b9ffda0']){window.freeance_loaded_js['2f91c28280cf481fb8796cde9b9ffda0']=1;
ZoomBar = function(newID, newParent, newXPosition, newYPosition, newZIndex, newVisibility, mapObject, ratio, newHeight,startColor,endColor,activeColor)
{
  if (arguments.length > 0)
    this.init(newID, newParent, newXPosition, newYPosition, newZIndex, newVisibility, mapObject, ratio, newHeight,startColor,endColor,activeColor);
};

ZoomBar.prototype = new GuiWidget();
ZoomBar.prototype.constructor = ZoomBar;
ZoomBar.superclass = GuiWidget.prototype;

ZoomBar.prototype.init = function(newID, newParent, newXPosition, newYPosition, newZIndex, newVisibility, newMapObject, ratio, newHeight,startColor,endColor,activeColor)
{
  this._WIDTH = 15;
  this._DIVHEIGHT = 11;
  ZoomBar.superclass.init.call(this, newID, newParent, newXPosition, newYPosition, newZIndex, this._WIDTH, newHeight, newVisibility, "zoomBar");
  this.ratio = ratio;
  this.numDivs = parseInt((newHeight-50) / this._DIVHEIGHT);
  this.startColor = startColor;
  this.endColor = endColor;
  this.mapObject = newMapObject;
  this.mapObject.zoomBar = this;
  this.divStats = null;  //will be an object containing info about each div
  this.divColors = null;
  this.activeDiv = null;
  this.activeColor = activeColor;
  this.activeDivColor = null;
  this.activeZoomTarget = null;
  this.initialized = false;
};

ZoomBar.prototype.initialize = function()
{
  //build initial zoom bar
  this.initialMapArea = Math.abs((this.mapObject.initialExtent[1]-this.mapObject.initialExtent[0])*(this.mapObject.initialExtent[3]-this.mapObject.initialExtent[2]));
  this.updateIntervals();
  this.draw();
  this.initialized = true;
};

ZoomBar.prototype.updateIntervals = function()
{
  if (this.mapObject==null)
    return;
  if ((this.mapObject.initialExtent==null)||(this.mapObject.extent==null))
    return;
  //recompute the value of each zoom bar div based on the starting extent and div count
  this.divStats = new Array();
  var Bottom = this.mapObject.extent[0];
  var Top = this.mapObject.extent[1];
  var Left = this.mapObject.extent[2];
  var Right = this.mapObject.extent[3];

  var CenterY = Bottom+((Top - Bottom)/2.0);
  var CenterX = Left+((Right - Left)/2.0);
  var FullBottom = this.mapObject.initialExtent[0];
  var FullTop = this.mapObject.initialExtent[1];
  var FullLeft = this.mapObject.initialExtent[2];
  var FullRight = this.mapObject.initialExtent[3];
  var FullHeight = FullTop - FullBottom;
  var FullWidth = FullRight - FullLeft;
  
  var NumDivisions = this.numDivs;
  var Ratio = this.ratio;
  
  var SumTheDivs = 0;
  var SomeExtentWidth = 0;
  var SomeExtentHeight = 0;
  var dx = 0;
  var dy = 0;
  var subfactor = 0;
  var ZoombarWidth = 0;
  var ZoombarHeight = 0;

  var newBottom = 0; 
  var newTop = 0;
  var newLeft = 0;
  var newRight = 0;
  
  for (var Division = 0; Division < NumDivisions; Division++)
  {
    if (Division == (NumDivisions-1)) // go to full extent direct to avoid rounding errors
    {
      newBottom = FullBottom;
      newTop = FullTop;
      newLeft = FullLeft;
      newRight = FullRight;
    }
    else
    {
      /* Why was this? */
      SumTheDivs = 0;
      for (lcv = NumDivisions-1; lcv > 0; lcv--)
        SumTheDivs = SumTheDivs + lcv;
      if (SumTheDivs <= 0)    // error here
        alert('Unknown Error in ZoomBar.updateIntervals');
        
      /* What is this?? */
      SomeExtentWidth = Ratio * FullWidth;
      SomeExtentHeight = Ratio * FullHeight;
      dx = (FullWidth - SomeExtentWidth)/(SumTheDivs);
      dy = (FullHeight - SomeExtentHeight)/(SumTheDivs);
      /* Don't know... */
      subfactor = 0;
      for (lcv = NumDivisions-1; lcv >= Division; lcv--)
        subfactor = subfactor + lcv;
      /* At least I recall variables now */
      ZoombarWidth = FullWidth - (dx * subfactor);
      ZoombarHeight = FullHeight - (dy * subfactor);
      /* Finally */
      newBottom = CenterY - (ZoombarHeight / 2.0);
      newTop = CenterY + (ZoombarHeight / 2.0);
      newLeft = CenterX - (ZoombarWidth / 2.0);
      newRight = CenterX + (ZoombarWidth / 2.0);
    }    
    this.divStats[Division] = Math.abs((newTop-newBottom)*(newRight-newLeft));
  }
};

ZoomBar.prototype.highlightNearestDiv = function()
{
  if (this.initialized)
  {
    //calculate the area of the current extent
    var currentArea = Math.abs((this.mapObject.extent[1]-this.mapObject.extent[0])*(this.mapObject.extent[3]-this.mapObject.extent[2]));
    //loop through divStats array to find closest area
    var bestGuessDiv = -1;
    var oldBestGuess = -1;
    for (var currentDiv = 0; currentDiv < this.divStats.length; currentDiv++)
    {
      if (currentArea<=this.divStats[currentDiv])
      {
        bestGuessDiv = currentDiv;
        if (currentDiv < (this.divStats.length-1))
        {
          if (Math.abs(currentArea-this.divStats[currentDiv])<Math.abs(currentArea-this.divStats[currentDiv+1]))
            bestGuessDiv++;
        }
        break;
      }
    }
    if ((bestGuessDiv==-1)||(bestGuessDiv>=this.divStats.length))
    {
      bestGuessDiv=this.divStats.length-1;
    }
    else
    {
      if ((bestGuessDiv>0)&&(bestGuessDiv<this.divStats.length))
        bestGuessDiv--;
    }
    if (this.activeDiv != null) //fix old div color
    {
      var element = document.getElementById(this.id+'.zoomBarDiv['+this.activeDiv+']');
      if (element!=null)
        element.style["backgroundColor"] = this.activeDivColor;
    }
    var element = document.getElementById(this.id+'.zoomBarDiv['+bestGuessDiv+']');
    if (element!=null)  //update div
    {
      this.activeDivColor = element.style["backgroundColor"];
      element.style["backgroundColor"] = this.activeColor;
      this.activeDiv = bestGuessDiv;
    }
    else
    {
      this.activeDiv = null;
      this.activeColor = null;
    }
  }
};

ZoomBar.prototype.draw = function()
{
  this.divColors = linearGradient(this.startColor, this.endColor,this.numDivs);
  var html = '<TABLE cellpadding="0" cellspacing="2"><TR height="15px">'+
  '<TD style="text-align: center; cursor: pointer;" width="10px" onmouseover="document.mapObject.mapImage.showZoomInTarget();" onmouseout="document.mapObject.mapImage.hideZoomInTarget();" onclick="document.mapObject.zoomIn();"><div style="width:10px;height:10px;overflow:hidden;"><IMG style="height:40px;width:10px;top:-20px;position:relative;" src="./'+GuiWidget.THEME_PATH+'/'+GuiWidget.THEME+'/images/'+'miniIcon.png" /></div></TD></TR>';
  for (var lcv=0;lcv < this.numDivs;lcv++)
  {
    html = html + '<TR>'+
    '<TD id="'+this.id+'.zoomBarDiv['+lcv+']" height="'+this._DIVHEIGHT+'" class="zoomBarCell">'+
    '<IMG src="./'+GuiWidget.THEME_PATH+'/'+GuiWidget.THEME+'/images/'+'blank.gif" class="zoomBarCell" height="5" width="10" onmouseover="document.mapObject.zoomBar.mouseOverDiv('+lcv+'); this.src = \'./'+GuiWidget.THEME_PATH+'/'+GuiWidget.THEME+'/images/'+'zoomBarHighlight.gif\';" onmouseout="document.mapObject.zoomBar.mouseOutDiv('+lcv+'); this.src=\'./'+GuiWidget.THEME_PATH+'/'+GuiWidget.THEME+'/images/blank.gif\'" onclick="document.mapObject.zoomBar.mouseClickDiv('+lcv+'); document.mapObject.zoombar('+this.ratio+','+lcv+','+this.numDivs+');"></TD></TR>';
  }
  html = html + '<TR height="15px"><TD style="text-align: center; cursor: pointer;" onmouseover="document.mapObject.mapImage.showZoomOutTarget();" onmouseout="document.mapObject.mapImage.hideZoomOutTarget();"  onclick="document.mapObject.zoomOut();"><div style="width:10px;height:10px;overflow:hidden;"><IMG style="height:40px;width:10px;top:-10px;position:relative;" src="./'+GuiWidget.THEME_PATH+'/'+GuiWidget.THEME+'/images/'+'miniIcon.png" /></div></TD></TR></TABLE>';
  this.element.innerHTML = html;
  var element = null;
  for (var lcv=0;lcv < this.numDivs;lcv++)
  {
    element = document.getElementById(this.id+'.zoomBarDiv['+lcv+']');
    if (element!=null)
    {
      element.style.background = this.divColors[lcv];
    }
  };
  this.activeDiv = null;
  this.activeDivColor = null;
};

ZoomBar.prototype.rebuild = function(newHeight)
{
  this.height(newHeight);
  this.width(this._WIDTH);
  this.numDivs = parseInt((newHeight-50) / this._DIVHEIGHT);
  this.updateIntervals();
  this.draw();
  this.highlightNearestDiv();
};

ZoomBar.prototype.mouseOverDiv = function(divIndex)
{
  //show appropriate zoom target on the map
  if (document.extensionConfig.zoomOverlay.enabled)
  {
  if (this.activeDiv != null)
  {
    if (divIndex < this.activeDiv)
    {
      this.mapObject.mapImage.showZoomInTarget();
      this.activeZoomTarget = 'zoomIn';
    }
    else
    {
      if (divIndex == this.activeDiv)
      {
        this.activeZoomTarget = '';
      }
      else
      {
        this.mapObject.mapImage.showZoomOutTarget();
        this.activeZoomTarget = 'zoomOut';
      }
    }
  }
  }
};

ZoomBar.prototype.mouseOutDiv = function(divIndex)
{
  //hide zoom target again
  if (document.extensionConfig.zoomOverlay.enabled)
  {
    switch (this.activeZoomTarget)
    {
      case 'zoomIn':
        this.mapObject.mapImage.hideZoomInTarget();
        break;
      case 'zoomOut':
        this.mapObject.mapImage.hideZoomOutTarget();
        break;
    }
  }
};

ZoomBar.prototype.mouseClickDiv = function(divIndex)
{
  //hide zoom target again
  if (document.extensionConfig.zoomOverlay.enabled)
  {
    switch (this.activeZoomTarget)
    {
      case 'zoomIn':
        this.mapObject.mapImage.hideZoomInTarget();
        break;
      case 'zoomOut':
        this.mapObject.mapImage.hideZoomOutTarget();
        break;
    }
  }
};}
/* FILE:FreeanceWeb/Client/PublicKiosk1/lib/MapLib/Scalebar.js */ if(!window.freeance_loaded_js['a6eacebf7108af6a553b48025e32f97e']){window.freeance_loaded_js['a6eacebf7108af6a553b48025e32f97e']=1;
//Scalebar.js
//Draw a scale bar on the map
//Config definition:
//Array of Array(<units_top>,<unitSize_top>,<top_in_mapUnits>,<units_bottom>,<unitSize_bottom>,<bottom_in_mapUnits>,<maximum width of map in map units>);
//units_top is the unit the top bar uses; unitSize_top is the length of the top bar in the specified units
//maxBarWidth is the maximum width of the map in map units to display this zoom bar

function Scalebar(){
  var _FT_=0;
  var _YD_=1;
  var _MI_=2;
  var _M_ =3;
  var _KM_=4;
  var _LL_=5;
  var unitLookup={'FT':_FT_,'YD':_YD_,'M':_M_,'MI':_MI_,'KM':_KM_,'LL':_LL_};
  var unitLabels=Array('FT','YD','MI','m','km');
  document.mapObject.scalebar = this;
  this.element = null;
  this.initialize = function()
  {
    if(document.applicationConfig.mapUnits=='LL') return null;
    this.mapObject = document.mapObject;
    this.mapImage = this.mapObject.mapImage;
    if (this.element==null)
      this.createElements();
    this.baseUnits = unitLookup[document.applicationConfig.mapUnits];

    this.config = new Array();
    if (this.mapObject.config.scalebarConfig==null)
    {
      //unit conversion populates config[2] and config[5]
      this.config[0] = new Array(_FT_,10,null,_M_,1,null,250);
      this.config[1] = new Array(_FT_,100,null,_M_,10,null,500);
      this.config[2] = new Array(_FT_,200,null,_M_,50,null,2000);
      this.config[3] = new Array(_FT_,500,null,_M_,100,null,3000);
      this.config[4] = new Array(_FT_,1000,null,_M_,250,null,6000);
      this.config[5] = new Array(_MI_,1,null,_KM_,1,null,25000);
      this.config[6] = new Array(_MI_,2,null,_KM_,2,null,50000);
      this.config[7] = new Array(_MI_,2.5,null,_KM_,2.5,null,90000);
      this.config[8] = new Array(_MI_,5,null,_KM_,5,null,110000);
    }
    else
    {
      for (var lcv=0;lcv<this.mapObject.config.scalebarConfig.length;lcv++)
      {
        this.config[lcv] = new Array(this.mapObject.config.scalebarConfig[lcv][0],this.mapObject.config.scalebarConfig[lcv][1],null,this.mapObject.config.scalebarConfig[lcv][2],this.mapObject.config.scalebarConfig[lcv][3],null,this.mapObject.config.scalebarConfig[lcv][4]);
      }
    }
    for (var lcv=0;lcv<this.config.length; lcv++)
    {
      this.config[lcv][2]=this.convertUnits(this.config[lcv][1],this.config[lcv][0],this.baseUnits);
      this.config[lcv][5]=this.convertUnits(this.config[lcv][4],this.config[lcv][3],this.baseUnits);
    }
  };
  
  this.createElements = function()
  {
    this.element = document.createElement('DIV');
    this.mapImage.rasterDrawPlaneNode.appendChild(this.element);
    
    this.element.id = this.mapObject.id+'.scalebar';
    this.element.style.position = 'absolute';
    this.element.style.display = 'none';
    this.element.style.height = 30;
    this.element.style.bottom = 10;
    this.element.style.left = 10;
    this.element.style.width = 100;
    this.element.style["font"] = '7pt Helvetica, sans-serif';
    
    this.leftBarElement = document.createElement('DIV');
    this.element.appendChild(this.leftBarElement);
    this.leftBarElement.style.position = 'absolute';
    this.leftBarElement.style.backgroundColor = '#000000';
    this.leftBarElement.style.top = 0;
    this.leftBarElement.style.left = 0;
    this.leftBarElement.style.width = xIE4Up?4:2;
    this.leftBarElement.style.height = 30;
    this.leftBarElement.style.borderWidth = 1;
    this.leftBarElement.style.borderColor = '#FFFFFF';
    this.leftBarElement.style.borderStyle = 'solid';
    
    this.barElement = document.createElement('DIV');
    this.element.appendChild(this.barElement);
    
    this.barElement.style.position = 'absolute';
    this.barElement.style.display = 'block';
    this.barElement.style.height = xIE4Up?4:2;
    this.barElement.style.width = 100;
    this.barElement.style.backgroundColor = '#000000';
    this.barElement.style.top = 14;
    this.barElement.style.left = 3;
    this.barElement.style.borderTopWidth = 1;
    this.barElement.style.borderBottomWidth = 1;
    this.barElement.style.borderRightWidth = 1;
    this.barElement.style.borderLeftWidth = 0;
    this.barElement.style.borderColor = '#FFFFFF';
    this.barElement.style.borderStyle = 'solid';
    this.barElement.style.overflow = 'hidden'; //stop IE from ignoring height
    
    this.topLabelElement = document.createElement('DIV');
    this.element.appendChild(this.topLabelElement);
    this.topLabelElement.style.position = 'absolute';
    this.topLabelElement.style.display = 'block';
    this.topLabelElement.style.height = 12;
    this.topLabelElement.style.left=4;
    this.topLabelElement.style.bottom = 16;
    
    this.upperBarElement = document.createElement('DIV');
    this.element.appendChild(this.upperBarElement);
    this.upperBarElement.style.position = 'absolute';
    this.upperBarElement.style.display = 'block';
    this.upperBarElement.style.width = xIE4Up?4:2;
    this.upperBarElement.style.height = xIE4Up?11:10;
    this.upperBarElement.style.top = 4;
    this.upperBarElement.style.left = 2;
    this.upperBarElement.style.backgroundColor = '#000000';
    this.upperBarElement.style.borderTopWidth = 1;
    this.upperBarElement.style.borderBottomWidth = 0;
    this.upperBarElement.style.borderRightWidth = 1;
    this.upperBarElement.style.borderLeftWidth = 1;
    this.upperBarElement.style.borderColor = '#FFFFFF';
    this.upperBarElement.style.borderStyle = 'solid';
    this.upperBarElement.style.overflow = 'hidden'; //stop IE from ignoring height
    
    this.bottomLabelElement = document.createElement('DIV');
    this.element.appendChild(this.bottomLabelElement);
    this.bottomLabelElement.style.position = 'absolute';
    this.bottomLabelElement.style.display = 'block';
    this.bottomLabelElement.style.top=17;
    this.bottomLabelElement.style.left=4;

    this.lowerBarElement = document.createElement('DIV');
    this.element.appendChild(this.lowerBarElement);
    this.lowerBarElement.style.position = 'absolute';
    this.lowerBarElement.style.display = 'block';
    this.lowerBarElement.style.width = xIE4Up?4:2;
    this.lowerBarElement.style.height = xIE4Up?11:10;
    this.lowerBarElement.style.top = 17;
    this.lowerBarElement.style.left = 6;
    this.lowerBarElement.style.backgroundColor = '#000000';
    this.lowerBarElement.style.borderTopWidth = 0;
    this.lowerBarElement.style.borderBottomWidth = 1;
    this.lowerBarElement.style.borderRightWidth = 1;
    this.lowerBarElement.style.borderLeftWidth = 1;
    this.lowerBarElement.style.borderColor = '#FFFFFF';
    this.lowerBarElement.style.borderStyle = 'solid';
    this.lowerBarElement.style.overflow = 'hidden'; //stop IE from ignoring height
    
  };
  
  this.drawScalebar = function()
  {
    if(document.applicationConfig.mapUnits=='LL') return null;
    var bestGuess = 0;
    var mapWidth = Math.abs(this.mapObject.extent[3]-this.mapObject.extent[2]);
    for (var activeConfig=0;activeConfig<this.config.length;activeConfig++)
    {
      if (this.config[activeConfig][6]>mapWidth)
        break;
      else
        bestGuess = activeConfig;
    }
    if (bestGuess > this.config.length) return null;
    //calculate width of scalebar
    var upperBarWidth = this.mapImage.width()*(this.config[bestGuess][2]/mapWidth);
    var lowerBarWidth = this.mapImage.width()*(this.config[bestGuess][5]/mapWidth);

    //construct scalebar
    this.topLabelElement.innerHTML = this.config[bestGuess][1]+'&nbsp;'+unitLabels[this.config[bestGuess][0]];
    this.bottomLabelElement.innerHTML = this.config[bestGuess][4]+'&nbsp;'+unitLabels[this.config[bestGuess][3]];
    
    this.element.style.width = ((upperBarWidth>lowerBarWidth)?(upperBarWidth):(lowerBarWidth));
    this.barElement.style.width = ((upperBarWidth>lowerBarWidth)?(upperBarWidth):(lowerBarWidth));
    this.upperBarElement.style.left = upperBarWidth-(xIE4Up?1:0);
    this.lowerBarElement.style.left = lowerBarWidth-(xIE4Up?1:0);
    this.element.style.display = 'block';
  };
  this.clearScalebar = function()
  {
    this.element.style.display = 'none';
  };
  
  this.convertUnits = function(dist,srcUnit,dstUnit)
  {
  if (srcUnit == dstUnit)
    return(dist);
  var newdist = 0;
  /* step 1: convert to ft */
  switch (srcUnit)
  {
    case _FT_:
      newdist = dist;
      break;
    case _YD_:
      newdist = dist * 3;
      break;
    case _MI_:
      newdist = dist * 5280;
      break;
    case _M_:
      newdist = dist * 3.2808399;
      break;
    case _KM_:
      newdist = dist * 3280.8399;
      break;
  };
  /* step 2: convert from ft to requested units */
  switch (dstUnit)
  {
    case _FT_:break;
    case _YD_:
      newdist = newdist / 3.0;
      break;
    case _MI_:
      newdist = newdist / 5280.0;
      break;
    case _M_:
      newdist = newdist / 3.2808399;
      break;
    case _KM_:
      newdist = newdist / 3280.8399;
      break;
  };
  return(newdist);
  };
};}
/* FILE:FreeanceWeb/Client/PublicKiosk1/lib/MapLib/ZoomBox.js */ if(!window.freeance_loaded_js['232f336fbda87b327f84cd0a0fdc2822']){window.freeance_loaded_js['232f336fbda87b327f84cd0a0fdc2822']=1;
//ZoomBox.js
//used by the map image object to handle drawing a box.  returns size of drawn box.

ZoomBox = function(newID, newParent, newXOffset, newYOffset, newMapImage)
{
  if (arguments.length > 0)
    this.init(newID, newParent, newXOffset, newYOffset, newMapImage);
};

ZoomBox.prototype = new GuiWidget();
ZoomBox.prototype.constructor = ZoomBox;
ZoomBox.superclass = GuiWidget.prototype;

/*******************************************/

ZoomBox.prototype.init = function(newID, newParent, newXOffset, newYOffset, newMapImage)
{
  ZoomBox.superclass.init.call(this, newID, newParent, 1, 1, 2, 1, 1, false, "zoomBox");
  this.xStart = 0;
  this.yStart = 0;
  this.xOffset = newXOffset;
  this.yOffset = newYOffset;
  this.mapImage = newMapImage;
  this.isActive = false;
};

/*******************************************/

ZoomBox.prototype.setActive = function (newXStart, newYStart)
{
  xMoveTo(this.element,0,0);
  xResizeTo(this.element,1,1);
  
  this.xStart = newXStart;
  this.yStart = newYStart;
  
  this.isActive = true;
  xMoveTo(this.element,this.xStart, this.yStart);
  xResizeTo(this.element,1,1);
  xShow(this.element);
};

/*******************************************/

ZoomBox.prototype.update = function (newXPosition, newYPosition)
{
  this.xEnd = newXPosition+this.xOffset;
  this.yEnd = newYPosition+this.yOffset;
  if ((this.isActive) && (this.xEnd > (this.mapImage.zoomBoxMargin)) && (this.xEnd < (this.mapImage.width() - this.mapImage.zoomBoxMargin)) && (this.yEnd > (this.mapImage.zoomBoxMargin)) && (this.yEnd < (this.mapImage.height() - this.mapImage.zoomBoxMargin)))
  {
    xMoveTo(this.element,(this.xStart<this.xEnd)?this.xStart:this.xEnd ,(this.yStart<this.yEnd)?this.yStart:this.yEnd);
    xResizeTo(this.element,Math.abs(this.xStart - this.xEnd), Math.abs(this.yStart - this.yEnd));
  }
  else
    this.setInactive(newXPosition, newYPosition);
};

/*******************************************/

ZoomBox.prototype.setInactive = function(newXPosition, newYPosition)
{
  this.isActive = false;
  this.xStart = 0;
  this.yStart = 0;
  this.xEnd = 0;
  this.yEnd = 0;
  xResizeTo(this.element,2,2);
  xMoveTo(this.element,1,1);
  xHide(this.element);
};}
/* FILE:FreeanceWeb/Client/PublicKiosk1/lib/MapLib/Selection.js */ if(!window.freeance_loaded_js['8f302dd0c3e5a6f9066ca1de15d66952']){window.freeance_loaded_js['8f302dd0c3e5a6f9066ca1de15d66952']=1;
//Selection.js
//Selection object.  Initialized from a selection controller.
//
//On initialization,a user-defined function is called (if it exists)
//  allowing customization.

Selection = function(newId,newThemeIndex,newSelectionControl,newMapObject,newData,newPrev,newNext)
{
  if (arguments.length > 0)
    this.init(newId,newThemeIndex,newSelectionControl,newMapObject,newData,newPrev,newNext);
};

Selection.prototype.init = function(newId,newThemeIndex,newSelectionControl,newMapObject,newData,newPrev,newNext)
{
  this.id = newId;
  this.themeIndex = newThemeIndex;
  this.selectionControl = newSelectionControl;
  this.mapObject = newMapObject;
  this.data = newData;
  this.prev = newPrev;
  this.next = newNext;
  this.handle = this.data[0];
  this.identifier = this.data[1][this.mapObject.config.themes[this.themeIndex].selectOptions.idField];
  this.keyField = this.mapObject.config.themes[this.themeIndex].selectOptions.keyField;
  this.keyValue = this.data[1][this.keyField];
  this.renderTarget = null;
  this.resultTemplate = this.mapObject.config.themes[this.themeIndex].selectOptions.resultTemplate;
};

Selection.prototype.getSelectionByKeyValue = function (newKeyValue)
{
  if (this.keyValue == newKeyValue)
    return this;
  else 
    if (this.next == null)
      return null;
    else
      return this.next.getSelectionByKeyValue(newKeyValue);
};

Selection.prototype.getSelectionByHandle = function(newSelectionHandle)
{
  if (this.handle == newSelectionHandle)
    return this;
  else 
    if (this.next == null)
      return null;
    else
      return this.next.getSelectionByHandle(newSelectionHandle);
};

Selection.prototype.render = function()
{
  if(this.renderTarget == null)
    return;
  var source = document.getTemplate(this.resultTemplate);
  if(source)
    this.renderTarget.innerHTML = source.run(this.data).replace(/document.selectionPanel.selection.runQuery\(/g,'document.selectionControl.runLinkedQuery(\''+this.themeIndex+'\',') + '<div class="pseudolink" style="text-align:right" onClick="mapObject.clearAllSelections();mapObject.redraw();">Clear Results</div>';
};

Selection.prototype.printData = function()
{
  var printTarget = document.getPrintTarget();
  var source = document.getTemplate(this.resultTemplate);
  if (source)
    printTarget.innerHTML = source.run(this.data);
  document.printCurrentData();
  return;
};

Selection.prototype.getAttachmentElem = function()
{
  return(this.renderTarget);
};

Selection.prototype.clear = function()
{
  if (this.prev == null)
    this.selectionControl.selections[this.themeIndex].list = this.next;
  else
    this.prev.next = this.next;
  if (this.next != null)
    this.next.prev = this.prev;
  this.next = null;
  this.prev = null; 
};

Selection.prototype.unlink = function()
{
  //unlinks node from selection list.
  //before doing this, verify that the list head is set properly!
  if (this.prev != null)
    this.prev.next = this.next;
  if (this.next != null)
    this.next.prev = this.prev;
  this.prev = null;
  this.next = null;
  
};

Selection.prototype.clearAll = function()
{
  if (this.next != null)
    this.next.clearAll();
  this.next = null;
  return this.clear();
};

Selection.prototype.length = function()
{
  if (this.next == null)
    return 1;
  else
    return this.next.length() + 1;
};

Selection.prototype.lastElement = function()
{
  if (this.next == null)
    return this;
  else
    return (this.next.lastElement());
};

Selection.prototype.createBuffer = function(newTargetTheme, newBufferDistance)
{
  this.mapObject.bufferOnSelection(this.handle, this.themeIndex, newTargetTheme, newBufferDistance, null, null, true);
};}
/* FILE:FreeanceWeb/Client/PublicKiosk1/lib/MapLib/SelectionControl.js */ if(!window.freeance_loaded_js['98580adaf36b736f49fd08fe7668ee81']){window.freeance_loaded_js['98580adaf36b736f49fd08fe7668ee81']=1;
//SelectionControl.js
//
//Handles management of selections associated with a given map.
//Selections are displayed in a set of tabs at the moment
//
//Future implementation plan:
//   Establish an virtual callback function invoked when the xml response
//    is recieved.  This function will be responsible for establishing the
//    appropriate target element for the data.  This could be anything from
//    validating the existance of a DIV to creating a new tab in a tab panel.
//  Establish a virtual callback function invoked when a clear selection request
//    is recieved.  This function will be responsible for erasing and cleaning
//    up after the selection.
//
//
//Attributes:
//  map        = pointer to map object associated with the selection object.
//  layerIndex = index of the layer in the map's layer array.
//  handle     = selection handle in the session on the server.
//  data       = selection data returned from the server
//
//Methods:
//  init       average ordinary constructor.  takes map, layerIndex as parameters.
//  callback   xmlrpc callback function.  accepts the xml response as a parameter.
//             also invokes a function in the map object, providing the updated map
//             information

SelectionControl = function(newId, newMapObject, newMapId, selectionPanelTarget)
{
  if (arguments.length > 0)
    this.init(newId, newMapObject, newMapId, selectionPanelTarget);
};

SelectionControl.prototype.init = function(newId, newMapObject, newMapId, selectionPanelTarget)
{
  //Initialize selection array
  //Selections are implemented as a linked list
  //  one list per theme
  //  based on the number of selections allowed per theme, we
  //  can determine what to do when a new selection is added.
  this.id = newId;

  if (newMapId!=null)
  {
    this.mapObject = OBJECT_MANAGER.getControl(newMapId);
    this.mapId = newMapId;
  }
  else
  {
    this.mapObject = newMapObject;
    this.mapId = newMapObject.id;
  }
  this.mapObject.selectionControl = this;
  OBJECT_MANAGER.addControl(this,'selectionControl', newId);
  this.selectionPanel = selectionPanelTarget;
};

SelectionControl.prototype.initialize = function()
{
  this.selections = null;
  this.selections = new Object;
  for (var i in this.mapObject.config.themes)
  {
    if(i=='toJSONString')continue;
    if (this.mapObject.config.themes[i]["selectOptions"])
    {
      this.selections[i] = {
        list: null,
        length: 0,
        maxLength: this.mapObject.config.themes[i]["selectOptions"]["limit"],
        panel: document.createElement('DIV')
      }
      this.selections[i].panel.style.display='none';
      this.selectionPanel.appendChild(this.selections[i].panel);
    }
  }
};

SelectionControl.prototype.setSelectionListHead = function(themeIndex, newListHead)
{
   //serves three purposes
   //  1) if the first selection in a list has been killed, allows the second to take its place
   //  2) allows a list to be explicitally set to a particular selection pointer.
   //  3) if the only element in a list has been killed, clears the list completely
   this.selections[themeIndex].list = newListHead;
   if (newListHead == null)
     this.selections[themeIndex].length = 0;
   else
     this.selections[themeIndex].length = this.getNumSelections(themeIndex);
};

SelectionControl.prototype.getNumSelections = function(themeIndex)
{
  if (this.selections[themeIndex].list != null)
    return this.selections[themeIndex].list.length();
  else
    return 0;
};

SelectionControl.prototype.removeSelectionListHead = function(themeIndex)
{
  if (this.selections[themeIndex].list.next != null)
    this.selections[themeIndex].list = this.selections[themeIndex].list.next;
  else
    this.selections[themeIndex].list = null;
};

SelectionControl.prototype.clearAll = function()
{
  for (var i in this.selections){
    var sel=this.selections[i];
    if(sel['list']) sel['list'].clearAll();
    sel['length']=0;
    sel['panel'].innerHTML='';
    sel['panel'].style.display='none';
  }
};

SelectionControl.prototype.clearSelection = function(themeIndex, handle)
{
  this.mapObject.clearSelection(themeIndex, handle);
};

SelectionControl.prototype.clearTheme = function(themeIndex)
{
  this.mapObject.clearThemeSelections(themeIndex); 
};

SelectionControl.prototype.zoomTo = function(themeIndex, handle)
{
  var currentSelection = this.getSelection (themeIndex, handle);
  this.mapObject.zoomTo_(themeIndex, currentSelection.keyField, this.mapObject.config.themes[themeIndex]['selectOptions']['keyFieldType'], currentSelection.keyField, false);
};

SelectionControl.prototype.getSelection = function(themeId, handle)
{
  return this.selections[themeId].list.getSelectionByHandle(handle); 
};

SelectionControl.prototype.printSelection = function(themeId, handle)
{
  this.selections[themeId].list.getSelectionByHandle(handle).printData();
};

SelectionControl.prototype.getAttachmentElem = function(themeId, handle)
{
  return(this.selections[themeId].list.getSelectionByHandle(handle).getAttachmentElem());
};

SelectionControl.prototype.displaySelection = function(newThemeIndex, newSelectionHandle)
{
  var selection = this.getSelection(newThemeIndex, newSelectionHandle);
  var currentSelectionTheme = newThemeIndex;
  var currentSelectionHandle = newSelectionHandle;
  if (selection == null)
    alert('Application Error in\n'+this.id+'.displaySelection('+newThemeIndex+','+newSelectionHandle+'):\nSelection '+newSelectionHandle+' on theme '+newThemeIndex+' not found\nUnable to display selection');
  else
  {
    selection.renderTarget = this.selections[newThemeIndex].panel;
    selection.renderTarget.style.display='block';
    selection.render();
    if (this.onSelectionDisplay)
      this.onSelectionDisplay();
  }
};

SelectionControl.prototype.callback = function (serverReplyDoc, requestDetails)
{
  //data returned from server:
  //  [0] = Map data array - pass directly to mapObject.
  //  [1..n] = selections
  //    [0] = selection handle (integer)
  //    [1] = data from theme
  //    [2] = data from cascaded SQL queries

  //Prepare response data
  //alert(this.id+'.callback');
  var xmlstr = '';
  if (serverReplyDoc != null)
      xmlstr = (typeof(serverReplyDoc.xml)=='function')?serverReplyDoc.xml():serverReplyDoc.xml;
  if((serverReplyDoc == null) || (xmlstr == '') || (serverReplyDoc.documentElement.nodeName == 'parsererror'))
  {
    return(this.mapObject.selectionCallback(null));
  }
  else
  {
    var clientReply = new XMLRPCResponse();
    //clientReply.setResponseByStr(serverReplyDoc.xml);
    clientReply.setResponseByDoc(serverReplyDoc);
  }

  //Verify data
  if(clientReply.isFault())
  {
    var data = null;
    
    if (clientReply.getFaultCode() != 1013)  //ignore case where no selections found
      alert('Error in Selection operation\nFault Code:'+clientReply.getFaultCode()+'\n"'+clientReply.getFaultString()+'"');
    return(this.mapObject.selectionCallback(null));
  }
  else  //data is good, process
  {
    var data = clientReply.getObject();
    switch (requestDetails.request)
    {
      case 'newSelection':                        //new selection(s) added
        var themeId = requestDetails.themeId;
        var existingElement = null;
        /** TODO:  Handle multiple selections differently from single selections.  if more than one, show index instead of the selection itself. **/
        for (var currentSelection=1; currentSelection<data.length; currentSelection++)
        {
          //check to see if this feature is already selected
          if (existingElement == null)
          {
            newSelection = new Selection(this.id+'.selection', themeId,this, this.mapObject, data[currentSelection], null, null);
            if (this.selections[themeId].list == null)
            {
              this.selections[themeId].list = newSelection;
            }
            else
            {
              if (this.selections[themeId].list.length() == 1)
              {
                newSelection.next = this.selections[themeId].list.next;
                if (newSelection.next != null)
                {
                  newSelection.next.prev = newSelection;
                }
                this.selections[themeId].list.clear();
                this.selections[themeId].list = newSelection;
              }
              else
              {
                newSelection.prev = this.selections[themeId].list.lastElement();
                this.selections[themeId].list.lastElement().next = newSelection;
              }
            }
            this.displaySelection(themeId,newSelection.handle);
          }
        }
        //scrollToUpperMapRange();  // out for now as it shuns the banner
        this.mapObject.selectionCallback(data[0]);   //pass map data to mapObject
        break;
      case 'clearSelection':
        var currentSelection = this.getSelection(requestDetails.themeIndex, requestDetails.handle);
        currentSelection.clear();  //unlinks selection from list
        this.selections[themeId].panel.innerHTML = '';
        this.mapObject.redraw();
        this.mapObject.setWaiting(false);  //call after requesting redraw so that the waiting image doesn't go out briefly
        break;
      case 'clearTheme':
        var themeId = requestDetails.themeIndex;
        if (this.selections[themeId].list != null)
          this.selections[themeId].list.clearAll();
        this.selections[themeId].panel.innerHTML = '';
        this.mapObject.redraw();
        this.mapObject.setWaiting(false);  //call after requesting redraw so that the waiting image doesn't go out briefly
        break;
      default:
        break;
    }
  }
  return;
};

SelectionControl.prototype.runLinkedQuery = function(lid,qid,qvars){
  //qid = id of a predefined query in the client context
  //qvars = string defining how to match the selection data with the predefined query.
  //  format:  <pdqVar1>=<IMSfield1>;<pdqVar2>=<IMSfield2>;...<pdqVarN>=<IMSfieldN>;
  var sel=this.selections[lid];
  var queryValuePairs=[];
  var queryVariables=qvars.split(';');
  var queryVarSplit = null;
  for (var i=0;i<queryVariables.length;i++)
  {
    if (queryVariables[i]!='')
    {
      queryVarSplit=queryVariables[i].split('=');
      queryValuePairs[i]=[queryVarSplit[0],sel.list.data[1][queryVarSplit[1]]];
    }
  };
  document.queryControl.runQuery(qid,queryValuePairs,1,true);
};}
/* FILE:FreeanceWeb/Client/PublicKiosk1/lib/MapLib/BufferControl.js */ if(!window.freeance_loaded_js['75d5154fdea570318611e78e91e1a3f2']){window.freeance_loaded_js['75d5154fdea570318611e78e91e1a3f2']=1;
BufferControl = function (newId, newMapObject, newMapId, newResultTarget)
{
  if (arguments.length > 0)
    this.init(newId, newMapObject, newMapId, newResultTarget);
};

BufferControl.prototype = new Object();
BufferControl.constructor = BufferControl;
BufferControl.superclass = Object.prototype;
 
BufferControl.prototype.init = function (newId, newMapObject, newMapId, newResultTarget)
{
  this.id = newId;
  if (newMapId!=null)
  {
    this.mapObject = OBJECT_MANAGER.getControl(newMapId);
    this.mapId = newMapId;
  }
  else
  {
    this.mapObject = newMapObject;
    this.mapId = newMapObject.id;
  }
  
  this.mapObject.bufferControl = this;
  this.resultTarget = newResultTarget;
  this.activeTheme = '';
  this.activeSelection = '';
  this.buffers = new Object;

  this.bufferConfig = new Object;
  this.activeQuery = null;          //currently active buffer query (if any)
  this.bufferRadioButtonGroup = null;
  this.enabled = false;
  
  this.lastThemeBuffered = '';
  this.currentBufferCount = 0;
};

BufferControl.prototype.initialize = function(bufferableThemes)
{
  //argument is an array of all bufferable theme ids in the map
  this.enabled = (bufferableThemes.length > 0);
  for (var i = 0; i < bufferableThemes.length; i++)
    this.buffers[bufferableThemes[i]] = null;
};

BufferControl.prototype.getSQLParams = function()
{
  return null;
  //check to see if a query panel is active.
  if (this.activeQuery != null)
  {
    var queryIndex = this.activeQuery.queryId;
    var dataPairs = this.activeQuery.getDataPairs();
    var sqlParams = new Array(this.activeQuery.queryConfig.request.pdqIdentifier,dataPairs);
  }
  else
    var sqlParams = null;
  return (sqlParams);
};

BufferControl.prototype.convertUnits = function(dist, srcUnits, destUnits)
{
  return convertDistance(dist,srcUnits,destUnits);
};

BufferControl.prototype.hasBufferedResults = function()
{
  // switch to this.buffers[...] loop check?
  return(this.currentBufferCount > 0);
};

BufferControl.prototype.clearAllBuffers = function()
{
  if (!this.hasBufferedResults())  // one buffer at a time
    return;  // nothing to do
  //clear the buffer form and local data.
  for (var currentBufferTheme in this.buffers){
    if(currentBufferTheme=='toJSONString')continue;
    this.buffers[currentBufferTheme] = null;
  }
  this.resultTarget.innerHTML = '';
  this.currentBufferCount = 0;
  if (this.onBufferClear)
    this.onBufferClear();
};

BufferControl.prototype.callback = function(serverReplyDoc, pendingOperation)
{
  this.mapObject.setWaiting(false);
  if (!validateXMLDoc(serverReplyDoc))
    return null;
  var clientReply = new XMLRPCResponse();
  clientReply.setResponseByDoc(serverReplyDoc);
  if(clientReply.isFault())
  {
    switch (parseInt(clientReply.getFaultCode()))
    {
      case 1018:  //no results found
        this.mapObject.callback(serverReplyDoc,pendingOperation[0]); //no elements found...
        this.mapObject.redraw();
        var templateName = this.mapObject.config.themes[pendingOperation[1]].bufferOptions.invalidTemplate;
        var templateData = new Array();
        templateData[0] = new Array();
        var source = document.getTemplate(templateName);
        this.buffers[pendingOperation[1]] = null;  //remove buffer handle...
        this.resultTarget.innerHTML = source.run(templateData);
        this.currentBufferCount = 0;
        if (this.onBufferDisplay)
          this.onBufferDisplay();
        break;
      default:
        alert(this.id+'.callback:  clientReply fault:\n\n'+clientReply.getFaultCode()+'\n'+clientReply.getFaultString());
        this.mapObject.callback(serverReplyDoc,pendingOperation[0]); //no elements found...
        break;
    };
  }
  else
    var data = clientReply.getObject();
  if (data != null)
  {
    switch (pendingOperation[0])
    {
      case 'BufferXY':
      case 'BufferOnSelection':
        this.lastThemeBuffered = pendingOperation[1];
        var templateName = this.mapObject.config.themes[pendingOperation[1]].bufferOptions.resultTemplate;
        this.buffers[pendingOperation[1]] = Array(data[1],data[2]);  //handle, queryData
        this.currentBufferCount = data[2].length;
        var templateData = data[2];
        var templateSpecialRequests = Array();
        /* Check to see if this theme wants to export the buffer data to CSV */
        if (this.mapObject.config.themes[pendingOperation[1]].bufferOptions['export'].csv.enabled==true)
          templateSpecialRequests["includeExportBufferToCSV"] = true;

        var source = document.getTemplate(templateName,false,templateSpecialRequests);
		var cleanData = new Array();
	    for (var i=0;i<templateData.length;i++)
	    {
	      var current_result = templateData[i];
		  cleanData[i] = new Array();
	      if (current_result[1])
	      {
	        if ((current_result[1].length==0)||(current_result[1].length==null)){//no chained query results are present.
	          cleanData[i][0] = currentResult[0];
	        }
	        else{ //one or more chained query rows have been returned
			  cleanData[i][0] = current_result[0];
			  for (var chainedResult in current_result[1][0]){
				cleanData[i][0][chainedResult] = current_result[1][0][chainedResult];
			  }
	        }
	      }
	      else{
	        cleanData[i][0] = current_result[0];
	      }
	    };
        this.resultTarget.innerHTML = source.run(cleanData);
        this.mapObject.callback(serverReplyDoc,'BufferXY');
        if (this.onBufferDisplay)
          this.onBufferDisplay();
        break;
      case 'clearThemeBuffer':
        this.buffers[pendingOperation[1]] = null;
        this.currentBufferCount = 0;
        this.mapObject.callback(serverReplyDoc,'clearThemeBuffer');
        if (this.onBufferClear)
          this.onBufferClear();
        break;
      case 'Exporter.toCSV':
      case 'Exporter.toXML':
        this.mapObject.setWaiting(false);
        var url = data;
        downloadFile(url);
        break;
    };
  }
};}
/* FILE:FreeanceWeb/Client/PublicKiosk1/lib/MapLib/LayerControl2.js */ if(!window.freeance_loaded_js['f3a28d36608e52c8d483bbea12b47b9d']){window.freeance_loaded_js['f3a28d36608e52c8d483bbea12b47b9d']=1;
LayerControl = function(htmlTargetEle)
{
  var layerInput =  {};           //assoc array of layer ids; each entry is an array of checkboxes
  var groupToggleEles = []; //array of checkboxes for group toggles.  first element is always null.
  var groupContentEles = []; //array of group table elements
  var groupConfigLookup = []; //array of 
  var radioGroups = {};
  var layersInRadioGroups = {};
  this.mapObject = (arguments.length>1)?arguments[1]:document.mapObject;
  if(this.mapObject){
    this.config = this.mapObject.config.themeGroups;
    this.mapObject.layerControl = this;
  }
  
  for (var currentTheme in this.mapObject.config['themes']){
    if(currentTheme=='toJSONString')continue;
    layerInput[currentTheme] = [];
  }
  
  this.drawPanel = function()
  {
    var $_this = this;
    var htmlString = this.getGroupHTML(this.config,0);
    htmlTargetEle.innerHTML = htmlString;
    //set up event handlers
    var inputEles = htmlTargetEle.getElementsByTagName('input');
    var attachLayerClick = function(ele,layerid){xAddEventListener(ele,'click',function(){$_this.toggleTheme(layerid);});};
	var attachLayerRadioClick = function(ele,layerid){xAddEventListener(ele,'click',function(){$_this.radioClickTheme(layerid);});};
    var attachGroupClick = function(ele){xAddEventListener(ele,'click',function(){$_this.toggleGroup(parseInt(ele.getAttribute('FREEANCE_GROUP_INDEX')),ele.checked);});};
    for (var i=0;i<inputEles.length;i++)
    {
      switch(inputEles[i].getAttribute('FREEANCE_TYPE'))
      {
        case 'LAYER_TOGGLE':
          var layerid = inputEles[i].getAttribute('FREEANCE_LAYER_ID');
          if(!layerInput[layerid])
            layerInput[layerid] = [];
          layerInput[layerid].push(inputEles[i]);
          attachLayerClick(inputEles[i],layerid);
          break;
        case 'LAYER_RADIO':
          var layerid = inputEles[i].getAttribute('FREEANCE_LAYER_ID');
          if(!layerInput[layerid])
            layerInput[layerid] = [];
		  if(!radioGroups[inputEles[i].getAttribute('name')])
			radioGroups[inputEles[i].getAttribute('name')] = [];
		  radioGroups[inputEles[i].getAttribute('name')].push(inputEles[i]);
		  if(!layersInRadioGroups[layerid])
		    layersInRadioGroups[layerid] = [];
		  layersInRadioGroups[layerid].push(inputEles[i].getAttribute('name'));
		  layerInput[layerid].push(inputEles[i]);
          attachLayerRadioClick(inputEles[i],layerid);
          break;
        case 'GROUP_TOGGLE':
          attachGroupClick(inputEles[i]);
          groupToggleEles[parseInt(inputEles[i].getAttribute('FREEANCE_GROUP_INDEX'))] = inputEles[i];
          break;
      }
    }
    
    //SET UP COLLAPSABLE GROUP HEADINGS
    var attachHeaderClick=function(spanEle,trEle){xAddEventListener(spanEle,'click',function(){trEle.style.display=(trEle.style.display=='none')?('block'):'none'});};
    var headers = [];  //array of header spans
    var rows = []; //array of group container rows
    var spanEles = htmlTargetEle.getElementsByTagName('span');
    var divEles = htmlTargetEle.getElementsByTagName('div');
    for (var i=0;i<spanEles.length;i++)
      if(spanEles[i].getAttribute('FREEANCE_TYPE')=='GROUP_LABEL')
        headers[parseInt(spanEles[i].getAttribute('FREEANCE_GROUP_INDEX'))]=spanEles[i];
    for (var i=0;i<divEles.length;i++)
      if(divEles[i].getAttribute('FREEANCE_TYPE')=='LAYER_GROUP_CONTENTS')
        rows[parseInt(divEles[i].getAttribute('FREEANCE_GROUP_INDEX'))]=divEles[i];
    for (var i=0;i<rows.length;i++)
      if((rows[i]!=null)&&(headers[i]!=null))
        attachHeaderClick(headers[i],rows[i]);
  };

  this.toggleTheme = function (themeId)
  {
    if (_MAP_INITIALIZED){
      this.mapObject.setThemeState(themeId,!this.mapObject.config["themes"][themeId]["visibility"]);
      this.update();
    }
  };
  
  this.radioClickTheme = function(layerid){
    var themeArray = [];
	if(layersInRadioGroups[layerid]){
		for(var i = 0; i < layersInRadioGroups[layerid].length; i++){
			var radioGroupId = layersInRadioGroups[layerid][i];
			for(var j = 0; j < radioGroups[radioGroupId].length; j++){
				var radioButton = radioGroups[radioGroupId][j];
				var radioButtonLID = radioButton.getAttribute('FREEANCE_LAYER_ID');
				if(radioButtonLID != ''){
					themeArray.push([radioButtonLID,radioButtonLID==layerid]);
				}
			}
		}
	}
	this.mapObject.setThemesState(themeArray);
	this.update();
  };
  
  this.toggleGroup = function(groupIndex,newState)
  {
    var activeGroup = groupConfigLookup[groupIndex];
    if (activeGroup)
      this.setGroupState(activeGroup,newState);
    this.update();
  };
  
  this.setGroupState = function(groupConfig,newState)
  {
    //contains layers and groups  if a layer, set state to match.  if a group, recursive call 
    for (var i=0;i<groupConfig.length;i++)
    {
      switch(groupConfig[i].type)
      {
        case 'layer':
          this.mapObject.setThemeState(groupConfig[i].layerid,newState);
          for (var j=0;j<layerInput[groupConfig[i].layerid].length;j++)
            layerInput[groupConfig[i].layerid][j].checked = newState;
          break;
        case 'group':
          if(groupConfig[i].children.length>0)
            this.setGroupState(groupConfig[i].children,newState);
          break;
      }
    }
  };
  
  this.getGroupHTML = function(groupConfig,groupIndex,isRadioGroup)
  {
    //groupConfig is an array of groupItems. groupIndex is the current index of the group in the lookup table.
    groupConfigLookup[groupIndex] = groupConfig;
    groupConfig.groupIndex = groupIndex;
    var newGroupIndex=groupIndex+1;
    var htmlString = ['<div FREEANCE_TYPE="LAYER_GROUP_CONTENTS" FREEANCE_GROUP_INDEX="'+groupIndex+'"><table width="100%" cellpadding="0" cellspacing="0">'];
    for (var i=0;i<groupConfig.length;i++)
    {
      switch(groupConfig[i].type)
      {
        case 'label':
          htmlString.push('<tr><td colspan="2" class="rightPanelFormHeaderActive" style="margin-bottom: 0px;cursor:default;">'+groupConfig[i].name+'</td></tr>');
          break;
        case 'layer':
          htmlString.push('<tr><td width="25px" class="layerControlLeftColumn">');
          if(groupConfig[i].toggle){
		    if(isRadioGroup){
				htmlString.push('<input type="radio"  name="',groupIndex,'" FREEANCE_TYPE="LAYER_RADIO" FREEANCE_LAYER_ID="'+groupConfig[i].layerid+'" />');
			}
			else{
				htmlString.push('<input type="checkbox"  FREEANCE_TYPE="LAYER_TOGGLE" FREEANCE_LAYER_ID="'+groupConfig[i].layerid+'" />');
			}
		  }
          htmlString.push('&nbsp;</td><td class="layerControlLayerName">'+
            this.mapObject.config['themes'][groupConfig[i].layerid]['themeName']+'</td></tr>');
          break;
        case 'radio_none':
          htmlString.push('<tr><td width="25px" class="layerControlLeftColumn">');
		  htmlString.push('<input type="radio"  name="',groupIndex,'" FREEANCE_TYPE="LAYER_RADIO" FREEANCE_LAYER_ID="" />');
          htmlString.push('&nbsp;</td><td class="layerControlLayerName">'+groupConfig[i].name+'</td></tr>');
          break;
        case 'radio_group':
          htmlString.push('<tr><td width="25px" class="layerControlLeftColumn">');
          htmlString.push('&nbsp;</td><td class="rightPanelFormHeaderActive"><span FREEANCE_TYPE="GROUP_LABEL" FREEANCE_GROUP_INDEX="'+(newGroupIndex)+'">'+groupConfig[i].name+'</span></td><tr>',
            '<tr><td width="25px" class="layerControlLeftColumn"></td><td>',
            this.getGroupHTML(groupConfig[i].children,newGroupIndex,true),'</td></tr>');
          newGroupIndex++;
          break;
        case 'group':
          htmlString.push('<tr><td width="25px" class="layerControlLeftColumn">');
          if(groupConfig[i].toggle)
            htmlString.push('<input type="checkbox" FREEANCE_TYPE="GROUP_TOGGLE" FREEANCE_GROUP_INDEX="'+(newGroupIndex)+'" />');
          htmlString.push('&nbsp;</td><td class="rightPanelFormHeaderActive"><span FREEANCE_TYPE="GROUP_LABEL" FREEANCE_GROUP_INDEX="'+(newGroupIndex)+'">'+groupConfig[i].name+'</span></td><tr>',
            '<tr><td width="25px" class="layerControlLeftColumn"></td><td>',
            this.getGroupHTML(groupConfig[i].children,newGroupIndex),'</td></tr>');
          newGroupIndex++;
          break;
      }
    }
    htmlString.push('</table></div>');
    return htmlString.join('');
  };
  
  this.update = function()
  {
    //set checkboxes for all layers
    for (var currentTheme in this.mapObject.config['themes'])
    {
      if(currentTheme=='toJSONString')continue;
      if(layerInput[currentTheme]){
        var newvis=this.mapObject.config['themes'][currentTheme]['visibility'];
        for (var i=0;i<layerInput[currentTheme].length;i++)
        {
          layerInput[currentTheme][i].checked = newvis;
        }
      }
    }
  };
  this.drawPanel();
};}
/* FILE:FreeanceWeb/Client/PublicKiosk1/lib/MapLib/QueryControl.js */ if(!window.freeance_loaded_js['5065b220709aac37573bd30effab77c8']){window.freeance_loaded_js['5065b220709aac37573bd30effab77c8']=1;
document.queryControl = new(function(newId)
{
  OBJECT_MANAGER.addControl(this,'queryControl', newId);
  this.id = newId;
  this.config = null;
  this.resultTarget = null;
  this.currentQueryPage = 0;
  this.currentQueryId = null;
  this.currentQueryValuePairs = null;
  this.numQueries = 0;
  this.zoomToMarkupHandle = null;

this.setConfig = function(newConfig)
{
  //sets the configration to the specified data structre.
  this.config  = newConfig;
  for (var currentQuery in this.config){
    if(currentQuery=='toJSONString')continue;
    this.numQueries++;
    document.registeredSearches[document.registeredSearches.length] = 'customQuery['+currentQuery+']';
  }
};

this.initialize = function()
{

};

this.setFormPanel = function(newFormPanel)
{
  //set the form panel reference and do initial population
  this.formPanel = newFormPanel;
};

this.formTitleEventListener = function(e)
{
  var evt = new xEvent(e);
  while((evt.target != null) && (evt.target.nodeName == '#text'))
    evt.target = evt.target.parentNode;
  if (evt.target == null)
    return;
  var currentQuery = evt.target.queryId;
  switch (evt.type){
    case 'mouseover':
      setClass(evt.target,'searchFormTitleHighlight');
      break;
    case 'mouseout':
      setClass(evt.target,((document.activeSearch=='customQuery['+currentQuery+']')?('searchFormTitleActive'):('searchFormTitle')));
      break;
    case 'click':
      toggleSearchForm('customQuery['+currentQuery+']');
      break;
  }
};

this.drawFormPanel = function(hiddenQueries){
  if(hiddenQueries == null)
    hiddenQueries = {};
  $('customQueryFormContainer').innerHTML = '';
  for (var currentQuery in this.config){
    if(currentQuery == 'toJSONString') continue;
	  if(hiddenQueries[currentQuery]) continue;
    if(!this.config[currentQuery]['display'] && hiddenQueries[currentQuery]!={}) continue;
    var titleContainer = document.createElement('DIV');
    var formContainer = document.createElement('DIV');
    titleContainer.id = 'customQuery['+currentQuery+']TitleContainer';
    formContainer.id = 'customQuery['+currentQuery+']Form';
    formContainer.style.display = 'none';
    this.formPanel.appendChild(titleContainer);
    this.formPanel.appendChild(formContainer);
    var titleElement = document.createElement('SPAN');
    titleElement.id = 'customQuery['+currentQuery+']Title';
    titleContainer.appendChild(titleElement);
    titleElement.queryId = currentQuery;
    setClass(titleElement,'searchFormTitle');
    xAddEventListener(titleElement,'mouseover',this.formTitleEventListener,false);
    xAddEventListener(titleElement,'mouseout',this.formTitleEventListener,false);
    xAddEventListener(titleElement,'click',this.formTitleEventListener,false);
    titleElement.innerHTML = this.config[currentQuery]['title'];
    formContainer.innerHTML =   '<div class="leftColumnFormBorder"><div>'+
      this.config[currentQuery]['HTMLForm']+
      '</div><div class="leftColumnFormButton">'+
      '<input type="submit" class="submitButton" value="Go" onclick="return submitCustomQuery(\''+currentQuery+'\');">'+
      '</div>'+
      '</div>';
    var inputElements = formContainer.getElementsByTagName('input');
    for(var elementIndex=0;elementIndex<inputElements.length;elementIndex++){
      inputElements[elementIndex].queryId = currentQuery;
      inputElements[elementIndex].queryControl = this;
      xAddEventListener(inputElements[elementIndex],'keypress',function(e){evt = new xEvent(e);if (evt.keyCode==13){submitCustomQuery(evt.target.queryId);}});
    }
    if(this.config[currentQuery].suggestConfig!=null)
      for(var currentSuggestIndex = 0; currentSuggestIndex < this.config[currentQuery].suggestConfig.length; currentSuggestIndex++)
        document.SuggestControl.addSuggest(this.config[currentQuery].suggestConfig[currentSuggestIndex]);
    //set up any dynamic selection fields
    for(var i=0;i<this.config[currentQuery]["fieldList"].length;i++)
      if(this.config[currentQuery]["fieldList"][i].fieldType=='dynamicselectField')
        this.buildDynamicSelect(currentQuery,i);
  }
};

this.buildDynamicSelect = function(queryid,fieldid){
  var fieldName = this.config[queryid]["fieldList"][fieldid]["fieldName"],
   config=this.config[queryid]["fieldList"][fieldid]["dynamicList"],
   container=$('sqlQuery.'+queryid+'.'+fieldName+'InputContainer');
  if(container){
    container.innerHTML='Loading...';
    var htmstr=['<select id="sqlQuery.'+queryid+'.'+fieldName+'InputField">'],
    dbid=config['dbid'],table=config['table'],
    valuefield=config['valuefield'], labelfield=config['labelfield'],
    fields=labelfield+','+valuefield, where=config['whereclause'], limit=config['limit'];
    freeance_request(function(resp){
      if(resp.XMLRPC_FAULT){
        htmstr.push('<option value=""></option>');  
      }
      else{
        var data=resp['data'];
        for (var i=0;i<data.length;i++){
          var opt=data[i];
          htmstr.push('<option value="',opt[valuefield],'">',opt[labelfield],'</option>');
        }
      }
      htmstr.push('</select>');
      container.innerHTML=htmstr.join('');
    },'SQL.query.limitselect',dbid,[labelfield,valuefield].join(','),table,where,limit,0);
  }
};

this.setResultTarget = function(newResultTarget)
{
  //set a reference to the target element for query results.
  this.resultTarget = newResultTarget;
};

this.getFormValues = function(newQueryId)
{
  var queryValuePairs = [];
  var fieldList = this.config[newQueryId]['fieldList'];
  for(var i=0;i<fieldList.length;i++){
    var fieldName = fieldList[i]['fieldName'];
    var inputElement = $('sqlQuery.'+newQueryId+'.'+fieldName+'InputField');
    if(inputElement){
      queryValuePairs.push([fieldName,inputElement.value.strtrim()?inputElement.value.strtrim():fieldList[i]['defaultValue']]);
      inputElement.value = "";
    }
    else
      queryValuePairs.push([fieldName,fieldList[i]['defaultValue']]);
  }
  return queryValuePairs;
};

this.submitQueryForm = function(newQueryId)
{
  //build value pairs array based on field names.  If a field can't be found, use it's default values.
  this.runQuery(newQueryId, this.getFormValues(newQueryId), 1, true);
};


this.runQuery = function(queryId, newValuePairs, newStartPage, firstRun)
{
  this.currentQueryId = queryId;
  this.currentQuery = this.config[queryId];
  this.currentSourceValuePairs = newValuePairs;
  templatehow = 'elem';
  this.currentQueryPage = newStartPage;
  this.currentQueryValuePairs = new Array();
  var valueIndex = 0;
  for(var currentValue in newValuePairs){
    if(currentValue=='toJSONString') continue;
    this.currentQueryValuePairs[valueIndex] = new Array(newValuePairs[currentValue][0],newValuePairs[currentValue][1]);
    valueIndex++;
  }
  var requestInfo = new Object;
  requestInfo.request = 'runQuery';
  requestInfo.queryId = queryId;
  requestInfo.queryTitle = this.currentQuery.title;
  document.getElementById('textResultTabContainer').innerHTML = '';
  if (this.loadImage != null)
    document.getWidgetById(this.loadImage).show();
  if (this.onQuerySubmit)
    this.onQuerySubmit();
  document.mapObject.redraw();
  if (this.zoomToMarkupHandle != null){
    makeSyncPostRequest(XMLRPC_URL,'GIS.DrawPlane.remove.Shape',document.mapObject.sessionID,0,this.zoomToThemeId,this.zoomToMarkupHandle, document.mapObject.mapImage.width(),document.mapObject.mapImage.height());
    document.mapObject.redraw();
    this.zoomToMarkupHandle = null;
  }
  var data = makeASyncPostRequest(this,this.currentQuery,XMLRPC_URL,this.currentQuery.request.requestMethod,this.currentQuery.request.pdqIdentifier,this.currentQuery.templates.pageRows,this.currentQueryPage,this.currentQueryValuePairs);
};

this.loadNextPage = function()
{
  this.runQuery(this.currentQueryId,this.currentSourceValuePairs,this.currentQueryPage+1, false);
};

this.loadPreviousPage = function()
{
  this.runQuery(this.currentQueryId,this.currentSourceValuePairs,this.currentQueryPage-1, false);
};

this.resultTarget_onclick = function(e)
{
  var evt = e || window.event;
  var targetElem = evt.target || evt.srcElement;
  if (typeof(targetElem.onclick) == 'function')
    return false;   // already assigned, preexisting-style
  switch(targetElem.tagName.toLowerCase()){
    case 'span':
      if(targetElem.getAttribute('maplayer')!=null){
        document.mapObject.zoomTo_(targetElem.getAttributeNode('maplayer').value,targetElem.getAttributeNode('themefield').value,targetElem.getAttributeNode('themefieldtype').value,targetElem.getAttributeNode('datavalue').value,true);
        return true;
	    }
      break;
  }
  return false;
};

this.callback = function(serverReplyDoc, requestInfo)
{
  if (this.loadImage != null)
    document.getWidgetById(this.loadImage).hide();
  /* begin error checks */
  if (serverReplyDoc == null)
    return (null);
  var xmlstr = (typeof(serverReplyDoc.xml)=='function')?serverReplyDoc.xml():serverReplyDoc.xml;
  if (xmlstr == '') 
    return (null);
  if (serverReplyDoc.documentElement.nodeName == 'parsererror')
    return (null);
  var clientReply = new XMLRPCResponse();
  clientReply.setResponseByDoc(serverReplyDoc);
  if (clientReply.isFault()){
    var sqlData = null;
    //We're expecting this to happen, suppress certain fault messages
    switch(clientReply.XMLRPC_FAULT_CODE*1){
      case 2003:  //Requested page number less than 1
  			this.currentQueryPage++;
        break;
      case 2004:  //requested page number greater than last page
        this.currentQueryPage--;
        break;
      case 2005:  //no results found.
        templateData = new Array();
        templateData[0] = new Array();
        var source = document.getTemplate(this.currentQuery.templates.invalidTemplate);
        this.resultTarget.innerHTML = source.run(templateData);
        document.getElementById('textResultTabContainer').innerHTML = 'No Results Found';
        break;
      default:
        alert('An error occurred in the query operation:\n\nError Code:  '+clientReply.XMLRPC_FAULT_CODE+'\nError Message:  '+clientReply.XMLRPC_FAULT_MESSAGE);
        break;
    }
  }
  else{
    if(typeof requestInfo == "object")
      requestType = requestInfo.request;
    switch (requestType){
      case 'GIS.Zoom.to.queryResults':
        var data = clientReply.getObject();
        if (document.mapObject.measureControl != null)
           document.mapObject.measureControl.distanceReset();
        document.mapObject.extent = data.mapImages[0][2];
        document.mapObject.mapImage.imageNode.src = document.mapObject.correctURL(data.mapImages[0][1]);
        if (document.mapObject.vmapPresent)
          document.mapObject.vmapImage.imageNode.src = document.mapObject.correctURL(data.mapImages[1][1]);
        if (document.mapObject.legendVisible)
          document.mapObject.loadLegend();
        this.zoomToMarkupHandle = data.handle;
        document.mapObject.setWaiting(false);
        break;
      case 'SQL.export.execute':
        var url = clientReply.getObject();
        downloadFile(url);
        break;
      default:
        var sqlData = clientReply.getObject();
        if ((sqlData != null) && (sqlData != false)){
          this.currentResultData = cloneObject(sqlData);
          var source = document.getTemplate(this.currentQuery.templates.validTemplate);
          try{
            this.resultTarget.innerHTML = source.run(sqlData);
            this.resultTarget.onclick = this.resultTarget_onclick;
          }
          catch(e){
            this.resultTarget.innerHTML = '';
          }
          var tags = cssQuery('[title]',this.resultTarget.getElementsByTagName('TH')[0]);
          for(var idx in tags){
            if(idx=='toJSONString')continue;
            tags[idx].title = document.babelfish.translateWord(tags[idx].title);
          }
          this.resultTarget.query = this;
          var usePlural = (sqlData.length!=1);
          document.getElementById('textResultTabContainer').innerHTML = sqlData[3].length+' Result'+(usePlural?'s':'')+' Found '+((sqlData[1]>1)?('(Page '+sqlData[0]+' of '+sqlData[1]+')'):(''));
          if((sqlData[3].length == 1) && (this.currentQuery.zoomto.autoMaplink)){
            var spans = this.resultTarget.getElementsByTagName('SPAN');
            for(var i=0;i<spans.length;i++)
              if(spans[i].getAttribute('maplayer')!=null)
                if (this.currentQuery.zoomto.maplinkLayer == spans[i].getAttributeNode('themefield').value){
                  document.mapObject.zoomTo_(spans[i].getAttributeNode('maplayer').value,spans[i].getAttributeNode('themefield').value,spans[i].getAttributeNode('themefieldtype').value,spans[i].getAttributeNode('datavalue').value,true);
                  i=spans.length;
                }
          }
          scrollToSearchResultsRange();
        }
    }
  }
  if (this.onQueryReturn)
    this.onQueryReturn();
};

this.clearResults = function()
{
  if(this.resultTarget){
    document.getElementById('textResultTabContainer').innerHTML = '';
    this.resultTarget.style.display = 'none';
    this.resultTarget.innerHTML = '';  // faster to clear after hiding, omits a rendering op
  }
  if(this.zoomToMarkupHandle != null){
    makeSyncPostRequest(XMLRPC_URL,'GIS.DrawPlane.remove.Shape',document.mapObject.sessionID,0,this.zoomToThemeId,this.zoomToMarkupHandle, document.mapObject.mapImage.width(),document.mapObject.mapImage.height());
    document.mapObject.redraw();
    this.zoomToMarkupHandle = null;
  }
};

})('queryControl');}
/* FILE:FreeanceWeb/Common/lib/QuerySuggest.js */ if(!window.freeance_loaded_js['3fb042f0f195e9e70c3a42e94b36f117']){window.freeance_loaded_js['3fb042f0f195e9e70c3a42e94b36f117']=1;
/*
  config format - part of a defined query.
 <suggestConfig>
    <suggestInput pdqfield="name" elementId="sqlQuery.OwnerSearch.nameInputField" resultElementId="sqlQuery.OwnerSearch.nameInputFieldSuggestList" timeout="500" pdq_dbid="AllenCoOHData" pdq_table="ALLJOINED" pdq_field="ALLJOINED.OWNNAM1" pdq_limit="10" />
 </suggestConfig>
*/

QuerySuggest = function(inputElement,resultElement,timeout,pdq_dbid,pdq_field,pdq_table,pdq_limit){
  var keyCounter = 0;
  var typing=false;
  var focused = false;
  var last_search = '';
  var useHiddenResults = resultElement.style.display == 'none';
  
  //define event callback functions
  function hideResults(){
    if (useHiddenResults)
      resultElement.style.display = 'none';
  };
  
  function addResultValueEvents(ele){
    xAddEventListener(ele,'mousedown',function(evt){inputElement.value = ele.firstChild.nodeValue;hideResults();});
    xAddEventListener(ele,'mouseover',function(evt){setClass(ele,'querySuggestListRowActive');});
    xAddEventListener(ele,'mouseout',function(evt){setClass(ele,'querySuggestListRowInactive');});
  };
  
  function keyUpCallback(){
    keyCounter++;
    var currentCount = keyCounter;
    var currentValue = inputElement.value;
    setTimeout(function(){
      if ((keyCounter==currentCount)&&(currentValue == inputElement.value)){
        var searchString = inputElement.value;
        if ((searchString.strtrim()!='')&&(searchString!=last_search)){
          hideResults();
          last_search = searchString;
          var whereClause = 'Upper("'+pdq_field+'") like \''+searchString.toUpperCase()+'%\'';
          freeance_request(
            function(clientReply){
              if((keyCounter==currentCount)&&(currentValue == inputElement.value)){
                var currentNode = null;
                var noResults = false;
                if (clientReply.XMLRPC_FAULT){
                  if(typeof(console)!='undefined')
                    console.warn(clientReply.XMLRPC_FAULT_MESSAGE);
                  else
                    dprintf(clientReply.XMLRPC_FAULT_MESSAGE);
                }
                else{
                  var results = clientReply.data;
                  var nl=resultElement.childNodes.length;
                  for (var n=0;n<nl;n++){
                    resultElement.removeChild(resultElement.childNodes.item(nl-n-1));
                  };
				  //resultElement.innerHTML = '';
                  for (var currentResult=0;currentResult < results.length; currentResult++){
                    var currentNode = document.createElement('DIV');
                    currentNode.innerHTML = results[currentResult][pdq_field];
                    resultElement.appendChild(currentNode);
					addResultValueEvents(currentNode);
                  }
                  if (useHiddenResults){
                    resultElement.style.display = 'block';
                  }
                }
              }
            },
            'SQL.query.limitselect',
            pdq_dbid,'distinct '+pdq_field,pdq_table,whereClause,pdq_limit,0);
        }
      }
    },timeout);
  };
  
  function blurCallback(){
    hideResults();
  }
  
  this.linkElements=function(inele,outele){
    //make sure that the elements have appropriate data associated with them and that pointers are correct
    inputElement = inele;
    resultElement = outele;
    inputElement.autocomplete = 'off';  //disable native browser autocomplete
    xAddEventListener(inputElement,'keyup',keyUpCallback);
    xAddEventListener(inputElement,'blur',blurCallback);
  };
  
  this.enabled = true;
  if((!inputElement)||(!resultElement)){
    this.enabled = false;
  }
  else{
    useHiddenResults = resultElement.style.display == 'none';
    this.linkElements(inputElement,resultElement);
  }
};

SuggestControl = function(){
  this.suggestIndex = new Array;
  this.lookupTable = new Object; //find index by element name
  this.addSuggest = function(suggestConfigObject){
    if (this.lookupTable[suggestConfigObject.elementId]==null){
      var newIndex = this.suggestIndex.length;
      //console.dir(suggestConfigObject);
      var newSuggest = this.suggestIndex[newIndex] = new QuerySuggest(
        document.getElementById(suggestConfigObject.elementId),
        document.getElementById(suggestConfigObject.resultElementId),suggestConfigObject.timeout,
        suggestConfigObject.dbid,suggestConfigObject.fieldname,suggestConfigObject.tablename,suggestConfigObject.resultlimit);
      this.lookupTable[suggestConfigObject.elementId] = newIndex;
    }
    else{
      //already built; relink elements just-in-case.
      this.suggestIndex[this.lookupTable[suggestConfigObject.elementId]].linkElements(document.getElementById(suggestConfigObject.elementId),document.getElementById(suggestConfigObject.resultElementId));
    }
  };
};
document.SuggestControl = new SuggestControl();}
/* FILE:FreeanceWeb/Client/PublicKiosk1/lib/PrintManager.js */ if(!window.freeance_loaded_js['3d82bebeb7a7144858061b47b1dc0c2c']){window.freeance_loaded_js['3d82bebeb7a7144858061b47b1dc0c2c']=1;
function PrintManager_activate(){
document.printManager = new (function(){
  var $_this = this;
  var mode = '';  //<map|search>

  //base elements
  var printPopup = $('printPopup');
  var printTypeForm = null;
  
  //html printing
  var htmlpreview_container = null;
  var select_enabled = false;
  var search_enabled=true; //always allowed

  //print type radio buttons
  var printtype_mapimg_btn = null;
  var printtype_search_btn = null;
  
  //map template handling
  var mapoption_container = null;
  var maptemplate_select_container = null;
  var maptemplate_select_ele = null;
  var map_enabled=false;
  
  function clearForm()
  {
    printtype_mapimg_btn.checked = false;
    printtype_search_btn.checked = false;
    htmlpreview_container.innerHTML = '';
  };
  this.clearForm = clearForm;
  
  function setMode(newMode){
    clearForm();
    
    switch(newMode)
    {
      case 'map':
        printtype_mapimg_btn.checked = true;
        mapoption_container.style.display="block";
        htmlpreview_container.style.display="none";
        selectoption_container.style.display = 'none';
        if (map_enabled)
          setMapTemplate(parseInt(maptemplate_select_ele.value));
        break;
      case 'search':
        printtype_search_btn.checked = true;
        mapoption_container.style.display="none";
        htmlpreview_container.style.display="block";
        selectoption_container.style.display = 'none';
        xHeight(htmlpreview_container,xHeight(printPopup)-xHeight($('printmanager_header'))-xHeight($('printmanager_upperform'))-xHeight($('printmanager_footer')));
        htmlpreview_container.innerHTML = $('bottomPanelContainer').innerHTML;
        break;
      default:
        break;
    }
    mode = newMode;
  };
  this.setMode = setMode;
  
  function setMapTemplate(templateId)
  {
    $('printmanager_mapinput').innerHTML='';
    var config = document.mapObject.config.printConfig.templates[templateId];
    if(config.userinput.length)
    {
      var htmlString=['<table cellpadding="0" cellspacing="0"><tr><th style="font-size: 8pt; text-align: left; padding-left: 5px; border-right: 1px #C0C0C0 solid; border-bottom: 1px #C0C0C0 solid;">Custom Text</th><th style="font-size: 8pt;  text-align: left; padding-left: 5px; border-bottom: 1px #C0C0C0 solid;">Description</th></tr>'];
      for(var i=0;i<config.userinput.length;i++)
        htmlString.push('<tr><td style="padding-left: 5px; border-right: 1px #C0C0C0 solid; border-bottom: 1px #C0C0C0 solid;"><input type="text" FREEANCE_INDEX="'+i+'" /></td><td style="padding-left: 5px; border-bottom: 1px #C0C0C0 solid;">'+config.userinput[i].description+'</td></tr>');
      htmlString.push('</table>');
      $('printmanager_mapinput').innerHTML=htmlString.join('');
    }
  };
  this.setMapTemplate = setMapTemplate;
  
  function runPrint()
  {
    switch(mode)
    {
      case 'selection':
      case 'search':
        window.printContent = htmlpreview_container.innerHTML;
        var newwindow = window.open('./printFrame.html');
        break;
      case 'map':
        if(map_enabled){
        var config = document.mapObject.config.printConfig.templates[parseInt(maptemplate_select_ele.value)];
        document.mapObject.config.printConfig.activeTemplate = parseInt(maptemplate_select_ele.value);
        //get custom user input
        var templatevars=[];
        if(config.userinput.length){
          var inputeles = $('printmanager_mapinput').getElementsByTagName('input');
          for (var i=0;i<inputeles.length;i++){
            var freeance_index=inputeles[i].getAttribute('FREEANCE_INDEX');
            if(freeance_index){
              var inputindex=parseInt(freeance_index);
              templatevars.push([config.userinput[inputindex].id,inputeles[i].value]);
            }
          }
        }
        //get scale data
        if($('printmanager_scaletype_viewport').checked){
		  if(document.mapObject.scalebar){
		      var bestGuess = 0;
			  var scalebarConf = document.mapObject.scalebar.config;
		      var mapWidth = Math.abs(document.mapObject.extent[3]-document.mapObject.extent[2]);
		      for (var activeConfig=0;activeConfig<scalebarConf.length;activeConfig++){
		        if (scalebarConf[activeConfig][6]>mapWidth)
		          break;
		        else
		          bestGuess = activeConfig;
		      }
		      
			  var mapunits = ['ft','yd','mi','m','km'];
			  var mapunit = mapunits[scalebarConf[bestGuess][0]];
			  var barwidth = document.mapObject.mapImage.width()*(scalebarConf[bestGuess][2]/mapWidth)/90;
	          var pageunit = config.unit;
	          var scale_pagewidth = barwidth;  //width of scalebar in page units
	          var scale_mapwidth = scalebarConf[bestGuess][1];   //width of scalebar in map units
			  
			  
	          if(isNaN(scale_pagewidth)||(scale_pagewidth==0)){
	            scale_pagewidth=1;
	          }
	          if(isNaN(scale_mapwidth)||(scale_mapwidth==0)){
	            scale_mapwidth=1;
	          }
	          var scale_pageunit = $('printmanager_scalebar_pageunits').value;
	          var scale_mapunit = mapunit;
		  }
          if(scale_mapunit){
            var scale_pagewidth_adjusted = convertDistance(scale_pagewidth,scale_pageunit,pageunit);  //convert to proper page units 
            var scale_mapwidth_adjusted = convertDistance(scale_mapwidth,scale_mapunit,document.applicationConfig.mapUnits);  //convert to proper map units
            var scalebar_config = [scale_pagewidth_adjusted,scale_mapwidth,scale_mapunit];
            var scale_ratio = scale_mapwidth_adjusted/scale_pagewidth_adjusted;  //scalevalue is now ratio of map units to page units
            //size of extent:
            var mapheight = config.mapheight*scale_ratio;
            var mapwidth = config.mapwidth*scale_ratio;
            var current_extent = document.mapObject.extent;
            var mapcenter = [0.5*(current_extent[3]+current_extent[2]),0.5*(current_extent[0]+current_extent[1])];
            var maporigin = [mapcenter[0]-(0.5*mapwidth),mapcenter[1]-(0.5*mapheight)];
            var printextent = [maporigin[1],maporigin[1]+mapheight,maporigin[0],maporigin[0]+mapwidth];
            document.mapObject.print(templatevars,function(response){$_this.map_callback(response);},printextent,scalebar_config,this.extractPrintDataFromSelectionHTML());
          }
          else
            document.mapObject.print(templatevars,function(response){$_this.map_callback(response);},null,null,this.extractPrintDataFromSelectionHTML());
        }
        else{
          var pageunit = config.unit;
          var scale_pagewidth = Math.abs(parseFloat($('printmanager_scalesize').value));  //width of scalebar in page units
          var scale_mapwidth=Math.abs(parseFloat($('printmanager_scaleratio').value));   //width of scalebar in map units
          
          if(isNaN(scale_pagewidth)||(scale_pagewidth==0)){
            scale_pagewidth=1;
		  }
          if(isNaN(scale_mapwidth)||(scale_mapwidth==0)){
            scale_mapwidth=1;
		  }
            var scale_pageunit = $('printmanager_scalebar_pageunits').value
            var scale_mapunit = $('printmanager_scale_mapunits').value;
          if(scale_mapunit){
            var scale_pagewidth_adjusted = convertDistance(scale_pagewidth,scale_pageunit,pageunit);  //convert to proper page units 
            var scale_mapwidth_adjusted = convertDistance(scale_mapwidth,scale_mapunit,document.applicationConfig.mapUnits);  //convert to proper map units
            var scalebar_config = [scale_pagewidth_adjusted,scale_mapwidth,scale_mapunit];
            var scale_ratio = scale_mapwidth_adjusted/scale_pagewidth_adjusted;  //scalevalue is now ratio of map units to page units
            //size of extent:
            var mapheight = config.mapheight*scale_ratio;
            var mapwidth = config.mapwidth*scale_ratio;
            var current_extent = document.mapObject.extent;
            var mapcenter = [0.5*(current_extent[3]+current_extent[2]),0.5*(current_extent[0]+current_extent[1])];
            var maporigin = [mapcenter[0]-(0.5*mapwidth),mapcenter[1]-(0.5*mapheight)];
            var printextent = [maporigin[1],maporigin[1]+mapheight,maporigin[0],maporigin[0]+mapwidth];
            document.mapObject.print(templatevars,function(response){$_this.map_callback(response);},printextent,scalebar_config);
          }
          else
            document.mapObject.print(templatevars,function(response){$_this.map_callback(response);});

        }
        }
        break;
    }
    hide();
  };
  this.runPrint = runPrint;
  
  this.map_callback = function(response){
    document.mapObject.setWaiting(false);
    if(Freeance_Error.is_error(response))
      alert('An error occurred while printing\nError Code:'+Freeance_Error.get_code(response)+'\nDescription:  '+Freeance_Error.get_message(response));
    else
      window.open(response.data);
  };
  function show(){
    if(arguments.length>0)
      setMode(arguments[0]);
    printPopup.style.display = 'block';
  };
  this.show = show;
  
  function hide(){printPopup.style.display = 'none';};  
  this.hide = hide;
  
  function initialize(formHTML)
  {
    printPopup.innerHTML = formHTML;
    dprintf('printManager.initialize');
    printTypeForm = $('printmanager_form');
    htmlpreview_container = $('printmanager_html_preview_container');
    
    selectoption_container = $('printmanager_selection_option_container');
    printtype_mapimg_btn = $('printmanager_type_mapimage');
    printtype_search_btn = $('printmanager_type_search');
    
    xAddEventListener(printtype_mapimg_btn,'click',function(){$_this.setMode('map');});
    xAddEventListener(printtype_search_btn,'click',function(){$_this.setMode('search');});
    xAddEventListener($('printmanager_print_button'),'click',function(){$_this.runPrint();});
    xAddEventListener($('printmanager_cancel_button'),'click',function(){$_this.hide();});
    
    //build options for map templates
    mapoption_container = $('printmanager_map_option_container');
    maptemplate_select_container = $('printmanager_map_template_select_container');
    
    var mapPrintConfig = document.mapObject.config.printConfig;
    if(mapPrintConfig.templates.length==0){
      maptemplate_select_container.innerHTML = '<span class="error">No map layouts are currently defined.</span>';
    }
    else{
      var htmlString = ['<select>'];
      for (var i=0;i<mapPrintConfig.templates.length;i++){
        htmlString.push('<option value="'+i+'">'+escapeHTML(mapPrintConfig.templates[i].displayName)+' '+'('+mapPrintConfig.templates[i].width+mapPrintConfig.templates[i].unit+' x '+mapPrintConfig.templates[i].unit+mapPrintConfig.templates[i].height+') '+((mapPrintConfig.templates[i].orientation=='L')?'landscape':'portrait')+'</option>');
      }
      htmlString.push('</select>');
      maptemplate_select_container.innerHTML = htmlString.join('');
      maptemplate_select_ele = maptemplate_select_container.getElementsByTagName('select')[0];
      xAddEventListener(maptemplate_select_ele,'change',function(){$_this.setMapTemplate(parseInt(maptemplate_select_ele.value));});
      map_enabled = true;
    }
    
    //var printButton = (document.mapToolbar.showButton('printButton'))?document.mapToolbar.getButton('printButton'):document.mapToolbar.addButton('printButton',ToolBar.BUTTON_IMAGE,ToolBar.ADD_BUTTON_LAST,null,25,25,true,'print.png','Print','');
    var printButton = document.printButton;
    printButton.clickEvent = function(){show('map');};
  };
  //this.initialize = initialize;
  
	this.extractPrintDataFromSelectionHTML = function(){
		var selectionDiv = $('bottomPanelContainer');
		var trs = selectionDiv.getElementsByTagName('TR');
		var data = [];
		for(var i = 0; i < trs.length; i++){
			var tds = trs[i].getElementsByTagName('TD');
			if(tds[0].className == 'template_selectionHeading'){
				data[i] = {heading:tds[0].innerHTML};
			}
			else{
				data[i] = {label:'',values:[]};
				for(var j = 0; j < tds.length; j++){
					if(tds[j].className == "template_selectionIndex"){
						data[i].label = tds[j].innerHTML;
					}
				}
				var spans = trs[i].getElementsByTagName('SPAN');
				for(var j = 0; j < spans.length; j++){
					if(spans[j].className == "template" && spans[j].getAttribute('datavalue') != null){
						data[i].values.push(spans[j].innerHTML);
					}
				}
			}
		}
		return data;
	};
  
  XmlHttp.loadTextASync('./layouts/PrintManager.html',function(formHTML){initialize(formHTML);});
})();
}}
/* FILE:FreeanceWeb/Client/PublicKiosk1/lib/Main2.js */ if(!window.freeance_loaded_js['71421721fe1037c336fb7f1bc7353e1a']){window.freeance_loaded_js['71421721fe1037c336fb7f1bc7353e1a']=1;
languageHandler();
if(typeof(this.notifyFirebug) == "undefined")
  this.notifyFirebug = function(){};
if(typeof(parent.onFirebugReady) == "undefined")
  this.onFirebugReady = function(){};
if(typeof(console) == "undefined")
	console = {
			log: function(){},
			debug: function(){},
			info: function(){},
			warn: function(){},
			error: function(){},
			assert: function(){},
			dir: function(){},
			dirxml: function(){},
			group: function(){},
			groupEnd: function(){},
			time: function(){},
			timeEnd: function(){},
			count: function(){},
			trace: function(){},
			profile: function(){},
			profileEnd: function(){}
	};
if(!APP_URLParameters.DEBUG)
{
  console.log = function(){};
	console.debug = function(){};
	console.info = function(){};
	console.warn = function(){};
	console.error = function(){};
	console.assert = function(){};
	console.dir = function(){};
	console.dirxml = function(){};
	console.group = function(){};
	console.groupEnd = function(){};
	console.time = function(){};
	console.timeEnd = function(){};
	console.count = function(){};
	console.trace = function(){};
	console.profile = function(){};
	console.profileEnd = function(){};
}

/* Set global constants that control page layout */
/* These can be overridden by the application config if necessary */
_PageHeaderHeight = 70;  //if this is set to 0, no page header will be displayed.
_MapToolBarWidth = 30;
_MapDetailToolbarWidth = 50;  //width in pixels of the text adjacent to the map toolbar buttons
_LeftColumnWidth = 250;
_SchemeButtonRowHeight = 35;
_MapImagePadding = 4;
_TextResultTabHeight = 20;
_TextResultPanelHeight = 50;
_EnableLeftPanel = true;
_EnableLayerControl = true;
_DisplayLayerControl = false;
_EnableLegend = true;
_DisplayLegend = true;
_CustomLegendURL = '';

//These can be overridden in the theme configuration
_ZoomBarCellHeight = 11;  //height of an individual element in the zoom bar
_ZoomBarStartColor = '#FFA701';  //'Zoom In' end of zoom bar
_ZoomBarEndColor = '#FCFCFC';    //zoom out end of zoom bar
_ZoomBarActiveColor = '#FF0000';    //zoom out end of zoom bar
_ZoomBarRatio = 0.01;
_ScrollToTopSpeed = 500;  // default
_ScrollToMapSpeed = 1000;  // default
_ScrollToSearchResultsSpeed = 1000;  // default

_SearchToolCount = 0;

GUI_THEME_PATH = './themes';      //can be overridden from application config
GUI_THEME =      '';               //will be defined from application config

document.setSessionID = function(newID){ document.sessionID = newID; };
document.getSessionID = function() { return(document.sessionID); };
document.dynamicExtensions = new Object; // IDEA: DE
document.mapToolIdTable = new Object;
document.registeredSearches = new Array('findAddress','findIntersection','findNearby');
document.activeSearch = null;

window.onload = function()
{
  /*load */
  formatBaseLayout();
  xAddEventListener(window, 'resize', winOnResize, false);

  //add event handler to buffer form
  for (var currentId in {'bufferDistanceInput':null,'bufferDistanceUnitInput':null})
  {
    if(currentId=='toJSONString')continue;
    var currentElement = document.getElementById(currentId);
    xAddEventListener(currentElement,'keypress',function (e){evt=new xEvent(e);if (evt.keyCode==13){bufferButtonClick();}});
  }
  dynamicLoadExtensions();
};

function verifyXMLDocument(newXMLDoc)
{
  /**************************
	   generic xml document validator; makes sure that it actually loaded; nothing more.
	 **************************/
  var returnValue = true;
  if (newXMLDoc == null)
	returnValue = false;
  else
  {
    var xmlstr = (typeof(newXMLDoc.xml)=='function')?newXMLDoc.xml():newXMLDoc.xml;
    if (xmlstr == '')
      returnValue = false;
    else
      if (newXMLDoc.documentElement.nodeName == 'parsererror')
        returnValue = false;
  }
  return returnValue;
};

/* Start of dynamicLoad stuff here */
function dynamicLoadExtensions()
{
  document.configDoc = XmlHttp.loadSync(CONFIG_XML);
  if (!verifyXMLDocument(document.configDoc))
  {
    loadConfig(document.configDoc);
    return;
  }
  var extensions = document.configDoc.getElementsByTagName('extension');
  var dynamicCount = 0;

  //assemble initial list of extensions to load.
  for(var lcv=0;lcv < extensions.length;lcv++)
  {
    var dynamicFile = '';
    try {
      dynamicFile = extensions[lcv].getAttribute('dynamicfile');
    } catch(e) { dynamicFile = null; }

    if ((dynamicFile != '') && (dynamicFile != null) && (extensions[lcv].getAttribute('enabled')=='true'))
    {
      dynamicCount++;
      var requestInfo = extensions[lcv].getAttribute('name');
      document.dynamicExtensions[requestInfo] = { loaded:false, initcode:'',dynamicFile:dynamicFile };
    }
  }

  if (dynamicCount > 0)
  {
    for(var currentExtension in document.dynamicExtensions)
    {
      if(currentExtension=='toJSONString')continue;
      XmlHttp.loadTextAsync2(document.dynamicExtensions[currentExtension]['dynamicFile'],dynamicLoadExtensionCallback,currentExtension);
    }
  }
  else // no extensions need loaded, just load as usual
	loadConfig(document.configDoc);
}

function dynamicLoadExtensionCallback(extJS,requestInfo) // IDEA:DE
{
  document.dynamicExtensions[requestInfo].loaded = true;
  try { eval(extJS); }
	catch(e)
  { /* faulty load */
	  alert('Load failed on extension '+requestInfo+'.\n'+e+': Line '+e.lineNumber+' of '+e.fileName);
		//alert("An exception occurred in the script. Error name: " + e.name + ". Error message: " + e.message);
		delete(document.dynamicExtensions[requestInfo]);
  }
  for(var idx in document.dynamicExtensions)
  {
    if(idx=='toJSONString')continue;
    if (document.dynamicExtensions[idx].loaded == false)
      return;
  }
  // we were last extension to load, continue on with process
  loadConfig(document.configDoc);
}
/* End of dynamicLoad stuff here */

function loadConfig (loadedDocument)
{
  var returnValue = null;
  if (!verifyXMLDocument(loadedDocument))
    document.write('<span class="criticalError">'+document.babelfish.translateWord('Unable to load config file!')+'</span>',true);
  else
  {
    document.freeance_config_parser = new FreeanceXMLParser();  //extended version of the base xml parser that reads freeance configurations
    document.freeance_config_parser.setDocumentByDoc(loadedDocument);

    //Set basic application config
    var applicationConfig = document.freeance_config_parser.getObject('applicationConfig');
    document.applicationConfig = applicationConfig;
    if(applicationConfig.customOptions.showDisclaimer){
      $('disclaimerTextContainer').innerHTML = applicationConfig.customOptions.disclaimerText;
      $('disclaimerButtons').style.display = 'block';
      xAddEventListener($('denyDisclaimerButton'),'click',function(){window.location.href=applicationConfig.customOptions.disclaimerURL;});
    }
    else{
      $('disclaimerContainer').style.display='none';
    }
    document.title = applicationConfig.title + ':   '+document.babelfish.translateWord('Powered By Freeance')+' '+FREEANCE_VERSION+' - TDC Group Inc.';
    initGuiLib(applicationConfig.stylesheet);
    try{
      eval(XmlHttp.loadTextSync('./themes/'+applicationConfig.stylesheet+'/themeVars.js'));
      formatBaseLayout(); //if custom javascript exists, adjust page layout to compensate
    }
    catch(e){
      alert('unable to load custom theme javascript\nError Details:\n'+describeObject('',e,'\n'));
    }
    if (applicationConfig.customOptions != null)
    {
      _PageHeaderHeight = applicationConfig.customOptions.pageHeaderHeight;
      _EnableLeftPanel = applicationConfig.customOptions.leftPanelDisplay;
      _EnableLegend = applicationConfig.customOptions.legendEnable;
      _DisplayLegend = applicationConfig.customOptions.legendDisplay;
      _EnableLayerControl = applicationConfig.customOptions.layerEnable;
      _DisplayLayerControl = applicationConfig.customOptions.layerDisplay;
      _TextResultPanelHeight = applicationConfig.customOptions.resultPanelHeight;
      _CustomLegendURL = applicationConfig.customOptions.customLegendURL;

      if (_PageHeaderHeight==0)
        document.getElementById('pageHeader').style.display = 'none';
      if (!_EnableLeftPanel){
        _LeftColumnWidth = 0;
        document.getElementById('leftColumnContainer').style.display = 'none';
      }
      if (!_EnableLegend)
      {
        document.getElementById('mapLegendPanelToggle').style.display = 'none';
        document.getElementById('mapLegendPanel').style.display = 'none';
      }
      else
        document.getElementById('mapLegendPanel').style.display = (_DisplayLegend?'block':'none');
      if (!_EnableLayerControl)
      {
        document.getElementById('mapLayerControlToggle').style.display = 'none';
        document.getElementById('mapLayerControl').style.display = 'none';
      }
      else
        document.getElementById('mapLayerControl').style.display = (_DisplayLayerControl?'block':'none');
    }

    /** Map Initialization **/
    var extensionConfig = document.freeance_config_parser.getObject('extensionConfig');
    document.extensionConfig = extensionConfig;
    var mapConfig = document.freeance_config_parser.getObject('mapConfig');
    var templateConfig = document.freeance_config_parser.getObject("templateConfig",null);
    if (templateConfig['UserIntro']!=null)
    {
      if (applicationConfig.customOptions.customPanelPosition!=0)
      {
        //USERINTRO_POSITION_5
        var containerHandle = document.getElementById('userIntroContainer');
        containerHandle.parentNode.removeChild(containerHandle);
        document.getElementById('leftColumnContainer').insertBefore(containerHandle,document.getElementById('USERINTRO_POSITION_'+applicationConfig.customOptions.customPanelPosition));
        containerHandle.style.display = 'block';
        document.getElementById('userIntroToggle').innerHTML = applicationConfig.customOptions.customPanelTitle;
        document.getElementById('userIntroPanelForm').innerHTML = templateConfig['UserIntro'];
      }
    }
    document.getElementById('pageHeader').innerHTML = templateConfig["PageHeader"];
    document.mapObject = new Map('map0');
    document.mapObject.setConfig(mapConfig);
    if (document.mapObject.config.mapSchemeConfig==null)
      _SchemeButtonRowHeight=0;
    if (_CustomLegendURL!='')
      document.mapObject.customLegendImage = _CustomLegendURL;
    drawScriptedMapImage();
    document.layerControl = new LayerControl(document.getElementById('layerControlContainer'));

    if (document.mapObject.selectionsExist)
    {
      var selectionPanel = document.createElement('DIV');
      document.selectionControl = new SelectionControl('map0SelectionControl',document.mapObject,null, document.getElementById('bottomPanelContainer'));
      document.selectionControl.onSelectionDisplay = function()
      {
        document.selectionControl.selectionPanel.style.display = 'block';
        document.getElementById('textResultTabContainer').innerHTML = 'Found At This Location';
      };
    }
    else
      document.selectionControl = null;
    if (document.mapObject.selectionsExist && document.mapObject.buffersExist)
    {
      var bufferPanel = document.createElement('DIV');
      document.getElementById('bottomPanelContainer').appendChild(bufferPanel);
      bufferPanel.style.display = 'none';
      document.bufferControl = new BufferControl('map0BufferControl',document.mapObject,null, bufferPanel);
      _SearchToolCount++;
      //set up 'find nearby' tool
      document.getElementById('findNearbyTool').style.display = 'block';
      var bufferThemeSelectString = '<select id="bufferThemeSelectInput">';
      for (var bufferThemeIndex = 0; bufferThemeIndex < document.mapObject.bufferableThemes.length; bufferThemeIndex++)
      {
        var currentTheme = document.mapObject.bufferableThemes[bufferThemeIndex];
        bufferThemeSelectString+='<option value="'+currentTheme+'">'+document.mapObject.config.themes[document.mapObject.bufferableThemes[bufferThemeIndex]].themeName+'</option>';
      }
      bufferThemeSelectString+='</select>';
      document.getElementById('bufferThemeSelectContainer').innerHTML = bufferThemeSelectString;
      document.bufferControl.onBufferDisplay = function()
      {
        document.queryControl.clearResults();
        document.mapObject.clearAllSelections();
        document.mapObject.clearAllGeocodePoints();
        document.bufferControl.resultTarget.style.display = 'block';
        var usePlural = (document.bufferControl.currentBufferCount!=1);
        document.getElementById('textResultTabContainer').innerHTML = document.bufferControl.currentBufferCount+' Feature'+((usePlural)?('s'):(''))+' Found Nearby';
      };
      document.bufferControl.onBufferClear = function()
      {
        this.resultTarget.style.display = 'none';
      };
    }
    else
    {
      document.bufferControl = null;
      document.getElementById('findNearbyTool').style.display = 'none';
    }

    if (document.mapObject.config.geocodeConfig != null)
    {
      if (extensionConfig.geocodeAddress.enabled)
        _SearchToolCount++;
      else
        document.getElementById('findAddressExtForm').style.display = 'none';
      if (extensionConfig.geocodeIntersection.enabled)
        _SearchToolCount++;
      else
        document.getElementById('findIntersectionExtForm').style.display = 'none';
    }
    else
    {
      document.getElementById('findAddressExtForm').style.display = 'none';
      document.getElementById('findIntersectionExtForm').style.display = 'none';
    }

    /** QUERY INITIALIZATION **/
    var queryConfig = document.freeance_config_parser.getObject('queryConfig');
    document.queryControl.setConfig(queryConfig);
    if (document.queryControl.numQueries > 0)
    {
      for (var currentQuery in document.queryControl.config){
        if(currentQuery=='toJSONString') continue;
        if(!document.queryControl.config[currentQuery]['display']) continue;
        _SearchToolCount++;
      }
      var queryFormPanelElement = document.getElementById('customQueryFormContainer');
      var queryResultPanel = document.createElement('DIV');
      document.getElementById('bottomPanelContainer').appendChild(queryResultPanel);
      queryResultPanel.style.display = 'none';
      document.queryControl.setFormPanel(queryFormPanelElement);
      document.queryControl.drawFormPanel();
      document.queryControl.setResultTarget(queryResultPanel);
      queryFormPanelElement.style.display = 'block';
      document.queryControl.onQuerySubmit = function ()
      {
        clearAllData();
        document.mapObject.setWaiting(true);
      };
      document.queryControl.onQueryReturn = function ()
      {
        document.queryControl.resultTarget.style.display = 'block';
        document.mapObject.setWaiting(false);
      };
    }
    clearSearchResultPanel = clearAllData;
    document.getElementById('searchPanelContainer').style.display = ((_SearchToolCount==0)?('none'):('block'));

    /** PRINT INITIALIZATION **/
    var printConfig = mapConfig.printConfig;

    /** SET DEFAULT VALUES FOR EXTENSIONS **/
    document.measureControl = null;
    document.markupControl = null;

    /** EXECUTE INITIALIZTION CODE FOR EXTENSIONS **/
    for(var idx in document.dynamicExtensions)
    {
      if(idx=='toJSONString')continue;
      if (typeof(document.dynamicExtensions[idx].initcode) == 'string')
      {
        try { eval(document.dynamicExtensions[idx].initcode); }
        catch(e) { }
      }
      else // function
      {
        try { document.dynamicExtensions[idx].initcode(document.freeance_config_parser); }
        catch(e)
        {
          alert('initCode failed for '+idx+'\n'+e+'\nLine: '+e.lineNumber+' of '+e.fileName); //note: this doesn't always give information
          //alert("An exception occurred in the script. Error name: " + e.name + ". Error message: " + e.message);
        }
      }
    }

    drawMapToolbar();
    if (mapConfig.mapSchemeConfig != null)
    {
      if(mapConfig.mapSchemeConfig.mapSchemes.length>0)
        drawMapSchemeToolbar(mapConfig.mapSchemeConfig.defaultMapScheme);
    }
  }

  //set zoom in as the active tool
  setActiveMapTool('ZoomIn');
  formatBaseLayout(); //sanity check

  //disable area fill for unsupported browsers
  if (document.measureControl!=null)
    if (!document.measureControl.canvasEnabled)
      document.getElementById('measureControlAreaDrawContainer').style.display = 'none';

  if ((extensionConfig.scalebar!=null) && (extensionConfig.scalebar.enabled))
    document.mapObject.scalebar = new Scalebar();
  if ((extensionConfig.compass!=null) && (extensionConfig.compass.enabled))
    document.mapObject.mapImage.showCompass();
  document.mapObject.setLegendImage(document.getElementById('mapLegendImage',true));

  if ((document.queryControl.shownQueries > 0)||(document.mapObject.selectionsExist)||(document.mapObject.buffersExist)||(document.mapObject.config.printConfig.templates.length>0))
  {
    //see if map print configurations exist and add button if appropriate
    document.printButton = document.mapToolbar.addButton('printMapButton',ToolBar.BUTTON_IMAGE,ToolBar.ADD_BUTTON_LAST,null,25,25,225,true,'toolBar.png','Print');
    //printButton.clickEvent = function (e) {if (document.mapObject.sessionID!=null){document.mapObject.print();}};
    PrintManager_activate();  //loadJavaScript('./lib/PrintManager.js');
  }

  if (document.mapObject.config.mapSchemeConfig!=null)
    if(mapConfig.mapSchemeConfig.mapSchemes.length>0)
      document.mapObject.initialize('',document.mapObject.config.mapSchemeConfig.defaultMapScheme);  //initialize a new session for the map.
    else
      document.mapObject.initialize('');  //initialize a new session for the map.
  else
    document.mapObject.initialize('');  //initialize a new session for the map.
}

function formatBaseLayout()
{
  var clientWidth = xClientWidth();
  var clientHeight = xClientHeight();
  //arrange the page elements based on the application layout constants
  xHeight(document.getElementById('pageHeader'),_PageHeaderHeight);

  //if map schemes are present, adjust interface to match.
  if (document.mapObject!=null)
  {
    if (document.mapObject.config.mapSchemeConfig!=null)
    {
      if(document.mapObject.config.mapSchemeConfig.mapSchemes.length>0){
        xHeight(document.getElementById('mapSchemeButtonContainer'),_SchemeButtonRowHeight);
        xWidth(document.getElementById('mapSchemeButtonContainer'),xClientWidth()-_LeftColumnWidth);
        xTop(document.getElementById('mapSchemeButtonContainer'),_PageHeaderHeight);
        xLeft(document.getElementById('mapSchemeButtonContainer'),_LeftColumnWidth);
        document.getElementById('mapSchemeButtonContainer').style.display = 'block';
      }
      else
        document.getElementById('mapSchemeButtonContainer').style.display = 'none';
    }
    else
      document.getElementById('mapSchemeButtonContainer').style.display = 'none';
  }
  xTop(document.getElementById('leftColumnContainer'),_PageHeaderHeight);
  xWidth(document.getElementById('leftColumnContainer'),_LeftColumnWidth);
  xLeft(document.getElementById('leftColumnContainer'),0);

  xTop(document.getElementById('textResultTabContainer'),xClientHeight()-_TextResultTabHeight-_TextResultPanelHeight);
  xHeight(document.getElementById('textResultTabContainer'),_TextResultTabHeight);
  xWidth(document.getElementById('textResultTabContainer'),xClientWidth()-_MapImagePadding-_LeftColumnWidth-35);
  xLeft(document.getElementById('textResultTabContainer'),_LeftColumnWidth);

  xTop(document.getElementById('bottomPanelContainer'),xClientHeight()-_TextResultPanelHeight);
  xWidth(document.getElementById('bottomPanelContainer'),xClientWidth()-_MapImagePadding-_LeftColumnWidth-35);
  xLeft(document.getElementById('bottomPanelContainer'),_LeftColumnWidth);

  //print popup window
  var printPopup = $('printPopup');
  var printFrame = $('printFrame');
  var printWidth = 0.75*clientWidth;
  var printHeight = 0.75*clientHeight;
  var printLeft = 0.125*clientWidth;
  var printTop = 0.125*clientHeight;
  xLeft(printPopup,printLeft);
  xTop(printPopup,printTop);
  xWidth(printPopup,printWidth);
  xHeight(printPopup,printHeight);
  xWidth(printFrame,printWidth);
  xHeight(printFrame,printHeight-20);
}

winOnResize = function()
{
  var cw = xClientWidth(), ch = xClientHeight();
  //reset map width (height is preserved)
  document.mapObject.mapImage.width(xClientWidth()-_MapToolBarWidth-_MapImagePadding_Top-_LeftColumnWidth-35);

  var mapTop = _PageHeaderHeight+_MapImagePadding+_SchemeButtonRowHeight;
  var mapLeft = _LeftColumnWidth+_MapToolBarWidth;
  var mapWidth = xClientWidth()-_MapToolBarWidth-_MapImagePadding-_LeftColumnWidth-35; //the 35 compensates for the browser scroll bar
  var mapHeight = xClientHeight()-_PageHeaderHeight-_SchemeButtonRowHeight-_TextResultTabHeight-_TextResultPanelHeight;
  document.mapObject.mapImage.resizeTo(mapWidth,mapHeight);
  document.mapToolbar.height(mapHeight);

  var zoomBarTop = mapTop+(document.mapObject.mapImage.height() / 4);
  var zoomBarLeft = mapLeft+document.mapObject.mapImage.width()+1;
  var zoomBarHeight = document.mapObject.mapImage.height() / 2;

  document.zoomBar.rebuild(zoomBarHeight);
  document.zoomBar.top(zoomBarTop);
  document.zoomBar.left(zoomBarLeft);

  //reset map scheme button container width
  xWidth(document.getElementById('mapSchemeButtonContainer'),xClientWidth()-_LeftColumnWidth);

  //reset text result tab container width
  var bottomPanelWidth = xClientWidth()-_MapToolBarWidth-_MapImagePadding-_LeftColumnWidth;
  xWidth(document.getElementById('textResultTabContainer'),bottomPanelWidth);
  xWidth(document.getElementById('bottomPanelContainer'),bottomPanelWidth);
  xTop(document.getElementById('textResultTabContainer'),xClientHeight()-_TextResultTabHeight-_TextResultPanelHeight);
  xTop(document.getElementById('bottomPanelContainer'),xClientHeight()-_TextResultPanelHeight);
  xLeft(document.getElementById('textResultTabContainer'),_LeftColumnWidth);

  if(document.mapSchemeControl)
	  document.mapSchemeControl.resize();

  //redraw the map
  if (document.mapObject.sessionID!=null)
    document.mapObject.redraw();
};

function runCMDs()
{
  /**TODO:  ENABLE MULTIPLE PARAMETERS TO BE ACCEPTED! **/
  /**THIS CAN BE DONE BY SEPARATING THEM WITH SEMICOLONS PROBABLY....**/
  if (APP_URLParameters["CMD"] == null)
    return;
  var cmdName = APP_URLParameters["CMD"];
  switch (cmdName)
  {
    case 'zoomTo': runCMD_zoomTo(); break;
    case 'extent': runCMD_extent(); break;
  }
}

function runCMD_zoomTo()
{
  var themeID = APP_URLParameters["THEMEID"];
  if (themeID==null)
    themeID = APP_URLParameters["THEMENAME"];
  var fieldName = APP_URLParameters["FIELDNAME"];
  var fieldValue = APP_URLParameters["FIELDVALUE"];
  document.mapObject.zoomTo_(themeID,fieldName,null,fieldValue,(document.selectionControl!=null));
};

function runCMD_extent()
{
  var b=parseFloat(APP_URLParameters["B"]);
  var t=parseFloat(APP_URLParameters["T"]);
  var l=parseFloat(APP_URLParameters["L"]);
  var r=parseFloat(APP_URLParameters["R"]);
  document.mapObject.zoomToExtent([b,t,l,r]);
};

/***********************************************************
  default mouse up handler for document; useful sometimes
***********************************************************/
function winMouseUpListener(evt)
{
  if (document.mouseUpCallbackObject)
    document.mouseUpCallbackObject.mouseUpCallback(evt);
}
function initGuiLib(guiTheme)
{
  GUI_THEME = guiTheme;
  GuiWidget.THEME_PATH = './themes';
  GuiWidget.THEME = GUI_THEME;
  var themeName = guiTheme.toLowerCase();
  switch(themeName)
  {
	case 'default':
	  document.addStylesheet('../../../Freeance/Server/GetResourceBundle.php?clienttype=pik1&bundlename=theme_'+themeName+'&bundletype=text/css');
	  break;
	default:
	  document.addStylesheet(GuiWidget.THEME_PATH+'/'+GuiWidget.THEME+'/guilib.css');
	  document.addStylesheet(GuiWidget.THEME_PATH+'/'+GuiWidget.THEME+'/freeance.css');
  }
  GuiWidget.tooltipOffset = new Array(15,5);
  GuiWidget_onLoad();
}

function drawScriptedMapImage()
{
  /*****************
	   set up a map and vicinity map image panel for the map control.
	 *******************/
  var pageContainer = document.body;
  var mapTop = _PageHeaderHeight+((document.mapObject.config.mapSchemeConfig==null)?(0):((document.mapObject.config.mapSchemeConfig.mapSchemes.length>0)?(_MapImagePadding_Top+_SchemeButtonRowHeight):0));
  var mapWidth = xClientWidth()-_MapToolBarWidth-_MapImagePadding-_LeftColumnWidth-35; //the 35 compensates for the browser scroll bar
  var mapHeight = xClientHeight()-_PageHeaderHeight-_SchemeButtonRowHeight-_TextResultTabHeight-_TextResultPanelHeight;
  var mapLeft = _LeftColumnWidth+_MapToolBarWidth;
  var scriptedMapImage = new MapImage('scriptedMapImage', pageContainer,mapLeft,mapTop,0,mapWidth,mapHeight,true,document.mapObject,'MASTER');
  document.mapObject.mapImage = scriptedMapImage;
  scriptedMapImage.setMouseMode('ZoomWindow');

  var zoomBarTop = mapTop+(mapHeight / 4);
  var zoomBarLeft = mapLeft+mapWidth+1;
  var zoomBarHeight = mapHeight / 2;
  document.zoomBar = new ZoomBar('zoomBar', pageContainer, zoomBarLeft, zoomBarTop, 1, true, document.mapObject, _ZoomBarRatio, zoomBarHeight,_ZoomBarStartColor,_ZoomBarEndColor,_ZoomBarActiveColor);

  if (document.mapObject.vmapPresent)
  {
    var overviewMapContainer = document.getElementById('overviewMapContainer');
    var imageWidth = xWidth(overviewMapContainer);
    document.overviewMapImage = new MapImage('scriptedVmapImage', overviewMapContainer, 0, 0, 0,imageWidth,document.applicationConfig.vmapHeight,true,document.mapObject,'SLAVE');

    document.mapObject.vmapImage = document.overviewMapImage;
    document.overviewMapImage.element.style.position = 'relative';
    document.getElementById('overviewMapPlaceholder').style.display = 'none';
    _VicinityMapExists = true;
  }
  else
  {
    document.getElementById("overviewMapPanelToggle").style.display = 'none';
    document.getElementById("overviewMapPanel").style.display = 'none';
  }
}

function drawMapToolbar()
{
  var mapConfig = document.mapObject.config;
  var pageContainer = document.getElementById('pageContainer');
  var mapToolbar = document.mapToolbar = new ToolBar('mapToolbar', pageContainer, _LeftColumnWidth, _PageHeaderHeight+((document.mapObject.config.mapSchemeConfig==null)?(0):((document.mapObject.config.mapSchemeConfig.mapSchemes.length>0)?(_MapImagePadding_Top+_SchemeButtonRowHeight):0)), 0, _MapToolBarWidth,xClientHeight()-_PageHeaderHeight-_SchemeButtonRowHeight-_TextResultTabHeight-_TextResultPanelHeight, true, '', ToolBar.ALIGN_VERTICAL);
  var mapCursorRadioButtonGroup = mapToolbar.mapCursorRadioButtonGroup = new RadioButtonGroup('mapCursorRadioButtonGroup');

  var zoomInButton = mapToolbar.addButton('zoomInButton',ToolBar.BUTTON_RADIO,ToolBar.ADD_BUTTON_LAST,null,25,25,125,true,'toolBar.png','Zoom In',mapCursorRadioButtonGroup,'');
  var zoomOutButton = mapToolbar.addButton('zoomOutButton',ToolBar.BUTTON_RADIO,ToolBar.ADD_BUTTON_LAST,null,25,25,75,true,'toolBar.png','Zoom Out',mapCursorRadioButtonGroup,'');
  var panButton = mapToolbar.addButton('panButton',ToolBar.BUTTON_RADIO,ToolBar.ADD_BUTTON_LAST,null,25,25,0,true,'toolBar.png','Move / Recenter',mapCursorRadioButtonGroup,'');

  zoomInButton.clickEvent = function () {document.getWidgetById('scriptedMapImage').setMouseMode('ZoomWindow');setActiveMapTool('ZoomIn');/*document.getElementById('mapToolPanelNameField').innerHTML = document.babelfish.translateWord('Zoom In');*/};
  document.mapToolIdTable['ZoomIn'] = 'Zoom In';
  zoomOutButton.clickEvent = function () {document.getWidgetById('scriptedMapImage').setMouseMode('ZoomOut');setActiveMapTool('ZoomOut');/*document.getElementById('mapToolPanelNameField').innerHTML = document.babelfish.translateWord('Zoom Out');*/};
  document.mapToolIdTable['ZoomOut'] = 'Zoom Out';
  panButton.clickEvent = function () {document.getWidgetById('scriptedMapImage').setMouseMode('DragMap');setActiveMapTool('Pan');/*document.getElementById('mapToolPanelNameField').innerHTML = document.babelfish.translateWord('Pan / Recenter');*/};
  document.mapToolIdTable['Pan'] = 'Recenter';

  //If the map configuration has selectable themes, include a selection button on the toolbar
  if (document.mapObject.selectionsExist)
  {
    var selectButton = mapToolbar.addButton('selectButton',ToolBar.BUTTON_RADIO,ToolBar.ADD_BUTTON_LAST,null,25,25,150,true,'toolBar.png','Get More Information',mapCursorRadioButtonGroup,'');
    document.mapToolIdTable['Select'] = 'Get Information';
    selectButton.clickEvent = function ()
    {
      /** NOTE: THIS CLIENT DOES NOT HAVE AN 'ACTIVE THEME' CONCEPT **/
      document.getWidgetById('scriptedMapImage').setMouseMode('Select');
      setActiveMapTool('Select');
      if (document.activeSearch!=null)
        toggleSearchForm(document.activeSearch);
    };
    document.mapObject.onSelect = function(){};
  }
	if(document.measureControl != null)
  {
	  var measureButton = mapToolbar.addButton('measureButton',ToolBar.BUTTON_RADIO,ToolBar.ADD_BUTTON_LAST,null,25,25,25,true,'toolBar.png','Measure',mapCursorRadioButtonGroup,'');
	  document.mapToolIdTable['MeasureDistance'] = 'Measure';
	  if (measureButton != null)
	  {
      document.measureControl.setDisplayElement(document.getElementById('measurePanelDistanceContainer'));
      document.measureControl.setAreaDisplayElement(document.getElementById('measurePanelAreaContainer'));
      measureButton.clickEvent = function (e)
      {
        document.getWidgetById('scriptedMapImage').setMouseMode('MeasureDistance');
        setActiveMapTool('MeasureDistance');
      };
      measureButton.setInactiveEvent = function()
      {
        document.measureControl.distanceReset();
      };
	  }
  }

  var redrawButton = mapToolbar.addButton('redrawButton',ToolBar.BUTTON_IMAGE,ToolBar.ADD_BUTTON_LAST,null,25,25,200,true,'toolBar.png','Refresh Map');
  var backButton = mapToolbar.addButton('backButton',ToolBar.BUTTON_IMAGE,ToolBar.ADD_BUTTON_LAST,null,25,25,50,true,'toolBar.png','Go Back to Last Location');
  var homeButton = mapToolbar.addButton('zoomInitialButton',ToolBar.BUTTON_IMAGE,ToolBar.ADD_BUTTON_LAST,null,25,25,100,true,'toolBar.png','Go to Map Home View');

  redrawButton.clickEvent = function (e) {if (document.mapObject.sessionID!=null){document.mapObject.redraw();}};
  backButton.clickEvent = function(){if (document.mapObject.sessionID!=null){document.mapObject.zoomToPrevious();}};
  homeButton.clickEvent = function (e) {if (document.mapObject.sessionID!=null){document.mapObject.zoomInitialExtent();}};
  if ((document.extensionConfig.saveMap) && (document.extensionConfig.saveMap.enabled))
  {
    var saveMapButton = mapToolbar.addButton('saveMapButton',ToolBar.BUTTON_IMAGE,ToolBar.ADD_BUTTON_LAST,null,25,25,175,true,'toolBar.png','Save Map Image');
    saveMapButton.clickEvent = function (e) {window.open(document.mapObject.mapImage.imageNode.src);};
  }
  //set zoom in as the active tool
  if (xIE4Up)
    window.setTimeout('setInitialMapTool();document.mapToolbar.updateButtons();',1000);
  else
    setInitialMapTool();
}
function setInitialMapTool()
{
  document.mapToolbar.mapCursorRadioButtonGroup.setActiveButton('zoomInButton');
  setActiveMapTool('ZoomIn');
}

MapSchemeControl = function(){
	var mapConfig = document.mapObject.config;
	var mapSchemeButtons = [];
	var leftmostTab = 0;

	activeScheme = arguments.length>0?parseInt(arguments[0]):0; //global

	if (mapConfig.mapSchemeConfig != null)
	{
		var mapSchemeButtonContainer = $('mapSchemeButtonContainer');

		var currentTab = 0;

		var wrapper = document.createElement("div");
		mapSchemeButtonContainer.appendChild(wrapper);
		wrapper.style.position="absolute";
		wrapper.style.display="block";
		wrapper.style.overflow="hidden";
		wrapper.style.top="10px";
		wrapper.style.paddingTop="0px";

		var tabContainer = document.createElement("table");
		wrapper.appendChild(tabContainer);
		xTop(wrapper,10);

		tabContainer.setAttribute("border",0);
		tabContainer.setAttribute("cellPadding",0);
		tabContainer.setAttribute("cellSpacing",0);
		tabContainer.style.position="relative";
		tabContainer.style.display="block";
		xTop(tabContainer,0);

		var buttonLeft = new ImageButton('mapSchemeLeftScroll',mapSchemeButtonContainer,2, 10, 2,20,20,0,true,'tabControl.png','');
		buttonLeft.imageNode.style.filter = 'progid:DXImageTransform.Microsoft.AlphaImageLoader(src=\''+buttonLeft.imageNode.src+'\', sizingMethod=\'image\')';
		buttonLeft.imageNode.style.height = 50;
		
		var buttonRight = new ImageButton('mapSchemeRightScroll',mapSchemeButtonContainer,2, 10, 2,	20,20,25,true,'tabControl.png','');
		buttonRight.imageNode.style.filter = 'progid:DXImageTransform.Microsoft.AlphaImageLoader(src=\''+buttonRight.imageNode.src+'\', sizingMethod=\'image\')';
		buttonRight.imageNode.style.height = 50;

		buttonLeft.clickEvent = function(){
			var taboffset=0;
			leftmostTab--;
			for (var i=0;i<leftmostTab;i++) {
				taboffset+=xWidth(mapSchemeButtons[i]);
			}
			xLeft(tabContainer,-taboffset);
		}
		buttonRight.clickEvent = function(){
			var taboffset=0;
			leftmostTab++;
			for (var i=0;i<leftmostTab;i++) {
				taboffset+=xWidth(mapSchemeButtons[i]);
			}
			xLeft(tabContainer,-taboffset);
		}
		mapSchemeButtonContainer.style.overflow="hidden";
		mapSchemeButtonContainer.style.paddingLeft="0px";
		xLeft(wrapper,20);
		var tabrow = tabContainer.insertRow(0);
		var schemeCount = mapConfig.mapSchemeConfig.mapSchemes.length;
		for (var currentScheme =0;currentScheme<schemeCount;currentScheme++)
		{
			var isActive=(mapConfig.mapSchemeConfig.mapSchemes[currentScheme]["id"]==activeScheme);
			if(isActive){
				currentTab = currentScheme;
			}
			var tabCell = tabrow.insertCell(currentScheme);
			var theTab = document.createElement("table");

			theTab.className="schemeButtonTable";
			theTab.setAttribute("id","mapScheme"+currentScheme+"Container");
			theTab.setAttribute("cellPadding",0);
			theTab.setAttribute("cellSpacing",0);
      
      if(mapConfig.mapSchemeConfig.mapSchemes[currentScheme].link){
        (function(theTab,currentScheme){xAddEventListener(theTab,"click",function(){
          document.mapObject.newWindowExtent('../../Client/'+mapConfig.mapSchemeConfig.mapSchemes[currentScheme].clientType+'/index.html?appconfig='+escape(mapConfig.mapSchemeConfig.mapSchemes[currentScheme].link));
        });})(theTab,currentScheme);
      }
      else if(mapConfig.mapSchemeConfig.mapSchemes[currentScheme].extLink){
        (function(theTab,currentScheme){xAddEventListener(theTab,"click",function(){
          document.mapObject.newWindowExtent(mapConfig.mapSchemeConfig.mapSchemes[currentScheme].extLink);
        });})(theTab,currentScheme);
      }
      else{
        (function(theTab,currentScheme){xAddEventListener(theTab,"click",function(){setActiveMapScheme(currentScheme)});})(theTab,currentScheme);
      }

			var tr = theTab.insertRow(0);
			var td1 = tr.insertCell(0);
			var td2 = tr.insertCell(1);
			var td3 = tr.insertCell(2);

			td1.className = "schemeButtonLeft"+(isActive?'_active':'');
			td2.className = "schemeButtonCenter"+(isActive?'_active':'');
			td3.className = "schemeButtonRight"+(isActive?'_active':'');

			td1.innerHTML = '<div style="width:10px;">&nbsp;</div>';
			td2.innerHTML = '<div style="width:10px;">&nbsp;</div>';
			td3.innerHTML = '<div style="width:10px;">&nbsp;</div>';

			//td2.appendChild(document.createTextNode(mapConfig.mapSchemeConfig.mapSchemes[currentScheme].name));
			td2.innerHTML = '<span style="white-space:nowrap;">'+escapeHTML(mapConfig.mapSchemeConfig.mapSchemes[currentScheme].name).replace(/ /g,'&nbsp;')+'</span>';

			tabCell.appendChild(theTab);
			mapSchemeButtons[currentScheme] = theTab;
		}
		setActive(currentTab);
		resize();
	}

	function setActiveMapScheme(newScheme){
		if (document.mapObject.sessionID!=null){
			setInactive(currentTab);
			currentTab = newScheme;
			setActive(currentTab);
			document.mapObject.setMapScheme(new String(newScheme));
		}
	}
	this.setActiveMapScheme = setActiveMapScheme;

	function setActive(tabIndex){
		currentTab = tabIndex;
		var tab = mapSchemeButtons[tabIndex];
		var tds = tab.getElementsByTagName("td");
		tds[0].className = "schemeButtonLeft_active";
		tds[1].className = "schemeButtonCenter_active";
		tds[2].className = "schemeButtonRight_active";
	}
	this.setActive = setActive;

	function setInactive(tabIndex){
		var tab = mapSchemeButtons[tabIndex];
		var tds = tab.getElementsByTagName("td");
		tds[0].className = "schemeButtonLeft";
		tds[1].className = "schemeButtonCenter";
		tds[2].className = "schemeButtonRight";
	}
	this.setInactive = setInactive;

	function resize(){
		xWidth(mapSchemeButtonContainer,xWidth($('textResultTabContainer')));
		xWidth(wrapper,xWidth(mapSchemeButtonContainer)-40);
		buttonRight.left(xWidth(mapSchemeButtonContainer)-20);
	}
	this.resize = resize;
	this.setActiveMapScheme = setActiveMapScheme;
}

function drawMapSchemeToolbar() {
	if(!document.mapSchemeControl) {
		document.mapSchemeControl = new MapSchemeControl();
	}
}

function setActiveMapScheme(newScheme)
{
	document.mapSchemeControl.setActiveMapScheme(newScheme);
};
/**/


function setActiveMapTool(toolId)
{
  var oldToolDescription = document.getElementById('mapToolDetail'+document.currentMapTool);
  var newToolDescription = document.getElementById('mapToolDetail'+toolId);
  var toolIdContainer = document.getElementById('mapToolIdContainer');
  document.currentMapTool = toolId;
  oldToolDescription.style.display = 'none';
  newToolDescription.style.display = 'block';
  document.currentMapTool = toolId;
  toolIdContainer.innerHTML = document.mapToolIdTable[toolId];
}

function printResultFrame()
{
  var printTarget = document.getPrintTarget();
  var searchResultsContent = document.getWidgetById("searchResultPanel");
  document.mapObject.setWaiting(true);
  printTarget.innerHTML = duplicateNodeTreeEmbeddingStylesSubset(searchResultPanel).innerHTML;
  document.printCurrentData();
  document.mapObject.setWaiting(false);
}

TW = new TemplateWidget();
document.currentMapTool = 'ZoomIn';

function togglePanel(panelId)
{
  var panelElement = document.getElementById(panelId);
  panelElement.style.display = ((panelElement.style.display=='none')?('block'):('none'));
}

function toggleSearchForm(searchId)
{
  for (var currentSearch=0; currentSearch<document.registeredSearches.length; currentSearch++)
  {
    document.mapObject.mapImage.bufferTargetNode.style.display = 'none';
    if(document.getElementById(document.registeredSearches[currentSearch]+'Form')){
      document.getElementById(document.registeredSearches[currentSearch]+'Form').style.display = 'none';
      setClass(document.getElementById(document.registeredSearches[currentSearch]+'Title'),'searchFormTitle');
    }
  }
  if (document.activeSearch==searchId)
    document.activeSearch = null;
  else
  {
    document.activeSearch = searchId;
    setClass(document.getElementById(searchId+'Title'),'searchFormTitleActive');
    document.getElementById(searchId+'Form').style.display = 'block';
    try{
      var inputEles = document.getElementById(searchId+'Form').getElementsByTagName('INPUT');
      if(inputEles.length>0)
        inputEles[0].focus();
    }
    catch(e){}
    if (searchId=='findNearby')
      document.mapObject.mapImage.bufferTargetNode.style.display = 'block';
  }
}

function submitCustomQuery(queryId)
{
  document.queryControl.submitQueryForm(queryId);
  return false;
}

function bufferButtonClick()
{
  var bufferTheme = document.getElementById('bufferThemeSelectInput').value;
  var bufferDistance = Math.abs(parseFloat(document.getElementById('bufferDistanceInput').value));
  bufferDistance = isNaN(bufferDistance)?0:bufferDistance;
  document.getElementById('bufferDistanceInput').value = bufferDistance;
  var bufferUnits = document.getElementById('bufferDistanceUnitInput').value;
  if (document.mapObject.sessionID!=null){
    bufferDistance =document.mapObject.bufferControl.convertUnits(bufferDistance,bufferUnits,document.applicationConfig.mapUnits);
    document.mapObject.clearAllSelections();
    document.mapObject.bufferOnCenter(bufferTheme, bufferDistance, 0);
  }
  return false;
}

function clearAllData()
{
  if (document.mapObject.sessionID!=null){
    document.mapObject.clearAllSelections();
    document.mapObject.clearAllBuffers();
    document.mapObject.clearAllGeocodePoints();
  }
  if (document.queryControl)
    document.queryControl.clearResults();
}
function submitGeocodeAddressForm()
{
  clearAllData();
  document.geocodeControl.submitAddressForm();
  return false;
}
function submitGeocodeIntersectionForm()
{
  document.geocodeControl.submitIntersectionForm();
  return false;
}
function scrollToTopOfScreen()
{
  xWinScrollTo(window, 0, 0, _ScrollToTopSpeed);
}
function scrollToUpperMapRange()
{
  xWinScrollTo(window,0,xPageY('mapSchemeButtonContainer'),_ScrollToMapSpeed);
}
function scrollToSearchResultsRange()
{
  xWinScrollTo(window,0,xPageY('textResultTabContainer'),_ScrollToSearchResultsSpeed);
}}
