/*

*/

var JSAN = function () { JSAN.addRepository(arguments) }

JSAN.VERSION = 0.10;

/*

*/

JSAN.globalScope   = self;
JSAN.includePath   = ['.', 'lib'];
JSAN.errorLevel    = "none";
JSAN.errorMessage  = "";
JSAN.loaded        = {};
JSAN.loading       = {};

/*

*/

JSAN.use = function () {
    var classdef = JSAN.require(arguments[0]);
    if (!classdef) return null;

    var importList = JSAN._parseUseArgs.apply(JSAN, arguments).importList;
    JSAN.exporter(classdef, importList);

    return classdef;
}

/*

*/

JSAN.require = function (pkg) {
    var path = JSAN._convertPackageToPath(pkg);

    if (JSAN.loaded[path]) {
        return JSAN.loaded[path];
    }

    if (JSAN.loading[path]) {
        return null;
    }

    try {
        var classdef = eval(pkg);
        if (typeof classdef != 'undefined') {
          JSAN.loaded[path] = classdef;
          JSAN.loading[path] = false;
          return classdef;
        }
    } catch (e) { /* nice try, eh? */ }

    JSAN.loading[path] = true;

    for (var i = 0; i < JSAN.includePath.length; i++) {
        var js;
        try{
            var url = JSAN._convertPathToUrl(path, JSAN.includePath[i]);
                js  = JSAN._loadJSFromUrl(url);
        } catch (e) {
            if (i == JSAN.includePath.length - 1) throw e;
        }
        if (js != null) {
            var classdef = JSAN._createScript(js, pkg);
            JSAN.loaded[path] = classdef;
            JSAN.loading[path] = false;
            return classdef;
        }
    }
    return false;

}

/*

*/

JSAN.exporter = function () {
    JSAN._exportItems.apply(JSAN, arguments);
}

/*

*/

JSAN.addRepository = function () {
    var temp = JSAN._flatten( arguments );
    // Need to go in reverse to do something as simple as unshift( @foo, @_ );
    for ( var i = temp.length - 1; i >= 0; i-- )
        JSAN.includePath.unshift(temp[i]);
    return JSAN;
}

JSAN._flatten = function( list1 ) {
    var list2 = new Array();
    for ( var i = 0; i < list1.length; i++ ) {
        if ( typeof list1[i] == 'object' ) {
            list2 = JSAN._flatten( list1[i], list2 );
        }
        else {
            list2.push( list1[i] );
        }
    }
    return list2;
};

JSAN._findMyPath = function () {
    if (document) {
        var scripts = document.getElementsByTagName('script');
        for ( var i = 0; i < scripts.length; i++ ) {
            var src = scripts[i].getAttribute('src');
            if (src) {
                var inc = src.match(/^(.*?)\/?JSAN.js/);
                if (inc && inc[1]) {
                    var repo = inc[1];
                    for (var j = 0; j < JSAN.includePath.length; j++) {
                        if (JSAN.includePath[j] == repo) {
                            return;
                        }
                    }
                    JSAN.addRepository(repo);
                }
            }
        }
    }
}
JSAN._findMyPath();

JSAN._convertPathToUrl = function (path, repository) {
    return repository.concat('/' + path);
};


JSAN._convertPackageToPath = function (pkg) {
    var path = pkg.replace(/\./g, '/');
        path = path.concat('.js');
    return path;
}

JSAN._parseUseArgs = function () {
    var pkg        = arguments[0];
    var importList = [];

    for (var i = 1; i < arguments.length; i++)
        importList.push(arguments[i]);

    return {
        pkg:        pkg,
        importList: importList
    }
}

JSAN._loadJSFromUrl = function (url) {
    return new JSAN.Request().getText(url);
}

JSAN._findExportInList = function (list, request) {
    if (list == null) return false;
    for (var i = 0; i < list.length; i++)
        if (list[i] == request)
            return true;
    return false;
}

JSAN._findExportInTag = function (tags, request) {
    if (tags == null) return [];
    for (var i in tags)
        if (i == request)
            return tags[i];
    return [];
}

JSAN._exportItems = function (classdef, importList) {
    var exportList  = new Array();
    var EXPORT      = classdef.EXPORT;
    var EXPORT_OK   = classdef.EXPORT_OK;
    var EXPORT_TAGS = classdef.EXPORT_TAGS;

    if (importList.length > 0) {
       importList = JSAN._flatten( importList );

       for (var i = 0; i < importList.length; i++) {
            var request = importList[i];
            if (   JSAN._findExportInList(EXPORT,    request)
                || JSAN._findExportInList(EXPORT_OK, request)) {
                exportList.push(request);
                continue;
            }
            var list = JSAN._findExportInTag(EXPORT_TAGS, request);
            for (var i = 0; i < list.length; i++) {
                exportList.push(list[i]);
            }
        }
    } else {
        exportList = EXPORT;
    }
    JSAN._exportList(classdef, exportList);
}

JSAN._exportList = function (classdef, exportList) {
    if (typeof(exportList) != 'object') return null;
    for (var i = 0; i < exportList.length; i++) {
        var name = exportList[i];

        if (JSAN.globalScope[name] == null)
            JSAN.globalScope[name] = classdef[name];
    }
}

JSAN._makeNamespace = function(js, pkg) {
    var spaces = pkg.split('.');
    var parent = JSAN.globalScope;
    eval(js);
    var classdef = eval(pkg);
    for (var i = 0; i < spaces.length; i++) {
        var name = spaces[i];
        if (i == spaces.length - 1) {
            if (typeof parent[name] == 'undefined') {
                parent[name] = classdef;
                if ( typeof classdef['prototype'] != 'undefined' ) {
                    parent[name].prototype = classdef.prototype;
                }
            }
        } else {
            if (parent[name] == undefined) {
                parent[name] = {};
            }
        }

        parent = parent[name];
    }
    return classdef;
}

JSAN._handleError = function (msg, level) {
    if (!level) level = JSAN.errorLevel;
    JSAN.errorMessage = msg;

    switch (level) {
        case "none":
            break;
        case "warn":
            alert(msg);
            break;
        case "die":
        default:
            throw new Error(msg);
            break;
    }
}

JSAN._createScript = function (js, pkg) {
    try {
        return JSAN._makeNamespace(js, pkg);
    } catch (e) {
        // 214 is the eval line number
        JSAN._handleError("Could not create namespace[" + pkg + "]: " + e.message + " line " + (e.lineNumber - 214 + 1));
    }
    return null;
}


JSAN.prototype = {
    use: function () { JSAN.use.apply(JSAN, arguments) }
};


// Low-Level HTTP Request
JSAN.Request = function (jsan) {
    if (JSAN.globalScope.XMLHttpRequest) {
        this._req = new XMLHttpRequest();
    } else {
        this._req = new ActiveXObject("Microsoft.XMLHTTP");
    }
}

JSAN.Request.prototype = {
    _req:  null,

    getText: function (url) {
        this._req.open("GET", url, false);
        try {
            this._req.send(null);
            if (this._req.status == 200 || this._req.status == 0)
                return this._req.responseText;
        } catch (e) {
            JSAN._handleError("File not found: " + url);
            return null;
        };

        JSAN._handleError("File not found: " + url);
        return null;
    }
};


/*

*/

if (typeof(Class) == 'undefined') {
    Class = {};
}

Class.NAME = 'Class';
Class.VERSION = '0.04';
Class.__repr__ = function () {
    return "[" + this.NAME + " " + this.VERSION + "]";
}
Class.toString = function () {
    return this.__repr__();
}
Class.EXPORT = [];
Class.EXPORT_OK = ['create', 'extend', 'subclass'];
Class.EXPORT_TAGS = {
    ':all': Class.EXPORT_OK,
    ':common': Class.EXPORT
};

/*

*/

Class.__new__ = function () {
    // private token, naked unique object
    var __clone__ = {};
    // the incrementing counter for instances created
    var instanceCounter = 0;
    // This is the representation of class objects
    var classToString = function () {
        return "[Class " + this.NAME + "]";
    };
    // Representation of instance objects
    var instanceToString = function () {
        return "[" + this.__class__.NAME + " #" + this.__id__ + "]";
    };
    var forwardToRepr = function () {
        return this.__repr__();
    };
    var proxyFunction = function (func) {
        var callFunc = func.__orig__;
        if (typeof(callFunc) == 'undefined') {
            callFunc = func;
        }
        var newFunc = function () {
            return callFunc.apply(this, arguments);
        }
        for (var k in func) {
            newFunc[k] = func[k];
        }
        newFunc.__orig__ = callFunc;
        return newFunc;
    };

    var getNextMethod = function (self) {
        var next_method = null;
        try {
            return this.__class__.superClass.prototype[this.__name__];
        } catch (e) {
            throw new TypeError("no super method for " + this.NAME);
        }
    }

    var nextMethod = function (self) {
        var args = [];
        for (var i = 1; i < arguments.length; i++) {
            args.push(arguments[i]);
        }
        var next = this.getNextMethod();
        if ( typeof( next ) == 'function' ) {
            next.apply(self, args);
        }
    };

    this.create = function () {
        var body = null;
        var name = "Some Class";
        var superClass = Object;

        if ( arguments.length == 1 ) {
            body = arguments[0];
        }
        else if ( arguments.length == 2 ) {
            if ( typeof arguments[0] == 'string' ) {
                name = arguments[0];
            }
            else {
                superClass = arguments[0];
            }
            body = arguments[1];
        }
        else {
            name = arguments[0];
            superClass = arguments[1];
            body = arguments[2];
        }

        // this is the constructor we're going to return
        var rval = function (arg) {
            // allow for "just call" syntax to create objects
            var o = this;
            if (!(o instanceof rval)) {
                o = new rval(__clone__);
            } else {
                o.__id__ = ++instanceCounter;
            }
            // don't initialize when using the stub method!
            if (arg != __clone__) {
                if (typeof(o.initialize) == 'function') {
                    o.initialize.apply(o, arguments);
                }
            }
            return o;
        };

        rval.NAME = name;
        rval.superClass = superClass;
        rval.toString = forwardToRepr;
        rval.__repr__ = classToString;
        rval.__MochiKit_Class__ = true;

        if ( body ) {
            this.extend( rval, superClass, body );
        }

        return rval;
    };

    this.extend = function ( rval, superClass, body ) {

        var proto = null;
        if (superClass.__MochiKit_Class__) {
            proto = new superClass(__clone__);
        } else {
            proto = new superClass();
        }

        if (typeof(proto.toString) == 'undefined' || (proto.toString == Object.prototype.toString)) {
            proto.toString = instanceToString;
        }
        if (typeof(proto.__repr__) == 'undefined') {
            proto.__repr__ = instanceToString;
        }
        if (proto.toString == Object.prototype.toString) {
            proto.toString = forwardToRepr;
        }
        if (typeof(body) != 'undefined' && body != null) {
            for (var k in body) {
                var o = body[k];
                if (typeof(o) == 'function' && typeof(o.__MochiKit_Class__) == 'undefined') {
                    if (typeof(o.__class__) != 'undefined') {
                        if (o.__class__ != rval) {
                            continue;
                        }
                        o = proxyFunction(o);
                    }
                    o.__class__ = rval;
                    o.__name__ = k;
                    o.NAME = rval.NAME + '.' + k;
                    o.nextMethod = nextMethod;
                    o.getNextMethod = getNextMethod;
                }
                proto[k] = o;
            }
        }
        proto.__id__ = ++instanceCounter;
        proto.__class__ = rval;

        proto.__super__ = function ( methname ) {
            if ( typeof( this[methname] ) != 'function' ) return;
            var args = [];
            for ( var i = 1; i < arguments.length; i++ )
                args.push( arguments[i] );

            this[methname].nextMethod( this, args );
        };

        proto.__super__.__class__ = superClass;
        proto.__super__.__name__ = '__super__';
        proto.__super__.NAME = rval.NAME + '.__super__';
        proto.__super__.nextMethod = nextMethod;
        proto.__super__.getNextMethod = getNextMethod;

        rval.prototype = proto;
    };

    this.subclass = function () {
        var body = {};
        var name = "Some Class";
        var superClass = Object;

        if ( arguments.length == 1 ) {
            body = arguments[0];
        }
        else if ( arguments.length == 2 ) {
            superClass = arguments[0];
            body = arguments[1];
        }
        else {
            name = arguments[0];
            superClass = arguments[1];
            body = arguments[2];
        }

        var rval = this.create( name, superClass, body );
        this.extend( rval, superClass, body );

        return rval;
    };
    this.subclass.NAME = this.NAME + "." + "subclass";
};

Class.__new__();
/*

*/

/*

*/


var LOADING_STATUS_PAGE = HTTP_SHARED_PATH + 'loading.html';

JSAN.includePath = [HTTP_SHARED_PATH + 'js'];
JSAN.errorLevel = "die";

if(Limb == undefined) var Limb = {};

Limb.post_load_hooks = [];

function isset(obj)
{
  return typeof(obj) != undefined && obj != null;
}

if(!isset(Limb.ON_LOAD_SET))
  Limb.ON_LOAD_SET = 0;

Limb.post_load_handler = function()
{
  for(i in Limb.post_load_hooks)
  {
    hook = Limb.post_load_hooks[i];
    if(typeof(hook) == 'function') hook();
  }
}

if(Limb.ON_LOAD_SET == 0) //protection from repeated setup.js includes
{
  //we can't use nice add event here, because it may be not loaded yet
  Limb.prev_window_on_load_handler = window.onload;
  window.onload = function()
  {
    if(typeof(Limb.prev_window_on_load_handler) == 'function')
      Limb.prev_window_on_load_handler();

    Limb.post_load_handler();
  }
  Limb.ON_LOAD_SET = 1;
}


if (Limb == undefined) var Limb = {};
if (Limb.browser == undefined) Limb.browser = {};

var agt = navigator.userAgent.toLowerCase();
Limb.browser.is_ie = (agt.indexOf("msie") != -1) && (agt.indexOf("opera") == -1);
Limb.browser.is_gecko = navigator.product == "Gecko";
Limb.browser.is_opera  = (agt.indexOf("opera") != -1);
Limb.browser.is_mac    = (agt.indexOf("mac") != -1);
Limb.browser.is_mac_ie = (Limb.browser.is_ie && Limb.browser.is_mac);
Limb.browser.is_win_ie = (Limb.browser.is_ie && !Limb.browser.is_mac);

Limb.browser.detectFlash = function(requiredVersion)
{
  var flashVersion = 0;

  if (!navigator.plugins)
    return false;

  if(Limb.browser.is_win_ie)
  {
    var flashPresent = false;

    for(var version = requiredVersion; version<10; version++)
    {
      try
      {
        flashPresent = flashPresent || new ActiveXObject('ShockwaveFlash.ShockwaveFlash.' + version);
      }
      catch(e) {}
    }

    return flashPresent;
  }

  if (navigator.plugins["Shockwave Flash 2.0"]
      || navigator.plugins["Shockwave Flash"])
  {

    var isVersion2 = navigator.plugins["Shockwave Flash 2.0"] ? " 2.0" : "";
    var flashDescription = navigator.plugins["Shockwave Flash" + isVersion2].description;

    var flashVersion = parseInt(flashDescription.substring(16));
  }

  if(navigator.userAgent.indexOf("WebTV") != -1) actualVersion = 4;

  if (flashVersion < requiredVersion)
    return false;

  return true;
}



if (Limb == undefined) var Limb = {};
if (Limb.md5 == undefined) Limb.md5 = {};

//MD5 stuff

Limb.md5.hexcase = 0;  /* hex output format. 0 - lowercase; 1 - uppercase        */
Limb.md5.b64pad  = ""; /* base-64 pad character. "=" for strict RFC compliance   */
Limb.md5.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
 */
Limb.md5.hex_md5 = function (s){ return Limb.md5.binl2hex(Limb.md5.core_md5(Limb.md5.str2binl(s), s.length * Limb.md5.chrsz));}
Limb.md5.str_md5 = function (s){ return Limb.md5.binl2str(Limb.md5.core_md5(Limb.md5.str2binl(s), s.length * Limb.md5.chrsz));}

Limb.md5.core_md5 = function (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 = Limb.md5.ff(a, b, c, d, x[i+ 0], 7 , -680876936);
    d = Limb.md5.ff(d, a, b, c, x[i+ 1], 12, -389564586);
    c = Limb.md5.ff(c, d, a, b, x[i+ 2], 17,  606105819);
    b = Limb.md5.ff(b, c, d, a, x[i+ 3], 22, -1044525330);
    a = Limb.md5.ff(a, b, c, d, x[i+ 4], 7 , -176418897);
    d = Limb.md5.ff(d, a, b, c, x[i+ 5], 12,  1200080426);
    c = Limb.md5.ff(c, d, a, b, x[i+ 6], 17, -1473231341);
    b = Limb.md5.ff(b, c, d, a, x[i+ 7], 22, -45705983);
    a = Limb.md5.ff(a, b, c, d, x[i+ 8], 7 ,  1770035416);
    d = Limb.md5.ff(d, a, b, c, x[i+ 9], 12, -1958414417);
    c = Limb.md5.ff(c, d, a, b, x[i+10], 17, -42063);
    b = Limb.md5.ff(b, c, d, a, x[i+11], 22, -1990404162);
    a = Limb.md5.ff(a, b, c, d, x[i+12], 7 ,  1804603682);
    d = Limb.md5.ff(d, a, b, c, x[i+13], 12, -40341101);
    c = Limb.md5.ff(c, d, a, b, x[i+14], 17, -1502002290);
    b = Limb.md5.ff(b, c, d, a, x[i+15], 22,  1236535329);

    a = Limb.md5.gg(a, b, c, d, x[i+ 1], 5 , -165796510);
    d = Limb.md5.gg(d, a, b, c, x[i+ 6], 9 , -1069501632);
    c = Limb.md5.gg(c, d, a, b, x[i+11], 14,  643717713);
    b = Limb.md5.gg(b, c, d, a, x[i+ 0], 20, -373897302);
    a = Limb.md5.gg(a, b, c, d, x[i+ 5], 5 , -701558691);
    d = Limb.md5.gg(d, a, b, c, x[i+10], 9 ,  38016083);
    c = Limb.md5.gg(c, d, a, b, x[i+15], 14, -660478335);
    b = Limb.md5.gg(b, c, d, a, x[i+ 4], 20, -405537848);
    a = Limb.md5.gg(a, b, c, d, x[i+ 9], 5 ,  568446438);
    d = Limb.md5.gg(d, a, b, c, x[i+14], 9 , -1019803690);
    c = Limb.md5.gg(c, d, a, b, x[i+ 3], 14, -187363961);
    b = Limb.md5.gg(b, c, d, a, x[i+ 8], 20,  1163531501);
    a = Limb.md5.gg(a, b, c, d, x[i+13], 5 , -1444681467);
    d = Limb.md5.gg(d, a, b, c, x[i+ 2], 9 , -51403784);
    c = Limb.md5.gg(c, d, a, b, x[i+ 7], 14,  1735328473);
    b = Limb.md5.gg(b, c, d, a, x[i+12], 20, -1926607734);

    a = Limb.md5.hh(a, b, c, d, x[i+ 5], 4 , -378558);
    d = Limb.md5.hh(d, a, b, c, x[i+ 8], 11, -2022574463);
    c = Limb.md5.hh(c, d, a, b, x[i+11], 16,  1839030562);
    b = Limb.md5.hh(b, c, d, a, x[i+14], 23, -35309556);
    a = Limb.md5.hh(a, b, c, d, x[i+ 1], 4 , -1530992060);
    d = Limb.md5.hh(d, a, b, c, x[i+ 4], 11,  1272893353);
    c = Limb.md5.hh(c, d, a, b, x[i+ 7], 16, -155497632);
    b = Limb.md5.hh(b, c, d, a, x[i+10], 23, -1094730640);
    a = Limb.md5.hh(a, b, c, d, x[i+13], 4 ,  681279174);
    d = Limb.md5.hh(d, a, b, c, x[i+ 0], 11, -358537222);
    c = Limb.md5.hh(c, d, a, b, x[i+ 3], 16, -722521979);
    b = Limb.md5.hh(b, c, d, a, x[i+ 6], 23,  76029189);
    a = Limb.md5.hh(a, b, c, d, x[i+ 9], 4 , -640364487);
    d = Limb.md5.hh(d, a, b, c, x[i+12], 11, -421815835);
    c = Limb.md5.hh(c, d, a, b, x[i+15], 16,  530742520);
    b = Limb.md5.hh(b, c, d, a, x[i+ 2], 23, -995338651);

    a = Limb.md5.ii(a, b, c, d, x[i+ 0], 6 , -198630844);
    d = Limb.md5.ii(d, a, b, c, x[i+ 7], 10,  1126891415);
    c = Limb.md5.ii(c, d, a, b, x[i+14], 15, -1416354905);
    b = Limb.md5.ii(b, c, d, a, x[i+ 5], 21, -57434055);
    a = Limb.md5.ii(a, b, c, d, x[i+12], 6 ,  1700485571);
    d = Limb.md5.ii(d, a, b, c, x[i+ 3], 10, -1894986606);
    c = Limb.md5.ii(c, d, a, b, x[i+10], 15, -1051523);
    b = Limb.md5.ii(b, c, d, a, x[i+ 1], 21, -2054922799);
    a = Limb.md5.ii(a, b, c, d, x[i+ 8], 6 ,  1873313359);
    d = Limb.md5.ii(d, a, b, c, x[i+15], 10, -30611744);
    c = Limb.md5.ii(c, d, a, b, x[i+ 6], 15, -1560198380);
    b = Limb.md5.ii(b, c, d, a, x[i+13], 21,  1309151649);
    a = Limb.md5.ii(a, b, c, d, x[i+ 4], 6 , -145523070);
    d = Limb.md5.ii(d, a, b, c, x[i+11], 10, -1120210379);
    c = Limb.md5.ii(c, d, a, b, x[i+ 2], 15,  718787259);
    b = Limb.md5.ii(b, c, d, a, x[i+ 9], 21, -343485551);

    a = Limb.md5.safe_add(a, olda);
    b = Limb.md5.safe_add(b, oldb);
    c = Limb.md5.safe_add(c, oldc);
    d = Limb.md5.safe_add(d, oldd);
  }
  return Array(a, b, c, d);

}

Limb.md5.cmn = function (q, a, b, x, s, t)
{
  return Limb.md5.safe_add(Limb.md5.bit_rol(Limb.md5.safe_add(Limb.md5.safe_add(a, q), Limb.md5.safe_add(x, t)), s),b);
}
Limb.md5.ff = function (a, b, c, d, x, s, t)
{
  return Limb.md5.cmn((b & c) | ((~b) & d), a, b, x, s, t);
}
Limb.md5.gg = function (a, b, c, d, x, s, t)
{
  return Limb.md5.cmn((b & d) | (c & (~d)), a, b, x, s, t);
}
Limb.md5.hh = function (a, b, c, d, x, s, t)
{
  return Limb.md5.cmn(b ^ c ^ d, a, b, x, s, t);
}
Limb.md5.ii = function (a, b, c, d, x, s, t)
{
  return Limb.md5.cmn(c ^ (b | (~d)), a, b, x, s, t);
}

Limb.md5.core_hmac = function (key, data)
{
  var bkey = Limb.md5.str2binl(key);
  if(bkey.length > 16) bkey = Limb.md5.core_md5(bkey, key.length * Limb.md5.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 = Limb.md5.core_md5(ipad.concat(Limb.md5.str2binl(data)), 512 + data.length * Limb.md5.chrsz);
  return Limb.md5.core_md5(opad.concat(hash), 512 + 128);
}

Limb.md5.safe_add = function (x, y)
{
  var lsw = (x & 0xFFFF) + (y & 0xFFFF);
  var msw = (x >> 16) + (y >> 16) + (lsw >> 16);
  return (msw << 16) | (lsw & 0xFFFF);
}

Limb.md5.bit_rol = function (num, cnt)
{
  return (num << cnt) | (num >>> (32 - cnt));
}

Limb.md5.str2binl = function (str)
{
  var bin = Array();
  var mask = (1 << Limb.md5.chrsz) - 1;
  for(var i = 0; i < str.length * Limb.md5.chrsz; i += Limb.md5.chrsz)
    bin[i>>5] |= (str.charCodeAt(i / Limb.md5.chrsz) & mask) << (i%32);
  return bin;
}

Limb.md5.binl2str = function (bin)
{
  var str = "";
  var mask = (1 << Limb.md5.chrsz) - 1;
  for(var i = 0; i < bin.length * 32; i += Limb.md5.chrsz)
    str += String.fromCharCode((bin[i>>5] >>> (i % 32)) & mask);
  return str;
}

Limb.md5.binl2hex = function (binarray)
{
  var hex_tab = Limb.md5.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;
}

Limb.md5.binl2b64 = function (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 += Limb.md5.b64pad;
      else str += tab.charAt((triplet >> 6*(3-j)) & 0x3F);
    }
  }
  return str;
}



if (Limb == undefined) var Limb = {};
if (Limb.window == undefined) Limb.window = {};




if (Limb == undefined) var Limb = {};

Limb.Coordinates = {};

if (Limb == undefined) var Limb = {};
if (Limb.Coordinates == undefined) Limb.Coordinates = {};



Limb.Coordinates.Point = Class.create();

Limb.Coordinates.Point.prototype = {
  initialize: function(x, y)
  {
    this.x = x || 0;
    this.y = y || 0;
  },

  setX: function(x)
  {
    this.x = x;
  },

  setY: function(y)
  {
    this.y = y;
  },

  getX: function()
  {
    return this.x;
  },

  getY: function()
  {
    return this.y;
  }
}


if (Limb == undefined) var Limb = {};
if (Limb.Coordinates == undefined) Limb.Coordinates = {};




Limb.Coordinates.Rect = Class.subclass(Limb.Coordinates.Point, {
  initialize: function(x, y, width, height)
  {
    arguments.callee.nextMethod(this, x, y);

    this.width = width || 0;
    this.height = height || 0;
  },

  setWidth: function(width)
  {
    this.width = width;
  },

  setHeight: function(height)
  {
    this.height = height;
  },

  getWidth: function()
  {
    return this.width;
  },

  getHeight: function()
  {
    return this.height;
  },

  getRight: function()
  {
    return this.x + this.width;
  },

  getBottom: function()
  {
    return this.y + this.height;
  },

  setSize: function(width, height)
  {
    this.width = width || 0;
    this.height = height || 0;
  },

  createWithCenter: function(point, width, height)
  {
    if(!point)
      return;

    this.setSize(width, height);
    this.alignToCenter(point);
  },

  alignToCenter: function(point)
  {
    this.x = point.x - this.width / 2;
    this.y = point.y - this.height / 2;
  },

  getCenter: function()
  {
    return new Limb.Coordinates.Point(this.x + (this.width / 2), this.y + (this.height / 2));
  }
});



if (Limb == undefined) var Limb = {};
if (Limb.Window == undefined) Limb.Window = {};

Limb.Window.Params = Class.create();

Limb.Window.Params.prototype = {
  initialize: function(initArray)
  {
    this.params = initArray || [];
  },

  setParameter: function(name, value)
  {
    this.params[name] = value;
  },

  addParameter: function(name, value)
  {
    if(isset(this.params[name]))
      return;

    this.setParameter(name, value);
  },

  getParameter: function(name)
  {
     return params[name];
  },

  toString: function()
  {
    var result = '';

    for(var name in this.params)
      result += name + '=' + this.params[name] + ',';

    return result.slice(0, -1);
  },

  toArray: function()
  {
    return this.params;
  }
}

/*

=head1 NAME

Function.bind

=head1 DESCRIPTION

This provides a new method to the core class Function. The method, called bind(), is used to create closures for use with window.setTimeout().

=head1 DEPENDENCIES

This requires JSAN and Upgrade to be installed.

=cut

*/

try {
    JSAN.use( 'Upgrade.Function.apply' );
} catch (e) {
    throw "Function.bind requires JSAN to be loaded";
}

/*

=head1 CORE CLASS EXTENSIONS

These are extensions to core classes provided by JavaScript.

=cut

*/

/*

=head2 Function.prototype.bind( object )

The C<bind()> method is added to the core Function class, providing the ability to create a closure over a method useful for passing to setTimeout().

  var obj = new SomeClass();

  var closure = obj.someMethod.bind( this );
  window.setTimeout( closure, 10 );

=cut

*/

if ( ! Function.prototype.bind ) {
    Function.prototype.bind = function( object ) {
        var __method = this;
        return function() {
            __method.apply( object, arguments );
        };
    };
}

/*

=head1 CAVEATS

Modifying the prototype of core Javascript classes should be avoided, if possible. By doing this, you are modifying B<ALL> objects of this class, regardless of when they were instantiated or by whom, For some classes, such as Number and String, this includes primitives. This can lead to surprising effects and action-at-a-distance.

You have been warned.

=head1 SUPPORT

Currently, there is no mailing list or IRC channel. Please send bug reports and patches to the author.

=head1 AUTHOR

Rob Kinyon (rob.kinyon@iinteractive.com)

Originally written by Sam Stephenson (sam@conio.net)

My time is generously donated by Infinity Interactive, Inc. L<http://www.iinteractive.com>

=cut

*/



Limb.window = Class.create();

Limb.window.prototype = {
  initialize: function()
  {
    this.parentWindow = null;
    this.windowName = this._generateName();
    this.onLoadEvents = [];
    this.onUnloadEvents = [];

    if(arguments.length == 0)
      this.window = window;

    // arguments[0] instanceof Window does not work in IE
    if(typeof(arguments[0]) == 'object')
      this.window = win;

    if(arguments.length == 2 || arguments.length == 3)
      this.window = this._createWindow(arguments[0], arguments[1], arguments[2]);

    Limb.events.add_event(this.window, 'load', this.onOpen.bind(this), false);
    Limb.events.add_event(this.window, 'close', this.onClose.bind(this), false);
  },

  getWindowObject: function()
  {
    return this.window;
  },

  centreWindow: function(width, height)
  {
    var newWindowRect = this._getRectInParentCenter(width, height);
    this.setRect(newWindowRect);
  },

  _getRectInParentCenter: function(width, height)
  {
    var windowRect = this.parentWindow.getRect();

    var result = new Limb.Coordinates.Rect();
    result.createWithCenter(windowRect.getCenter(), width, height);

    return result;
  },

  _getDefaultParams: function()
  {
    var width = 150;
    var height = 100;

    var newWindowRect = this._getRectInParentCenter(width, height);

    var params = new Limb.Window.Params();
    params.addParameter('left', newWindowRect.getX());
    params.addParameter('top', newWindowRect.getY());
    params.addParameter('width', width);
    params.addParameter('height', height);

    params.addParameter('scrollbars', 'yes');
    params.addParameter('resizable', 'yes');
    params.addParameter('help', 'no');
    params.addParameter('status', 'yes');

    return params;
  },

  _makeParamsString: function(params)
  {
    var result = '';

    for(var name in params)
      result += name + '=' + params[name] + ',';

    return result.slice(0, -1);
  },

  _generateName: function()
  {
    return Math.round(Math.random() * 1000) + '_generate';
  },

  _createWindow: function(href, windowName, createParams)
  {
    this.parentWindow = new Limb.window();

    if(windowName)
      this.windowName = windowName;

    if(!isset(createParams))
      createParams = this._getDefaultParams();

    var win = window.open(href, this.windowName, createParams.toString());

    return win;
  },

  getRect: function()
  {
    if(Limb.browser.is_ie)
      return new Limb.Coordinates.Rect(this.window.screenLeft,
                                       this.window.screenTop,
                                       this.window.document.body.clientWidth,
                                       this.window.document.body.clientHeight);
    else
      return new Limb.Coordinates.Rect(this.window.screenX + this.window.outerWidth - this.window.innerWidth,
                                       this.window.screenY + this.window.outerHeight - this.window.innerHeight,
                                       this.window.innerWidth,
                                       this.window.innerHeight);
  },

  setRect: function(rect)
  {
    if(!rect)
      return false;

    this.window.moveTo(rect.getX(), rect.getY());
    this.window.resizeTo(rect.getWidth(), rect.getHeight());

    return true;
  },

  onOpen: function()
  {
    Limb.window.register(this.windowName, this);

    if(!this.window.limbWindowWidth)
      this.window.limbWindowWidth = this.parentWindow.getRect().getWidth() * 0.85;

    if(!this.window.limbWindowHeight)
      this.window.limbWindowHeight = this.parentWindow.getRect().getHeight() * 0.9;

    this.centreWindow(this.window.limbWindowWidth, this.window.limbWindowHeight);

    this.openHandler();
  },

  onClose: function()
  {
    Limb.window.remove(this.windowName);

    this.closeHandler();
  },

  openHandler: function() {},
  closeHandler: function() {}
}

Limb.window.register = function(windowName, win)
{
  if(!isset(Limb.window.createdWindows))
    Limb.window.createdWindows = [];

  Limb.window.createdWindows[windowName] = win;
}

Limb.window.remove = function(windowName)
{
  if(!isset(Limb.window.createdWindows)||
     !isset(Limb.window.createdWindows[windowName]))
    return;

  Limb.window.createdWindows[windowName] = null;
  delete Limb.window.createdWindows[windowName];
}

Limb.window.current = function()
{
 if(!isset(Limb.window.createdWindows))
    return null;

  for(var i in Limb.window.createdWindows)
    if(Limb.window.createdWindows[i].getWindowObject() == window)
      return Limb.window.createdWindows[i];

  return null;
}

Limb.window.get_close_popup_handler = function ()
{
  return window.opener.popups[window.name]['close_popup_handler'];
}

Limb.window.get_init_popup_handler = function ()
{
  return window.opener.popups[window.name]['init_popup_handler'];
}

Limb.window.optimize_window = function ()
{
  var w = window;
  var top_opener = window;

  var x_ratio = 0.85;
  var y_ratio = 0.85;
  var screen_x = (Limb.browser.is_gecko) ? top_opener.screenX : top_opener.screenLeft;

  while(typeof(top_opener.top.opener) != 'undefined' && top_opener.top.opener != null && screen_x >= 0)
  {
    screen_x = (Limb.browser.is_gecko) ? top_opener.screenX : top_opener.screenLeft;
    top_opener = top_opener.top.opener;
  }

  if (Limb.browser.is_ie)
  {
    openerWidth = top_opener.top.document.body.clientWidth;
    openerHeight = top_opener.top.document.body.clientHeight;
    openerLeft = top_opener.top.screenLeft;
    openerTop = top_opener.top.screenTop;
  }
  else if(Limb.browser.is_gecko || Limb.browser.is_opera)
  {
    openerWidth = top_opener.top.innerWidth;
    openerHeight = top_opener.top.innerHeight;
    openerLeft = top_opener.top.screenX + top_opener.top.outerWidth - top_opener.top.innerWidth;
    openerTop = top_opener.top.screenY + top_opener.top.outerHeight - top_opener.top.innerHeight;
  }
  else
  {
    openerWidth = top_opener.document.body.clientWidth;
    openerHeight = top_opener.document.body.clientHeight;
    openerLeft = top_opener.screenLeft;
    openerTop = top_opener.screenTop;
  }

  if(window.WINDOW_WIDTH)
    newWidth = window.WINDOW_WIDTH;
  else
    newWidth = openerWidth*x_ratio;

  if(window.WINDOW_HEIGHT)
    newHeight = window.WINDOW_HEIGHT;
  else
    newHeight = openerHeight*y_ratio;


  newLeft = openerLeft + (openerWidth - newWidth)/2;
  newTop = openerTop + (openerHeight - newHeight)/2;

  w.moveTo(newLeft, newTop);
  w.resizeTo(newWidth, newHeight);
}

Limb.window.get_popup_params = function ()
{
  var w = window;
  var top_opener = window;

  var screen_x = (Limb.browser.is_gecko) ? top_opener.screenX : top_opener.screenLeft;

  while(typeof(top_opener.top.opener) != 'undefined' && top_opener.top.opener != null && screen_x >= 0)
  {
    screen_x = (Limb.browser.is_gecko) ? top_opener.screenX : top_opener.screenLeft;
    top_opener = top_opener.top.opener;
  }

  if (Limb.browser.is_ie)
  {
    openerWidth = top_opener.top.document.body.clientWidth;
    openerHeight = top_opener.top.document.body.clientHeight;
    openerLeft = top_opener.top.screenLeft;
    openerTop = top_opener.top.screenTop;
  }
  else if(Limb.browser.is_gecko || Limb.browser.is_opera)
  {
    openerWidth = top_opener.top.innerWidth;
    openerHeight = top_opener.top.innerHeight;
    openerLeft = top_opener.top.screenX + top_opener.top.outerWidth - top_opener.top.innerWidth;
    openerTop = top_opener.top.screenY + top_opener.top.outerHeight - top_opener.top.innerHeight;
  }
  else
  {
    openerWidth = document.body.clientWidth;
    openerHeight = document.body.clientHeight;
    openerLeft = screenLeft;
    openerTop = screenTop;
  }

  var x_ratio = 0.85;
  var y_ratio = 0.85;

  newWidth = openerWidth * x_ratio;
  newHeight = openerHeight * y_ratio;

  newLeft = openerLeft + (openerWidth - newWidth)/2;
  newTop = openerTop + (openerHeight - newHeight)/2;

  var params = 'width=' + newWidth + ',height=' + newHeight + ',top=' + newTop + ',left=' + newLeft;
  params += ',scrollbars=yes,resizable=yes,help=no,status=yes';

  return params;
}

//makes popup window at href address
Limb.window.popup = function (href, window_name, window_params, dont_set_focus, on_close_handler, on_init_handler)
{
  href = Limb.http.add_url_query_item(href, 'popup', 1);

  if (typeof(window_name) == 'undefined' || window_name == null)
    window_name = '_generate';

  new_left = window.screen.width / 2 - 100;
  new_top = window.screen.height / 2 - 50;

  if (typeof(window_params) == 'undefined' || window_params == null)
    window_params = Limb.window.get_popup_params();

  if (window_name.toLowerCase() == '_generate')
    window_name = 'w' + Limb.md5.hex_md5(href) + 's';

  if (typeof(window.popups) != 'array')
    window.popups = new Array();

  if (typeof(window.popups[window_name]) != 'array')
    window.popups[window_name] = new Array();

  if (typeof(on_close_handler) != 'undefined')
    window.popups[window_name]['close_popup_handler'] = on_close_handler;

  if (typeof(on_init_handler) != 'undefined')
    window.popups[window_name]['init_popup_handler'] = on_init_handler;

  window.popups[window_name]['status'] = 'popped_up';

  w = window.open(LOADING_STATUS_PAGE, window_name, window_params);
  if (href != LOADING_STATUS_PAGE)
   w.location.href = href;

  if(!dont_set_focus)
    w.focus();

  return w;
}

Limb.window.process_popup = function ()
{
  href = window.location.href;

  if(window.opener)
  {
    if(Limb.http.get_query_item(href, 'reload_parent'))
      window.opener.location.reload();
    else if(window.opener.popups)
      window.opener.popups[window.name]['status'] = 'processed';
  }
}

Limb.window.open_page = function (message, href, window_name, window_params)
{
  if (typeof(window_name) == 'undefined' || window_name == null)
    window_name = '_generate';

  if (typeof(window_params) == 'undefined' || window_params == null)
    window_name = 'height=400,width=600,status=yes,toolbar=no,menubar=no,location=no,scrollbars=yes,resizable=yes';

  if (confirm(message))
    Limb.window.popup(href, window_name, window_params)
}


Limb.post_load_hooks = [];

Limb.post_load_hooks.push(
function()
{
  if(Limb.http.get_query_item(location.href, 'popup'))
    Limb.window.process_popup();
});




if (Limb == undefined) var Limb = {};
if (Limb.http == undefined) Limb.http = {};

Limb.http.get_query_item = function (page_href, item_name)
{
  arr = Limb.http.get_query_items(page_href);

  if(arr[item_name])
    return arr[item_name];
  else
    return null;
}

Limb.http.build_query = function (items)
{
  query = '';
  for(index in items)
  {
    query = query + index + '=' + items[index] + '&';
  }
  return query;
}

Limb.http.get_query_items = function (uri)
{
  query_items = new Array();

  arr = uri.split('?');
  if(!arr[1])
    return query_items;

  query = arr[1];

  arr = query.split('&');

  for(index in arr)
  {
    if(arr[index])
    {
      key_value = arr[index].split('=');
      if(!key_value[1])
        continue;

      query_items[key_value[0]] = key_value[1];
    }
  }

  return query_items;
}

Limb.http.add_url_query_item = function (uri, parameter, val)
{
  uri_pieces = uri.split('?');

  items = Limb.http.get_query_items(uri);
  items[parameter] = val;

  return uri_pieces[0] + '?' + Limb.http.build_query(items);
}

Limb.http.add_random_to_url = function (page_href)
{
  if(page_href.indexOf('?') == -1)
    page_href = page_href + '?';

  page_href = page_href.replace(/&*rn=[^&]+/g, '');

  items = page_href.split('#');

  page_href = items[0] + '&rn=' + Math.floor(Math.random()*10000);

  if(items[1])
    page_href = page_href + '#' + items[1];

  return page_href;
}

//makes window w(current if not specified) go to href address
Limb.http.jump = function (href, w)
{
  if(!w)
    w = window;

  w.location.href = LOADING_STATUS_PAGE;
  w.location.href = href;
}

//makes window w(current if not specified) reload itself with new get request
Limb.http.jump_change_get = function (get, w)
{
  href = document.location.href;
  is_get = href.indexOf('?');

  if(is_get > -1)
    href = href.substring(0, '?')//get_begin);

  Limb.http.jump(href + '?' + get, w);
}

Limb.http.click_href = function (href, window_name)
{
  is_popup = href.indexOf('popup=1');

  if(is_popup > -1)
  {
    new Limb.window(href, window_name);
  }

  return !(is_popup > -1);
}

Limb.http.goto_page = function (message, href)
{
  if (confirm(message))
    Limb.http.jump(href)
}


if (Limb == undefined) var Limb = {};
if (Limb.events == undefined) Limb.events = {};

Limb.events.add_event = function (control, type, fn, use_capture)
{
 if (control.addEventListener)
 {
   control.addEventListener(type, fn, use_capture);
   return true;
 }
 else if (control.attachEvent)
 {
   var r = control.attachEvent("on" + type, fn);
   return r;
  }
}




if (Limb == undefined) var Limb = {};
if (Limb.tabs == undefined) Limb.tabs = {};
if (Limb.tabs.containers == undefined) Limb.tabs.containers = [];


/*

=head1 NAME

DOM.Utils

=head1 DESCRIPTION

This provides a group of useful functions for use within the DOM.

=head1 DEPENDENCIES

This requires JSAN to be installed.

=cut

*/

if ( DOM == undefined ) var DOM = {};

/*
try {
    // If a jsan variable has already been defined, use that, as in the case of tests.
    if ( typeof jsan != 'undefined' )
        jsan = new JSAN();

} catch (e) {
    throw "DOM.Utils requires JSAN to be loaded";
}
*/

/*

=head1 FUNCTIONS

These are functions that are exported to the JSAN.use()er's namespace.

=head2 $()

This function will attempt, if given a string, to find an element in the DOM that corresponds to that string. If given anything else, it will return that back.

It will attempt to call the following methods, in order:

=over 4

=item * document.getElementById( arg )

=item * document.getElementsByName( arg )[0]

=item * document.getElementsByClass( arg )[0]

=item * document.getElementsByTag( arg )[0]

=back

In the case where a method returns back a collection, the first one from that collection will be chosen.

  function someFunction ( element, ... ) {
      // Guarantee that element is actually an element object
      element = $(element);
      ...
  }

=cut

*/

DOM.Utils = {
    EXPORT: [ '$' ]
   ,'$' : function () {
        var elements = new Array();

        for (var i = 0; i < arguments.length; i++) {
            var element = arguments[i];

            if (typeof element == 'string')
                element = document.getElementById(element)
                    || document.getElementsByName(element)[0]
                    || document.getElementsByClass(element)[0]
                    || document.getElementsByTagName(element)[0]
                    || undefined
                ;

            if (arguments.length == 1)
                return element;

            elements.push( element );
        }

        return elements;
    }
};

/*

=head1 ADDITIONS TO document

=head2 getElementsByClass()

This method acts as getElementsByName(), but checks against the classes vs. the name.

getElementsByClassName() is an alias that is provided for Prototype API compatibility.

=cut

*/

document.getElementsByClass = function(className) {
    var children = document.getElementsByTagName('*') || document.all;
    var elements = new Array();

    for (var i = 0; i < children.length; i++) {
        var child = children[i];
        var classNames = child.className.split(' ');
        for (var j = 0; j < classNames.length; j++) {
            if (classNames[j] == className) {
              elements.push(child);
              break;
            }
        }
    }

    return elements;
};
document.getElementsByClassName = document.getElementsByClass;

/*

=head1 SUPPORT

Currently, there is no mailing list or IRC channel. Please send bug reports and patches to the author.

=head1 AUTHOR

Rob Kinyon (rob.kinyon@iinteractive.com)

Originally written by Sam Stephenson (sam@conio.net)

My time is generously donated by Infinity Interactive, Inc. L<http://www.iinteractive.com>

=cut

*/



Limb.tabs.tab = Class.create();

Limb.tabs.tab.prototype =
{
  initialize: function (container, tab_data)
  {
    this.id = tab_data.id;
    this.container = container;
    this.label = $(tab_data.id);
    this.label.style.cursor = 'pointer'
    this.label.tab = this;
    this.content = $(tab_data.id + '_content');

    if(tab_data.src == '/') tab_data.src = '';
    this.data = tab_data;

    this.prev_height = this.content.style.height;
    this.prev_width = this.content.style.width;
    this.prev_css = this.content.cssText;

    this.onmousedown_handler = tab_data.onmousedown_handler;
    this.activate_handler = tab_data.activate_handler;
    this.deactivate_handler = tab_data.deactivate_handler;

    var hit_obj = Limb.cp.get_obj_by_id(this.label.getElementsByTagName('*') , "tab-label");
    if(!isset(hit_obj)) hit_obj = this.label

    hit_obj.tab = this
    hit_obj.onclick = function()
    {
      if(!this.tab.container.active_tab) return;

      this.tab.activate();

      if(this.tab.onclick)
        this.tab.onclick();
    }
  },

  activate: function()
  {
    if(this.container.active_tab == this)
      return;

    if(this.container.active_tab)
      this.container.active_tab.deactivate();

    this.container.active_tab = this;

    this.label.className = this.container.active_tab_class_name;

    Limb.cookie.set_multi_cookie('TABs', this.container.id + 'active_tab', this.id)

    if(this.activate_handler)
      this.activate_handler(this);
    else
    {
      if(Limb.browser.is_gecko)
      {
        if(this.content.style.visibility == 'hidden')
          this.content.style.visibility = 'visible';

        this.content.style.cssText  = this.prev_css;
        if(this.prev_height && this.prev_width)
        {
          this.content.style.height = this.prev_height;
          this.content.style.width = this.prev_width;
        }
      }
      else
      {
        this.content.style.display = 'block';
      }
    }
  },

  deactivate: function()
  {
    this.label.className = this.container.normal_tab_class_name;

    if(this.deactivate_handler)
      this.deactivate_handler(this);
    else
    {
      if(Limb.browser.is_gecko)
      {
        this.prev_height = this.content.style.height;
        this.prev_width = this.content.style.width;
        this.prev_css = this.content.style.cssText;

        this.content.style.cssText = '';
        this.content.style.height = '0';
        this.content.style.width = '0';
        this.content.style.visibility = 'hidden';
      }
      else
        this.content.style.display = 'none';
    }
  },

  contains_element: function(element_id)
  {
    if(Limb.dom.findChild(this.content, element_id) != null)
      return true;
  },

  get_label_element: function()
  {
    return this.label;
  },

  get_content_element: function()
  {
    return this.content;
  }
}

Limb.tabs.tabs_container = Class.create();

Limb.tabs.tabs_container.prototype =
{
  initialize: function (id, tab_data)
  {
     this.tab_items = []
     this.active_tab = null;
     this.id = id

    if(!tab_data) tab_data = []
    if(typeof(tab_data.active_tab_class_name) == undefined || tab_data.active_tab_class_name == null)
      tab_data.active_tab_class_name = 'tab-active';

    if(typeof(tab_data.normal_tab_class_name) == undefined || tab_data.normal_tab_class_name == null)
      tab_data.normal_tab_class_name = 'tab';

    this.active_tab_class_name = tab_data.active_tab_class_name;
    this.normal_tab_class_name = tab_data.normal_tab_class_name;

    Limb.tabs.containers.push(this);
  },

  register_tab_item: function(tab_data)
  {
    this.tab_items[tab_data.id] = new Limb.tabs.tab(this, tab_data);
  },

  activate: function(tab_id)
  {
    var active_tab_id, first_tab_id;

    for(var id in this.tab_items)
    {
      if(typeof(this.tab_items[id]) != 'object')
        continue;
      if (!first_tab_id)
        first_tab_id = id;

      if(id == tab_id)
      {
        this.tab_items[id].activate();
        active_tab_id = tab_id;
      }
      else
        this.tab_items[id].deactivate();
    }

    if (!active_tab_id)
      this.tab_items[first_tab_id].activate();
  },

  activate_default: function()
  {
    var id = Limb.cookie.get_multi_cookie('TABs', this.id + 'active_tab')
    if (id) this.activate(id);
    else
      this.activate('');
  },

  get_tabs: function()
  {
    return this.tab_items;
  }
}

Limb.tabs.find_element_tab = function(element_id)
{
  for(var i in Limb.tabs.containers)
  {
    tabs = Limb.tabs.containers[i].get_tabs();
    for(var j in tabs)
    {
      if(tabs[j].contains_element(element_id))
        return tabs[j];
    }
  }
  return null;
}

Limb.tabs.highlight_tab = function(container, tab_id)
{
  if(!container.tab_items[tab_id])
    return;

  container.tab_items[tab_id].label.className = container.active_tab_class_name;
  container.active_tab = container.tab_items[tab_id];
}

Limb.tabs.page_tabs = new Limb.tabs.tabs_container('page_tabs');

Limb.tabs.activate_page_tab = function(tab)
{
  var current_path = window.location.pathname + window.location.search;
  if (current_path != tab.data.src)
   if (last_tab_url = Limb.cookie.get_multi_cookie('TABs', tab.id + '_last_url'))
     window.location.href = last_tab_url;
   else
     window.location.href = HTTP_GATEWAY_PATH + tab.data.src;
}




if (Limb == undefined) var Limb = {};
if (Limb.form_errors == undefined) Limb.form_errors = {};

Limb.form_errors.get_label_for_field = function (id)
{
  if(document.getElementsByTagName('label').length > 0)
  {
    labels = document.getElementsByTagName('label');
    for(c=0; c<labels.length; c++)
    {
      if(labels[c].htmlFor == id)
        return labels[c].innerHTML;
    }
  }
  return null;
}

Limb.form_errors.default_form_field_error_printer = function (id, msg)
{
  obj = document.getElementById(id);
  span = document.createElement('SPAN');
  br = document.createElement('BR');
  text = document.createTextNode(msg);
  span.appendChild(text);
  span.style.color = 'red';

  obj.parentNode.insertBefore(span, obj);
  obj.parentNode.insertBefore(br, obj);
  obj.style.borderColor = 'red';
  obj.style.borderStyle = 'solid';
  obj.style.borderWidth = '1px';
}

Limb.form_errors.default_form_field_error_label_printer = function (id, msg)
{
  var span = null;
  var i = 0;
  do
  {
    span = document.getElementById("label_for_" + id + "_" + i);
  }
  while(span && span.firstChild);

  if(!span) return;

  label = Limb.form_errors.get_label_for_field(id);

  //dirty workaround for non-labelled fields
  if(!label) label = id;

  newa = document.createElement('a');
  newa.appendChild(document.createTextNode(label));
  newa.href = '#'+id;
  newa.isid = id;
  newa.onclick = function()
  {
    try
    {
      if(tab = Limb.tabs.find_element_tab(this.isid))
        tab.activate();

      if(e = document.getElementById(this.isid))
        e.focus();
    }
    catch(ex){}

    return false;
  }

  var content = span.firstChild
  span.insertBefore(newa, content);
  if(content)
  {
    span.insertBefore(document.createTextNode(' ('), content);
    span.appendChild(document.createTextNode(')'), content);
  }
}

Limb.form_errors.set_form_field_error = function (id, msg)
{
  obj = document.getElementById(id);
  if(!obj) return;

  if(typeof(Limb.form_errors.form_field_error_printer) == "function")
    Limb.form_errors.form_field_error_printer(id, msg);
  else
    Limb.form_errors.default_form_field_error_printer(id, msg);

  if(typeof(Limb.form_errors.form_field_error_label_printer) == "function")
    Limb.form_errors.form_field_error_label_printer(id, msg);
  else
    Limb.form_errors.default_form_field_error_label_printer(id, msg);
}

Limb.form_errors.check_form_errors = function ()
{
  //someday client validation will be here
  return true;
}


if (Limb == undefined) var Limb = {};
if (Limb.forms == undefined) Limb.forms = {};

Limb.forms.change_form_action = function (form, action)
{
  if(!form)
    return;

  form.action = action;
}

Limb.forms.add_form_action_parameter = function (form, parameter, val)
{
  if(!form)
    return;

  form.action = Limb.http.add_url_query_item(form.action + '', parameter, val);
}

Limb.forms.add_form_hidden_parameter = function (form, parameter, val)
{
  if(!form)
    return;

  hidden = document.getElementById(parameter + '_hidden_parameter');
  if(hidden)
  {
    hidden.value = val;
    form.appendChild(hidden);
  }
  else
  {
    hidden = document.createElement('INPUT');
    hidden.id = parameter + '_hidden_parameter';
    hidden.type = 'hidden';
    hidden.name = parameter;
    hidden.value = val;
    form.appendChild(hidden);
  }
}

Limb.forms.submit_form = function (form, form_action)
{
  is_popup = form_action.indexOf('popup=1');
  if(is_popup > -1)
  {
    window_name = 'w' + Limb.md5.hex_md5(form_action) + 's';
    w = Limb.window.popup(LOADING_STATUS_PAGE, window_name);
    form.target = w.name;
  }

  if(form_action)
    form.action = form_action;

  form.submit();
}

Limb.forms.get_grid_form_action = function (selector_id)
{
  menu = document.getElementById(selector_id);
  action = menu.options[menu.selectedIndex].value;
  return action;
}

Limb.forms.process_action_control = function (droplist)
{
  if (typeof(droplist.value) != 'undefined')
    value = droplist.value;
  else
    value = droplist[0].value;

  Limb.forms.submit_form(droplist.form, value);
}

Limb.forms.sync_action_controls = function (obj)
{
  col = obj.form.elements[obj.name];
  if (typeof(col.length) != 'undefined' && col.length>0)
    for(i=0; i<col.length; i++)
    {
      col(i).selectedIndex = obj.selectedIndex;
    }
}

Limb.forms.transfer_value = function (target_id, transfer_value)
{
  obj = document.getElementById(target_id);
  if(obj)
  {
    obj.value = transfer_value;
  }
}

Limb.forms.transfer_img_src = function (target_id, transfer_src)
{
  obj = document.getElementById(target_id);
  if(obj)
  {
    obj.src = transfer_src;
  }
}

Limb.forms.bulk_options = function (start, end, selected, options_attrs)
{
  options = '';
  for(i = start; i <= end; i++)
    if (i == selected) options += '<option value=' + i + ' selected ' + options_attrs + '>'+i;
      else options += '<option value=' + i + ' ' + options_attrs + '>'+i;
  document.write(options)
}


if (Limb == undefined) var Limb = {};
if (Limb.cookie == undefined) Limb.cookie = {};

Limb.cookie.set_multi_cookie = function (cookiename, id, val)
{
  var cookie = "";
  cookie = Limb.cookie.get_cookie(cookiename);

  found = 0;
  newcookie = Array();

  if(cookie!=null)
  {
    cookies = cookie.split("_DIV_");
    for(i=0;i<cookies.length;i++)
    {
      c = cookies[i];
      cc = c.split("_EQ_");
      if(cc[0]==id)
      {
        c = id+'_EQ_'+val;
        found=1;
      }
      newcookie[i]=c;
    }
  }
  if(!found)
  {
    if(newcookie.length==0)
      newcookie[0] = id+'_EQ_'+val;
    else
      newcookie[i] = id+'_EQ_'+val;
  }

  newcookie = newcookie.join("_DIV_");
  Limb.cookie.set_cookie(cookiename,newcookie)//,expires,COOKIE_PATH, COOKIE_DOMAIN);
}

Limb.cookie.get_multi_cookie = function (cookiename,id)
{
  var cookie = "";
  cookie = Limb.cookie.get_cookie(cookiename);
  if(cookie==''||cookie==null)
    return;

  var found = 0;

  cookies = cookie.split("_DIV_");

  for(i=0;i<cookies.length;i++)
  {
     cc = cookies[i].split("_EQ_");

    if(cc[0] == id)
    {
      found = 1;
      break;
    }
  }
  if(!found) return;
  return cc[1];
}

Limb.cookie.get_cookie = function (name)
{
  var a_cookie = document.cookie.split("; ");
  for (var i=0; i < a_cookie.length; i++)
  {
    var a_crumb = a_cookie[i].split("=");
    if (name == a_crumb[0])
      return unescape(a_crumb[1]);
  }
  return null;
}

Limb.cookie.set_cookie = function (name, value, path, expires)
{
  path_str = (path) ? '; path=' + path : '; path=/';
  expires_str = (expires) ? '; expires=' + expires : '';

  cookie_str = name + '=' + value + path_str + expires_str;

  document.cookie = cookie_str;
}

Limb.cookie.remove_cookie = function (name, path)
{
  Limb.cookie.set_cookie(name, 0, path, '1/1/1980');
}

Limb.cookie.add_cookie_element = function (cookie_name, element)
{
  cookie_elements = Limb.cookie.get_cookie(cookie_name);
  if (cookie_elements == null || cookie_elements == 'undefined')
    cookie_elements_array = new Array();
  else
    cookie_elements_array = cookie_elements.split(',');
  present = 0;
  for(i=0; i<cookie_elements_array.length; i++)
  {
    if (cookie_elements_array[i] == element)
    {
      present = 1;
      break;
    }
  }
  if (!present)
  {
    cookie_elements_array.push(element);
    new_cookie_elements = cookie_elements_array.join(',');
    Limb.cookie.set_cookie(cookie_name, new_cookie_elements);
  }
}

Limb.cookie.remove_cookie_element = function (cookie_name, element)
{
  cookie_elements = Limb.cookie.get_cookie(cookie_name);
  if (cookie_elements == null || cookie_elements == 'undefined')
    cookie_elements_array = new Array();
  else
    cookie_elements_array = cookie_elements.split(',');
  new_cookie_elements_array = new Array();
  present = 0;
  for(i=0; i<cookie_elements_array.length; i++)
  {
    if (cookie_elements_array[i] != element)
      new_cookie_elements_array.push(cookie_elements_array[i]);
    else
      present = 1;
  }
  if (present)
  {
    new_cookie_elements = new_cookie_elements_array.join(',');
    Limb.cookie.set_cookie(cookie_name, new_cookie_elements);
  }
}


if (Limb == undefined) var Limb = {};
if (Limb.dom == undefined) Limb.dom = {};

Limb.dom.containsDOM  = function (container, containee)
{
  var isParent = false;
  do {
    if ((isParent = container == containee))
      break;
    containee = containee.parentNode;
  }
  while (containee != null);
  return isParent;
}

Limb.dom.findChild = function(node, id)
{
  if(node.id == id) return node;

  if(!node.hasChildNodes()) return null;

  result = null;

  for(var i = 0; (i < node.childNodes.length && !result); i++)
    result = Limb.dom.findChild(node.childNodes[i], id);

  return result;
}

//shouldn't be here???
Limb.dom.checkMouseEnter  = function (element, evt)
{
  if (element.contains && evt.fromElement)
    return !element.contains(evt.fromElement);
  else if (evt.relatedTarget)
    return !Limb.dom.containsDOM(element, evt.relatedTarget);
}

//shouldn't be here???
Limb.dom.checkMouseLeave  = function (element, evt)
{
  if (element.contains && evt.toElement)
    return !element.contains(evt.toElement);
  else if (evt.relatedTarget)
    return !Limb.dom.containsDOM(element, evt.relatedTarget);
}



if (Limb == undefined) var Limb = {};
if (Limb.security == undefined) Limb.security = {};

Limb.security.scramble = function (str, offset)
{
  if (!offset)
    offset = 1;

  var r = '';
  for(var i=0;i<str.split('').length;i++)
    r += String.fromCharCode(str.split('')[i].charCodeAt(0) + offset);
  return r
}


if (Limb == undefined) var Limb = {};
if (Limb.string == undefined) Limb.string = {};

String.prototype.trim = function(){
     var r=/^\s+|\s+$/;
     return this.replace(r,'');
}

Limb.string.trim = function (str)
{
  var r=/^\s+|\s+$/;
  return str.replace(r,'');
}


if (Limb == undefined) var Limb = {};
if (Limb.rollover == undefined) Limb.rollover = {};

Limb.rollover.rollover_preload_images = function ()
{
  var d = document;
  if(d.images)
  {
    if(!d.rollover_p)
      d.rollover_p = new Array();
    var i,j = d.rollover_p.length, a = Limb.rollover.rollover_preload_images.arguments;

    for(i=0; i<a.length; i++)
      if (a[i].indexOf("#")!=0)
      {
        d.rollover_p[j] = new Image;
        d.rollover_p[j++].src = a[i];
      }
  }
}

Limb.rollover.rollover_swap_restore = function ()
{
  var i,x,a = document.rollover_sr;
  for(i=0; a && i<a.length && (x=a[i]) && x.oSrc;i++)
    x.src = x.oSrc;
}

Limb.rollover.rollover_find_obj = function (n, d)
{
  var p,i,x;  if(!d) d=document;
  if((p=n.indexOf("?"))>0&&parent.frames.length)
  {
    d = parent.frames[n.substring(p+1)].document;
    n = n.substring(0,p);
  }

  if(!(x=d[n])&&d.all)
    x = d.all[n];

  for (i=0;!x&&i<d.forms.length;i++)
    x = d.forms[i][n];

  for(i=0;!x&&d.layers&&i<d.layers.length;i++)
    x = Limb.rollover.rollover_find_obj(n,d.layers[i].document);

  if(!x && d.getElementById)
    x = d.getElementById(n);

  return x;
}

Limb.rollover.rollover_swap = function ()
{
  var i,j=0,x,a = Limb.rollover.rollover_swap.arguments;

  document.rollover_sr=new Array;

  for(i=0;i<(a.length-2);i+=3)
   if ((x=rollover_find_obj(a[i]))!=null)
   {
    document.rollover_sr[j++] = x;
    if(!x.oSrc)
      x.oSrc = x.src;
    x.src=a[i+2];
   }
}



