if(!window.freeance_loaded_js)window.freeance_loaded_js={};
FREEANCE_VERSION='5.0.0.2502';
/* 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/PublicAccess1/lib/Main.js */ if(!window.freeance_loaded_js['c14c199fab9ec1b9f7bd93d2587510b2']){window.freeance_loaded_js['c14c199fab9ec1b9f7bd93d2587510b2']=1;
FREEANCE_XMLRPC_URL = XMLRPC_URL = '../../Server/Dzeims3.php';         //Location of server code.  This must be on the same server.
_FIRST_INITIALIZE=true;
_JSLIB_PREFIX_="./loadscript.php?lib=";
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('=');
    if (paramNameValuePair.length == 1)
		  params[tempParams[lcv].toUpperCase()] = '';
    else
		  params[paramNameValuePair[0].toUpperCase()] = paramNameValuePair[1];
	}
	return(params);
};
APP_URLParameters = parseURLParameters();

var appConfigName = '';
if (APP_URLParameters["APPCONFIG"] != null)
{
	appConfigName = APP_URLParameters["APPCONFIG"];
	LOAD_APP = true;
}
else
{
	LOAD_APP = false;
	window.location = '../appNotFound.html';
}
if ((APP_URLParameters["COMPRESS"] != null) && (APP_URLParameters["COMPRESS"].toUpperCase() == "N"))  // disable compression
{} else XMLRPC_URL += "?autocompress=Y";
DEBUG_TEXT = '';
DEBUG_MODE = (APP_URLParameters["DEBUG"] != null);  // enable debugging
if (DEBUG_MODE)
  dprintf = function (debugString){ DEBUG_TEXT+=debugString+'<br />\n'; };
else
  dprintf = function(debugString) {}
/*************
	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());
//declare global variables
document.setSessionID = function(newID){ document.sessionID = newID; };
document.getSessionID = function() { return(document.sessionID); };

function downloadFile(url) { $('downloadIFrame').src = url; };
function exportBufferToCSV() { if (document.bufferControl) document.bufferControl.exportToCSV(); };

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(){};
}}
/* FILE:FreeanceWeb/Common/lib/contrib/x/x-minimal.js */ if(!window.freeance_loaded_js['3c3bc383e44b06b1e019f14eb8682223']){window.freeance_loaded_js['3c3bc383e44b06b1e019f14eb8682223']=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) 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;
};

// 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

// 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;
};


// 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

// 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;
};


// 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;
}

// 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);};

// 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;
};

// 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;
};

// 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;
};

// 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;
};

// 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);};

// 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';
  };
};

// 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;
};

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;
};

// 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);
  };
};


// 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;
};

// 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/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. 2.35
The latest version is available at
http://www.walterzorn.com
or http://www.devira.com
or http://www.walterzorn.de

Copyright (c) 2002-2004 Walter Zorn. All rights reserved.
Created 3. 11. 2002 by Walter Zorn (Web: http://www.walterzorn.com )
Last modified: 29. 5. 2006

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 and ellipses
- 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_ihtm, jg_ie, jg_fast, jg_dom, jg_moz,
jg_n4 = (document.layers && typeof document.classes != "undefined");


function chkDHTM(x, i)
{
	x = document.body || null;
	jg_ie = x && typeof x.insertAdjacentHTML != "undefined";
	jg_dom = (x && !jg_ie &&
		typeof x.appendChild != "undefined" &&
		typeof document.createRange != "undefined" &&
		typeof (i = document.createRange()).setStartBefore != "undefined" &&
		typeof i.createContextualFragment != "undefined");
	jg_ihtm = !jg_ie && !jg_dom && x && typeof x.innerHTML != "undefined";
	jg_fast = jg_ie && document.all && !window.opera;
	jg_moz = jg_dom && typeof x.style.MozOpacity != "undefined";
};


function pntDoc()
{
	this.wnd.document.write(jg_fast? this.htmRpc() : this.htm);
	this.htm = '';
};


function pntCnvDom()
{
	var x = 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 pntCnvIhtm()
{
	if(this.cnv) this.cnv.innerHTML += this.htm;
	this.htm = '';
};


function pntCnv()
{
	this.htm = '';
};


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>';
};


function mkLyr(x, y, w, h)
{
	this.htm += '<layer '+
		'left="' + x + '" '+
		'top="' + y + '" '+
		'width="' + w + '" '+
		'height="' + h + '" '+
		'bgcolor="' + this.color + '"><\/layer>\n';
};


var regex =  /%%([^;]+);([^;]+);([^;]+);([^;]+);([^;]+);/g;
function htmRpc()
{
	return this.htm.replace(
		regex,
		'<div style="overflow:hidden;position:absolute;background-color:'+
		'$1;left:$2;top:$3;width:$4;height:$5"></div>\n');
};


function htmPrtRpc()
{
	return this.htm.replace(
		regex,
		'<div style="overflow:hidden;position:absolute;background-color:'+
		'$1;left:$2;top:$3;width:$4;height:$5;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)
		{
			++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)
			{
				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)
			{
				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)
		{
			++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)
			{
				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)
			{
				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)
		{
			if (drw) this.mkDiv(x, y, 1, 1);
			drw = !drw;
			if (p > 0)
			{
				y += yIncr;
				p += pru;
			}
			else p += pr;
			++x;
		};
		if (drw) this.mkDiv(x, y, 1, 1);
	}

	else
	{
		var pr = dx<<1,
		pru = pr - (dy<<1),
		p = pr-dy;
		while ((dy--) > 0)
		{
			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)+1,
	cx = left+a, cy = top+b,
	x = 0, y = b,
	ox = 0, oy = b,
	aa = (a*a)<<1, bb = (b*b)<<1,
	st = (aa>>1)*(1-(b<<1)) + bb,
	tt = (bb>>1) - aa*((b<<1)-1),
	w, h;
	while (y > 0)
	{
		if (st < 0)
		{
			st += bb*((x<<1)+3);
			tt += (bb<<1)*(++x);
		}
		else if (tt < 0)
		{
			st += bb*((x<<1)+3) - (aa<<1)*(y-1);
			tt += (bb<<1)*(++x) - aa*(((y--)<<1)-3);
			w = x-ox;
			h = oy-y;
			if (w&2 && h&2)
			{
				this.mkOvQds(cx, cy, -x+2, ox+wod, -oy, oy-1+hod, 1, 1);
				this.mkOvQds(cx, cy, -x+1, x-1+wod, -y-1, y+hod, 1, 1);
			}
			else this.mkOvQds(cx, cy, -x+1, ox+wod, -oy, oy-h+hod, w, h);
			ox = x;
			oy = y;
		}
		else
		{
			tt -= aa*((y<<1)-3);
			st -= (aa<<1)*(--y);
		}
	};
	this.mkDiv(cx-a, cy-oy, a-ox+1, (oy<<1)+hod);
	this.mkDiv(cx+ox+wod, cy-oy, a-ox+1, (oy<<1)+hod);
};


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)+1,
	cx = left+a, cy = top+b,
	x = 0, y = b,
	aa = (a*a)<<1, bb = (b*b)<<1,
	st = (aa>>1)*(1-(b<<1)) + bb,
	tt = (bb>>1) - aa*((b<<1)-1);

	if (s-4 < 0 && (!(s-2) || width-51 > 0 && height-51 > 0))
	{
		var ox = 0, oy = b,
		w, h,
		pxl, pxr, pxt, pxb, pxw;
		while (y > 0)
		{
			if (st < 0)
			{
				st += bb*((x<<1)+3);
				tt += (bb<<1)*(++x);
			}
			else if (tt < 0)
			{
				st += bb*((x<<1)+3) - (aa<<1)*(y-1);
				tt += (bb<<1)*(++x) - aa*(((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, ox-pxw+w+wod, -oy, -h+oy+hod, pxw, h);
				ox = x;
				oy = y;
			}
			else
			{
				tt -= aa*((y<<1)-3);
				st -= (aa<<1)*(--y);
			}
		};
		this.mkDiv(cx-a, cy-oy, s, (oy<<1)+hod);
		this.mkDiv(cx+a+wod-s+1, cy-oy, s, (oy<<1)+hod);
	}

	else
	{
		var _a = (width-((s-1)<<1))>>1,
		_b = (height-((s-1)<<1))>>1,
		_x = 0, _y = _b,
		_aa = (_a*_a)<<1, _bb = (_b*_b)<<1,
		_st = (_aa>>1)*(1-(_b<<1)) + _bb,
		_tt = (_bb>>1) - _aa*((_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)
			{
				st += bb*((x<<1)+3);
				tt += (bb<<1)*(++x);
				pxl[pxl.length] = x;
				pxt[pxt.length] = y;
			}
			else if (tt < 0)
			{
				st += bb*((x<<1)+3) - (aa<<1)*(y-1);
				tt += (bb<<1)*(++x) - aa*(((y--)<<1)-3);
				pxl[pxl.length] = x;
				pxt[pxt.length] = y;
			}
			else
			{
				tt -= aa*((y<<1)-3);
				st -= (aa<<1)*(--y);
			};

			if (_y > 0)
			{
				if (_st < 0)
				{
					_st += _bb*((_x<<1)+3);
					_tt += (_bb<<1)*(++_x);
					_pxb[_pxb.length] = _y-1;
				}
				else if (_tt < 0)
				{
					_st += _bb*((_x<<1)+3) - (_aa<<1)*(_y-1);
					_tt += (_bb<<1)*(++_x) - _aa*(((_y--)<<1)-3);
					_pxb[_pxb.length] = _y-1;
				}
				else
				{
					_tt -= _aa*((_y<<1)-3);
					_st -= (_aa<<1)*(--_y);
					_pxb[_pxb.length-1]--;
				}
			};
		};

		var ox = 0, 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+1, ox+wod, -oy, _oy+hod, x-ox, oy-_oy);
					ox = x;
					oy = pxt[i];
					_oy = _pxb[i];
				}
			}
			else
			{
				x = pxl[i];
				this.mkDiv(cx-x+1, 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,
	cx = left+a, cy = top+b,
	x = 0, y = b,
	aa2 = (a*a)<<1, aa4 = aa2<<1, bb = (b*b)<<1,
	st = (aa2>>1)*(1-(b<<1)) + bb,
	tt = (bb>>1) - aa2*((b<<1)-1),
	drw = true;
	while (y > 0)
	{
		if (st < 0)
		{
			st += bb*((x<<1)+3);
			tt += (bb<<1)*(++x);
		}
		else if (tt < 0)
		{
			st += bb*((x<<1)+3) - aa4*(y-1);
			tt += (bb<<1)*(++x) - aa2*(((y--)<<1)-3);
		}
		else
		{
			tt -= aa2*((y<<1)-3);
			st -= aa4*(--y);
		};
		if (drw) this.mkOvQds(cx, cy, -x, x+wod, -y, y+hod, 1, 1);
		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(id, wnd)
{
	this.setColor = new Function('arg', 'this.color = arg.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 = jg_n4? mkLyr : 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, s)
	{
		for (var i=0 ; i<x.length-1 ; 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)>>1, b = (h -= 1)>>1,
		wod = (w&1)+1, hod = (h&1)+1,
		cx = left+a, cy = top+b,
		x = 0, y = b,
		ox = 0, oy = b,
		aa2 = (a*a)<<1, aa4 = aa2<<1, bb = (b*b)<<1,
		st = (aa2>>1)*(1-(b<<1)) + bb,
		tt = (bb>>1) - aa2*((b<<1)-1),
		pxl, dw, dh;
		if (w+1) while (y > 0)
		{
			if (st < 0)
			{
				st += bb*((x<<1)+3);
				tt += (bb<<1)*(++x);
			}
			else if (tt < 0)
			{
				st += bb*((x<<1)+3) - aa4*(y-1);
				pxl = cx-x;
				dw = (x<<1)+wod;
				tt += (bb<<1)*(++x) - aa2*(((y--)<<1)-3);
				dh = oy-y;
				this.mkDiv(pxl, cy-oy, dw, dh);
				this.mkDiv(pxl, cy+y+hod, dw, dh);
				ox = x;
				oy = y;
			}
			else
			{
				tt -= aa2*((y<<1)-3);
				st -= aa4*(--y);
			}
		};
		this.mkDiv(cx-a, cy-oy, w+1, (oy<<1)+hod);
	};


/* 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(integer_compare);
			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;'+
			'width:' +  w + 'px;'+
			'height:' + h + 'px;">'+
			'<img src="' + imgSrc + '" width="' + w + '" height="' + h + '"' + (a? (' '+a) : '') + '>'+
			'<\/div>';
	};


	this.clear = function()
	{
		this.htm = "";
		if (this.cnv) this.cnv.innerHTML = this.defhtm;
	};


	this.mkOvQds = function(cx, cy, xl, xr, yt, yb, w, h)
	{
		this.mkDiv(xr+cx, yt+cy, w, h);
		this.mkDiv(xr+cx, yb+cy, w, h);
		this.mkDiv(xl+cx, yb+cy, w, h);
		this.mkDiv(xl+cx, yt+cy, w, h);
	};

	this.setStroke(1);
	this.setFont('verdana,geneva,helvetica,sans-serif', String.fromCharCode(0x31, 0x32, 0x70, 0x78), Font.PLAIN);
	this.color = '#000000';
	this.htm = '';
	this.wnd = wnd || window;

	if (!(jg_ie || jg_dom || jg_ihtm)) chkDHTM();
	if (typeof id != 'string' || !id) this.paint = pntDoc;
	else
	{
		this.cnv = document.all? (this.wnd.document.all[id] || null)
			: document.getElementById? (this.wnd.document.getElementById(id) || null)
			: null;
		this.defhtm = (this.cnv && this.cnv.innerHTML)? this.cnv.innerHTML : '';
		this.paint = jg_dom? pntCnvDom : jg_ie? pntCnvIe : jg_ihtm? pntCnvIhtm : pntCnv;
	};

	this.setPrintable(false);
};



function integer_compare(x,y)
{
	return (x < y) ? -1 : ((x > y)*1);
};}
/* 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/Freeance_Extension_Manager.js */ if(!window.freeance_loaded_js['4172aa0e00de622f2c8c27d3d5d34e9b']){window.freeance_loaded_js['4172aa0e00de622f2c8c27d3d5d34e9b']=1;
Freeance_BundleExtension_Manager = new (function(){
  var $_this = this;
  var extensions = [];
  this.bundlesToLoad = [];
  this.bundlesToLoadGroupedExtensions = {};
  var _initialize_callback = null;
  
  this.add_extension = function(extid,bundlename)
  {
    //console.log('FBEM.add_extension! '+extid);
    extensions[extid] = {
      extid:extid,
      bundlename:bundlename,
      loaded:false,
      registered:false,
      initialized:false,
      initfcn:null
    };
  };
  
  this.register = function(extid,initfcn)
  {
    //console.log('FBEM.register! '+extid+' | '+typeof(extensions[extid]));
    if (typeof(extensions[extid]) == 'undefined')
      return(false);  // did not add extension
    if(extensions[extid].registered)
      return(false);  // only do once
    extensions[extid].registered=true;
    extensions[extid].initfcn=initfcn;
    //console.log('FBEM.register '+extid+' successfully registered');
    if (Freeance_BundleExtension_Manager.array_indexOf(Freeance_BundleExtension_Manager.bundlesToLoad,extensions[extid].bundlename) != -1)
    {
      // load process is waiting on our or any bundle-sibling extension registration
      var ext_siblings = Freeance_BundleExtension_Manager.bundlesToLoadGroupedExtensions[extensions[extid].bundlename];
      if (extid == ext_siblings[ext_siblings.length-1].extid)
      {
        //console.log('FBEM.register: bundle '+extensions[extid].bundlename+' - last sibling in list -> '+extid);
        Freeance_BundleExtension_Manager.bundlesToLoad.splice(Freeance_BundleExtension_Manager.array_indexOf(Freeance_BundleExtension_Manager.bundlesToLoad,extensions[extid].bundlename),1);
        if (Freeance_BundleExtension_Manager.bundlesToLoad.length == 0)
        {
          //console.log('FBEM.register: calling initialization callback');
          $_this.initialize_bundles($_this._initialize_callback);
        }
      }
    }
    return(true);
  };
  
  this.load_all = function(callback)
  {
    //console.log('FBEM.load_all!');
    // get a list of unique bundles that needed to be loaded aside from 'default'
    for(var extid in extensions)
    {
      if (extid == 'toJSONString') continue;
      var bundlename = extensions[extid].bundlename;
      if (bundlename == 'default')
        extensions[extid].loaded = true;
      else
      {
        if (Freeance_BundleExtension_Manager.array_indexOf(this.bundlesToLoad,bundlename)==-1)
        {
          this.bundlesToLoad.push(bundlename);
          this.bundlesToLoadGroupedExtensions[bundlename] = Array();
        }
        this.bundlesToLoadGroupedExtensions[bundlename].push(extensions[extid]);
      }
    }
    if (this.bundlesToLoad.length == 0)  // nothing but default
    {
      $_this.initialize_bundles(callback);
      return;
    }
    //console.log('FBEM: have non default bundles to load');
    //console.dir(this.bundlesToLoad);
    //console.dir(this.bundlesToLoadGroupedExtensions);
    //console.dir(extensions);
    this._initialize_callback = callback;
    var baseuri = '../../../Freeance5/Server/GetResourceBundle.php?clienttype=pa1&bundletype=text/javascript&bundlename=';
    for(var lcv=0;lcv < this.bundlesToLoad.length;lcv++)
    {
      var bundlename = this.bundlesToLoad[lcv];
      //console.log('bundle to load: '+baseuri + bundlename);
      loadJavaScript(baseuri + bundlename,(function(myExts){
        for(var ilv=0;ilv < myExts.length;ilv++)
        {
          var myid = myExts[ilv].extid;
          //console.log('loadJavaScript callback bundlename.myid = '+myExts[ilv].bundlename+'.'+myid);
          extensions[myid].loaded=true;
        }
      })(this.bundlesToLoadGroupedExtensions[bundlename]));
    }
  };
  
  this.initialize_bundles = function(callback)
  {
    for(var extid in extensions)
    {
      if (extid == 'toJSONString') continue;
      //console.log('FBEM.initialize_bundles: '+extid+' | '+extensions[extid].initialized+' | '+typeof(extensions[extid].initfcn));
      if ((!extensions[extid].initialized) && (typeof(extensions[extid].initfcn) == 'function'))
      {
        //console.log('FBEM.initialize_bundles: calling initfcn for extension['+extid+']');
        extensions[extid].initialized=extensions[extid].initfcn();
      }
    }
    if (typeof(callback) == 'function')
    {
      //console.log('FBEM.initialize_bundles: about to call callback');
      callback();
    }
    //else //console.log('FBEM.initialize_bundles: callback is not a function?');
  };
  
  this.array_indexOf = function(arr,lookfor)
  {
    if(arr.indexOf)
      return(arr.indexOf(lookfor));  // don't punish the sensible
    // else: ie and opera, i'm looking at you...
    for(var lcv=0;lcv<arr.length;lcv++)
	    if(arr[lcv]==lookfor)
        return lcv;
    return -1;
  };
})();

//handles dynamic loading of extensions
Freeance_Extension_Manager = new (function(){
  var $_this = this;
  var extensions = [];
  var id_lookup = {};
  this.add_extension = function(id,filename){
    var _requested=false;
    var _loaded=false;
    var _type='script';
    if (arguments.length == 4)
    {
      _type=arguments[2];
      _requested=arguments[3];
      //_loaded=arguments[3];
    }
    id_lookup[id]=extensions.length;
    extensions.push({
      id:id,
      file:filename,
      type:_type,
      requested:_requested,
      loaded:_loaded,
      registered:false,
      initialized:false,
      initfcn:null
    });
    //console.log('FEM.add_extension: '+id+', ext count='+extensions.length+', '+filename);
  };
  this.load_allORIG=function(callback){
    for(var i=0;i<extensions.length;i++){
      if(!extensions[i].requested){
        (function(idx){
          loadJavaScript(extensions[idx].file,function(){
            extensions[idx].loaded=true;
            $_this.load_all_callback(callback);
          });
        })(i);
        extensions[i].requested=true
      }
    }
  };
  this.load_all=function(callback)
  {
    //console.log('FEM.load_all: extensions.length = '+extensions.length);
    if (extensions.length == 0)
    {
      callback();
      return;
    }
    var extArray = [];
    for(var i=0;i<extensions.length;i++)
    {
      //console.log('extensions['+i+'] ('+extensions[i].file+') requested? '+extensions[i].requested);
      if(!extensions[i].requested)
      {
        extArray.push({file:extensions[i].file,idx:i});
        extensions[i].requested=true;
        //console.log('extensions['+i+'].requested set to true with idx '+i);
      } // requested
    }
    for(var i=0;i<extArray.length;i++)
    {
      //console.log('loadJavaScript extArray['+i+'].file = '+extArray[i].file);
      loadJavaScript(extArray[i].file,(function(myExt){
        var myidx = myExt.idx;
        //console.log('loadJavaScript callback myidx = '+myidx);
        extensions[myidx].loaded=true;
        $_this.load_all_callback(callback);
      })(extArray[i]));
    }
  };
  this.load_allBundleStyleTODO=function(callback)
  {
    var extArray = [];
    for(var i=0;i<extensions.length;i++)
    {
      if(!extensions[i].requested)
      {
        extArray.push({file:extensions[i].file,idx:i});
        extensions[i].requested=true;
      } // requested
    }
    loadJavaScript(extArray,function(){
      for(var lcv=0;lcv < extArray.length;lcv++)
        extensions[extArray[lcv].idx].loaded=true;
      $_this.load_all_callback(callback);      
    });
  };
  this.load_all_callback = function(callback){
    //console.log('FEM.load_all_callback!');
    //an extension has loaded.  if all have finished loading, call the callback function.
    for (var i=0;(i<extensions.length)&&(extensions[i].loaded);i++);
    if (i==extensions.length) callback();
    //else //console.log('FEM.load_all_callback... not yet');
  };
  this.initialize_all=function(maxtimeout,callback){
    //console.log('FEM.initialize_all!');
    var ready=true;
    for(var i=0;(i<extensions.length)&&(ready);i++)
    if(!extensions[i].registered)ready=false;
    if((ready)||(maxtimeout==0)){
      for(var i=0;(i<extensions.length);i++)
      {
        if((!extensions[i].initialized)&&(typeof(extensions[i].initfcn)=='function'))
        {
          //console.log('FEM.initialize_all: calling initfcn for extension['+i+'] '+extensions[i].id);
          extensions[i].initialized=extensions[i].initfcn();
        }
      }
      if(typeof(callback)=='function')callback();
    }
    else
    {
      window.setTimeout(function(){$_this.initialize_all(parseInt(maxtimeout)/2,callback)},parseInt(maxtimeout)/2)
    }
  };
  this.register = function(extid,initfcn){
    //console.log('FEM.register! '+extid);
    var idx = id_lookup[extid];
    if(idx!=null){
      if(extensions[idx].registered)
        return false;
      else {
        extensions[idx].registered=true;
        extensions[idx].initfcn=initfcn;
        //console.log('FEM.register '+extid+' successfully registered');
      }
    }
    else 
      return false;
  };
  this.get_unregistered=function()
  {
    var returnval=[];
    for (var i=0;(i<extensions.length);i++)
      if (!extensions[i].registered) returnval.push(extensions[i].id);
    return returnval;
  };
  this.get_uninitialized=function(){
    var returnval=[];
    for (var i=0;(i<extensions.length);i++)
      if (!extensions[i].initialized) returnval.push(extensions[i].id);
    return returnval;
  };
})();}
/* FILE:FreeanceWeb/Client/PublicAccess1/lib/RightPanel_State_Manager.js */ if(!window.freeance_loaded_js['231e89b3449439f801f200912d59e3e0']){window.freeance_loaded_js['231e89b3449439f801f200912d59e3e0']=1;
RightPanel_State_Manager = new (function(){
  var $_this = this;
  var labels=[];
  var labelLookup = {};
  var panels= [];
  var panelLookup = {};
  var activePanelType= '';  //currently active panel
  var oldActivePanelType= '';  //panel last set inactive
  
  this.addLabel=function(labelID,panelType,labelText)
  {
    if (labelLookup[labelID]!=null) return(false);//already exists
    var ele = document.createElement('DIV');
    ele.id = labelID;
    ele.className = 'controlPanelButton';
    ele.innerHTML = '<div class="controlPanelButtonText">'+labelText+'</div>';
    $('rightControlPanelContainer').appendChild(ele);
    xAddEventListener(ele,'click',function() {$_this.showPanel(panelType);});
    
    labelLookup[labelID]=labels.length;
    labels.push({
      labelID: labelID,
      panelType: panelType,
      labelText: labelText,
      labelEle: ele
    });
    return(true);
  };
  
  this.addPanel=function(panelType,panelID/*visibilityFunction,panelHTML,panelURL*/)
  {
    var vis_fcn=function(newstate){panelEle.style.display=(newstate?'block':'none');};
    if (panelLookup[panelType]) return(false);
    
    //get arguments
    var visibilityFunction = (arguments.length>2)?arguments[2]:vis_fcn;
    if(!visibilityFunction){visibilityFunction=vis_fcn;};
    var panelHTML = (arguments.length>3)?arguments[3]:null;
    var panelURL = (arguments.length>4)?arguments[4]:null;
    
    //find panel.  if it does not yet exist, create it.
    var panelEle = $(panelID);
    if (!panelEle){
      panelEle = document.createElement('DIV');
      panelEle.id = panelID;
      panelEle.style.display = 'none';
      if (panelHTML)
        panelEle.innerHTML = panelHTML;
      else
        if (panelURL)
          XmlHttp.loadTextAsync(panelURL,function(htmlcode){panelEle.innerHTML=htmlcode;});
      $('rightPanelBody').appendChild(panelEle);
    }
    
    panelLookup[panelType]=panels.length;
    panels.push({
      panelID:   panelID,
      panelType: panelType,
      setVisible:visibilityFunction,
      panelEle: $(panelID)
    });
    return(panelEle); // in case anyone wants to know
  };
  
  this.showPanel = function(newPanelType)
  {
    if (panelLookup[newPanelType]==null) return(false);
    
    if((activePanelType!='')&&(activePanelType!=newPanelType))
      panels[panelLookup[activePanelType]].setVisible(false,panels[panelLookup[activePanelType]]['panelEle']);
    oldActivePanelType = activePanelType;
    activePanelType = newPanelType;
    panels[panelLookup[newPanelType]].setVisible(true,panels[panelLookup[newPanelType]]['panelEle']);
  };
  
  this.getActivePanel = function(){return activePanelType;};
  this.getPreviousActivePanel = function(){return oldActivePanelType;};
  
  this.getPanelElement=function(panelType){
    return panelLookup[newPanelType]?panels[panelLookup[newPanelType]]['panelEle']:null;
  };
})();}
/* FILE:FreeanceWeb/Client/PublicAccess1/lib/PageLayout.js */ if(!window.freeance_loaded_js['6fba9098a802a9a74bbf35d1bfac5ab6']){window.freeance_loaded_js['6fba9098a802a9a74bbf35d1bfac5ab6']=1;
/* Set global constants that control page layout */
/* These can be overridden by the application config if necessary */
_PageHeaderHeight = 30;
_RightPanelWidth = 250;
_MapToolBarWidth = 30;
_MapToolOptionHeight = 100;
_VicinityMapWidthOpen = 130;
_VicinityMapExists = false;
_VicinityMapWidthClosed = 0;
_ExpandSearchPanel = false;
_DefaultActivePanel = 'userIntro';

GUI_THEME_PATH = './themes';      //can be overridden from application config
GUI_THEME =      '';               //will be defined from application config


//array of functions to call when window resizes.  each fcn will be passed the width and height of the viewport
window.resize_functions = [];

function formatBaseLayout()
{
  var clientWidth = xClientWidth();
  var clientHeight = xClientHeight();
  var panelWidth = 0;

  if (_ExpandSearchPanel)
	var rightPanelHeight = xHeight($('rightPanel'),clientHeight-_PageHeaderHeight-_MapToolOptionHeight);
  else
	var rightPanelHeight = xHeight($('rightPanel'),clientHeight-_PageHeaderHeight);
  var homeLinkHeight = xHeight($('homeLink'));
  var rightPanelToolbarHeight = xHeight($('rightPanelToolbar'));

  xHeight($('rightPanelBody'),rightPanelHeight-homeLinkHeight-rightPanelToolbarHeight);
  xWidth($('homeLink'),_RightPanelWidth);

  xHeight($('pageHeader'),_PageHeaderHeight);
  xTop($('rightPanel'),_PageHeaderHeight);
  xWidth($('rightPanel'),_RightPanelWidth);
  xWidth($('rightPanelBody'),_RightPanelWidth);
  xHeight($('searchResultPanel'),_MapToolOptionHeight);
  xHeight($('searchResultPanel'),_MapToolOptionHeight);
  xHeight($('geocodeResultPanel'),_MapToolOptionHeight);
  xHeight($('mapToolOptionPanel'),_MapToolOptionHeight);
  xHeight($('mapToolOptionPanelBody'),_MapToolOptionHeight-xHeight($('mapToolOptionPanelHeader')));
  xWidth($('mapSchemeButtonContainer'),clientWidth-_RightPanelWidth);

  if (_VicinityMapExists)
  {
	xLeft($('mapToolOptionPanel'),_VicinityMapWidthOpen);
	xLeft($('searchResultPanel'),_VicinityMapWidthOpen);
	xLeft($('geocodeResultPanel'),_VicinityMapWidthOpen);
	if (_ExpandSearchPanel){
	  panelWidth = clientWidth-_VicinityMapWidthOpen;
	  xWidth($('mapToolOptionPanel'),panelWidth);
	  xWidth($('searchResultPanel'),panelWidth);
	  xWidth($('geocodeResultPanel'),panelWidth);

	}
	else{
	  panelWidth = clientWidth-_RightPanelWidth-_VicinityMapWidthOpen;
	  xWidth($('mapToolOptionPanel'),panelWidth);
	  xWidth($('searchResultPanel'),panelWidth);
	  xWidth($('geocodeResultPanel'),panelWidth);
	}
  }
  else
  {
	xLeft($('mapToolOptionPanel'),_VicinityMapWidthClosed);
	xLeft($('searchResultPanel'),_VicinityMapWidthClosed);
	xLeft($('geocodeResultPanel'),_VicinityMapWidthClosed);
	if (_ExpandSearchPanel){
	  xWidth($('mapToolOptionPanel'),clientWidth);
	  xWidth($('searchResultPanel'),clientWidth);
	  xWidth($('geocodeResultPanel'),clientWidth);
	}
	else{
	  panelWidth = clientWidth-_RightPanelWidth;
	  xWidth($('mapToolOptionPanel'),panelWidth);
	  xWidth($('searchResultPanel'),panelWidth);
	  xWidth($('geocodeResultPanel'),panelWidth);
	}
  }

  //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);

  //inline print window
  var pwindow=$('printwindow_inline');
  var iframe_ele=$('printwindow_inline_frame');
  var iframe_offsety=xHeight($('printwindow_inline_titlebar'));
  xLeft(pwindow,printLeft);
  xTop(pwindow,printTop);
  xWidth(pwindow,printWidth);
  xHeight(pwindow,printHeight);
  xWidth(iframe_ele,printWidth);
  xHeight(iframe_ele,printHeight-iframe_offsety);
  if(document.mapSchemeControl){
	  document.mapSchemeControl.resize();
  }
};

function winOnResize()
{
  formatBaseLayout();
  if (window.resize_functions)
	for (var i=0;i<window.resize_functions.length;i++)
	  window.resize_functions[i](xClientWidth(),xClientHeight());
};

function initGuiLib(guiTheme)
{
  GUI_THEME = guiTheme;
  GuiWidget.THEME_PATH = './themes';
  GuiWidget.THEME = GUI_THEME;
  var themeName = guiTheme.toLowerCase();
  switch(themeName)
  {
	case 'default':
	case 'classic':
	  document.addStylesheet('../../../Freeance5/Server/GetResourceBundle.php?clienttype=pa1&bundlename=theme_'+themeName+'&bundletype=text/css');
	  break
	case 'yellowgreen':
	  document.addStylesheet('../../../Freeance5/Server/GetResourceBundle.php?clienttype=pa1&bundlename=theme_yellowGreen&bundletype=text/css');
	  break;
	case 'arcexplorer':
	  document.addStylesheet('../../../Freeance5/Server/GetResourceBundle.php?clienttype=pa1&bundlename=theme_arcExplorer&bundletype=text/css');
	  break;
	default:
	  document.addStylesheet(GuiWidget.THEME_PATH+'/'+GuiWidget.THEME+'/guilib.css');
	  document.addStylesheet(GuiWidget.THEME_PATH+'/'+GuiWidget.THEME+'/freeance.css');
	  document.addStylesheet(GuiWidget.THEME_PATH+'/'+GuiWidget.THEME+'/templateStyles.css');
  }
  GuiWidget.tooltipOffset = new Array(5,5);
  GuiWidget_onLoad();
};

function setBottomPanel(panelName)
{
  xHide($('geocodeResultPanel'));
  xHide($('searchResultPanel'));
  xHide($('mapToolOptionPanel'));
  xShow($(panelName));
  document.currentBottomPanel = panelName;
};

function clearSearchResultPanel()
{
  var templateObject = document.templateConfig;
  var resultPanel = $('searchResultPanel');
  if (resultPanel.scrollHandler!=null)
	resultPanel.scrollHandler.cleanup();

  resultPanel.innerHTML = templateObject['EmptySearch'];
};

document.rotateBottomPanel = function()
{
  switch (document.currentBottomPanel)
  {
	case 'mapToolOptionPanel':
	  setBottomPanel('searchResultPanel');
	  break;
	case 'searchResultPanel':
	  if (document.geocodeControl!=null)
	  {
		if (document.extensionConfig.geocode.enabled)
		  setBottomPanel('geocodeResultPanel');
		else
		  setBottomPanel('mapToolOptionPanel');
	  }
	  else
		setBottomPanel('mapToolOptionPanel');
	  break;
	case 'geocodeResultPanel':
	  setBottomPanel('mapToolOptionPanel');
	  break;
	default:
	  setBottomPanel('mapToolOptionPanel');
	  break;
  }
};


function showQueryIndexPanel()
{
  document.queryControl.currentQueryForm = null;
  hideSearchForms();
  $('queryBookmarkContainer').style.display = 'none';
  $('searchIndexContainer').style.display = 'block';
  $('queryContainer').style.display = 'block';
};

function hideSearchIndexPanel(){$('searchIndexContainer').style.display = 'none';};

function hideSearchForms()
{
  //hide forms for everything in the search panel.
  //do this before displaying a specific form.
  document.queryControl.hideAllForms();
  if (document.geocodeControl)
	document.geocodeControl.hideAllForms();
  if (document.proximitySearchControl)
	document.proximitySearchControl.hideAllForms();
  $('proximitySearchFormContainer').style.display = 'none';
  $('queryBookmarkContainer').style.display = 'none';
  $('searchFormContainer').style.display = 'none';
};
document.hideSearchForms = hideSearchForms;

function showSearchFormContainer()
{
  $('searchFormContainer').style.display = 'block';
}}
/* FILE:FreeanceWeb/Client/PublicAccess1/lib/MapLayout.js */ if(!window.freeance_loaded_js['c0c85b08d878f09987b67087135b4d44']){window.freeance_loaded_js['c0c85b08d878f09987b67087135b4d44']=1;
/* Set global constants that control map layout */
/* These can be overridden by the application config if necessary */
_MapAutoRedraw = true;     //redraw the map automatically on browser resize
_ZoomBarPresent = false;    //use a zoom bar?
_SchemeButtonRowHeight=25;
_MAP_INITIALIZED = false;  //has a map been initialized yet?
_FIRST_INITIALIZE = true;  //for url commands - indicate that the application is initializing for the first time.
_CustomLegendURL = '';
_ZoomBarWidth = 17;
_ZoomBarCellHeight = 8;  //height of an individual element in the zoom bar
_ZoomBarStartColor = '#FFFFFF';  //'Zoom In' end of zoom bar
_ZoomBarEndColor = '#0000FF';    //zoom out end of zoom bar
_ZoomBarActiveColor = '#00FF00';    //zoom out end of zoom bar
_ZoomBarRatio = 0.01;


function pageformat_mapTop(){return _PageHeaderHeight+((document.mapObject.config.mapSchemeConfig.mapSchemes.length>0)?_SchemeButtonRowHeight:2);};
function pageformat_mapLeft(){return _MapToolBarWidth;};
function pageformat_mapWidth(){return xClientWidth()-_MapToolBarWidth-_RightPanelWidth-((xIE4Up)?0:2);};
function pageformat_mapHeight(){return xClientHeight()-_PageHeaderHeight-_MapToolOptionHeight-((document.mapObject.config.mapSchemeConfig.mapSchemes.length>0)?_SchemeButtonRowHeight:4);};

function create_map_interface()
{
  var cw = xClientWidth(), ch = xClientHeight();
  var pageContainer = $('pageContainer');
  var mapTop = _PageHeaderHeight+((document.mapObject.config.mapSchemeConfig.mapSchemes.length>0)?_SchemeButtonRowHeight:2);
  var mapLeft = _MapToolBarWidth;
  var mapWidth = cw-_MapToolBarWidth-_RightPanelWidth-((xIE4Up)?0:2);
  var mapHeight = ch-_PageHeaderHeight-_MapToolOptionHeight-((document.mapObject.config.mapSchemeConfig.mapSchemes.length>0)?_SchemeButtonRowHeight:4);
  document.mapObject.mapImage = new MapImage('scriptedMapImage', pageContainer, mapLeft, mapTop, 0, mapWidth, mapHeight, true, document.mapObject, 'MASTER');
  document.mapObject.mapImage.setMouseMode('ZoomWindow');
  if (document.mapObject.vmapPresent)
  {
	document.mapObject.vmapImage = new MapImage('scriptedVmapImage', pageContainer, 3, xClientHeight()-_MapToolOptionHeight, 0, 124, _MapToolOptionHeight-5, true, document.mapObject,'SLAVE');
	_VicinityMapExists = true;
  }

  //toolbar with built-in controls
  var mapToolbar = document.mapToolbar = new ToolBar('mapToolbar', pageContainer, 0,mapTop, 0, _MapToolBarWidth,mapHeight, true, '', ToolBar.ALIGN_VERTICAL);

  //this was a global variable.  some things may break.
  var mapCursorRadioButtonGroup = mapToolbar.mapCursorRadioButtonGroup = new RadioButtonGroup('mapCursorRadioButtonGroup');

  var zoomInButton = mapToolbar.addButton('zoomInButton',ToolBar.BUTTON_RADIO,ToolBar.ADD_BUTTON_LAST,null,25,25,175,true,'toolBar.png','Zoom In',mapCursorRadioButtonGroup);
  var zoomOutButton = mapToolbar.addButton('zoomOutButton',ToolBar.BUTTON_RADIO,ToolBar.ADD_BUTTON_LAST,null,25,25,125,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','Pan/Recenter',mapCursorRadioButtonGroup);

  //these are part of the standard interface but are not necessarily enabled by default.  actions will be assigned by the extensions.
  var selectButton = mapToolbar.addButton('selectButton',ToolBar.BUTTON_RADIO,ToolBar.ADD_BUTTON_LAST,null,25,25,225,false,'toolBar.png','Identify Features',mapCursorRadioButtonGroup);
  var bufferButton = mapToolbar.addButton('bufferButton',ToolBar.BUTTON_RADIO,ToolBar.ADD_BUTTON_LAST,null,25,25,75,false,'toolBar.png','Buffer Features',mapCursorRadioButtonGroup);
  var measureButton = mapToolbar.addButton('measureButton',ToolBar.BUTTON_RADIO,ToolBar.ADD_BUTTON_LAST,null,25,25,25,false,'toolBar.png','Measure',mapCursorRadioButtonGroup);
  var latLonButton = mapToolbar.addButton('latLonButton',ToolBar.BUTTON_RADIO,ToolBar.ADD_BUTTON_LAST,null,25,25,50,false,'toolBar.png','Find Lat - Lon<br />Coordinates',mapCursorRadioButtonGroup);

  //these are pushbuttons
  var redrawButton = mapToolbar.addButton('redrawButton',ToolBar.BUTTON_IMAGE,ToolBar.ADD_BUTTON_LAST,null,25,25,275,true,'toolBar.png','Redraw Map');
  var backButton = mapToolbar.addButton('backButton',ToolBar.BUTTON_IMAGE,ToolBar.ADD_BUTTON_LAST,null,25,25,100,true,'toolBar.png','Zoom Previous');
  var homeButton = mapToolbar.addButton('zoomInitialButton',ToolBar.BUTTON_IMAGE,ToolBar.ADD_BUTTON_LAST,null,25,25,150,true,'toolBar.png','Initial Extent');

  //optional pushbuttons; depends on configuration
  var printButton = mapToolbar.addButton('printMapButton',ToolBar.BUTTON_IMAGE,ToolBar.ADD_BUTTON_LAST,null,25,25,325,false,'toolBar.png','Print');
  var saveMapButton = mapToolbar.addButton('saveMapButton',ToolBar.BUTTON_IMAGE,ToolBar.ADD_BUTTON_LAST,null,25,25,250,false,'toolBar.png','Save Map Image');

  //this button rotates the bottom panel.  it is not strictly part of the toolbar and is not affected by toolbar format functions
  var bottomPanelSwitchOMatic = new ImageButton('bottomPanelSwitchOMatic', mapToolbar.element, 2, mapToolbar.height()-30, 0, 25,25,200,true,'toolBar.png','Change Bottom Panel Mode');

  //assign events for initial tools
  zoomInButton.clickEvent = function () {document.mapObject.mapImage.setMouseMode('ZoomWindow');setActiveMapTool('ZoomIn');$('mapToolPanelNameField').innerHTML = 'Zoom In';};
  zoomOutButton.clickEvent = function () {document.mapObject.mapImage.setMouseMode('ZoomOut');setActiveMapTool('ZoomOut');$('mapToolPanelNameField').innerHTML = 'Zoom Out';};
  panButton.clickEvent = function () {document.mapObject.mapImage.setMouseMode('DragMap');setActiveMapTool('Pan');$('mapToolPanelNameField').innerHTML = 'Pan / Recenter';};
  redrawButton.clickEvent = function (e) {if (_MAP_INITIALIZED) document.mapObject.redraw();};
  backButton.clickEvent = function(){if (_MAP_INITIALIZED) document.mapObject.zoomToPrevious();};
  homeButton.clickEvent = function (e) {if (_MAP_INITIALIZED) document.mapObject.zoomInitialExtent();};
  bottomPanelSwitchOMatic.clickEvent = function (e){document.rotateBottomPanel();};

  //set the default button active
  window.setTimeout(function(){mapCursorRadioButtonGroup.setActiveButton('zoomInButton');mapToolbar.updateButtons();bottomPanelSwitchOMatic.moveTo(0,mapToolbar.height()-30);},1000); //IE will choke if it runs immediately

  if (_CustomLegendURL!=''){
	document.mapObject.customLegendImage = _CustomLegendURL;
	$('map0legend').src = _CustomLegendURL;
  }
  document.mapObject.setLegendImage($('map0legend'),false);

  //if map schemes are present, adjust interface to match.
  if (document.mapObject.config.mapSchemeConfig)
  {
	_SchemeButtonRowHeight = xHeight($('rightPanelToolbar'));
	if (document.mapObject.config.mapSchemeConfig.mapSchemes.length>0)
	{
	  xHeight($('mapSchemeButtonContainer'),_SchemeButtonRowHeight);
	  xWidth($('mapSchemeButtonContainer'),xClientWidth()-_RightPanelWidth);
	  xTop($('mapSchemeButtonContainer'),_PageHeaderHeight);
	  xLeft($('mapSchemeButtonContainer'),0);
	  $('mapSchemeButtonContainer').style.display = 'block';
	  drawMapSchemeToolbar(document.mapObject.config.mapSchemeConfig.defaultMapScheme);
	}
	else
	  $('mapSchemeButtonContainer').style.display = 'none';
  }
  formatBaseLayout();

  window.resize_functions.push(function(cw,ch){
	var mapWidth = pageformat_mapWidth();
	var mapHeight = pageformat_mapHeight();

	if (document.mapObject){
	  document.mapObject.mapImage.resizeTo(mapWidth,mapHeight);
	  if (document.mapObject.vmapImage)
		document.mapObject.vmapImage.moveTo(3, ch-_MapToolOptionHeight);
	}
	mapToolbar.resizeTo(_MapToolBarWidth, mapHeight);
	bottomPanelSwitchOMatic.moveTo(0,mapToolbar.height()-30);
	if (_MAP_INITIALIZED&&_MapAutoRedraw)
	  document.mapObject.redraw();
  });
};


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="0px";
		wrapper.style.paddingTop="0px";

		var tabContainer = document.createElement("table");
		wrapper.appendChild(tabContainer);
		xTop(wrapper,0);

		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, 0, 0, 20, 
			xHeight(mapSchemeButtonContainer), 
			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, 0, 0, 20, 
			xHeight(mapSchemeButtonContainer), 
			25,true,'tabControl.png','');
		buttonRight.imageNode.style.height = 50;
		//buttonRight.imageNode.style.filter = 'progid:DXImageTransform.Microsoft.AlphaImageLoader(src=\''+buttonRight.imageNode.src+'\', sizingMethod=\'image\')';
		
		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);
			(
				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.innerHTML = "&nbsp;";
			td2.innerHTML = "&nbsp;";
			td3.innerHTML = "&nbsp;";

			td1.className = "schemeButtonLeft"+(isActive?'_active':'');
			td2.className = "schemeButtonCenter"+(isActive?'_active':'');
			td3.className = "schemeButtonRight"+(isActive?'_active':'');

			//td2.appendChild(document.createTextNode(mapConfig.mapSchemeConfig.mapSchemes[currentScheme].name));
			td2.innerHTML = escapeHTML(mapConfig.mapSchemeConfig.mapSchemes[currentScheme].name).replace(/ /g,'&nbsp;');

			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){
		var tab = mapSchemeButtons[tabIndex];
		var tds = tab.getElementsByTagName("td");
		tds[0].className = "schemeButtonLeft_active";
		tds[1].className = "schemeButtonCenter_active";
		tds[2].className = "schemeButtonRight_active";
	}

	function setInactive(tabIndex){
		var tab = mapSchemeButtons[tabIndex];
		var tds = tab.getElementsByTagName("td");
		tds[0].className = "schemeButtonLeft";
		tds[1].className = "schemeButtonCenter";
		tds[2].className = "schemeButtonRight";
	}

	function resize(){
		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 = $('mapToolDetail'+document.currentMapTool);
  var newToolDescription = $('mapToolDetail'+toolId);
  oldToolDescription.setAttribute((xIE4Up?("className"):("class")),"mapToolDetailFormHidden");
  newToolDescription.setAttribute((xIE4Up?("className"):("class")),"mapToolDetailForm");
  document.currentMapTool = toolId;
  setBottomPanel('mapToolOptionPanel');
};


function toggleSelectionOptionDisplay()
{
  var currentStyle = $("selectionOptionsPanel").style.display;
  switch (currentStyle.toLowerCase())
  {
	case 'block':
	  $("selectionOptionsPanel").style.display = 'none';
	  break;
	case 'none':
	  $("selectionOptionsPanel").style.display = 'block';
	  break;
	default:
	  //when in doubt.. do nothing!
	  alert('document.toggleSelectionOptionDisplay()\nAttempting to process unknown display state "'+currentStyle+'"');
	  break;
  }
};
document.toggleSelectionOptionDisplay = toggleSelectionOptionDisplay;}
/* FILE:FreeanceWeb/Common/lib/contrib/md5.js */ if(!window.freeance_loaded_js['75816ac72b56489e7ffb090293bcd518']){window.freeance_loaded_js['75816ac72b56489e7ffb090293bcd518']=1;
/*
 * A JavaScript implementation of the RSA Data Security, Inc. MD5 Message
 * Digest Algorithm, as defined in RFC 1321.
 * Version 2.0 Copyright (C) Paul Johnston 1999 - 2002.
 * Other contributors: Greg Holt, Ydnar
 * Distributed under the BSD License
 * See http://pajhome.org.uk/crypt/md5 for more info.
 */

/*
 * Configurable variables. You may need to tweak these to be compatible with
 * the server-side, but the defaults work in most cases.
 */
var hexcase = 0;  /* hex output format. 0 - lowercase; 1 - uppercase        */
var b64pad  = ""; /* base-64 pad character. "=" for strict RFC compliance   */
var chrsz   = 8;  /* bits per input character. 8 - ASCII; 16 - Unicode      */

/*
 * These are the functions you'll usually want to call
 * They take string arguments and return either hex or base-64 encoded strings
 */
function hex_md5(s){ return binl2hex(core_md5(str2binl(s), s.length * chrsz));};
function b64_md5(s){ return binl2b64(core_md5(str2binl(s), s.length * chrsz));};
function hex_hmac_md5(key, data) { return binl2hex(core_hmac_md5(key, data)); };
function b64_hmac_md5(key, data) { return binl2b64(core_hmac_md5(key, data)); };

/* Backwards compatibility - same as hex_md5() */
function calcMD5(s){ return binl2hex(core_md5(str2binl(s), s.length * chrsz));};

/* 
 * Perform a simple self-test to see if the VM is working 
 */
function md5_vm_test()
{
  return hex_md5("abc") == "900150983cd24fb0d6963f7d28e17f72";
};

/*
 * Calculate the MD5 of an array of little-endian words, and a bit length
 */
function core_md5(x, len)
{
  /* append padding */
  x[len >> 5] |= 0x80 << ((len) % 32);
  x[(((len + 64) >>> 9) << 4) + 14] = len;
  
  var a =  1732584193;
  var b = -271733879;
  var c = -1732584194;
  var d =  271733878;

  for(var i = 0; i < x.length; i += 16)
  {
    var olda = a;
    var oldb = b;
    var oldc = c;
    var oldd = d;
 
    a = md5_ff(a, b, c, d, x[i+ 0], 7 , -680876936);
    d = md5_ff(d, a, b, c, x[i+ 1], 12, -389564586);
    c = md5_ff(c, d, a, b, x[i+ 2], 17,  606105819);
    b = md5_ff(b, c, d, a, x[i+ 3], 22, -1044525330);
    a = md5_ff(a, b, c, d, x[i+ 4], 7 , -176418897);
    d = md5_ff(d, a, b, c, x[i+ 5], 12,  1200080426);
    c = md5_ff(c, d, a, b, x[i+ 6], 17, -1473231341);
    b = md5_ff(b, c, d, a, x[i+ 7], 22, -45705983);
    a = md5_ff(a, b, c, d, x[i+ 8], 7 ,  1770035416);
    d = md5_ff(d, a, b, c, x[i+ 9], 12, -1958414417);
    c = md5_ff(c, d, a, b, x[i+10], 17, -42063);
    b = md5_ff(b, c, d, a, x[i+11], 22, -1990404162);
    a = md5_ff(a, b, c, d, x[i+12], 7 ,  1804603682);
    d = md5_ff(d, a, b, c, x[i+13], 12, -40341101);
    c = md5_ff(c, d, a, b, x[i+14], 17, -1502002290);
    b = md5_ff(b, c, d, a, x[i+15], 22,  1236535329);

    a = md5_gg(a, b, c, d, x[i+ 1], 5 , -165796510);
    d = md5_gg(d, a, b, c, x[i+ 6], 9 , -1069501632);
    c = md5_gg(c, d, a, b, x[i+11], 14,  643717713);
    b = md5_gg(b, c, d, a, x[i+ 0], 20, -373897302);
    a = md5_gg(a, b, c, d, x[i+ 5], 5 , -701558691);
    d = md5_gg(d, a, b, c, x[i+10], 9 ,  38016083);
    c = md5_gg(c, d, a, b, x[i+15], 14, -660478335);
    b = md5_gg(b, c, d, a, x[i+ 4], 20, -405537848);
    a = md5_gg(a, b, c, d, x[i+ 9], 5 ,  568446438);
    d = md5_gg(d, a, b, c, x[i+14], 9 , -1019803690);
    c = md5_gg(c, d, a, b, x[i+ 3], 14, -187363961);
    b = md5_gg(b, c, d, a, x[i+ 8], 20,  1163531501);
    a = md5_gg(a, b, c, d, x[i+13], 5 , -1444681467);
    d = md5_gg(d, a, b, c, x[i+ 2], 9 , -51403784);
    c = md5_gg(c, d, a, b, x[i+ 7], 14,  1735328473);
    b = md5_gg(b, c, d, a, x[i+12], 20, -1926607734);

    a = md5_hh(a, b, c, d, x[i+ 5], 4 , -378558);
    d = md5_hh(d, a, b, c, x[i+ 8], 11, -2022574463);
    c = md5_hh(c, d, a, b, x[i+11], 16,  1839030562);
    b = md5_hh(b, c, d, a, x[i+14], 23, -35309556);
    a = md5_hh(a, b, c, d, x[i+ 1], 4 , -1530992060);
    d = md5_hh(d, a, b, c, x[i+ 4], 11,  1272893353);
    c = md5_hh(c, d, a, b, x[i+ 7], 16, -155497632);
    b = md5_hh(b, c, d, a, x[i+10], 23, -1094730640);
    a = md5_hh(a, b, c, d, x[i+13], 4 ,  681279174);
    d = md5_hh(d, a, b, c, x[i+ 0], 11, -358537222);
    c = md5_hh(c, d, a, b, x[i+ 3], 16, -722521979);
    b = md5_hh(b, c, d, a, x[i+ 6], 23,  76029189);
    a = md5_hh(a, b, c, d, x[i+ 9], 4 , -640364487);
    d = md5_hh(d, a, b, c, x[i+12], 11, -421815835);
    c = md5_hh(c, d, a, b, x[i+15], 16,  530742520);
    b = md5_hh(b, c, d, a, x[i+ 2], 23, -995338651);

    a = md5_ii(a, b, c, d, x[i+ 0], 6 , -198630844);
    d = md5_ii(d, a, b, c, x[i+ 7], 10,  1126891415);
    c = md5_ii(c, d, a, b, x[i+14], 15, -1416354905);
    b = md5_ii(b, c, d, a, x[i+ 5], 21, -57434055);
    a = md5_ii(a, b, c, d, x[i+12], 6 ,  1700485571);
    d = md5_ii(d, a, b, c, x[i+ 3], 10, -1894986606);
    c = md5_ii(c, d, a, b, x[i+10], 15, -1051523);
    b = md5_ii(b, c, d, a, x[i+ 1], 21, -2054922799);
    a = md5_ii(a, b, c, d, x[i+ 8], 6 ,  1873313359);
    d = md5_ii(d, a, b, c, x[i+15], 10, -30611744);
    c = md5_ii(c, d, a, b, x[i+ 6], 15, -1560198380);
    b = md5_ii(b, c, d, a, x[i+13], 21,  1309151649);
    a = md5_ii(a, b, c, d, x[i+ 4], 6 , -145523070);
    d = md5_ii(d, a, b, c, x[i+11], 10, -1120210379);
    c = md5_ii(c, d, a, b, x[i+ 2], 15,  718787259);
    b = md5_ii(b, c, d, a, x[i+ 9], 21, -343485551);

    a = safe_add(a, olda);
    b = safe_add(b, oldb);
    c = safe_add(c, oldc);
    d = safe_add(d, oldd);
  }
  return Array(a, b, c, d);
  
};

/*
 * These functions implement the four basic operations the algorithm uses.
 */
function md5_cmn(q, a, b, x, s, t)
{
  return safe_add(bit_rol(safe_add(safe_add(a, q), safe_add(x, t)), s),b);
};
function md5_ff(a, b, c, d, x, s, t)
{
  return md5_cmn((b & c) | ((~b) & d), a, b, x, s, t);
};
function md5_gg(a, b, c, d, x, s, t)
{
  return md5_cmn((b & d) | (c & (~d)), a, b, x, s, t);
};
function md5_hh(a, b, c, d, x, s, t)
{
  return md5_cmn(b ^ c ^ d, a, b, x, s, t);
};
function md5_ii(a, b, c, d, x, s, t)
{
  return md5_cmn(c ^ (b | (~d)), a, b, x, s, t);
};

/*
 * Calculate the HMAC-MD5, of a key and some data
 */
function core_hmac_md5(key, data)
{
  var bkey = str2binl(key);
  if(bkey.length > 16) bkey = core_md5(bkey, key.length * chrsz);

  var ipad = Array(16), opad = Array(16);
  for(var i = 0; i < 16; i++) 
  {
    ipad[i] = bkey[i] ^ 0x36363636;
    opad[i] = bkey[i] ^ 0x5C5C5C5C;
  }

  var hash = core_md5(ipad.concat(str2binl(data)), 512 + data.length * chrsz);
  return core_md5(opad.concat(hash), 512 + 128);
};

/*
 * Add integers, wrapping at 2^32. This uses 16-bit operations internally
 * to work around bugs in some JS interpreters.
 */
function safe_add(x, y)
{
  var lsw = (x & 0xFFFF) + (y & 0xFFFF);
  var msw = (x >> 16) + (y >> 16) + (lsw >> 16);
  return (msw << 16) | (lsw & 0xFFFF);
};

/*
 * Bitwise rotate a 32-bit number to the left.
 */
function bit_rol(num, cnt)
{
  return (num << cnt) | (num >>> (32 - cnt));
};

/*
 * Convert a string to an array of little-endian words
 * If chrsz is ASCII, characters >255 have their hi-byte silently ignored.
 */
function str2binl(str)
{
  var bin = Array();
  var mask = (1 << chrsz) - 1;
  for(var i = 0; i < str.length * chrsz; i += chrsz)
    bin[i>>5] |= (str.charCodeAt(i / chrsz) & mask) << (i%32);
  return bin;
};

/*
 * Convert an array of little-endian words to a hex string.
 */
function binl2hex(binarray)
{
  var hex_tab = hexcase ? "0123456789ABCDEF" : "0123456789abcdef";
  var str = "";
  for(var i = 0; i < binarray.length * 4; i++)
  {
    str += hex_tab.charAt((binarray[i>>2] >> ((i%4)*8+4)) & 0xF) +
           hex_tab.charAt((binarray[i>>2] >> ((i%4)*8  )) & 0xF);
  }
  return str;
};

/*
 * Convert an array of little-endian words to a base-64 string
 */
function binl2b64(binarray)
{
  var tab = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
  var str = "";
  for(var i = 0; i < binarray.length * 4; i += 3)
  {
    var triplet = (((binarray[i   >> 2] >> 8 * ( i   %4)) & 0xFF) << 16)
                | (((binarray[i+1 >> 2] >> 8 * ((i+1)%4)) & 0xFF) << 8 )
                |  ((binarray[i+2 >> 2] >> 8 * ((i+2)%4)) & 0xFF);
    for(var j = 0; j < 4; j++)
    {
      if(i * 8 + j * 6 > binarray.length * 32) str += b64pad;
      else str += tab.charAt((triplet >> 6*(3-j)) & 0x3F);
    }
  }
  return str;
};}
/* 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)
{
  /* TODO: eliminate initial conversion to meters to reduce rounding errors */
  if (srcUnit == destUnit)
    return(dist);
  var newdist = dist;
  /* convert to meters */
  switch (srcUnit.toLowerCase())
  {
    case 'mm':
      newdist = dist/1000.0;
      break;
    case 'cm':
      newdist = dist/100.0;
      break;
    case 'm':
      newdist = dist;
      break;
    case 'km':
      newdist = dist * 1000;
      break;
    case 'in':
      newdist = dist*0.0254;
      break;
    case 'ft':
      newdist = dist*0.3048;
      break;
    case 'yd':
      newdist = dist*0.9144;
      break;
    case 'mi':
      newdist = dist * 1609.344;
      break;
  }
  /* convert to requested units */
  switch (destUnit.toLowerCase())
  {
    case 'mm':
      newdist = newdist * 1000;
      break;
    case 'cm':
      newdist = newdist * 100;
      break;
    case 'in':
      newdist = newdist * 39.37007874;
      break;
    case 'ft':
      newdist = newdist * 3.2808399;
      break;
    case 'yd':
      newdist = newdist * 1.0936133;
      break;
    case 'mi':
      newdist = newdist * 0.00062137;
      break;
    case 'm':
      break;
    case 'km':
      newdist = newdist * .001;
      break;
  }
  return(newdist);
};


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)
  {
    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/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_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 '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 = '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/Client/PublicAccess1/lib/MapLib/Debug.js */ if(!window.freeance_loaded_js['5eb964caf2a54df66d4c803a424b8603']){window.freeance_loaded_js['5eb964caf2a54df66d4c803a424b8603']=1;
//debug.js
//debug functionality
//provides facilities for error logging and transmission
//These functions have a global scope.  Will be converted to an object in the future.
//DEBUG_MODE is a boolean indicating that debugging is enabled.
//DEBUG_TEXT is a string; all current debug information
//DEBUG_TARGET is a pointer to an html element used for display of debugging information
//DEBUG_ADDRESS is a string; email address of the recipient of debug emails


DEBUG_TARGET = null;
dprintf = function(msg)
{
  if(arguments.length>2){
    if(arguments[2]=='logWarning')
      console.warn(msg);
    else
      if(arguments[2]=='logError')
        console.error(msg);
      else
        console.log(msg);
  }
  else
    console.log(msg);
};}
/* 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/PublicAccess1/lib/XML/FreeanceXMLParser.js */ if(!window.freeance_loaded_js['9702a7c490ea700ddd611a351ef8960c']){window.freeance_loaded_js['9702a7c490ea700ddd611a351ef8960c']=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){};
FreeanceXMLParser.prototype = new XMLParser();
FreeanceXMLParser.prototype.constructor = FreeanceXMLParser;
FreeanceXMLParser.superclass = XMLParser.prototype;

FreeanceXMLParser.prototype.getApplicationConfig = function()
{
	var appNode = this.xmlDoc.getElementsByTagName('applicationConfig')[0];
	var styleindex=this.getNextNamedChildNodeIndex(appNode,0,"stylesheet");
	var customLayoutIndex = this.getNextNamedChildNodeIndex(appNode,0,"customOptions");
	var mapUnitIndex = this.getNextNamedChildNodeIndex(appNode,0,"mapUnits");
	var nodeIndex = this.getNextNamedChildNodeIndex(appNode,0,"userScripts");
	return {
		id: this.decodeSTRING(appNode.childNodes[this.getNextNamedChildNodeIndex(appNode,0,"applicationId")]),
		organization: this.decodeSTRING(appNode.childNodes[this.getNextNamedChildNodeIndex(appNode,0,"organization")]),
		title: this.decodeSTRING(appNode.childNodes[this.getNextNamedChildNodeIndex(appNode,0,"title")]),
		clientType: this.decodeSTRING(appNode.childNodes[this.getNextNamedChildNodeIndex(appNode,0,"clientType")]),
		stylesheet: (styleindex==-1)?'default':this.decodeSTRING(appNode.childNodes[styleindex]),
		administrator: this.decodeSTRING(appNode.childNodes[this.getNextNamedChildNodeIndex(appNode,0,"administrator")]),
		adminEmail: this.decodeSTRING(appNode.childNodes[this.getNextNamedChildNodeIndex(appNode,0,"adminEmail")]),
		customOptions: ((customLayoutIndex!=-1)?(this.parseApplicationCustomOptions(appNode.childNodes[customLayoutIndex])):(null)),
		mapUnits: (mapUnitIndex > -1)?(this.decodeSTRING(appNode.childNodes[mapUnitIndex])):('FT'),
		userScripts: (nodeIndex==-1)?(Array()):(this.parseUserScripts(appNode.childNodes[nodeIndex]))
	};
};

FreeanceXMLParser.prototype.parseUserScripts = function(parentNode)
{
	var config = [];
	var scriptNodes = parentNode.getElementsByTagName('scriptfile');
	for (var i=0;i<scriptNodes.length;i++)
		config.push(scriptNodes[i].getAttribute('url'));
	return config;
};

FreeanceXMLParser.prototype.parseApplicationCustomOptions = function (customNode)
{
	var activepanelindex=this.getNextNamedChildNodeIndex(customNode,0,"defaultActivePanel");
	var redrawIndex = this.getNextNamedChildNodeIndex(customNode,0,"mapAutoRedraw");
	var deselectIndex = this.getNextNamedChildNodeIndex(customNode,0,"clickDeselect");
	var freezeIndex = this.getNextNamedChildNodeIndex(customNode,0,"freezeTableHeader");
	var legendIndex=this.getNextNamedChildNodeIndex(customNode,0,"customLegendURL");
	var scriptIndex = this.getNextNamedChildNodeIndex(customNode,0,"customScriptURL");
	var expandSearchIndex =  this.getNextNamedChildNodeIndex(customNode,0,"expandSearch");
	var childNodes = customNode.childNodes;
	return {
		pageHeaderHeight: this.decodeINT(childNodes[this.getNextNamedChildNodeIndex(customNode,0,"pageHeaderHeight")]),
		rightPanelWidth: this.decodeINT(childNodes[this.getNextNamedChildNodeIndex(customNode,0,"rightPanelWidth")]),
		mapToolOptionHeight: this.decodeINT(childNodes[this.getNextNamedChildNodeIndex(customNode,0,"mapToolOptionHeight")]),
		vicinityMapWidthOpen: this.decodeINT(childNodes[this.getNextNamedChildNodeIndex(customNode,0,"vicinityMapWidthOpen")]),
		homeLinkHeight: this.decodeINT(childNodes[this.getNextNamedChildNodeIndex(customNode,0,"homeLinkHeight")]),
		defaultActivePanel: (activepanelindex>-1)?(this.decodeSTRING(childNodes[activepanelindex])):('userIntro'),
		mapAutoRedraw: (redrawIndex==-1)?(true):(this.decodeINT(childNodes[redrawIndex])==1),
		clickDeselect: (deselectIndex==-1)?(true):(this.decodeINT(childNodes[deselectIndex])==1),
		expandSearch: (expandSearchIndex==-1)?(false):(this.decodeINT(childNodes[expandSearchIndex])==1),
		freezeTableHeader: (freezeIndex==-1)?(true):(this.decodeINT(childNodes[freezeIndex])==1),
		customLegendURL: (legendIndex==-1)?(''):(this.decodeSTRING(childNodes[legendIndex])),
		customScriptURL: (scriptIndex==-1)?(''):(this.decodeSTRING(childNodes[scriptIndex]))
	};
};

FreeanceXMLParser.prototype.getMapConfig = function()
{
	var mapNode = this.xmlDoc.getElementsByTagName('map')[0];
	var vmapNodes = mapNode.getElementsByTagName('vicinityMap');
	var loginQueryNodes = mapNode.getElementsByTagName("loginQuery");
	var printNodes = mapNode.getElementsByTagName("pdfPrintConfig");
	var exportNodes = mapNode.getElementsByTagName('exportConfig');
	var proxSearchNodes = mapNode.getElementsByTagName('proximitySearchConfig');
	var mapSchemeNodes = mapNode.getElementsByTagName('mapSchemeDefinitions');

	var legendAttributeIndex = this.__helper__getNextElementNamedChildNode(mapNode,0,"legendAttributes");
	var legendIndex = this.__helper__getNextElementNamedChildNode(mapNode,0,"legend");
	var legendAttributes = this.parseLegendAttributes(mapNode.childNodes[(legendAttributeIndex>-1)?legendAttributeIndex:legendIndex]);
	var seamlessPanIdx=this.__helper__getNextElementNamedChildNode(mapNode,0,"seamlessPan");
	var seamlessPan = false;
	if(seamlessPanIdx!=-1)
		seamlessPan=(mapNode.childNodes[seamlessPanIdx].getAttribute('enabled')=='true');
	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]));

	var mapConfig = {
		configNode:mapNode,
		id: mapNode.getAttribute("id"),
		resourceId: this.decodeSTRING(mapNode.getElementsByTagName("resourceId")[0]),
		imsHostname: this.decodeSTRING(mapNode.getElementsByTagName("imsHostname")[0]),
		previousStates: this.decodeINT(mapNode.getElementsByTagName("previousStates")[0]),
		vmap: (vmapNodes.length)?this.parseVMapConfig(vmapNodes[0]):null,
		themes: this.parseThemeDefinitions(mapNode.getElementsByTagName("themeDefinitions")[0]),
		activeTheme: this.decodeSTRING(mapNode.getElementsByTagName("activeTheme")[0]),
		themeGroups: this.parseThemeGroups(mapNode),
		legendAttributes: legendAttributes,
		labelConfig: null,
		loginQuery: (loginQueryNodes.length)?this.parseMapLoginQuery(loginQueryNodes[0]):null,
		printConfig: (printNodes.length)?this.parsePdfPrintConfig(printNodes[0]):{templates: new Array,defaultTemplate: -1},
		exportConfig:(exportNodes.length)?this.parseExportConfig(exportNodes[0]):null,
		scalebarConfig:null,
		geocodeConfig:null,
		directMappingConfig:null,
		mapSchemeConfig: (mapSchemeNodes.length)?this.parseMapSchemeConfig(mapSchemeNodes[0]):{mapSchemes:[],defaultMapScheme:0},
		seamlessPan: seamlessPan,
		projectionId: projectionId
	};
	return mapConfig;
};

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')
		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;
};

XMLParser.prototype.parseBufferGroupConfig = function(){
	var configNode =  this.xmlDoc.getElementsByTagName('bufferGroups');
	var config = [];
	if(configNode.item(0)){
		var groupNodes = configNode.item(0).getElementsByTagName('bufferGroup');
		for(var i = 0; i < groupNodes.length; i++){
			var layers = [];
			var layerNodes = groupNodes[i].getElementsByTagName('layer');
			for(var j = 0; j < layerNodes.length; j++){
				if(this.decodeSTRING(layerNodes[j]) != ''){
					layers.push(this.decodeSTRING(layerNodes[j]));
				}
			}
			config.push({name: groupNodes[i].getAttribute('name'), group: layers});
		}
	} 
	return config;
};

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'));
			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')
				}
			};
			mapSchemes.push({
				id: currentMapSchemeId,
				name: this.decodeSTRING(mapSchemeTags[i].childNodes[this.__helper__getNextElementNamedChildNode(mapSchemeTags[i],0,"schemeName")]),
				themes: themes
			}
			);
		}
	};
	return {
		mapSchemes: mapSchemes,
		defaultMapScheme: parseInt(this.decodeSTRING(defaultMapSchemeNode))
	};
};


FreeanceXMLParser.prototype.parseVMapConfig = function(vmapNode)
{
	return {
		id: vmapNode.getAttribute("id"),
		resourceId: this.decodeSTRING(vmapNode.childNodes[this.getNextNamedChildNodeIndex(vmapNode,0,"resourceId")]),
		slaveType: this.decodeSTRING(vmapNode.childNodes[this.getNextNamedChildNodeIndex(vmapNode,0,"slaveType")]),
		boundBoxPercentMin: this.decodeDOUBLE(vmapNode.childNodes[this.getNextNamedChildNodeIndex(vmapNode,0,"boundBoxPercentMin")]),
		styleSheet: this.decodeSTRING(vmapNode.childNodes[this.getNextNamedChildNodeIndex(vmapNode,0,"styleSheet")])
	}
};


FreeanceXMLParser.prototype.getTemplateConfig = function(templateRootNode)
{
	var templateRootNode = this.xmlDoc.getElementsByTagName('templates')[0];
	var templates = new Object();
	var htmlString = '';
	for (var templateIndex = this.getNextNamedChildNodeIndex(templateRootNode,0,"template");templateIndex!=-1;templateIndex=this.getNextNamedChildNodeIndex(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;
	};
	return templates;
};

FreeanceXMLParser.prototype.getExtensionConfig = function()
{
	var extensionConfigNode = this.xmlDoc.getElementsByTagName('extensionConfig')[0];
	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');
		var module = extension.getAttribute('module');
		extensions[name] = {
			enabled: (enabled == 'true'),
			dynamicfile: extension.getAttribute('dynamicfile'),
			compressedfile: extension.getAttribute('compressedfile'),
			module: module
		};
		if (extensions[name].enabled)
		{
			var forceLoad = extension.getAttribute('forceLoad');
			extensions[name].forceLoad = ((typeof(forceLoad)=='string')?((forceLoad == 'true')?true:false):(false));
		};
		extensions[name].loaded = false;
	};
	return(extensions);
};


FreeanceXMLParser.prototype.parseThemeDefinitions = function (newNode)
{
	var themeDefinitions = {};
	var themeElements = newNode.getElementsByTagName('theme');
	for (var i=0;i<themeElements.length;i++)
	{
		themeDefinitions[themeElements[i].getAttribute("id")] = this.parseTheme(themeElements[i]);
	};
	return themeDefinitions;
};


FreeanceXMLParser.prototype.parseTheme = function (themeNode)
{
	var hideThemeValue = themeNode.getAttribute("hideTheme");
	var selectNodes = themeNode.getElementsByTagName('selectOptions');
	var bufferNodes = themeNode.getElementsByTagName('bufferOptions');
	var themeFieldsNodes = themeNode.getElementsByTagName('themeFields');
	var themeAttributes = {
		id: themeNode.getAttribute("id"),
		hideTheme: (hideThemeValue==null)?false:(hideThemeValue == 'true'),
		themeName: this.decodeSTRING(themeNode.getElementsByTagName('themeName')[0]),
		selectOptions: (selectNodes.length>0)?(this.parseThemeSelectOptions(selectNodes[0])):null,
		bufferOptions: (bufferNodes.length>0)?(this.parseThemeBufferOptions(bufferNodes[0])):null,
		visibility: false,
		altLegends: new Array(),
		themeFields: themeFieldsNodes.length?this.decodeSTRING(themeFieldsNodes[0]).parseJSON():{}
	};
	var altLegends = themeNode.getElementsByTagName('altLegend');
	for(var lcv=0;lcv < altLegends.length;lcv++)
	{
		themeAttributes["altLegends"].push({
			legendName: this.decodeSTRING(altLegends[lcv].getElementsByTagName("legendName")[0]),
			legendLabel: this.decodeSTRING(altLegends[lcv].getElementsByTagName("legendLabel")[0])
		});
	};
	return themeAttributes;
};


FreeanceXMLParser.prototype.parseThemeSelectOptions = function(newNode)
{
	var keyfieldTypeNodes = newNode.getElementsByTagName('keyFieldType');
	var zoomRatioNodes = newNode.getElementsByTagName('zoomExtentRatio');
	var sqlParamNodes = newNode.getElementsByTagName('sqlParams');
	return {
		styleSheet: this.decodeSTRING(newNode.getElementsByTagName("styleSheet")[0]),
		fieldList: this.decodeSTRING(newNode.getElementsByTagName("fieldList")[0]),
		limit: this.decodeINT(newNode.getElementsByTagName("limit")[0]),
		tolerance: this.decodeDOUBLE(newNode.getElementsByTagName("tolerance")[0]),
		idField: this.decodeSTRING(newNode.getElementsByTagName("idField")[0]),
		keyField: this.decodeSTRING(newNode.getElementsByTagName("keyField")[0]),
		keyFieldType: (keyfieldTypeNodes.length)?this.decodeSTRING(keyfieldTypeNodes[0]):"OID",
		zoomExtentRatio:(zoomRatioNodes.length)?this.decodeDOUBLE(zoomRatioNodes[0]):1.2,
		resultTemplate: this.decodeSTRING(newNode.getElementsByTagName("resultTemplate")[0]),
		sqlParams: (sqlParamNodes.length)?this.parseChainedQuerySqlParams(sqlParamNodes[0]):null
	};
};



FreeanceXMLParser.prototype.parseChainedQuerySqlParams = function(sqlParamsNode)
{
	var sqlParams = [];
	var sqlParamNodeList = sqlParamsNode.getElementsByTagName('sqlParam');
	var currentParam = null;
	for(var lcv=0;lcv < sqlParamNodeList.length;lcv++)
	{
		var theNode = sqlParamNodeList[lcv];
		currentParam = {
			pdqIdentifier: this.decodeSTRING(theNode.getElementsByTagName("pdqIdentifier")[0]),
			fieldList: []
		};
		var fieldListNode = theNode.getElementsByTagName("fieldList")[0];
		var fieldNodeList = fieldListNode.getElementsByTagName('field');
		for(var fieldIndex=0;fieldIndex < fieldNodeList.length;fieldIndex++)
		{
			currentParam["fieldList"].push({
				fieldName: this.decodeSTRING(fieldNodeList[fieldIndex].getElementsByTagName("fieldName")[0]),
				pdqFieldName: this.decodeSTRING(fieldNodeList[fieldIndex].getElementsByTagName("pdqFieldName")[0])
			});
		};
		if (this.getNextNamedChildNodeIndex(theNode,0,"queryType") > -1)
		{
			currentParam["queryType"] = this.decodeSTRING(theNode.getElementsByTagName("queryType")[0]);
			currentParam["numRows"] = this.decodeINT(theNode.getElementsByTagName("numRows")[0]);
			currentParam["startAt"] = this.decodeINT(theNode.getElementsByTagName("startAt")[0]);
		}
		else  // do not want.  use full select instead
		{
			currentParam["queryType"] = '';
			currentParam["numRows"] = 0;
			currentParam["startAt"] = 0;
		};
		sqlParams.push(currentParam);
	};
	if (sqlParams.length == 0)
		sqlParams = null;
	return(sqlParams);
};

FreeanceXMLParser.prototype.parseThemeBufferOptions = function(newNode)
{
	var areaStyleNodes= newNode.getElementsByTagName("areaStyleSheet");
	var areaStyle = (areaStyleNodes.length>0)?this.decodeSTRING(areaStyleNodes[0]):'';
	var bufferAttributes = {
		styleSheet: this.decodeSTRING(newNode.getElementsByTagName("styleSheet")[0]),
		areaStyleSheet: areaStyle,
		fieldList: this.decodeSTRING(newNode.getElementsByTagName("fieldList")[0]),
		limit: this.decodeINT(newNode.getElementsByTagName("limit")[0]),
		resultTemplate: this.decodeSTRING(newNode.getElementsByTagName("resultTemplate")[0]),
		invalidTemplate: this.decodeSTRING(newNode.getElementsByTagName("invalidTemplate")[0]),
		maxSelect: this.decodeINT(newNode.getElementsByTagName("maxSelect")[0])
	};
	var sqlParamsIndex = this.getNextNamedChildNodeIndex(newNode,0,"sqlParams");
	bufferAttributes["sqlParams"] = (sqlParamsIndex > -1)?this.parseChainedQuerySqlParams(newNode.childNodes[sqlParamsIndex]):null;
	if (this.getNextNamedChildNodeIndex(newNode,0,"filterQueries") != -1)
	{
		var queryListNode = newNode.childNodes[this.getNextNamedChildNodeIndex(newNode,0,"filterQueries")];
		bufferAttributes["filterQueries"] = new Object;
		for (var queryIndex = this.getNextNamedChildNodeIndex(queryListNode,0,"query");queryIndex!=-1;queryIndex=this.getNextNamedChildNodeIndex(queryListNode,queryIndex+1,"query"))
		{
			bufferAttributes["filterQueries"][this.decodeSTRING(queryListNode.childNodes[queryIndex])] = null;
		}
	}
	else
		bufferAttributes["filterQueries"] = null;
	if (this.getNextNamedChildNodeIndex(newNode,0,"export_csv")!=-1)
	{
		if (!bufferAttributes["export"])
			bufferAttributes["export"] = new Object;
		bufferAttributes["export"].csv = new Object;
		if(this.decodeSTRING(newNode.childNodes[this.getNextNamedChildNodeIndex(newNode,0,"export_csv")]) == 'true')
		{
			bufferAttributes["export"].csv.enabled = true;
			bufferAttributes["export"].csv.delim = this.decodeSTRING(newNode.childNodes[this.getNextNamedChildNodeIndex(newNode,0,"export_csv_delim")]);
			if(this.decodeSTRING(newNode.childNodes[this.getNextNamedChildNodeIndex(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)
{
	return {enabled: newNode.getAttribute('enabled')};
};


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 tnode=templateNodes[i];
		var inputNodes = tnode.getElementsByTagName('userinput');
		var userinput = [];
		for (var j=0;j<inputNodes.length;j++){
			var inode=inputNodes[j];
			userinput.push({
					id:inode.getAttribute('id'),
					description:inode.getAttribute('description'),
					maxlength:parseInt(inode.getAttribute('maxlength'))
			});
		};
		printConfig.templates.push({
			displayName: this.decodeSTRING(tnode.getElementsByTagName("displayname")[0]),
			templateName: this.decodeSTRING(tnode.getElementsByTagName("templatename")[0]),
			orientation: tnode.getAttribute('orientation'),
			unit: tnode.getAttribute('unit'),
			width: parseFloat(tnode.getAttribute('width')),
			height: parseFloat(tnode.getAttribute('height')),
			mapwidth: parseFloat(tnode.getAttribute('mapwidth')),
			mapheight: parseFloat(tnode.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.parseMapLoginQuery = function(queryNode)
{
	//var definedQueryNode = queryNode.childNodes[this.getNextNamedChildNodeIndex(queryNode,0,"definedQuery")];
	return null;//this.parseDefinedQuery(definedQueryNode);
};


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:'',
			auto: false
		}
	};
	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: (zoomtoNode.getAttribute("enabled") == "1"),
			queryfield:zoomtoNode.getAttribute("queryfield"),
			layerfield:zoomtoNode.getAttribute("layerfield"),
			layerfieldtype: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');
		var snode=null;
		for (var i=0;i<suggestNodes.length;i++)
		{
			snode=suggestNodes[i];
			config.suggestConfig.push({
				pdqfield: snode.getAttribute('pdqfield'),
				elementId: snode.getAttribute('elementId'),
				resultElementId: snode.getAttribute('resultElementId'),
				timeout: parseInt(snode.getAttribute('timeout')),
				dbid: snode.getAttribute('dbid'),
				tablename: snode.getAttribute('tablename'),
				fieldname: snode.getAttribute('fieldname'),
				resultlimit: parseInt(snode.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.getQueryConfig = function()
{
	var config = {};
	var queryParentNode = this.xmlDoc.getElementsByTagName('queryConfig')[0];
	var definedQueryNodes = queryParentNode.getElementsByTagName('definedQuery');
	for (var i=0;i<definedQueryNodes.length;i++)
		config[definedQueryNodes[i].getAttribute("id")] = this.parseDefinedQuery(definedQueryNodes[i]);
	return config;
};}
/* 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/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;
  //stop IE from screwing up the image size - seems to default to 25 for new images
  if (xIE4Up)
  {
    xWidth(this.imageNode,newWidth * 3);
    xHeight(this.imageNode,newHeight * 14);
  }
  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(Math.round((c2[0]-c1[0])/numSteps), Math.round((c2[1]-c1[1])/numSteps), Math.round((c2[2]-c1[2])/numSteps));

  for (i=0; i<numSteps; i++)
  {
    var R = (dC[0]*i+c1[0]);
    R=(R>0xff)?0xff:R;
    R=R.toString(16);
    var G = (dC[1]*i+c1[1]);
    G=(G>0xff)?0xff:G;
    G=G.toString(16);
    var B = (dC[2]*i+c1[2]);
    B=(B>0xff)?0xff: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/PublicAccess1/lib/MapLib/Map.js */ if(!window.freeance_loaded_js['79dee526f033fdf8c934491c83e2a666']){window.freeance_loaded_js['79dee526f033fdf8c934491c83e2a666']=1;
//Map.js

Map = function (newId)
{
	var $_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.savedQueryControl = null;
	this.zoomBar = null;
	this.scaleBar = null;

	/* TODO: Remove old handlers */
	this.extensionMapClickHandlers = [];  // JPW
	this.extensionMapMoveHandlers = [];

	//session specific data
	this.sessionID = null;
	this.extent    = [];        //extent of main map
	this.dragExtent = [0,0,0,0];  //drag extent tracker
	this.vmapExtent    = [];    //extent of vicinity map
	this.bookmarks = [];      //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.getExtent = function(){return [this.extent[0],this.extent[1],this.extent[2],this.extent[3]]};
this.eventHandlers = {
	initialize:[],
	extentChange: [],
	layerChange: [],
	imageChange: [],
	tileLoadStart: [],
	tileLoadFinish: []
};
//map interaction modes
//handled slightly differently than above
//which fcn is called is determined by mode name
/* TODO: move these to the map image object */
this.cursorEventHandlers={
	click:{},
	move:{},
	up:{},
	down:{},
	out:{},
	over:{}
};
this.addEventHandler = function(eventType,callback)
{
	//console.assert((typeof(callback)=='function'),'MapObject:  attempting to add an invalid "'+eventType+'" event handler');
	//console.log('MapObject:  adding event handler "'+eventType+'"');
	if (this.eventHandlers[eventType]!=null)  //empty array can eval to false
		this.eventHandlers[eventType].push(callback);
	return this.eventHandlers[eventType].length-1;
};
this.removeEventHandler = function(eventType,index)
{
	if (this.eventHandlers[eventType]!=null)  //empty array can eval to false
		this.eventHandlers[eventType][index]=null;
};
this.addCursorEventHandler=function(eventType,mode,callback){
	//console.assert((typeof(callback)=='function'),'MapObject:  attempting to add an invalid cursor "'+eventType+'" event handler for mode "'+mode+'"');
	//console.log('MapObject: adding cursor event handler "'+eventType+'" for mode "'+mode+'"');
	if(this.cursorEventHandlers[eventType]){
		if(this.cursorEventHandlers[eventType][mode]==null)
			this.cursorEventHandlers[eventType][mode]=new Array();
		retval=this.cursorEventHandlers[eventType][mode].length;
		this.cursorEventHandlers[eventType][mode].push(callback);
		return retval;
	}
	return null;
};


this.setConfig = function(newConfig)
{
	this.config = newConfig;
	if(this.config.configNode)
	{
		this.configDocNode = this.config.configNode;
		this.config.configNode = null;
	};
	this.selectionsExist = false;
	var selectionCount = 0;
	this.buffersExist = false;
	var bufferCount = 0;
	var bufferableThemes = new Array();
	for (var currentTheme in this.config.themes)
	{
		if(currentTheme=='toJSONString')continue;
		if (this.config.themes[currentTheme].selectOptions != null)
		{
			this.selectionsExist = true;
			selectionCount++;
		};
		if (this.config.themes[currentTheme].bufferOptions != null)
		{
			bufferableThemes[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(bufferableThemes);
	if (this.coordConvControl)
		this.coordConvControl.draw();
	if (this.measureControl)
		this.measureControl.initialize();
	if (this.savedQueryControl)
		this.savedQueryControl.initialize();
};

Map.prototype.setMapScheme = function(schemeId)
{
	var themeArray = [];
	for (var currentTheme in this.config.mapSchemeConfig.mapSchemes[schemeId].themes)
	{
		if(currentTheme=='toJSONString')continue;
		themeArray.push([
			this.config.mapSchemeConfig.mapSchemes[schemeId].themes[currentTheme].id,
			(this.config.mapSchemeConfig.mapSchemes[schemeId].themes[currentTheme].display==1),
			this.config.mapSchemeConfig.mapSchemes[schemeId].themes[currentTheme].legend
		]);
	};
	this.setWaiting(true);
	this.legendSync = false;
	freeance_request(function(data){$_this.callback(data, 'setMapScheme',true);}, 'GIS.Themes.setScheme', this.sessionID, 0, themeArray);
};

this.initialize = function(sessionID)
{
	//arguments[1] = scheme id (if present)
	var useMapScheme = false;
	if (arguments.length > 0)
		if (arguments[1] != null)
			useMapScheme = true;
	var map_args = [[this.config["resourceId"], this.config["previousStates"],this.mapImage.width(),this.mapImage.height(),false]];
	if(this.vmapImage!=null)
		map_args[1] = [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"]];
	if (this.scalebar != null)
		this.scalebar.initialize();
	this.setWaiting(true);

	if (useMapScheme)
	{
		var mapSchemes = this.config.mapSchemeConfig.mapSchemes;
		var schemeId = arguments[1];
		var idx=0;
		for (var i=0;i<mapSchemes.length;i++){
			if(mapSchemes[i]['id']==schemeId)
				idx=i;
		}
		this.activeMapScheme = schemeId;
		var scheme=mapSchemes[idx];
		var themeArray = new Array();
		for (var currentTheme in scheme.themes)
		{
			if(currentTheme=='toJSONString')continue;
			var theme=scheme.themes[currentTheme];
			themeArray.push([theme.id,(theme.display==1),theme.legend]);
		};
		freeance_request(function(data){$_this.callback(data,'Initialize_withScheme',true);},'GIS.Session.initialize.with.preset.scheme', sessionID, map_args, themeArray);
	}
	else
		freeance_request(function(data){$_this.callback(data,'Initialize',true);},'GIS.Session.initialize',sessionID,map_args);
};

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

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);
		}
	}
};

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

this.loadLegend = function()
{
	if (this.customLegendImage!=null)
		this.legendImage.src = this.customLegendImage;
	else{
		if (_MAP_INITIALIZED){
			this.setWaiting(true);
			freeance_request(function(data){$_this.callback(data,'Legend',true);},'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 result = freeance_request(null,'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 data = result.data;
		if(data != null)
		{
			this.legendImage.src = this.correctURL(data);
			this.legendSync = true;
		};
		this.setWaiting(false);
	}
};

this.mouseMove = function(xPos,yPos,width,height,XPercent,YPercent,clickMode)
{
	/* TODO: Remove old handlers */
 if (this.extensionMapMoveHandlers[clickMode]){
	 console.warn('deprecated event handler type used for '+clickMode);
	 this.extensionMapMoveHandlers[clickMode](xPos,yPos,width,height,XPercent,YPercent,clickMode);
 };
 var eventarr=this.cursorEventHandlers['move'][clickMode];
 if(eventarr){
	 for (var i=0;i<eventarr.length;i++){
		 if(typeof(eventarr[i])=='function')
			 eventarr[i](xPos,yPos,width,height,XPercent,YPercent,clickMode);
	 }
 };
};

this.click = function(xPos,yPos,width,height,XPercent,YPercent,clickMode)
{
	switch (clickMode)
	{
		case 'ZoomIn':
			this.setWaiting(true);
			freeance_request(function(data){$_this.callback(data,clickMode,true);},'GIS.Zoom.in.byPercent',this.sessionID,0,width,height,1.5,XPercent,YPercent);
			this.legendSync = false;
			break;
		case 'ZoomOut':
			this.setWaiting(true);
			freeance_request(function(data){$_this.callback(data,clickMode,true);},'GIS.Zoom.out.byPercent',this.sessionID,0,width,height,1.5,XPercent,YPercent);
			this.legendSync = false;
			break;
		case 'Center':
			this.setWaiting(true);
			freeance_request(function(data){$_this.callback(data,clickMode,true);},'GIS.Center.byPercent',this.sessionID,0,width,height,XPercent,YPercent);
			break;
		default:
			if (this.extensionMapClickHandlers[clickMode]){
				console.warn('deprecated event handler type used for '+clickMode);
				this.extensionMapClickHandlers[clickMode](xPos,yPos,width,height,XPercent,YPercent,clickMode);
			}
			break;
	}
	var eventarr=this.cursorEventHandlers['click'][clickMode];
	if(eventarr){
		for (var i=0;i<eventarr.length;i++){
			if(typeof(eventarr[i])=='function')
				eventarr[i](xPos,yPos,width,height,XPercent,YPercent,clickMode);
		}
	};
};

this.centerOnPoint = function(newMapX,newMapY)
{
	//accepts a new x,y coordinate pair in the current map units
	this.setWaiting(true);
	freeance_request(function(data){$_this.callback(data,'CenterOnPoint',true);},'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);
	freeance_request(function(data){$_this.callback(data,'CenterOnPoint',true);},'GIS.Center.onPoint',this.sessionID,0,this.mapImage.width(),this.mapImage.height(),mapX,mapY);
};

this.pan = function(DirStr)
{
	this.setWaiting(true);
	var mapData = freeance_request(function(data){$_this.callback(data,'Pan',true);},'GIS.Pan.byDirection',this.sessionID,0,this.mapImage.width(),this.mapImage.height(),DirStr,0.4);
};

this.zoomInitialExtent = function()
{
	this.setWaiting(true);
	this.legendSync = false;
	freeance_request(function(data){$_this.callback(data,'ZoomInitialExtent',true);},'GIS.Zoom.to.initialExtent',this.sessionID,0,this.mapImage.width(),this.mapImage.height());
};

this.zoomFullExtent = function()
{
	this.setWaiting(true);
	this.legendSync = false;
	freeance_request(function(data){$_this.callback(data,'ZoomInitialExtent',true);},'GIS.Zoom.to.fullExtent',this.sessionID,0,this.mapImage.width(),this.mapImage.height());
};

this.zoomPresetExtent = function(newPresetName)
{
	this.setWaiting(true);
	this.legendSync = false;
	freeance_request(function(data){$_this.callback(data,'ZoomPresetExtent',true);},'GIS.Zoom.to.presetExtent',this.sessionID,0,this.mapImage.width(),this.mapImage.height(),newPresetName);
};

this.zoomIn = function()
{
	this.setWaiting(true);
	this.legendSync = false;
	freeance_request(function(data){$_this.callback(data,'ZoomIn',true);},'GIS.Zoom.in',this.sessionID,0,this.mapImage.width(),this.mapImage.height(),this.zoomFactor);
};

this.zoomOut = function()
{
	this.setWaiting(true);
	this.legendSync = false;
	freeance_request(function(data){$_this.callback(data,'ZoomOut',true);},'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
	//
	console.log("mapObject.zoomTo("+themeIndex+","+SQLstr+","+select+")");
	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] = [configSQLParams[pos].pdqIdentifier];
				var fieldPairs = Array();
				for(var lcv=0;lcv < configSQLParams[pos].fieldList.length;lcv++)
				{
					fieldPairs.push([
						configSQLParams[pos].fieldList[lcv].fieldName,
						configSQLParams[pos].fieldList[lcv].pdqFieldName
					]);
				}
				sqlParams[pos][1] = fieldPairs;
				if (configSQLParams[pos].queryType != '')
				{
					sqlParams[pos][2] = [
						configSQLParams[pos].queryType,
						configSQLParams[pos].numRows,
						configSQLParams[pos].startAt
					];
				}
			};
			freeance_request(function(data){$_this.selectionControl.callback_newselection(data,themeIndex);},'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
			freeance_request(function(data){$_this.selectionControl.callback_newselection(data,themeIndex);},'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
	{
		freeance_request(function(data){$_this.callback(data,'zoomTo',true);},'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);
	}
};

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,value);
		this.zoomTo(layerid,sqlWhere,select);
	}
};

this.zoomToMany =  function(themeIndex, SQLstr, stylesheet){
	console.log("mapObject.zoomToMany("+themeIndex+","+SQLstr+","+stylesheet+")");
	this.setWaiting(true);
	this.legendSync = false;

	if(!stylesheet && this.selectionsExist)
		stylesheet = this.config.themes[themeIndex].selectOptions.styleSheet;

	freeance_request(function(data){$_this.callback(data,'zoomToMany',true);},'GIS.Zoom.to.queryResults',document.mapObject.sessionID,0,document.mapObject.mapImage.width(),document.mapObject.mapImage.height(),themeIndex,'',SQLstr,1.0,0,false,stylesheet);
};

this.zoomToMany_ = function(layerid,attrib,fieldtype,values,stylesheet)
{
	console.log('zoomToMany_('+layerid+','+attrib+','+fieldtype+','+values+','+stylesheet+')');

	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 sqlStmts = SQLWhereBuilder.stmt_compare(attrib,'=',quote,values);
    var whereClauseStr = SQLWhereBuilder.stmt_or(sqlStmts);
		
		this.zoomToMany(layerid,whereClauseStr,stylesheet);
	}
};

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

this.zoomToExtent = function(newExtent)
{
	this.setWaiting(true);
	this.legendSync = false;
	freeance_request(function(data){$_this.callback(data,'ZoomToExtent',true);},'GIS.Zoom.to.extent',this.sessionID,0,this.mapImage.width(),this.mapImage.height(),newExtent);
};

this.refresh = this.redraw = function()
{
	this.setWaiting(true);
	freeance_request(function(data){$_this.callback(data,'MapRedraw',true);},'GIS.Map.redraw',this.sessionID,0,this.mapImage.width(),this.mapImage.height());
};

this.zoomToPrevious = function()
{
	this.setWaiting(true);
	this.legendSync = false;
	freeance_request(function(data){$_this.callback(data,'ZoomPrevious',true);},'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;
	freeance_request(function(data){$_this.callback(data,'ZoomWindow',true);},'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;
	freeance_request(function(data){$_this.callback(data,'ZoomBar',true);},'GIS.Zoom.by.bar',this.sessionID,0,this.mapImage.width(),this.mapImage.height(),ratio,divnum,numdivs);
};

this.setThemes = function(newThemeList)
{
	for (var 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)
		freeance_request(function(data){$_this.callback(data,'getBookmarkList',true);},'GIS.Geobookmark.get.list',this.sessionID);
};

this.addBookmark = function (name)
{
	if (name != '')
		freeance_request(function(data){$_this.callback(data,'addBookmark',true);},'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;
	freeance_request(function(data){$_this.callback(data,'gotoBookmark',true);},'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);
	freeance_request(function(data){$_this.callback(data,'removeBookmark',true);},'GIS.Geobookmark.remove.state',this.sessionID,name);
};

this.loadThemes = function()
{
	this.setWaiting(true);
	freeance_request(function(data){$_this.callback(data,'getThemes',true);},'GIS.Themes.getList',this.sessionID,0);
};

this.setThemeState = function(themeName, visible)
{
	var themeArray = [[themeName,visible]];
	this.config["themes"][themeName]["visibility"] = visible;
	this.legendSync = false;
	freeance_request(function(data){$_this.callback(data, 'setThemes',true);}, 'GIS.Themes.setList', this.sessionID, 0, themeArray);
};

this.clearSelection = function(themeIndex, selectionHandle)
{
	var requestDetails = {
		request: 'clearSelection',
		themeIndex: themeIndex,
		handle: selectionHandle
	};
	this.setWaiting(true);
	freeance_request(function(data){$_this.selectionControl.clearSelection_callback(data,themeIndex,selectionHandle);},'GIS.Selection.clear.EntityFromTheme',this.sessionID,0,themeIndex, selectionHandle, this.mapImage.width(),this.mapImage.height());
};

this.clearDuplicateSelection = function(themeIndex, selectionHandle)
{
	this.setWaiting(true);
	freeance_request(function(data){$_this.selectionControl.clearSelection_callback(data,themeIndex,handle);},'GIS.Selection.clear.EntityFromTheme',this.sessionID,0,themeIndex, selectionHandle, this.mapImage.width(),this.mapImage.height());
};

this.clearThemeSelections = function(themeIndex)
{
	var requestDetails = {
		request: 'clearTheme',
		themeIndex: themeIndex
	};
	this.setWaiting(true);
	freeance_request(function(data){$_this.selectionControl.callback(data,requestDetails);},'GIS.Selection.clear.AllFromTheme',this.sessionID,0,themeIndex);
};

this.clearSyncSelection = function(themeIndex, selectionHandle)
{
	this.setWaiting(true);
	var mapData = freeance_request(null,'GIS.Selection.clear.EntityFromTheme',this.sessionID,0,this.themes[themeIndex][0][0], selectionHandle, this.mapImage.width(),this.mapImage.height());
	this.setWaiting(false);
};

this.callback = function(serverResponse, pendingOperation)
{
	var clearMeasurePoints = false;
	var data = serverResponse.data;
	if (serverResponse.XMLRPC_FAULT){
		switch(parseInt(serverResponse.XMLRPC_FAULT_CODE))
		{
			case 1018: // No Buffer elements found
				break;
			default:
        var errMsg = 'An error occurred in a Map request.\n\nOperation:  '+pendingOperation+'\nError Code: '+serverResponse.XMLRPC_FAULT_CODE+'\nError Message:\n'+serverResponse.XMLRPC_FAULT_MESSAGE;
				console.error(errMsg);
				alert(errMsg);  // need to show for those w/o debugging or console
				break;
		};
		this.setWaiting(false);
	};
	if (data!=null){
		switch (pendingOperation)
		{
			case 'Initialize':
			case 'Initialize_withScheme':
				_MAP_INITIALIZED = true;
				if (this.firstLoad)
				{
					this.firstLoad = false;
					var ext=data[0][1];
					this.initialExtent = [ext[0],ext[1],ext[2],ext[3]];
				};
				this.extent = data[0][1];
				if (this.mapImage != null)
				{
					this.setWaiting(true);
					var node = this.mapImage.imageNode;
					node.mapObject = this;
					node.onload=this.imageLoadCallback;
					this.setMapImage(data[0][0]);
				};
				if (this.vmapImage != null)
				{
					this.setWaiting(true);
					var node = this.vmapImage.imageNode;
					node.mapObject = this;
					node.onload=this.imageLoadCallback;
					node.src = this.correctURL(data[1][0]);
				};
				this.vmapExtent = data[1][1];
				this.sessionID = data[data.length-1];
				document.setSessionID(this.sessionID);
				var ext=data[0][1];
				this.extent = [ext[0],ext[1],ext[2],ext[3]]; //btlr
				var events = this.eventHandlers['extentChange'];
				for (var i=0;i<events.length;i++){if(events[i]){events[i]();}};
				this.loadThemes();
				this.loadLegend();
				this.getBookmarkList();
				if (document.savedQueryControl)
					document.savedQueryControl.initialize();
				if (this.zoomBar)
					this.zoomBar.initialize();
				var events = this.eventHandlers['initialize'];
				for (var i=0;i<events.length;i++){if(events[i]){events[i]();}};
				//runCMDs();
				break;
			case 'getThemes':
				for (i = 0; i < data.length; i++){
					try{
						this.config["themes"][data[i][0]]["visibility"] = data[i][1];
					}
					catch(e)
					{
						console.warn('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':
				var events = this.eventHandlers['layerChange'];
				for (var i=0;i<events.length;i++){if(events[i]){events[i]();}};
				break;
			case 'setMapScheme':
				this.loadThemes();
				this.redraw();
				break;
			case 'Legend':
				if (this.legendImage != null)
					this.legendImage.src = this.correctURL(data);
				this.legendSync = true;
				break;
			case 'LoadLayers':
				break;
			case 'getBookmarkList':
				if (this.bookmarkControl!=null)
					this.bookmarkControl.callback(data,'getBookmarkList');
				break;
			case 'addBookmark':
				if (this.bookmarkControl!=null)
					this.bookmarkControl.callback(data,'addBookmark');
				this.getBookmarkList();
				break;
			case 'removeBookmark':
				if (this.bookmarkControl!=null)
					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]);
				};
				var ext=data[0][2];
				this.extent = Array(ext[0],ext[1],ext[2],ext[3]); //btlr
				var events = this.eventHandlers['extentChange'];
				for (var i=0;i<events.length;i++){if(events[i]){events[i]();}};

				this.loadThemes();
				if (this.legendVisible)
					this.loadLegend();
				clearMeasurePoints = true;
				break;
			case 'Select':
				break;
			case 'dEmail':
				break;
			case 'BufferXY':
				var ext = data[0][0][2];
				this.extent = Array(ext[0],ext[1],ext[2],ext[3]); //btlr
				var events = this.eventHandlers['extentChange'];
				for (var i=0;i<events.length;i++){if(events[i]){events[i]();}};
				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':
			case 'zoomToSelection':
				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;
				var ext = data[0][0][2];
				this.extent = Array(ext[0],ext[1],ext[2],ext[3]); //btlr
				var events = this.eventHandlers['extentChange'];
				for (var i=0;i<events.length;i++){if(events[i]){events[i]();}};

				clearMeasurePoints = true;
				break;
			case 'zoomToMany':
				data = data.mapImages;
				var ext = data[0][2];
				this.extent = Array(ext[0],ext[1],ext[2],ext[3]); //btlr

				var events = this.eventHandlers['extentChange'];
				for (var i=0;i<events.length;i++){if(events[i]){events[i]();}};

				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.legendVisible && !this.legendSync)
				{
					this.loadLegend();
				};
				clearMeasurePoints = true;
				break;
			case 'getExportedMap':
				this.downloadExportedMap(data);
				break;
			case 'printMap':
				document.printMap(result.data);
				break;
			default:
				var ext = data[0][2];
				this.extent = Array(ext[0],ext[1],ext[2],ext[3]); //btlr

				var events = this.eventHandlers['extentChange'];
				for (var i=0;i<events.length;i++){if(events[i]){events[i]();}};

				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.legendVisible && !this.legendSync)
				{
					this.loadLegend();
				};
				clearMeasurePoints = true;
				break;
		};
		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.setMapImage = function(imgURL)
{
	//set image to correct path and load tiles (if used)
	this.mapImage.imageNode.src = this.correctURL(imgURL);

	for (i=0;i<this.mapImage.drawplanes.length;i++){
		if(this.mapImage.drawplanes[i]){
			if(this.mapImage.drawplanes[i]["freeance_drag"])
				xMoveTo(this.mapImage.drawplanes[i],0,0);
		}
	}

	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
		console.log('map tile request '+dragTileCounter+'['+dragTileCounter+'] cancelled');
};
this.width = function(){return this.mapImage.width();};
this.height = function(){return this.mapImage.height();};
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
		console.log('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
		console.log('map tile request '+dragTileCounter+'['+tileIndex+'] cancelled');

};

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

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

this.correctURL = function (newURL)
{
	var returnValue = newURL;
	if (typeof(returnValue) != 'string'){
		console.warn('Invalid url type - '+typeof(returnValue)+' :: '+returnValue);
	}
	if (returnValue.substr(0,1) == '/')  //trying to deal with relative paths
	{
		returnValue = 'http://'+this.config["imsHostname"]+newURL;
	}
	else
	{
		var url = /(\w+):\/\/([^\/]+)\/(\S*)/;
		var result = newURL.match(url);
		if (result == null)
			returnValue = newURL;  // setup doesn't have an ip or fully qualified name separated w/ .'s
		else
			returnValue = result[1]+'://'+this.config["imsHostname"]+'/'+result[3];
	};
	return returnValue;
};

this.exportMap = function()
{
	this.setWaiting(true);
	freeance_request(function(data){$_this.callback(data,'getExportedMap',true);},'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];
	var placeholderVariables = new Array();
	if (this.config.printConfig.defaultTemplate == -1)
	{
		alert('Freeance Internal Error:  Unable to Print.\nReason:  No print configurations have been defined.');
		console.error('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);
	}
};

};}
/* FILE:FreeanceWeb/Client/PublicAccess1/lib/MapLib/MapImage.js */ if(!window.freeance_loaded_js['2d5b1dfdd96998526320b5338b8c0e0d']){window.freeance_loaded_js['2d5b1dfdd96998526320b5338b8c0e0d']=1;
//MapImage.js
//displays and handles navigation for a map object

MapImage = function(newID, parentElement, newXPosition, newYPosition, newZIndex, newWidth, newHeight, newVisibility, newMapObject, newMapType)
{
  var $_this = this;
  this.drawplanes = [];
  this.id = newID;
  this.map = newMapObject;
  this.mapType = newMapType;  //valid types are 'MASTER','SLAVE'
  this.dragEnabled = false;
  this.currentCursor = 'MapImageWait';
  this.loadImage = null;
  this.waiting = false;
  var zoomBoxPending = false;
  this.mouseDownPosition = Array(0,0);  
  this.dragPending = false;
  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()
  };
  var zoomBox = {
    element: document.createElement('DIV'),
    xstart: 0,ystart: 0,xend: 0,yend: 0,xdelta:0,ydelta:0,
    setActive: function(x1,y1){
      this.xstart=x1;this.ystart=y1;
      xResizeTo(this.element,1,1);
      xMoveTo(this.element,x1,y1);
      xShow(this.element);
    },
    update: function (x2,y2){
      this.xend = x2;
      this.yend = y2;
      if ((this.xend > 0) && (this.xend < $_this.width()) && (this.yend > 0) && (this.yend < $_this.height()))
      {
        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();
    },
    setInactive: function(){xHide(this.element);}
  };
  setClass(zoomBox.element,'zoomBox');
  xHide(zoomBox.element);
/*******************************************/
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.addDrawplane=function(){
    //create a new drawplane layer and return the index
    //optional parameter, htmlelement
    var retval=this.drawplanes.length;
    var drawplane=(arguments.length>0)?arguments[0]:document.createElement('DIV');
    //drawplane.style.zIndex=eventHandlerNode.style.zIndex;
    drawplane.style.position='absolute';
    drawplane.style.left=0;
    drawplane.style.top=0;
    drawplane.style.display='block';
    drawplane.width=this.eventHandlerNode.width;
    drawplane.height=this.eventHandlerNode.height;
    //eventHandlerNode.style.zIndex++;
    this.customDrawPlaneNode.appendChild(drawplane);
    this.drawplanes.push(drawplane);
    return retval;
  };
  this.getDrawplane=function(idx){return this.drawplanes[idx];};
  this.removeDrawplane=function(idx){
    var drawplane=this.drawplanes[idx];
    this.customDrawPlaneNode.removeChild(drawplane);
    this.drawplanes[idx]=null;
    return drawplane;
  };

/*******************************************/
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;
  }
  if(arguments.length>1)
    this.eventHandlerNode.style.cursor = arguments[1];
};

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.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 = [X,Y];
  this.dragPending = false;
  if ((X == this.mouseDownPosition[0]) && (Y == this.mouseDownPosition[1]))
  {
    if (this.mapType == 'SLAVE'){
      //newX,newY are the local coordinates on the image that were clicked.
      //can calculate the new position based on this and the map extent... 
      return this.map.centerOnPoint(((X / this.width()) * (this.map.vmapExtent[3]-this.map.vmapExtent[2])) + this.map.vmapExtent[2],((1.0 - (Y / this.height())) * (this.map.vmapExtent[1]-this.map.vmapExtent[0])) + this.map.vmapExtent[0]);
    }
    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.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 = [X,Y];
  if (this.mapType != 'SLAVE')
  {
    var MapWidth = this.width();
    var MapHeight = this.height();
    this.map.mouseMove(X,Y,MapWidth,MapHeight,X / MapWidth,1.0 -(Y / MapHeight),this.mouseMode);
  }
  for (var i=0;i<this.eventCallbacks['mouseMove'].length;i++)
    if (this.eventCallbacks['mouseMove'][i])
      this.eventCallbacks['mouseMove'][i](e);
};


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);
  return this.map.click(X,Y,MapWidth,MapHeight,X / MapWidth,1.0 -(Y / MapHeight),'Center');
};

/*******************************************/
this.mouseOverCallback = function(e)
{
  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 = [-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();
     for (i=0;i<this.drawplanes.length;i++){
       if(this.drawplanes[i]){
         if(this.drawplanes[i]["freeance_drag"])
           xMoveTo(this.drawplanes[i],0,0);
       }
     }
   };
   this.dragEnabled = false;
   var pagex=xPageX(this.imageNode),pagey=xPageY(this.imageNode);
   if (!((e.pageX > pagex) &&
        (e.pageX < (pagex+xWidth(this.imageNode))) &&
        (e.pageY > pagey &&
        (e.pageY < (pagey+xHeight(this.imageNode))))
       ))
      zoomBox.setInactive();
  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 = [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 = [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':
      zoomBoxPending = true;
      zoomBox.xdelta = zoomBox.ydelta = 0;
      break;
    case 'DragMap':
      this.dragPending = true;
      this.element.appendChild(this.dragPlaneNode);
      this.positionDragTiles();
      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 (zoomBoxPending)
  {
    zoomBox.setActive(this.mouseDownPosition[0], this.mouseDownPosition[1]);
    zoomBoxPending = false;
  }
  if (((this.mouseMode == 'ZoomWindow') || (this.mouseMode == 'SelectWindow')) && (this.dragEnabled))
  {
    zoomBox.xdelta += dx;zoomBox.ydelta += dy;
    zoomBox.update(this.mouseDownPosition[0]+zoomBox.xdelta, this.mouseDownPosition[1]+zoomBox.ydelta);
  }
  if (this.dragPending)
  {
    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 (i=0;i<this.drawplanes.length;i++){
      if(this.drawplanes[i]){
        if(this.drawplanes[i]["freeance_drag"]){
          xMoveTo(this.drawplanes[i],this.dragDelta[0],this.dragDelta[1]);
        }
      }
    }
    
    
    
  }
  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(zoomBox.xdelta)>0) &&(Math.abs(zoomBox.ydelta)>0))
  {
    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]+zoomBox.xdelta;
  var y2 = this.mouseDownPosition[1]+zoomBox.ydelta;
  if(x1 < x2)
  {
    var left=x1,right=x2;
  }
  else
  {
    var left=x2,right=x1;
  } 
  if(y1 < y2)  // use reverse direction since web is flipped from gis
  {
    var top=y1,bottom=y2;
  }
  else
  {
    var top=y2,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':
          if(this.map.selectionControl)
            this.map.selectionControl.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 extent = this.map.vmapExtent;
      this.map.zoomToExtent([
          ((1.0 - (bottom / MapHeight)) * (extent[1]-extent[0])) + extent[0],
          ((1.0-(top / MapHeight)) * (extent[1]-extent[0])) + extent[0],
          ((left / MapWidth) * (extent[3]-extent[2])) + extent[2],
          ((right / MapWidth) * (extent[3]-extent[2])) + extent[2]
        ]);    
      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 (parentElement == null)
    parentElement = document.getElementsByTagName("body").item(0); 
	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++){
    var tile=document.createElement("IMG");
    tile.setAttribute((xIE4Up?("className"):("class")),'MapImage');
    tile.setAttribute('id','MapImage.dragTiles['+i+']');
    tile.src = GuiWidget.THEME_PATH+'/'+GuiWidget.THEME+'/images/blank.gif';
    this.dragPlaneNode.appendChild(tile);
    this.dragTiles.push(tile);
  }
  this.clearDragTiles();  
  this.drawPlaneNode = document.createElement("DIV");
  this.drawPlaneNode.setAttribute('id',this.id+'.drawPlaneNode');
  this.drawPlaneNode.appendChild(zoomBox.element);
  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.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);
  
  //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.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.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.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.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;
  
  if (this.measureCanvas)
    this.measureCanvas.style.position = 'absolute';
  this.eventHandlerNode.setAttribute((xIE4Up?("className"):("class")),'MapImage');
  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.drawPlaneNode, 0,0);
  xMoveTo(this.rasterDrawPlaneNode, 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);
  
  //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);
  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/PublicAccess1/lib/MapLib/LayerControl2.js */ if(!window.freeance_loaded_js['34d2dc991427b8964ccf4f8b78fdfab9']){window.freeance_loaded_js['34d2dc991427b8964ccf4f8b78fdfab9']=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 
  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 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 '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.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)
  {
    //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)
            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 '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/PublicAccess1/lib/SearchLib/QueryControl.js */ if(!window.freeance_loaded_js['113187e1bfcdf119fd4b7f9493edb3d9']){window.freeance_loaded_js['113187e1bfcdf119fd4b7f9493edb3d9']=1;
document.queryControl = new (function ()
{
	var $_this = this;
	this.id = 'queryControl';
	this.config = null;
	this.resultTarget = null;
	this.currentQueryForm = null;
	this.currentQueryPage = 0;
	this.currentQueryId = null;
	this.currentQueryValuePairs = null;
	this.onDrawIndexForm = new Array();
	this.onDrawQueryForm = new Array();

	this.eventHandlers = {
		indexDraw:[],
		formDraw:[],
		formShow:[],
		querySubmit: [],
		queryReturn: [],
		templateDraw: [],
		zoomtoSubmit: [],
		zoomtoReturn: [],
		exportSubmit: [],
		exportReturn: []
	};

this.setConfig = function(newConfig)
{
	//sets the configration to the specified data structre.
	this.config  = newConfig;
	this.shownQueries = 0;  //displayed queries
	this.totalQueries = 0;  //all queries
	for (var currentQuery in this.config)
	{
		if(currentQuery=='toJSONString')continue;
		this.totalQueries++;
		if(this.config[currentQuery].display)
			this.shownQueries++;
	};
	$('queryBookmarkContainer').style.display = 'none';
};

this.setIndexPanel = function(newIndexPanel)
{
	//set the index panel reference and do initial population.
	this.indexPanel = newIndexPanel;
};

this.drawIndexPanel = function()
{
	if (this.indexPanel == null) return false;

	this.currentQueryForm = null;
	if (this.shownQueries > 1)
	{
		var htmlString = [];
		for (var currentQuery in this.config)
		{
			if(currentQuery=='toJSONString')continue;
			var conf=this.config[currentQuery];
			if(conf.display)
				htmlString.push('<div class="queryIndexQueryTitle"><span FREEANCE_CONTROL_TYPE="queryformlink" QUERYID="',currentQuery,'" class="pseudolink">',
					conf['title'],
				 '</span></div><div class="queryIndexDescriptionForm">',conf['description'],'</div>');
		};
		this.indexPanel.innerHTML = htmlString.join('');
		var spanElements = this.indexPanel.getElementsByTagName('SPAN');
		var clickFcn = function(ele,queryid){xAddEventListener(ele,'click',function(e){$_this.showFormPanel(queryid);$_this.setFocus(queryid);})};
		for (var i=0;i<spanElements.length;i++){
			if (spanElements[i].getAttribute('FREEANCE_CONTROL_TYPE')=='queryformlink')
				clickFcn(spanElements[i],spanElements[i].getAttribute('QUERYID'));
		};
		$('queryBookmarkContainer').style.display = 'none';
		var events = this.eventHandlers['indexDraw'];
		for (var i=0;i<events.length;i++){
			if(events[i]){events[i]();}
		}
	}
	else
	{
		if (this.totalQueries!=0){  //accomodate case where no pdqs are present but geocode is
			for (var currentQuery in this.config)
			{
				if(currentQuery=='toJSONString')continue;
				if (this.config[currentQuery].display)
				{
					this.showFormPanel(currentQuery);
					break;
				}
			}
		}
	}
};

this.setFormPanel = function (newFormPanel)
{
	this.formPanel = newFormPanel;
};

this.showFormPanel = function(queryId)
{
	//hide index form for all searches (not just those belonging to query control)
	$('searchIndexContainer').style.display = 'none';
	this.currentQueryForm = queryId;
	//make sure all query forms are hidden initially
	var conf=this.config[queryId];
	if (conf){
		if (!conf.formElement)  //check to see if there is already an element.  if not, build the new one
		{
			this.createForm(queryId);
		};
		if (document.savedQueryControl)  //show saved query panel if needed
		{
			document.savedQueryControl.drawSavedQueryList(queryId);
			$('queryBookmarkContainer').style.display = 'block';
		};
		conf.formElement.style.display = 'block';
		this.formPanel.style.display = 'block';
		$('searchFormContainer').style.display = 'block'; //form for all searches
		var events = this.eventHandlers['formShow'];
		for (var i=0;i<events.length;i++){if(events[i]){events[i](queryId);}};
	}
	else
		alert('attempting to show an invalid query form for query \''+queryId+'\'');
};

this.setFocus = function(queryId)
{
	//try to set the focus to the first input element in this query
	try{
		var inputEles = this.config[queryId].formElement.getElementsByTagName('INPUT');
		if(inputEles.length>0)
			inputEles[0].focus();
	}
	catch(e){};
};

this.hideAllForms = function()
{
	for (var i in this.config){
		if(i=='toJSONString')continue;
		if (this.config[i].formElement)
			this.config[i].formElement.style.display = 'none';
	}
	if(this.formPanel)
		this.formPanel.style.display = 'none';
};

this.createForm = function(queryId)
{
	var $_queryId = queryId;
	var formElement = document.createElement('DIV');
	this.formPanel.appendChild(formElement);
	var query=this.config[queryId];
	query['formElement']=formElement;
	var htmlString = [];
	if (this.shownQueries > 1)
		htmlString.push('<div id="queryIndexToggle" class="selectionDisplayPanelHeader" style="text-align: center;"><span class="pseudolink" FREEANCE_CONTROL_TYPE="show_index">Show All Searches</span></div>');
	htmlString.push('<div class="rightPanelFormHeader2">'+query['title']+'</div><div class="queryIndexDescriptionForm"><div>'+query['HTMLForm']+'<div></div>');

	if ((query["export_"]) && (query["export_"].csv) && (query["export_"].csv.enabled==true))
		htmlString.push('<div style="text-align: center;"><span class="pseudolink" FREEANCE_CONTROL_TYPE="query_csv_export_link">Export Query to CSV</span></div>');

	if (document.savedQueryControl)
		htmlString.push('<div style="text-align: center;"><span class="pseudolink" FREEANCE_CONTROL_TYPE="save_query_link">Save Query Values</span></div>');
	htmlString.push('<div style="width: auto; text-align: center;"><button FREEANCE_TYPE="submit" class="submitButton">Run Search</button></div>');
	formElement.innerHTML = htmlString.join('');

	var buttonEles = formElement.getElementsByTagName('BUTTON');
	for (var i=0;i<buttonEles.length;i++){
		if(buttonEles[i].getAttribute('FREEANCE_TYPE')=='submit')
		(function(ele){
			xAddEventListener(ele,'click',function(){$_this.submitQueryForm(queryId);});
		})(buttonEles[i]);
	};
	var spanElements = formElement.getElementsByTagName('span');
	for (var elementIndex=0;elementIndex<spanElements.length;elementIndex++)
	{
		switch (spanElements[elementIndex].getAttribute('FREEANCE_CONTROL_TYPE'))
		{
			case 'show_index':
				xAddEventListener(spanElements[elementIndex],'click',function(){showQueryIndexPanel();});
				break;
			case 'query_csv_export_link':  //onclick="document.getGuiControl(\''+this.id+'\').runExportQuery(\''+queryId+'\',\'csv\');"
				xAddEventListener(spanElements[elementIndex],'click',function(){$_this.runExportQuery($_queryId,'csv');});
				break;
			case 'save_query_link':
				xAddEventListener(spanElements[elementIndex],'click',function(){$_this.saveQuery($_queryId);});
				break;
		}
	};
	//add enter button event to form elements
	var $_queryId = queryId;
	var inputElements = formElement.getElementsByTagName('input');
	var keyHandler = function(e){var evt = new xEvent(e);if (evt.keyCode==13){$_this.submitQueryForm($_queryId);}};
	for (var elementIndex=0;elementIndex<inputElements.length;elementIndex++){
		xAddEventListener(inputElements[elementIndex],'keypress',keyHandler);
	};

	if (query['suggestConfig'])
	{
		for (var i=0; i<query['suggestConfig'].length;i++){
			document.SuggestControl.addSuggest(query['suggestConfig'][i]);
		}
	};

	//set up any dynamic selection fields
	for(var i=0;i<this.config[queryId]["fieldList"].length;i++){
		if(this.config[queryId]["fieldList"][i].fieldType=='dynamicselectField'){
			this.buildDynamicSelect(queryId,i);
		}
	};
	var events = this.eventHandlers['formDraw'];
	for (var i=0;i<events.length;i++){if(events[i]){events[i](queryid);}};
};

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,['distinct '+labelfield,valuefield].join(','),table,where,limit,0);
	}
};


this.runExportQuery = function(queryId,exportType)
{
	this.exportQuery(exportType,queryId, this.getFormValues(queryId));
	var events = this.eventHandlers['exportSubmit'];
	for (var i=0;i<events.length;i++){if(events[i]){events[i](queryid,exportType);}};
};

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(fieldList[i]['fieldType']=='selectField')
		{
			queryValuePairs.push([fieldName,inputElement.value]);
		}else
		{
			if(inputElement)
				queryValuePairs.push([fieldName,inputElement.value.strtrim()?inputElement.value.strtrim():fieldList[i]['defaultValue']]);
			else
				queryValuePairs.push([fieldName,fieldList[i]['defaultValue']]);
		}
	};
	return queryValuePairs;
};

this.submitQueryForm = function (newQueryId)
{
	//called when the submit button is clicked.
	//loop through the fields in the form and build the name/value pairs.
	//The start page will be 0
	//firstRun will be true...

	//build value pairs array based on field names.  If a field can't be found, use its 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++;
	};
	freeance_request(function(data){$_this.callback(data,$_this.currentQuery.request.requestMethod)},this.currentQuery.request.requestMethod,this.currentQuery.request.pdqIdentifier,this.currentQuery.templates.pageRows,this.currentQueryPage,this.currentQueryValuePairs);
	if (this.loadImage != null)
		xShow(this.loadImage);
	/*if (this.onQuerySubmit)
		this.onQuerySubmit();*/
	var events = this.eventHandlers['querySubmit'];
	for (var i=0;i<events.length;i++){
		if(events[i]){events[i]();}
	}
};

this.exportQuery = function(exportType,queryId, newValuePairs)
{
	var queryConfig = this.config[queryId];
	var request = 'SQL.export.execute';
	var exportFormat = [exportType,true];  // UseZip
	var queryType = 'definedQuery';
	switch(exportType)
	{
		case 'csv':
			exportFormat[2] = queryConfig["export_"].csv.delim; // delim
			exportFormat[3] = queryConfig["export_"].csv.includeFieldNames; // includeFieldNames
			break;
	};
	freeance_request(function(data){$_this.callback(data,request);},request,exportFormat,queryType,queryConfig.request.pdqIdentifier,newValuePairs);
	document.mapObject.setWaiting(true);
};

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.zoomToResults = function(themeId,themeTargetField,queryFieldName,fieldType,stylesheet)  // JPW
{
	var realData = this.currentResultData[3];
	if ((realData.length == 0) || (document.mapObject.markupControl == null)) // haha very funny
	{
		if (this.loadImage != null)
			xShow(this.loadImage);
		if (realData.length == 0)
			alert('No data to zoom to.');
		else
			alert('This requires the markup extension to be enabled in this application.  Please notify your system administrator.');
		if (this.loadImage != null)
			xHide(this.loadImage); // see, it's FAST!
		return;
	}

  var fieldData = [];
	for(var lcv=0;lcv < realData.length;lcv++)
		fieldData.push(realData[lcv][queryFieldName]);
	document.mapObject.setWaiting(true);
	document.mapObject.zoomToMany_(themeId,themeTargetField,fieldType,fieldData,stylesheet);
	var events = this.eventHandlers['zoomtoSubmit'];
	for (var i=0;i<events.length;i++)
		if (events[i])
      events[i]();
};

this.addZoomToMarkupToIndex = function(themeID,data)  // JPW
{
	var markupObj = {
	handle: data.handle,
	themeName: themeID,
	themeID: themeID,
	labelName: stripQuotes(escapeHTML('Results: '+document.mapObject.config.themes[themeID].themeName)),
	markupID: stripQuotes(escapeHTML('Results: '+document.mapObject.config.themes[themeID].themeName)),
	description: stripQuotes(escapeHTML('Results: '+document.mapObject.config.themes[themeID].themeName)),
	extent: data.zoomExtent,
	viewExtent: data.zoomExtent,
	type: 'zoomToResults', // i guess...
	style: '0',
	mode: 'zoomToResults'
	};
	document.mapObject.markupControl.addToExistingMarkup(markupObj,markupObj.handle);
	document.mapObject.markupControl.drawMarkupExistingPanel();
};

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;
			}
      else if (targetElem.getAttribute('FREEANCE_TYPE')=='QUERY_ZOOMTO')
      {
        var zoomto=$_this.currentQuery.zoomto;
        console.log('QUERY_ZOOMTO: '+zoomto["layerid"]+","+zoomto["layerfield"]+","+zoomto["queryfield"]+","+zoomto["layerfieldtype"]+","+zoomto["stylesheet"]);
        $_this.zoomToResults(zoomto["layerid"],zoomto["layerfield"],zoomto["queryfield"],zoomto["layerfieldtype"],zoomto["stylesheet"]);
        return true;
      }
	case 'a':
	  return true;
      break;
  }
  return false;
};

this.callback = function(clientReply, requestType)
{
	if (this.resultTarget.scrollHandler!=null)
		this.resultTarget.scrollHandler.cleanup();
	var noResults = false;
	if (this.loadImage != null)
		xHide(this.loadImage);
	if (clientReply.XMLRPC_FAULT)
	{
		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.
  		  if (requestType!='SQL.export.execute')
        {
  				templateData = new Array();
				  templateData[0] = new Array();
				  var source = document.getTemplate(this.currentQuery.templates.invalidTemplate);
				  this.resultTarget.innerHTML = source.run(templateData);
				  this.resultTarget.scrollTop = 0;
			  }
        break;
      default:
        alert('An error occurred in the query operation:\n\nError Code:  '+clientReply.XMLRPC_FAULT_CODE+'\nError Message:  '+clientReply.XMLRPC_FAULT_MESSAGE);
        break;
    }
		var events = this.eventHandlers['queryReturn'];
		for (var i=0;i<events.length;i++)
			if (events[i]) events[i]();
	}
	else
	{
		if (typeof requestType == "object")
		{
			var requestInfo = requestType;
			requestType = requestType.request;
		}
		switch (requestType)
		{
			case 'GIS.Zoom.to.queryResults':
				var data = clientReply.data;
				if (document.mapObject.measureControl != null)
					 document.mapObject.measureControl.distanceReset();
				document.mapObject.extent = data.zoomExtent;
				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();
				document.mapObject.setWaiting(false);
				this.addZoomToMarkupToIndex(requestInfo.themeID,data);
				var events = this.eventHandlers['zoomtoReturn'];
				for (var i=0;i<events.length;i++)
					if (events[i]) events[i]();
				break;
			case 'SQL.storedDefinedQuery.save':
				noResults = true;
				if (this.savedQueryIndexPanel)
					this.savedQueryIndexPanel.getList();
				break;
			case 'SQL.export.execute':
				noResults = true;
				var url = clientReply.data;
				downloadFile(url);
				var events = this.eventHandlers['exportReturn'];
				for (var i=0;i<events.length;i++)
					if (events[i]) events[i](url);
				document.mapObject.setWaiting(false);
				break;
			default:
				var sqlData = clientReply.data;
				if ((sqlData != null) && (sqlData != false))
				{
					this.currentResultData = cloneObject(sqlData);// why cloned?
					var source = document.getTemplate(this.currentQuery.templates.validTemplate);
					var resultHTML = source.run(sqlData);
					if(this.currentQuery.zoomto.enabled)
						resultHTML += '<div style="text-align: center;"><span class="pseudolink" FREEANCE_TYPE="QUERY_ZOOMTO">Zoom To Result Set</span></div>';
					this.resultTarget.innerHTML = resultHTML;
					this.resultTarget.onclick = this.resultTarget_onclick;
					//add fixed-position header
					var tables = this.resultTarget.getElementsByTagName('TABLE');
					if ((tables.length>0)&&(!xOp7Up))
						var header = new ScrollableTable(tables[0],this.resultTarget,-2);
					this.resultTarget.scrollTop = 0;
					this.resultTarget.query = this;
					var events = this.eventHandlers['templateDraw'];
					for (var i=0;i<events.length;i++)
						if (events[i])
							events[i](this.currentQuery,this.currentResultData,this.resultTarget);

					if(sqlData[3].length == 1 && this.currentQuery.zoomto.enabled && this.currentQuery.zoomto.auto)
					{
						zoomto=this.currentQuery.zoomto;
						$_this.zoomToResults(zoomto["layerid"],zoomto["layerfield"],zoomto["queryfield"],zoomto["layerfieldtype"],zoomto["stylesheet"]);
					}
					else 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;
								}
					}
				}
				var events = this.eventHandlers['queryReturn'];
				for (var i=0;i<events.length;i++)
					if (events[i])
            events[i](this.currentQuery.id,sqlData);
		}
	}
};

this.redrawTemplate = function()
{
	if (this.resultTarget.scrollHandler!=null)
		this.resultTarget.scrollHandler.cleanup();

	if(this.currentResultData != null)
	{
		this.currentQuery = this.config[this.currentQueryId];
		if (this.currentQuery != null)
		{
			var source = document.getTemplate(this.currentQuery.templates.validTemplate);
			try{
				var resultHTML = source.run(this.currentResultData);
				if(this.currentQuery.zoomto.enabled){
					resultHTML += '<div style="text-align: center;"><span class="pseudolink" FREEANCE_TYPE="QUERY_ZOOMTO">Zoom To Result Set</span></div>';
				};
				this.resultTarget.innerHTML = resultHTML;
        this.resultTarget.onclick = this.resultTarget_onclick;
  			//add fixed-position header
				var tables = this.resultTarget.getElementsByTagName('TABLE');
				if ((tables.length>0)&&(!xOp7Up))
				{
					var header = new ScrollableTable(tables[0],this.resultTarget,-2);
				}
			}
			catch(e)
			{
				this.resultTarget.innerHTML = '';
			}
			this.resultTarget.scrollTop = 0;
			this.resultTarget.query = this;
			var events = this.eventHandlers['templateDraw'];
			for (var i=0;i<events.length;i++){
				if(events[i]){events[i](this.currentQuery,this.currentResultData,this.resultTarget);}
			}
		}
		else
			alert('Unable to display result template for query '+this.currentQueryId+'.\nThe query configuration could not be found.');
	}
	else
		alert('Unable to display result template for query '+this.currentQueryId+'.\nNo result data is present.');
};

this.addEventHandler = function(eventType,callback)
{
	if (this.eventHandlers[eventType]!=null)  //empty array can eval to false
		this.eventHandlers[eventType].push(callback);
	return this.eventHandlers[eventType].length-1;
};
this.removeEventHandler = function(eventType,index)
{
	if (this.eventHandlers[eventType]!=null)  //empty array can eval to false
		this.eventHandlers[eventType][index]=null;
};
})();}
/* FILE:FreeanceWeb/Client/PublicAccess1/lib/TemplateUtils.js */ if(!window.freeance_loaded_js['8bb1f48b44d2af123d6d1370e128bf26']){window.freeance_loaded_js['8bb1f48b44d2af123d6d1370e128bf26']=1;
document.templateFunctions = new Array();
document.getTemplateHTML = function(templateName)
{
  var templateObject = document.templateConfig;
  var templateString = templateObject[templateName];
  var _TemplateSearchString = /-!CURRENT_THEME!-/g;
  var _TemplateReplaceWith = document.applicationConfig.stylesheet;
  templateString = templateString.replace(_TemplateSearchString,_TemplateReplaceWith);
  return templateString;
};
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.templateConfig;
  var templateString = templateObject[templateName];
  var _TemplateSearchString = /-!CURRENT_THEME!-/g;
  var _TemplateReplaceWith = document.applicationConfig.stylesheet;
  templateString = templateString.replace(_TemplateSearchString,_TemplateReplaceWith);
  templateString = templateString.replace(/document\.getGuiControl\('map0'\)/g,'document.mapObject');
  templateString = templateString.replace(/document\.getGuiControl\('rightPanelQueryControl'\)/g,'document.queryControl');
  templateString = templateString.replace(/document\.getGuiControl\('queryControl'\)/g,'document.queryControl');
  
  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 = $("scratchpad");
  return element;
};

document.setScratchpadData = function(newData)
{
  $("scratchpad").innerHTML = newData;
};

document.printCurrentData = function()
{
  $('printPopup').style.display = 'block';
};}
/* 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);
  };
  
  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);
  };
  
  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/Common/lib/ScrollableTable.js */ if(!window.freeance_loaded_js['bdb51929ca0da68ed5e5fd72a5a4cfe2']){window.freeance_loaded_js['bdb51929ca0da68ed5e5fd72a5a4cfe2']=1;
ScrollableTable = function(tableElement)  
{
  var $_this = this;
  var scrollFunction = function(){$_this.overlayTable.style.top=$_this.scrollElement.scrollTop;};
  //optional second parameter for scroll element
  //optional third parameter to compensate for column drift
this.sourceTable = tableElement;
this.columnOffset = 0;
if (arguments.length > 1){
  if (arguments[1]!=null)
    this.scrollElement = arguments[1];
  if (arguments.length>2)
    this.columnOffset = arguments[2]
}
else
  this.scrollElement =  tableElement.parentNode;
//bail out if the table is already scrollable.
if (this.scrollElement.scrollHandler!=null) return null;

this.initialize = function()
{
  this.scrollElement.scrollHandler = this;
  this.overlayTable = this.sourceTable.cloneNode(false);  //preserves all base table attributes
  this.overlayTable.setAttribute('id','');  //don't want to confuse any scripts that may reference the table id
  this.overlayTable.setAttribute('SCROLLTABLE_HEADER','TRUE');
  this.overlayTable.style.position = 'absolute';
  this.overlayTable.style.top = 0;
  this.overlayTable.style.height = this.sourceTable.getElementsByTagName('TH')[0].height;
  this.overlayTable.style["z-index"] = parseInt(this.sourceTable.getAttribute('z-index'))+1;
  
  //build the new header row
  var newTbody = document.createElement('TBODY');
  var newTR = this.sourceTable.getElementsByTagName('TR')[0].cloneNode(true);
  newTbody.appendChild(newTR);
  this.overlayTable.appendChild(newTbody);
  //this.overlayTable.setAttribute('id','table2');

  this.scrollElement.appendChild(this.overlayTable);

  var sourceHeaderCells = this.sourceTable.getElementsByTagName('TH');
  var overlayHeaderCells = this.overlayTable.getElementsByTagName('TH');
  
  for (var i=0;i<sourceHeaderCells.length;i++)
  {
    //add a div to the header cell; forces width
    var newElement = document.createElement('DIV');
    newElement.style.width = parseInt(sourceHeaderCells[i].clientWidth)+this.columnOffset;
    newElement.style.height = 1;
    newElement.style.overflow = 'hidden';  //don't let browser expand div height 
    newElement.style.display = 'block';
    newElement.style.background = 'transparent';
    if (overlayHeaderCells[i])
      overlayHeaderCells[i].appendChild(newElement);
  };
  
  //attach scroll event to container element.
  if(this.scrollElement.addEventListener) 
    this.scrollElement.addEventListener('scroll',scrollFunction,true);
  else 
  if(this.scrollElement.attachEvent)
    this.scrollElement.attachEvent('onscroll',scrollFunction);
};

this.cleanup = function()
{
  if (this.scrollElement!=null){
    try{
      this.scrollElement.removeChild(this.overlayTable);
    }
    catch(e)
    {}
    finally
    {
      if(this.scrollElement.removeEventListener) 
        this.scrollElement.removeEventListener('scroll',scrollFunction,true);
      else 
      if(this.scrollElement.detachEvent)
        this.scrollElement.detachEvent('onscroll',scrollFunction);
      this.scrollElement.scrollHandler = null;
    };
    this.overlayTable = null;
    this.scrollElement = null;
  }
};
this.initialize();
}}
/* FILE:FreeanceWeb/Client/PublicAccess1/lib/Main2.js */ if(!window.freeance_loaded_js['9d71c6140da50bf406cf682e89587921']){window.freeance_loaded_js['9d71c6140da50bf406cf682e89587921']=1;
document.currentBottomPanel = 'mapToolOptionPanel';
document.setSessionID = function(newID){ document.sessionID = newID; };
document.getSessionID = function() { return(document.sessionID); };
document.dynamicExtensions = new Object();

window.onload = function()
{
	if(DEBUG_TEXT) console.log(DEBUG_TEXT);
	RightPanel_State_Manager.addPanel('userIntro','userIntroContainer');
	RightPanel_State_Manager.addPanel('control_panel_index','rightControlPanelContainer');
	RightPanel_State_Manager.addPanel('layer_control','layerPanelOuterContainer',function(state,panelEle){if(state){$('layerPanelOuterContainer').style.display = 'block';$('layerOptionsContainer').style.display = 'block';$('layerGroupDisplayContainer').style.display = 'block';}else{$('layerPanelOuterContainer').style.display = 'none';$('layerOptionsContainer').style.display = 'none';};});
	RightPanel_State_Manager.addPanel('legend','layerPanelOuterContainer',function(state,panelEle){if(state){document.mapObject.legendVisible = true;document.mapObject.loadLegend();$('layerPanelOuterContainer').style.display = 'block';$('legendContainer').style.display = 'block';$('layerOptionsContainer').style.display = 'none';}else{document.mapObject.legendVisible = false;$('layerPanelOuterContainer').style.display = 'none';$('legendContainer').style.display = 'none';};});
	RightPanel_State_Manager.addLabel('layercontrol_label','layer_control','Layer Control');
	RightPanel_State_Manager.addPanel('query','queryContainer',function(state,panelEle){
	var setfocus = false;
	if(state){
		if((RightPanel_State_Manager.getPreviousActivePanel()=='query')&&(document.queryControl.shownQueries > 1))
		{
			showQueryIndexPanel();$('queryBookmarkContainer').style.display = 'none';
		}
		else
		{
			if (document.queryControl.currentQueryForm==null)
			{
				$('queryBookmarkContainer').style.display = 'none';
				showQueryIndexPanel();
			}
			else
			{
				setfocus = true;
				$('queryBookmarkContainer').style.display = 'block';
			}
		};
		panelEle.style.display='block';
		if(setfocus){document.queryControl.setFocus(document.queryControl.currentQueryForm);};
	}
	else
	{
		panelEle.style.display='none';
	}
	});

	xAddEventListener($('homeLink'),'click',function(){RightPanel_State_Manager.showPanel('userIntro');});
	xAddEventListener($('mappingControlPanelButton'),'click',function(){RightPanel_State_Manager.showPanel('control_panel_index');});
	xAddEventListener(window, 'resize', winOnResize, false);
	formatBaseLayout();

	//load config file
	document.configDoc = XmlHttp.loadSync(CONFIG_XML);
	if (!Freeance_Error.xmldoc_is_valid(document.configDoc)){document.write('<span class="criticalError">Fatal Error:  Unable to load config file.</span>');}
	var parser = new FreeanceXMLParser();  //extended version of the base xml parser that reads freeance configurations
	document.freeance_config_parser = parser; //add to document namespace
	parser.setDocumentByDoc(document.configDoc);

	//set basic app parameters and load stylesheet data
	var applicationConfig = parser.getApplicationConfig();
	document.applicationConfig = applicationConfig;
	document.title = applicationConfig.title + ':  Powered By Freeance '+FREEANCE_VERSION+' - TDC Group Inc.';
	if(!applicationConfig.stylesheet)applicationConfig.stylesheet='default';
	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'));
	}
	//request additional utility functions
	var templateConfig = document.templateConfig = document.freeance_config_parser.getTemplateConfig();
	$('pageHeaderContent').innerHTML = document.getTemplateHTML("PageHeader");
	$('userIntroContainer').innerHTML = document.getTemplateHTML("UserIntro");
	$('searchResultPanel').innerHTML = document.getTemplateHTML("EmptySearch");

	if (applicationConfig.customOptions != null)
	{
		_PageHeaderHeight = applicationConfig.customOptions.pageHeaderHeight;
		_RightPanelWidth = applicationConfig.customOptions.rightPanelWidth;
		_MapToolOptionHeight = applicationConfig.customOptions.mapToolOptionHeight;
		_VicinityMapWidthOpen = applicationConfig.customOptions.vicinityMapWidthOpen;
		_DefaultActivePanel = applicationConfig.customOptions.defaultActivePanel;
		_MapAutoRedraw = applicationConfig.customOptions.mapAutoRedraw;
		_ExpandSearchPanel = applicationConfig.customOptions.expandSearch;
		_CustomLegendURL = applicationConfig.customOptions.customLegendURL;
	}

	//initialize mapping engine
	var mapConfig = parser.getMapConfig();
	var extensionConfig = document.extensionConfig = parser.getExtensionConfig();
	document.mapObject = new Map('map0');
	document.mapObject.setConfig(mapConfig);
	document.mapObject.setLegendImage($('map0legend'),false);
	document.layerControl = new LayerControl($('layerGroupDisplayContainer'));

	create_map_interface();
	//console.log('initializing');
	if (document.mapObject.config.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.

	//initialize search engine
	document.queryControl.setConfig(parser.getQueryConfig());
	if (document.queryControl.totalQueries > 0){
		document.queryControl.setResultTarget($("searchResultPanel"));
		document.queryControl.addEventHandler('querySubmit',function (){document.mapObject.setWaiting(true);});
		document.queryControl.addEventHandler('queryReturn',function (){setBottomPanel('searchResultPanel');document.mapObject.setWaiting(false);});
	}

	//add extensions built in to the client by default; the 'default_' attribute will let these be skipped when reprocessing for add-on extensions like freeance direct
	//this is mainly to make sure these are loaded in order, avoiding dependency conflicts
	if (extensionConfig.measure){
		extensionConfig.measure.default_=true;
		if (extensionConfig.measure.enabled){
			Freeance_Extension_Manager.add_extension('measure','./lib/MapLib/MeasureControl.js');
		}
	};
	if (extensionConfig.zoomBar){
		extensionConfig.zoomBar.default_=true;
		if (extensionConfig.zoomBar.enabled){
			Freeance_Extension_Manager.add_extension('zoomBar','./lib/MapLib/ZoomBar.js');
		}
	};
	if (extensionConfig.scalebar){
		extensionConfig.scalebar.default_=true;
		if (extensionConfig.scalebar.enabled){
			//Freeance_Extension_Manager.add_extension('scalebar','./lib/MapLib/Scalebar.js');
		}
	};
	if (extensionConfig.compass){
		extensionConfig.compass.default_=true;
		if (extensionConfig.compass.enabled){
			document.mapObject.mapImage.showCompass();
		}
	};
	if (extensionConfig.maptips){
		extensionConfig.maptips.default_=true;
		if (extensionConfig.maptips.enabled)
			Freeance_Extension_Manager.add_extension('maptips','./lib/MapLib/MapTip.js');
	};
	if (extensionConfig.coordConv){
		extensionConfig.coordConv.default_=true;
		if(extensionConfig.coordConv.enabled){
			Freeance_Extension_Manager.add_extension('coordConv','./lib/MapLib/CoordinateControl.js');
		}
	};
	if (extensionConfig.markup){
		extensionConfig.markup.default_=true;
		if(extensionConfig.markup.enabled){
			Freeance_Extension_Manager.add_extension('markup','./lib/MapLib/MarkupControl.js');
		}
	};
	if (extensionConfig.userlogin){
		extensionConfig.userlogin.default_=true;
		if(extensionConfig.userlogin.enabled){
			Freeance_Extension_Manager.add_extension('userlogin','./lib/MapLib/UserLoginControl.js');
		}
	};
	if (extensionConfig.bookmarks){
		extensionConfig.bookmarks.default_=true;
		if(extensionConfig.bookmarks.enabled){
			Freeance_Extension_Manager.add_extension('bookmarks','./lib/MapLib/BookmarkControl.js');
		}
	};
	if (extensionConfig.saveMap){
		extensionConfig.saveMap.default_=true;
		if (extensionConfig.saveMap.enabled){
			var saveMapButton = (document.mapToolbar.showButton('saveMapButton'))?document.mapToolbar.getButton('saveMapButton'):document.mapToolbar.addButton('saveMapButton',ToolBar.BUTTON_RADIO,ToolBar.ADD_BUTTON_LAST,null,25,25,true,'saveMap.png','Identify Features',document.mapToolbar.mapCursorRadioButtonGroup,'');saveMapButton.clickEvent = function (e) {window.open(document.mapObject.mapImage.imageNode.src);};
		}
	};

	//fix extension paths from pre-4.2 clients
	if(extensionConfig.savedQueries){
		extensionConfig.savedQueries.dynamicfile='./lib/SearchLib/SavedQueryControl.js'
	};

	//selections
/*	if (document.mapObject.selectionsExist)
	{
		Freeance_Extension_Manager.add_extension('selection_control2','./lib/MapLib/SelectionControl2.js');
		if(document.mapObject.buffersExist){
			Freeance_Extension_Manager.add_extension('buffer','./lib/MapLib/BufferControl.js');
		}
	}*/
	if (document.mapObject.selectionsExist)
	{
		if(document.mapObject.buffersExist){
			Freeance_BundleExtension_Manager.add_extension('selection_control2','SelectionBuffer');
			Freeance_BundleExtension_Manager.add_extension('buffer','SelectionBuffer');
		}
		else
			Freeance_BundleExtension_Manager.add_extension('selection_control2','Selection');
	}

	//add non-default extensions
	for (var i in extensionConfig)
	{
		if(i=='toJSONString')continue;
		if((extensionConfig[i].enabled)&&(!extensionConfig[i].default_)&&(extensionConfig[i].dynamicfile))
			Freeance_Extension_Manager.add_extension(i,extensionConfig[i].dynamicfile);
	}
	//console.log('main2: loading extension libraries');
	//load the extensions; this should happen in parallel with the map initialization
	Freeance_BundleExtension_Manager.load_all(function() { Freeance_Extension_Manager.load_all(function(){ Freeance_Extension_Manager.initialize_all(1000,init_extensions_callback);}); });
	return;
};

//alternate legends are not currently proper extensions; have to load no matter what!
Freeance_BundleExtension_Manager.add_extension('altlegendcontrol','default');
Freeance_BundleExtension_Manager.add_extension('scalebar','default');

function init_extensions_callback(){
	//console.log('main2: extension initialization complete');
	/** QUERY PANEL SETUP **/
	/** Needs to be after extension load; some exts may add new queries **/
	if (document.queryControl.shownQueries > 0)
	{
		document.queryControl.setIndexPanel($("queryIndexContainer"));
		document.queryControl.setFormPanel($("queryFormContainer"));
		document.queryControl.drawIndexPanel();
		$('queryControlPanelButton').style.display = 'block';
	}
	else
		$('queryControlPanelButton').style.display = 'none';

	formatBaseLayout();
	if (document.applicationConfig.userScripts){
		//console.log('loading user-defined scripts');
		for (var i=0;i<document.applicationConfig.userScripts.length;i++)
			(function(uscr){loadJavaScript(uscr,function(){console.log('user script "'+uscr+'" has loaded')})})(document.applicationConfig.userScripts[i]);
	}
	/** APP INITIALIZATION COMPLETE **/
	if ((document.queryControl.shownQueries > 0)||(document.mapObject.selectionsExist)||(document.mapObject.buffersExist)||(document.mapObject.config.printConfig.templates.length>0))
		PrintManager_activate();  //loadJavaScript('./lib/PrintManager.js',function(){console.log('print manager has loaded')});
	switch(_DefaultActivePanel)
	{
		case 'userIntro':
		case 'control_panel_index':
		case 'layer_control':
		case 'legend':
			RightPanel_State_Manager.showPanel(_DefaultActivePanel);
			break;
		case 'select':
			if (document.mapObject.selectionsExist)
				RightPanel_State_Manager.showPanel('select');
			else
				RightPanel_State_Manager.showPanel('userIntro');
			break;
		case 'layerControl':
			RightPanel_State_Manager.showPanel('layer_control');
			break;
		case 'search':
			if (document.queryControl.shownQueries > 0)
				RightPanel_State_Manager.showPanel('query');
			else
				RightPanel_State_Manager.showPanel('userIntro');
			break;
		default:
			RightPanel_State_Manager.showPanel('userIntro');
			break;
	}
	runCMDs();
};

/** URL parameter processing **/
function runCMDs()
{
	/**TODO:  ENABLE MULTIPLE PARAMETERS TO BE ACCEPTED! **/
	if (APP_URLParameters["CMD"] == null)
		return;
	if (_FIRST_INITIALIZE)
		_FIRST_INITIALIZE = false;
	else
		return;
	var cmdName = APP_URLParameters["CMD"];
	switch (cmdName.toLowerCase())
	{
		case 'zoomto': runCMD_zoomTo(); break;
		case 'latlon': runCMD_latLon(); break;
		case 'geocode': runCMD_geocode(); break;
	}
};

function runCMD_zoomTo()
{
	if (document.mapObject.sessionID==null)
		setTimeout("runCMD_zoomTo()",1000)
	else{
	var themeID = APP_URLParameters["THEMEID"];
	if (themeID==null)
		var themeID = APP_URLParameters["THEMENAME"];
	var fieldName = APP_URLParameters["FIELDNAME"];
	var fieldValue = APP_URLParameters["FIELDVALUE"];
	//document.mapObject.zoomTo(themeID,fieldName+' = \''+fieldValue+'\'',(document.selectionControl!=null));
	document.mapObject.zoomTo_(themeID,fieldName,null,fieldValue,(document.selectionControl!=null));
	}
};

function runCMD_latLon()
{
	if (document.mapObject.sessionID==null)
		setTimeout("runCMD_latLon()",1000)
	else{
	var latitude=parseFloat(APP_URLParameters["LAT"]);
	var longitude=parseFloat(APP_URLParameters["LON"]);
	var result = freeance_request(null,'CoordConv.LL.to.SP',document.mapObject.config.projectionId,latitude,longitude);
	if (!result.XMLRPC_FAULT)
		document.mapObject.centerOnPoint(result.data.x,result.data.y);
	}
};

function runCMD_geocode()
{
	if (document.mapObject.sessionID==null)
		setTimeout("runCMD_geocode()",1000)
	else{
	if (document.geocodeControl){
		var geocodeParams = {
			mode:APP_URLParameters["MODE"].toLowerCase(),
			Street:APP_URLParameters["STREET"],
			STREET:APP_URLParameters["STREET"],
			CrossStreet:APP_URLParameters["CROSSSTREET"],
			Zip:APP_URLParameters["ZIP"],
			Zone:APP_URLParameters["ZONE"]
		};
		document.geocodeControl.geocode(geocodeParams,null,null,20);
	}
	}
};
/***********************************************************
	default mouse up handler for document; useful sometimes
***********************************************************/

function winMouseUpListener(evt)
{
	if (document.mouseUpCallbackObject)
		document.mouseUpCallbackObject.mouseUpCallback(evt);
};

TW = new TemplateWidget();
document.currentMapTool = 'ZoomIn';

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);
	return;
};

function toggleBufferTarget()
{
	document.mapObject.mapImage.bufferTargetNode.style.display = (document.mapObject.mapImage.bufferTargetNode.style.display=='block')?'none':'block';
}}
/* FILE:FreeanceWeb/Client/PublicAccess1/lib/MapLib/AltLegendControl.js */ if(!window.freeance_loaded_js['574820aece07c42792d8fabde3894eb4']){window.freeance_loaded_js['574820aece07c42792d8fabde3894eb4']=1;
/***
AltLegendControl.js
library for handling the map markup functions.

Dependencies:
MapLib/map.js
MapLib/mapImage.js

***/

AltLegendControl = function (newId, newMapObject, newMapId)
{
  if (arguments.length > 0)
    this.init(newId, newMapObject, newMapId);
};

AltLegendControl.prototype = new Object();
AltLegendControl.constructor = AltLegendControl;

AltLegendControl.prototype.init = function (newId, newMapObject, newMapId)
{
  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.altLegendControl = this;
  this.altLegendPanel = null;
  this.activeLegends = new Array();  // index on themeID, retrieves index of alt legend 0 (default) ... n
  this.themeLegends = new Array();  // index on themeID, array of 0..n { legendName, legendLabel }
  this.configured = false;
  this.haveAltLegends = false; // default
};

AltLegendControl.prototype.initialize = function()
{
  if (!this.configured)
  {
    this.setConfig();
    this.configured = true;
  }
  if (this.altLegendPanel)
    this.drawAltLegendPanel();
};

AltLegendControl.prototype.setConfig = function()
{
  var config = this.mapObject.config;
  for (var themeID in config.themes)
  {
    if(themeID=='toJSONString')continue;
    if (config.themes[themeID].altLegends.length > 0)
    {
      this.haveAltLegends = true;
      this.activeLegends[themeID] = 0;
      this.themeLegends[themeID] = new Array();
      this.themeLegends[themeID][0] = { legendName:'', legendLabel:'Default Legend'};
      for(var idx in config.themes[themeID].altLegends){
        if(idx=='toJSONString')continue;
        this.themeLegends[themeID][this.themeLegends[themeID].length] = config.themes[themeID].altLegends[idx];
      }
    }
  }
};

AltLegendControl.prototype.getThemeNameByThemeID = function(themeID)
{
  for(var id in document.mapObject.config.themes){
    if(id=='toJSONString')continue;    
    if (id == themeID)
    return(document.mapObject.config.themes[id].themeName);
  }
  return('');
};

AltLegendControl.prototype.assignAltLegendPanel = function(elem)
{
  this.altLegendPanel = elem;
  if (this.configured)
    this.drawAltLegendPanel();
};

AltLegendControl.prototype.getActiveLegend = function(themeID)
{
  if (!this.themeLegends[themeID])
    return(null);
  return(this.themeLegends[themeID][this.activeLegends[themeID]]);
};
AltLegendControl.prototype.getActiveLegendIdx = function(themeID)
{
  if (!this.themeLegends[themeID])
    return(-1);
  return(this.activeLegends[themeID]);
};

AltLegendControl.prototype.setActiveLegend = function(themeID,altLegendIdx)
{
  var $_this = this;
  this.activeLegends[themeID] = altLegendIdx;
  var legend = this.getActiveLegend(themeID);
  if (!legend)
  {
    alert('No defined active legend for theme id: '+themeID);
    return;
  }
  var requestInfo = {
    mode: 'setActiveLegend',
    themeID: themeID,
    altLegendIdx: altLegendIdx,
    newLegend: legend
  };
  this.mapObject.setWaiting(true);
  freeance_request(function(data){$_this.callback(data,requestInfo);},'GIS.Theme.activeLegend.set',this.mapObject.sessionID,0,themeID,legend.legendName);
};

AltLegendControl.prototype.callback = function(clientReply, pendingOperation)
{
  this.mapObject.setWaiting(false);
  if(clientReply.XMLRPC_FAULT)
    alert('Fault '+clientReply.XMLRPC_FAULT_CODE+': '+clientReply.XMLRPC_FAULT_MESSAGE);
  var data = clientReply.data;
  if(data != null)
  {
    switch (pendingOperation.mode)
    {
      case 'setActiveLegend':
        this.mapObject.legendSync = false;
        this.mapObject.redraw();
        break;
    }
  }
};

AltLegendControl.prototype.drawAltLegendPanel = function()
{
  var indexHtml = '<table width="100%" cellpadding="0" cellspacing="0">';
  for (var themeID in this.themeLegends)
  {
    if(themeID=='toJSONString')continue;
    indexHtml += '<tr class="selectionIndexHeader">'
     +  '  <td colspan="4" class="selectionIndexHeader">'
     +  this.getThemeNameByThemeID(themeID)
     +  '  </td>'
     +  '  <td style="text-align:  right;" class="selectionIndexHeader">'
     +  '    '
     +  '  </td>'
     +  '</tr>';
    var rowcount = 0;
    for(var altLegendIdx in this.themeLegends[themeID])
    {
      if(altLegendIdx=='toJSONString')continue;
      indexHtml+= '<tr style="'+(((rowcount%2)==0)?'background: #FEFEFF;':'')+'">'
       +  '  <td width="5px">'
       +  '  </td>'
       +  '  <td width="100%" style="font-size:  8pt; border-left:  1px #b0c4de solid; border-bottom:  1px #b0c4de solid; padding-left:  2px;">'
       +      '<span class="pseudolink" onclick="document.altLegendControl.setActiveLegend(\''+themeID+'\','+altLegendIdx+');this.getElementsByTagName(\'INPUT\')[0].checked=true;"><INPUT type="radio" name="alternateLegendRadio'+themeID+'" '+((altLegendIdx == this.activeLegends[themeID])?'checked="checked"':'')+'>';
      indexHtml += escapeHTML(this.themeLegends[themeID][altLegendIdx].legendLabel)+'</span>'
       +  '  </td>'
       +  '  <td width="1px" style="background:  #FEFEFF;"></td>'
       +  '  <td width="1px" style="background:  #FEFEFF;"></td>'
       +  '  <td width="1px" style="background:  #FEFEFF;"></td>'
       +  '</tr>';
      rowcount++;
    }
  }
  indexHtml+='<tr height="4px" class="selectionIndexFooter">'
   +  '<td width="5px"></td>'
   +  '<td width="*" style="border-left:  1px black solid; border-top:  1px black solid;"></td>'
   +  '<td width="15px" style="border-top:  1px black solid;"></td>'
   +  '<td width="15px" style="border-top:  1px black solid;"></td>'
   +  '<td width="15px" style="border-top:  1px black solid;"></td>'
   +'</tr>'
   + '</table>';
  this.altLegendPanel.innerHTML = indexHtml;
};

//if (Freeance_Extension_Manager)
//  Freeance_Extension_Manager.register('altlegendcontrol',function(){
if (Freeance_BundleExtension_Manager)
  Freeance_BundleExtension_Manager.register('altlegendcontrol',function(){
    document.altLegendControl = new AltLegendControl('map0AltLegendControl', document.mapObject, null);
    document.altLegendControl.initialize();
    if (document.altLegendControl.haveAltLegends){
      RightPanel_State_Manager.addLabel('alternate_legend','alternate_legend','Alternate Legends');
      RightPanel_State_Manager.addPanel('alternate_legend','altLegendContainer');
      document.altLegendControl.assignAltLegendPanel($('altLegendContainer'));
    }
    return true;
  });}
/* FILE:FreeanceWeb/Client/PublicAccess1/lib/PrintManager.js */ if(!window.freeance_loaded_js['1d554f78a2e01bb776bdf1e4b2f74c0b']){window.freeance_loaded_js['1d554f78a2e01bb776bdf1e4b2f74c0b']=1;
function PrintManager_activate()
{
document.printManager = new (function()
{
  var $_this = this;
  var mode = '';  //<map|selection|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
  var selectoption_container = null;

  //print type radio buttons
  var printtype_mapimg_btn = null;
  var printtype_search_btn = null;
  var printtype_select_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 = 'off';
    printtype_search_btn.checked = 'off';
    printtype_select_btn.checked = 'off';
    htmlpreview_container.innerHTML = '';
  };
  this.clearForm = clearForm;
  
  function setMode(newMode){
    clearForm();
    
    switch(newMode)
    {
      case 'map':
        printtype_search_btn.checked = 'off';
        printtype_select_btn.checked = 'off';
        printtype_mapimg_btn.checked = 'on';
        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_mapimg_btn.checked = 'off';
        printtype_select_btn.checked = 'off';
        printtype_search_btn.checked = 'on';
        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 = $('searchResultPanel').innerHTML;
        var tempNode=document.createElement('div');
        var resultContainer = $('searchResultPanel');
        for (var i=0;i<resultContainer.childNodes.length;i++)
        {
          tempNode.appendChild(duplicateNodeTreeEmbeddingStylesSubset(resultContainer.childNodes[i]));
        }
        var tables=tempNode.getElementsByTagName('TABLE');
        for (var i=0;i<tables.length;i++){
          if(tables[i].getAttribute('SCROLLTABLE_HEADER')!=null)
          {
            tables[i].style.display="none";
            if(tables[i].parentNode){
              tables[i].parentNode.removeChild(tables[i]);
            }
          }
        }
        for (var i=0;i<htmlpreview_container.childNodes.length;i++){
          htmlpreview_container.removeChild(htmlpreview_container.childNodes[i]);
        } 
        htmlpreview_container.appendChild(tempNode);
        break;
      case 'selection':
        printtype_mapimg_btn.checked = 'off';
        printtype_search_btn.checked = 'off';
        printtype_select_btn.checked = 'on';
        mapoption_container.style.display="none";
        htmlpreview_container.style.display="block";
        selectoption_container.style.display = 'block';
        xHeight(htmlpreview_container,xHeight(printPopup)-xHeight($('printmanager_header'))-xHeight($('printmanager_upperform'))-xHeight($('printmanager_footer')));
        $_this.selections = [];
        if (document.mapObject.selectionsExist){
          var selectionControl = document.mapObject.selectionControl;
          if(selectionControl)
          {
            var selectstr=['<select>'];
            var maplyrs=document.mapObject.config.themes;
            for (var lyr in selectionControl.selections)
            {
              if(lyr=='toJSONString')continue;
              selectstr.push('<optgroup label="'+maplyrs[lyr]['themeName']+'">');
              for (var i=0;i<selectionControl.selections[lyr].length;i++){
                selectstr.push('<option value="'+$_this.selections.length+'">'+selectionControl.selections[lyr][i].displaytext+'</option>');
                selectionControl.selections[lyr][i].printSelectionId=$_this.selections.length;
				if(document.selectionControl.displaylyr == lyr && document.selectionControl.displaysid == i){
					var current_sel = $_this.selections.length;
				}
                $_this.selections.push(selectionControl.selections[lyr][i]);
              };
              selectstr.push('</optgroup>');
            };
            selectstr.push('</select>');
          };
          if($_this.selections.length>0){
            $('printmanager_selection_input_container').innerHTML = selectstr.join('');
            var selectele = $('printmanager_selection_input_container').getElementsByTagName('select')[0];
            xAddEventListener(selectele,'change',function(){$_this.setSelection(parseInt(selectele.value));});
			$_this.setSelection(current_sel);
          }
          else
          {
            $('printmanager_selection_input_container').innerHTML='No selections are currently available';
            htmlpreview_container.innerHTML = '';
          }
        };
        break;
      default:
        break;
    };
    mode = newMode;
  };
  this.setMode = setMode;

  this.setSelection = function(selectid)
  {
    //var selectdata = selectid.split('|');
    //selectdata[1]=parseInt(selectdata[1]);
    //var selection = document.mapObject.selectionControl.getSelection(selectdata[0],selectdata[1]);
    if($_this.selections){
      var selectele = $('printmanager_selection_input_container').getElementsByTagName('select')[0];
      selectele.value=selectid;
      var selection = $_this.selections[selectid];
      if(selection)
      {
        selectoption_container.style.display = 'block';
        htmlpreview_container.innerHTML = selection["htmlstr"];
        htmlpreview_container.style.display='block';
      }
      else
      {
        htmlpreview_container.innerHTML = '';
      };
    }
    else
      setMode('map');

  };
  
  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');
        if(!newwindow){
          $('printwindow_inline').style.display="block";
          $('printwindow_inline_frame').style.display="block";
          $('printwindow_inline_frame').src='./printFrame.html';
        };
        break;
      case 'map':
        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){  //viewport scaling
          document.mapObject.print(templatevars,function(response){$_this.map_callback(response);});
        }
        else  //custom scale
        {
          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{
      if(!window.open(response.data)){
        $('printwindow_inline').style.display="block";
        $('printwindow_inline_frame').style.display="block";
        $('printwindow_inline_frame').src=response.data;
      }
    }
  };
  function show(){
    printPopup.style.display = 'block';
    if(arguments.length>0)
      setMode(arguments[0]);
  };
  this.show = show;
  
  function hide(){printPopup.style.display = 'none';};  
  this.hide = hide;
  
  function initialize(formHTML)
  {
    printPopup.innerHTML = formHTML;
    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');
    printtype_select_btn = $('printmanager_type_selection');
    
    xAddEventListener(printtype_mapimg_btn,'click',function(){$_this.setMode('map');});
    xAddEventListener(printtype_search_btn,'click',function(){$_this.setMode('search');});
    xAddEventListener(printtype_select_btn,'click',function(){$_this.setMode('selection');});
    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)
    {
	  $('printmanager_typerow_mapimage').style.display = 'none';
      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('printMapButton',ToolBar.BUTTON_IMAGE,ToolBar.ADD_BUTTON_LAST,null,25,25,325,true,'toolBar.png','Print');
	if(mapPrintConfig.templates.length==0)
      printButton.clickEvent = function(){show('search');xHeight(htmlpreview_container,xHeight(printPopup)-xHeight($('printmanager_header'))-xHeight($('printmanager_upperform'))-xHeight($('printmanager_footer')));};
	else
	  printButton.clickEvent = function(){show('map');};
  };
  //this.initialize = initialize;
  XmlHttp.loadTextASync('./layouts/PrintManager.html',function(formHTML){initialize(formHTML);});
})();
}}
/* FILE:FreeanceWeb/Client/PublicAccess1/lib/MapLib/Scalebar.js */ if(!window.freeance_loaded_js['3172f95f2901f5e0799932eacd76c359']){window.freeance_loaded_js['3172f95f2901f5e0799932eacd76c359']=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 unitLookup={'FT':_FT_,'YD':_YD_,'M':_M_,'MI':_MI_,'KM':_KM_};
  var unitLabels=Array('FT','YD','MI','m','km');
  var initialized = false;
  document.mapObject.scalebar = this;
  this.element = null;
  this.initialize = function()
  {
    if(document.applicationConfig.mapUnits=='LL')
      return;
    this.mapObject = document.mapObject;
    this.mapImage = this.mapObject.mapImage;
    this.baseUnits = unitLookup[document.applicationConfig.mapUnits];
    if (this.element==null)
      this.createElements();
    //attempt to load config from file
    
    
    
    this.config = [];
    if (this.mapObject.config.scalebarConfig==null)
    {
      //unit conversion populates config[2] and config[5]
      this.config = [
      [_FT_,10,null,_M_,1,null,250],
      [_FT_,100,null,_M_,10,null,500],
      [_FT_,200,null,_M_,50,null,2000],
      [_FT_,500,null,_M_,100,null,3000],
      [_FT_,1000,null,_M_,250,null,6000],
      [_MI_,1,null,_KM_,1,null,25000],
      [_MI_,2,null,_KM_,2,null,50000],
      [_MI_,2.5,null,_KM_,2.5,null,90000],
      [_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);
    }
    initialized = true;
  };
  
  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.background = '#000000';
    this.leftBarElement.style.top = 0;
    this.leftBarElement.style.left = 0;
    this.leftBarElement.style.width = 2;
    this.leftBarElement.style.height = 30;
    
    this.barElement = document.createElement('DIV');
    this.element.appendChild(this.barElement);
    
    this.barElement.style.position = 'absolute';
    this.barElement.style.display = 'block';
    this.barElement.style.height = 2;
    this.barElement.style.width = 100;
    this.barElement.style.background = '#000000';
    this.barElement.style.top = 14;
    this.barElement.style.left = 0;
    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 = 2;
    this.upperBarElement.style.height = 10;
    this.upperBarElement.style.top = 4;
    this.upperBarElement.style.left = 0;
    this.upperBarElement.style.background = '#000000';
    
    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 = 2;
    this.lowerBarElement.style.height = 10;
    this.lowerBarElement.style.top = 16;
    this.lowerBarElement.style.left = 3;
    this.lowerBarElement.style.background = '#000000';
    
  };
  
  this.drawScalebar = function()
  {
    if(document.applicationConfig.mapUnits=='LL') return null;
    if (!initialized)
      this.initialize();
    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-2;
    this.lowerBarElement.style.left = lowerBarWidth-2;
    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);
  };
};


FreeanceXMLParser.prototype.parseScalebarConfig = function(mapNode)
{
  var scalebarNodes = mapNode.getElementsByTagName('scalebar');
  if(scalebarNodes.length)
  {
    var scalebarNode = scalebarNodes[0];
    var scalebarConfig = new Array();
    for (var levelIndex = this.getNextNamedChildNodeIndex(scalebarNode,0,"level");levelIndex!=-1;levelIndex=this.getNextNamedChildNodeIndex(scalebarNode,levelIndex+1,"level"))
    {
      var levelNode = scalebarNode.childNodes[levelIndex];
      var currentLevel = scalebarConfig.length;
      scalebarConfig[currentLevel] = [
        parseInt(levelNode.getAttribute('topUnit')),
        parseFloat(levelNode.getAttribute('topLength')),
        parseInt(levelNode.getAttribute('bottomUnit')),
        parseFloat(levelNode.getAttribute('bottomLength')),
        parseFloat(levelNode.getAttribute('mapWidth'))
      ];
    }
  }
  return scalebarConfig;
};

//if (Freeance_Extension_Manager)
//  Freeance_Extension_Manager.register('scalebar',function(){
if (Freeance_BundleExtension_Manager)
  Freeance_BundleExtension_Manager.register('scalebar',function(){
    if(document.mapObject.configDocNode)
      document.mapObject.config.scalebarConfig = document.freeance_config_parser.parseScalebarConfig(document.mapObject.configDocNode);
    document.mapObject.scalebar = new Scalebar();
    if (_MAP_INITIALIZED){document.mapObject.scalebar.drawScalebar();}
    return true;
  });}
