/**
 * Filename    : Array.js
 * Author      : Robert Cerny
 * Created     : 2006-07-26
 * Last Change : 2009-10-15
 *
 * Description:
 *   Some useful methods for the Array prototype.
 *
 * History:
 *   2009-10-15 Added same (like equals, but order is insignificant).
 *   2009-08-01 Modified sortedInsert to return the position.
 *   2009-08-01 Modified getInsertionIndex to handle empty arrays better.
 *   2008-09-26 Performance improvements on many methods.
 *   2008-09-25 Added pushUnique.
 *   2008-08-12 Added unique, removeAll.
 *   2008-01-21 Added intersect and overlaps.
 *   2007-12-08 Fixed boundaries bug in insertAt.
 *   2007-11-20 Removed the check for function of parameter cmpFunc in indexOf.
 *   2007-08-16 Removed returns the index of the item that is removed.
 *   2007-08-14 Added sortedInsert.
 *   2007-08-10 Added insertAt.
 *   2007-06-27 Added equals.
 *   2007-06-19 Corrected signature of contains.
 *   2007-05-17 Using short names for method and signature.
 *   2007-05-09 Modified append to accept null and undefined.
 *   2007-05-03 Refactored.
 *   2007-03-15 Added signatures.
 *   2007-01-06 Added interception.
 *   2006-12-09 Fixed bug in contains.
 *   2006-12-08 Fixed bug in append.
 *   2006-07-26 Created.
 */

CERNY.require("CERNY.js.Array");

(function() {

    var check = CERNY.check;
    var method = CERNY.method;
    var pre = CERNY.pre;
    var signature = CERNY.signature;

    CERNY.js.Array = {};

    Array.prototype.logger = CERNY.Logger("CERNY.js.Array");

    /**
     * Map an array onto another array based on func.
     *
     * func - the function that should be applied to all elements of this
     *        array
     * return - an array of the results of the applications of func to the
     *          items of this array
     */
    function map(func) {
        var result = [];
        for (var i = 0, l = this.length; i < l; i++) {
            result.push(func(this[i]));
        }
        return result;
    };
    signature(map, Array, "function");
    method(Array.prototype, "map", map);

    /**
     * Append array to this array.
     *
     * array - the array to append
     */
    function append(array) {
        if (array) {
            for (var i = 0, l = array.length; i < l; i++) {
                this.push(array[i]);
            }
        }
    };
    signature(append, "undefined", ["null", "undefined", Array]);
    method(Array.prototype, "append", append);

    if (!Array.prototype.push) {
        Array.prototype.push = function() {
            for (var i = 0; i < arguments.length; i++) {
                this[this.length] = arguments[i];
            }
            return this.length;
        };
    }

    /**
     * Filter this array through predicate.
     *
     * predicate - the predicate to apply to all items of array
     * return - a new array containing all items that return true on application of predicate
     */
    function filter(predicate) {
        var result = [],
            i = this.length,
            item;
        while (i--) {
            item = this[i];
            if (predicate(item)) {
                result.unshift(item);
            }
        }
        return result;
    };
    signature(filter, Array, "function");
    method(Array.prototype, "filter", filter);

    /**
     * Copy this array.
     *
     * return - a copy of this array
     */
    function copy() {
        return this.filter(function() {return true; });
    };
    signature(copy, Array);
    method(Array.prototype, "copy", copy);

    /**
     * Figure out the index of item in array based on cmpFunc.
     *
     * item - the item to look for in this array
     * cmpFunc - the function to use to decide on identity
     * return - the index of the position of item in this array or -1, if
     *          item is not in this array.
     */
    function indexOf(item, cmpFunc) {
        if (!cmpFunc) {
            cmpFunc = function (a, b) { return a == b; };
        }
        var i = this.length;
        while (i--) {
            if (cmpFunc(this[i], item)) {
                return i;
            }
        }
        return -1;
    };
    signature(indexOf, "number", "any", ["undefined", "function"]);
    method(Array.prototype, "indexOf", indexOf);

    /**
     * Figure out whether item is contained in this array.
     *
     * item - the item to look for in this array
     * cmpFunc - the function to use to decide on identity
     * return - true if x is in this array, false otherwise
     */
    function contains(item, cmpFunc) {
        return this.indexOf(item, cmpFunc) >= 0;
    }
    signature(contains, "boolean", "any", ["undefined", "function"]);
    method(Array.prototype, "contains", contains);

    /**
     * Remove item from this array.
     *
     * item - the item to remove
     * cmpFunc - the function to use to decide on identity
     * return - the index of the position the item was located
     */
    function remove(item, cmpFunc) {
        var i = this.indexOf(item, cmpFunc);
        if (i >= 0 ) {
            this.splice(i,1);
        }
        return i;
    };
    signature(remove, "number", "any", ["undefined", "function"]);
    method(Array.prototype, "remove", remove);

    /**
     * Replace an item in an array.
     *
     * replaced - the item to be replaced
     * replacing - the item to take the position of the replaced
     * cmpFunc - the function to use to decide on identity
     */
    function replace(replaced, replacing, cmpFunc) {
        var i = this.indexOf(replaced, cmpFunc);
        if (i < 0) {
            this.push(replacing);
        } else {
            this.splice(i, 1, replacing);
        }
    };
    signature(replace, "undefined", "any", "any", ["undefined", "function"]);
    method(Array.prototype, "replace", replace);

    /**
     * Figure out whether array is a sub array of this array based on
     * cmpFunc. Order is insignificant.
     *
     * array - the array that is checked whether it's a sub array
     * cmpFunc - the function to use to decide on identity
     * return - true, if there is no item in array that is not in this
     *          array, false otherwise
     */
    function isSubArray(array, cmpFunc) {
        for (var i = 0, l = this.length; i < l; i++) {
            if (array.indexOf(this[i], cmpFunc) < 0) {
                return false;
            }
        }
        return true;
    };
    signature(isSubArray, "boolean", Array, ["undefined", "function"]);
    method(Array.prototype, "isSubArray", isSubArray);

    /**
     * Figure out whether two arrays are equal based on cmpFunc. Order
     * is significant.
     *
     * array - the array to compare this array with
     * cmpFunc - the function to use to decide on identity
     * return - true, if this array is equal to to array, otherwise false
     */
    function equals(array, cmpFunc) {
        if (this.length != array.length) {
            return false;
        }
        for (var i = 0, l = this.length; i < l; i++) {
            if (array.indexOf(this[i], cmpFunc) != i) {
                return false;
            }
        }
        return true;
    }
    signature(equals, "boolean", Array, ["undefined", "function"]);
    method(Array.prototype, "equals", equals);

    /**
     * Return true if two arrays are the same based on cmpFunc. Order
     * is insignificant.
     *
     * array - the array to compare this array with
     * cmpFunc - the function to use to decide on identity
     * return - true, if this array is the same as array, otherwise false
     */
    function same(array, cmpFunc) {
        if (this.length != array.length) {
            return false;
        }
        return this.isSubArray(array, cmpFunc) && array.isSubArray(this, cmpFunc);
    }
    signature(same, "boolean", Array, ["undefined", "function"]);
    method(Array.prototype, "same", same);

    /**
     * Returns an array containing all items that this array has in
     * common with array.
     *
     * array - the array to intersect this array with
     * cmpFunc - the function to use to decide on identity of items
     * return - the intersection of this array and array
     */
    function intersect(array, cmpFunc) {
        return this.filter(function(item) {
            return array.contains(item, cmpFunc);
        });
    }
    signature(intersect, Array, Array, ["undefined", "function"]);
    method(Array.prototype, "intersect", intersect);

    /**
     * Determine whether this array overlaps array.
     *
     * array - the array to overlap this array with
     * cmpFunc - the function to use to decide on identity of items
     * return - true if this array has at least one item in common with array, otherwise false
     */
    function overlaps(array, cmpFunc) {
        return this.intersect(array, cmpFunc).length > 0;
    }
    signature(overlaps, "boolean", Array, ["undefined", "function"]);
    method(Array.prototype, "overlaps", overlaps);

    /**
     * Insert an item at a certain position in the array.
     *
     * index - the index of the position to insert the item at
     * item - the item to insert
     */
    function insertAt(index, item) {

        // Calculate the number of items that have to move.
        var moverCount = this.length - index;

        // Is the index within the current boundaries?
        if (moverCount > 0) {

            // Yes, splice the number of items to move, insert the new
            // one and append the movers.
            this.append(this.splice(index, moverCount, item));
        } else {

            // No, just put it there.
            this[index] = item;
        }
    }
    signature(insertAt, "undefined", "number", "any");
    method(Array.prototype, "insertAt", insertAt);
    pre(insertAt, function(index, item) {
        check(index >= 0, "index must be bigger than or equal to 0.");
    });

    /**
     * Gets the insertion index of an item into this array, depending on the
     * passed comperator.
     *
     * item - the item to insert
     * comperator - the comperator to use for compare items with
     *
     */
    function getInsertionIndex(item, comperator) {
        var i = 0;
        var l = this.length;
        while (i < l && comperator(this[i], item) < 1) {
            i += 1;
        }
        return i;
    }
    signature(getInsertionIndex, "number", "any", "function");
    method(Array.prototype, "getInsertionIndex", getInsertionIndex);

    /**
     * Performs an insert of an item into this array, depending on the
     * comperator.
     *
     * item - the item to insert
     * comperator - the comperator to use for compare items with
     */
    function sortedInsert(item, comperator) {
        var position = this.getInsertionIndex(item, comperator);
        this.insertAt(position, item);
        return position;

    }
    signature(sortedInsert, "number", "any", "function");
    method(Array.prototype, "sortedInsert", sortedInsert);

    /**
     * Creates a new array holding all items which occurr in this
     * array, but only once.
     *
     * cmpFunc - the function to use to decide on identity
     * return - an array without duplicates
     */
    function unique(cmpFunc) {
        var result = [],
            item,
            i = this.length;

        while (i--) {
            item = this[i];
            if (!result.contains(item, cmpFunc)) {
                result.unshift(item);
            }

        }
        return result;
    }
    signature(unique, Array, ["function", "undefined"]);
    method(Array.prototype, "unique", unique);

    /**
     * Pushes item onto this array, but only if item is not already
     * contained in the array.
     *
     * item - the item to push onto the array
     * cmpFunc - the function to use to decide on identity
     * return true, if the item was pushed, false, otherwise
     */
    function pushUnique(item, cmpFunc) {
        if (!this.contains(item, cmpFunc)) {
            this.push(item);
            return true;
        }
        return false;
    }
    signature(pushUnique, "boolean", "any", ["function", "undefined"]);
    method(Array.prototype, "pushUnique", pushUnique);

    /**
     * Remove all items from this array.
     */
    function removeAll() {
        var i = this.length;
        while (i--) {
            this.pop();
        }
    }
    signature(removeAll, "undefined");
    method(Array.prototype, "removeAll", removeAll);

}) ();
/**
 * Filename    : String.js
 * Author      : Robert Cerny
 * Created     : 2004-10-27
 * Last Change : 2007-05-17
 *
 * Description:
 *   Adds some useful methods for the String prototype.
 *
 * History:
 *   2007-05-17 Using short names for method and signature.
 *   2007-05-03 Refactored.
 *   2007-03-15 Added signatures.
 *   2007-01-06 Added interception.
 *   2007-01-05 Fixed bug in require statement.
 *   2004-10-27 Created.
 */

CERNY.require("CERNY.js.String");

(function() {

    var method = CERNY.method;
    var signature = CERNY.signature;

    CERNY.js.String = {};

    String.prototype.logger = CERNY.Logger("CERNY.js.String");

    function entityify() {
        return this.replace(/&/g, "&amp;").replace(/</g,"&lt;").replace(/>/g, "&gt;");
    }
    signature(entityify, "string");
    method(String.prototype, "entityify", entityify);

    function trim() {
        return this.replace(/^\s*(\S*(\s+\S+)*)\s*$/, "$1");
    }
    signature(trim, "string");
    method(String.prototype, "trim", trim);

    /**
     * Pad a string.
     *
     * padChr - the character which should be used for padding
     * length - how many characters should the string have after padding
     * front - if true, padding is added before the string
     * return - the padded string
     */
    function pad(padChr, length, front) {
        padChr = padChr.substring(0,1);
        if (!isBoolean(front)) {
            front = true;
        }
        var padSize = length - this.length;
        if (padSize > 0) {
            var padStr = "";
            for (var i = 0; i < padSize; i++) {
                padStr += padChr;
            }
            if (front) {
                return padStr + this;
            }
            return this + padStr;
        }
        return "" + this;
    }
    signature(pad, "string", "string", "number", ["undefined", "boolean"]);
    method(String.prototype, "pad", pad);

})();

function isNonEmptyString(s) {
    return !isNull(s) && isString(s) && s.trim().length > 0;
}
/**
 * Filename    : util.js
 * Author      : Robert Cerny
 * Created     : 2006-11-12
 * Last Change : 2009-09-11
 *
 * Description:
 *   Some general purpose utility functions.
 *
 * History:
 *   2009-09-11 Added escapeHtml.
 *   2008-05-10 Added getUriParameters. Made getUriParameterValue work with multiple occurrences.
 *   2007-06-15 Added compare, createComparator.
 *   2007-05-17 Refactored.
 *   2007-04-30 Added getUriParameterValue.
 *   2007-03-20 Corrected signature of CERNY.util.indent.
 *   2007-03-15 Added signatures.
 *   2007-02-23 Fixed bug in CERNY.parseUri (Result of "dev/".split(/\//) differs in IE and Firefox).
 *   2007-02-23 Added logger to CERNY.util.
 *   2007-02-19 Added getNameFromFqName.
 *   2007-02-09 Added parseUri.
 *   2006-11-12 Created.
 *
 */

CERNY.namespace("util");

CERNY.require("CERNY.util",
              "CERNY.js.Array",
              "CERNY.js.String");

(function() {

    var method = CERNY.method;
    var signature = CERNY.signature;

    var logger = CERNY.Logger("CERNY.util");
    CERNY.util.logger = logger;

    /**
     * Create an indentation string, a line feed followed by n spaces,
     * where n = indentation.
     *
     * indentation - the number of spaces to append to the line feed
     * return - a string
     */
    function indent(indentation) {
        var result = "\n";
        for (var i = 0; i < indentation; i++) {
            result += " ";
        }
        return result;
    };
    method(CERNY.util, "indent", indent);
    signature(indent, "string", "number");

    /**
     * Return (at least) two digit number as a String. If number smaller
     * than 10 return "0" + number.
     *
     * number - the number to fill
     * return - the filled number
     */
    function fillNumber(number) {
        var str = number.toString();
        return str.pad("0", 2);
    };
    method(CERNY.util, "fillNumber", fillNumber);
    signature(fillNumber, "string", "number");


    /**
     * Return the last n digits from the decimal String representation
     * of number.
     *
     * number - the number to get the digits from
     * n - how many digits to get
     * return - the last n digits
     */
    function cutNumber(number, size) {
        var str = "" + number.toString();
        return str.slice(str.length - size, str.length);
    };
    method(CERNY.util, "cutNumber", cutNumber);
    signature(cutNumber, "string", "number", "number");


    function escapeStrForRegexp(str) {
        if (str == ".") {
            return '\\' + str;
        }
        return str;
    };
    method(CERNY.util, "escapeStrForRegexp", escapeStrForRegexp);
    signature(escapeStrForRegexp, "string", "string");

    /**
     * Parses an URI into its components.
     *
     * Right now it cannot handle:
     *    "mailto:mduerst@ifi.unizh.ch"
     *    "news:comp.infosystems.www.servers.unix"
     *
     * uri - the uri to parse
     * return - an object containing the parts of the uri
     */
    function parseUri(uri) {

        // This regular expression is defined in RFC 2396 Appendix
        // B. Every slash in the original regexp was escaped by a
        // backslash. Furthermore it was surrounded by slash.
        var r = new RegExp(/^(([^:\/?#]+):)?(\/\/([^\/?#]*))?([^?#]*)(\?([^#]*))?(#(.*))?/);
        var m = r.exec(uri);

        var ensure = function (_str) {
            return _str != null ? _str : "";
        }

        var i = {};
        i.scheme = ensure(m[2]);
        i.authority = ensure(m[4]);
        i.path = ensure(m[5]);
        i.query = ensure(m[7]);
        i.fragment = ensure(m[9]);

        // The authority
        var ra = new RegExp(/^(([^@]+)@)?([^:]+)(:([0-9]*))?/);
        var ma = ra.exec(i.authority);

        if (ma) {
            i.userinfo = ensure(ma[2]);
            i.host = ensure(ma[3]);
            i.port = ensure(ma[5]);
        }

        // The path segments
        i.path_segments = i.path.replace(/^\//, "").split("/");

        return i;
    };
    method(CERNY.util, "parseUri", parseUri);
    signature(parseUri, "object", "string");


    /**
     * Return the short name from a fully qualified name.
     *
     * fqName - the fully qualified name
     * return - the short name
     */
    function getNameFromFqName(fqName) {
        var lastSegment = fqName.split("\.").pop();
        if (lastSegment.indexOf("_") >= 0) {
            lastSegment = lastSegment.split("_").pop();
        }
        return lastSegment;
    }
    method(CERNY.util, "getNameFromFqName", getNameFromFqName);
    signature(getNameFromFqName, "string", "string");


    /**
     * Return an object which maps the parameter onto its value. Since
     * a parameter can occurr more than once, the value is an array of
     * strings.
     *
     * uri - the uri to get the parameters for, if undefined the uri
     *       of the current document
     * return - an object with the parameters
     */
    function getUriParameters(uri) {
        if (!uri) {
            uri = document.URL;
        }

        var result = {};

        var query = parseUri(uri).query;
        var parts = query.split("&");
        parts.map(function(part) {
                var array = part.split("=");
                var parameter = array[0];
                var value = array[1];
                var current = result[parameter];
                if (current) {
                    current.push(value);
                } else {
                    result[parameter] = [decodeURIComponent(value)];
                }
        });
        return result;
    }
    method(CERNY.util, "getUriParameters", getUriParameters);
    signature(getUriParameters, "object", ["string", "undefined"]);

    /**
     * Return the value of a parameter passed in the query part of an URL.
     *
     * parameter - the name of the parameter
     * url - the url to look in, if undefined the url of the current document
     * return - the value as a string or an array of strings
     */
    function getUriParameterValue(parameter, uri) {
        if (!uri) {
            uri = document.URL;
        }

        var parameters = getUriParameters(uri);
        var value = parameters[parameter];

        // Keep the interface as it was
        if (!value) {
            value = null;
        } else {
            if (value.length == 1) {
                value = value[0];
            }
        }

        return value;
    }
    method(CERNY.util, "getUriParameterValue", getUriParameterValue);
    signature(getUriParameterValue, ["null","string", Array], ["string"], ["string", "undefined"]);


    /*
     * Returns -1, if a is smaller than b.
     * Returns 0, if a is equal to b.
     * Returns 1, if a is bigger than b.
     */
    function compare(a, b) {
        if (a == b) return 0;
        if (a > b) return 1;
        return -1;
    }
    method(CERNY.util, "compare", compare);
    signature(compare, "number", "any", "any");

    /**
     * Create a compare function, that allows sorting according to an
     * arbitrary order.
     *
     * order - the arbitrary order, an array of numbers
     * compare - the compare function, default is natural order
     * return - the comparator
     */
    function createComparator(order, compare) {

        if (!compare) {
            compare = CERNY.util.compare;
        }

        return function(a, b) {
            var indexA = order.indexOf(a);
            var indexB = order.indexOf(b);
            if (indexA < 0) {
                if (indexB < 0) {
                    return compare(a, b);
                }
                return 1;
            }
            if (indexB < 0) {
                return -1;
            }
            return compare(indexA, indexB);
        }
    }
    method(CERNY.util, "createComparator", createComparator);
    signature(createComparator, "function", Array, ["undefined", "function"]);

    /**
     * Escape the characters LESS_THAN, GREATER_THAN, and AMPERSAND by
     * their HTML encodings.
     *
     * str - the string to be escaped
     * return - the escaped string
     */
    function escapeHtml(str) {
        return str.split("&").join("&amp;").split( "<").join("&lt;").split(">").join("&gt;");
    }
    method(CERNY.util, "escapeHtml", escapeHtml);
    signature(escapeHtml, "string", "string");

})();
/**
 * Filename    : DateFormat.js
 * Author      : Robert Cerny
 * Created     : 2006-07-02
 * Last Change : 2009-06-24
 *
 * Description:
 *   This script provides a constructor to produce date formats. The
 *   constructor has attached some popular date formats.
 *
 * History:
 *   2007-10-22 Added ISO1.
 *   2007-05-17 Refactored.
 *   2007-03-15 Added signatures.
 *   2007-03-09 Removed the new in the DataFormat creations.
 *   2006-07-02 Created.
 */

CERNY.require("CERNY.text.DateFormat",
              "CERNY.util");

(function() {

    var cutNumber = CERNY.util.cutNumber;
    var fillNumber = CERNY.util.fillNumber;
    var identity = CERNY.identity;
    var signature = CERNY.signature;

    CERNY.text.DateFormat = DateFormat;

    /**
     * Create a date format.
     *
     * regexp - the regular expression defining the date format
     * return - an object representing the date format
     */
    function DateFormat(regexp) {
        var self = CERNY.object();
        self.regexp = regexp;
        self.separator = "";
        self.positions = {day: 1,
                          month: 2,
                          year: 3};
        self.formatters =  {day: identity,
                            month: identity,
                            year: identity};
        self.century = 20;
        return self;
    };
    signature(DateFormat, "object", RegExp);

    function cutLast2(x) {
        return cutNumber(x, 2);
    };

    var formatters1 = {day: fillNumber, month: fillNumber, year: identity};
    var formatters2 = {day: fillNumber, month: fillNumber, year: cutLast2};
    var formatters3 = {day: identity, month: identity, year: cutLast2};

    // Germany

    // 15.07.2006
    DateFormat.DE = DateFormat(/(\d\d)\.(\d\d)\.(\d\d\d\d)/);
    DateFormat.DE.separator = ".";
    DateFormat.DE.formatters = formatters1;

    // 15.07.06
    DateFormat.DE1 = DateFormat(/(\d\d).(\d\d).(\d\d)/);
    DateFormat.DE1.separator = ".";
    DateFormat.DE1.formatters = formatters2;

    // 15072006
    DateFormat.DE2 = DateFormat(/(\d\d)(\d\d)(\d\d\d\d)/);
    DateFormat.DE2.formatters = formatters1;

    // 150706
    DateFormat.DE3 = DateFormat(/(\d\d)(\d\d)(\d\d)/);
    DateFormat.DE3.formatters = formatters2;

    // 15.7.2006
    DateFormat.DE4 = DateFormat(/(\d\d?)\.(\d\d?)\.(\d\d\d\d)/);
    DateFormat.DE4.separator = ".";

    // 15.7.06
    DateFormat.DE5 = DateFormat(/(\d\d?)\.(\d\d?)\.(\d\d)/);
    DateFormat.DE5.separator = ".";
    DateFormat.DE5.formatters = formatters3;

    // USA

    var positionsUS = {month: 1, day: 2, year: 3};

    // 07/15/2006
    DateFormat.US = DateFormat(/(\d\d)\/(\d\d)\/(\d\d\d\d)/);
    DateFormat.US.separator = "/";
    DateFormat.US.positions = positionsUS;
    DateFormat.US.formatters = formatters1;

    // 07/15/06
    DateFormat.US1 = DateFormat(/(\d\d)\/(\d\d)\/(\d\d)/);
    DateFormat.US1.separator = "/";
    DateFormat.US1.positions = positionsUS;
    DateFormat.US1.formatters = formatters2;

    // 07152006
    DateFormat.US2 = DateFormat(/(\d\d)(\d\d)(\d\d\d\d)/);
    DateFormat.US2.positions = positionsUS;
    DateFormat.US2.formatters = formatters1;

    // 071506
    DateFormat.US3 = DateFormat(/(\d\d)(\d\d)(\d\d)/);
    DateFormat.US3.positions = positionsUS;
    DateFormat.US3.formatters = formatters2;

    // 7/15/2006
    DateFormat.US4 = DateFormat(/(\d\d?)\/(\d\d?)\/(\d\d\d\d)/);
    DateFormat.US4.separator = "/";
    DateFormat.US4.positions = positionsUS;

    // 7/15/06
    DateFormat.US5 = DateFormat(/(\d\d?)\/(\d\d?)\/(\d\d)/);
    DateFormat.US5.separator = "/";
    DateFormat.US5.positions = positionsUS;
    DateFormat.US5.formatters = formatters3;

    // ISO
    var positionsISO = {year: 1, month: 2, day: 3 };

    // 2006-07-15 (ISO extended)
    DateFormat.ISO = DateFormat(/(\d\d\d\d)-(\d\d)-(\d\d)/);
    DateFormat.ISO.separator = "-";
    DateFormat.ISO.positions = positionsISO;
    DateFormat.ISO.formatters = formatters1;

    // 20060715 (ISO basic)
    DateFormat.ISO1 = DateFormat(/(\d\d\d\d)(\d\d)(\d\d)/);
    DateFormat.ISO1.positions = positionsISO;
    DateFormat.ISO1.formatters = formatters1;

    // France, http://en.wikipedia.org/wiki/Date_and_time_notation_by_country#France
    var positionsFrance = {day: 1, month: 2, year: 3};

    // 24/06/2009
    DateFormat.FR = DateFormat(/(\d\d)\/(\d\d)\/(\d\d\d\d)/);
    DateFormat.FR.separator = "/";
    DateFormat.FR.positions = positionsFrance;
    DateFormat.FR.formatters = formatters1;

    // 07/15/06
    DateFormat.FR1 = DateFormat(/(\d\d)\/(\d\d)\/(\d\d)/);
    DateFormat.FR1.separator = "/";
    DateFormat.FR1.positions = positionsFrance;
    DateFormat.FR1.formatters = formatters2;


})();
/**
 * Filename    : Date.js
 * Author      : Robert Cerny
 * Created     : 2006-07-02
 * Last Change : 2008-08-03
 *
 * Description:
 *   Some useful methods for the Date prototype providing date
 *   formatting and parsing.
 *
 * History:
 *   2008-08-01 Added an optional parameter timezone format to formatDate.
 *   2008-08-01 Added many methods related to parsing and formatting of time and timezones.
 *   2007-05-17 Using short names for method and signature.
 *   2007-05-03 Refactored.
 *   2007-03-15 Added signatures.
 *   2007-01-06 Added interception.
 *   2006-07-02 Created.
 */

CERNY.require("CERNY.js.Date",
              "CERNY.util");

(function() {

    var method = CERNY.method;
    var signature = CERNY.signature;
    var fillNumber = CERNY.util.fillNumber;

    CERNY.js.Date = {};

    var TIMEZONE_OFFSET_PROPERTY_NAME = "timezoneOffsetInMinutes";
    var LOCAL_TIMEZONE_OFFSET = new Date().getTimezoneOffset();

    var logger = CERNY.Logger("CERNY.js.Date");
    Date.prototype.logger = logger;
    Date.logger = logger;

    /**
     * Format this date according to format.
     *
     * Ignores the time information (hour, minute and second) of this date.
     *
     * format - the format in which to format this date
     * separator - the separator character between the date and the time zone designator
     * timezoneFormat - the time zone format
     * return - a string containing the date formatted in format
     */
    function formatDate(format, separator, timezoneFormat) {
        var dateStr = "<1>" + format.separator + "<2>" + format.separator + "<3>";
        var year = this.getFullYear();
        var month = this.getMonth() + 1;
        var day = this.getDate();

        dateStr = dateStr.replace("<" + format.positions.year + ">", format.formatters.year(year));
        dateStr = dateStr.replace("<" + format.positions.month + ">", format.formatters.month(month));
        dateStr = dateStr.replace("<" + format.positions.day + ">", format.formatters.day(day));

        if (timezoneFormat) {
            dateStr += separator + timezoneFormat.format(CERNY.js.Date.getTimezoneOffset(this));
        }

        return dateStr;
    }
    signature(formatDate, "String", "object", ["undefined", "string"], ["undefined", "object"]);
    method(Date.prototype, "format", formatDate);
    method(Date.prototype, "formatDate", formatDate);

    /**
     * Format the time of this date according to the provided time
     * format.
     *
     * Ignores the date information (year, month and day) of this date.
     *
     * timeFormat - the time format in which to format the time of this date
     * separator - the optional separator between time and timezone
     * timezoneFormat - the optional time format
     * return - a string containing the time in format
     */
    function formatTime(timeFormat, separator, timezoneFormat) {
        var result = timeFormat.format(this);
        if (timezoneFormat) {
            result += separator + timezoneFormat.format(CERNY.js.Date.getTimezoneOffset(this));
        }
        return result;
    }
    signature(formatTime, "string", "object", ["undefined", "string"], ["undefined","object"]);
    method(Date.prototype, "formatTime", formatTime);

    /**
     * Format date and time of this date according to the provided
     * formats.
     *
     * dateFormat - the date format
     * separator1 - the separator between date and time
     * timeFormat - the time format
     * separator2 - the separator between date and time
     * timezoneFormat - the time zone format
     * return - a string in the format
     */
    function formatDateTime(dateFormat, separator1, timeFormat, separator2, timezoneFormat) {
        return this.formatDate(dateFormat) + separator1 + this.formatTime(timeFormat, separator2, timezoneFormat);
    }
    signature(formatDateTime, "string", "object", "string", "object");
    method(Date.prototype, "formatDateTime", formatDateTime);

    /**
     * Parse a date out of a dateStr based on the the formats provided.
     * If there there is more than one matches the first format is applied
     * to parse the dateStr.
     *
     * dateStr - the dateStr to parse
     * formats - a DateFormat or an array of DateFormats
     * return - if the dateStr can be parsed, a date is returned
     *          otherwise null is returned
     */
    function parseDate(dateStr, formats) {
        if (!isArray(formats) && isObject(formats) && formats.regexp) {
            formats = [formats];
        }

        var match = null;

        var i = 0;
        while (i < formats.length && !match) {
            match = dateStr.match(formats[i].regexp);
            if (match === null) {
                i += 1;
            }
        }

        if (match) {
            var format = formats[i];

            var year = match[format.positions.year];
            var month = match[format.positions.month];
            var day = match[format.positions.day];

            year = (year >= 100) ? year : "" + format.century + year;

            var date = new Date(year, month - 1, day);

            var aYear = date.getFullYear();
            var aMonth = date.getMonth();
            var aDay = date.getDay();

            if (year == date.getFullYear() &&
                month == date.getMonth() + 1 &&
                day == date.getDate()) {

                var tzdStr = extractTimezoneDesignator(dateStr);
                // Parse the timezone offset
                var offset = new Date().getTimezoneOffset();
                try {
                    offset = CERNY.text.TimezoneFormat.ISO.parse(tzdStr);
                } catch (e) {
                } finally {
                    CERNY.js.Date.setTimezoneOffset(date, offset);
                }
                return date;
            }

        }
        return null;
    }
    signature(parseDate, ["null", Date], "string", "object");
    method(Date, "_parse", parseDate);
    method(Date, "parseDate", parseDate);

    function parseTime(timeStr, timeFormat, date) {
        return timeFormat.parse(timeStr, date);
    }
    method(Date, "parseTime", parseTime);

    function parseDateTime(dateStr, dateFormat, timeStr, timeFormat) {
        var date = Date._parse(dateStr, dateFormat);
        Date.parseTime(timeStr, timeFormat, date);
        return date;
    }
    signature(parseDateTime, Date, "string");
    method(Date, "parseDateTime", parseDateTime);

    /**
     * The timezone offset on the JavaScript object cannot be
     * set. Since we want to deal with times in different time zones,
     * we define two functions getTimezoneOffset and setTimezoneOffset
     * to help us out. They use a member to store this information.
     *
     * date - the date to get the timezone offset of.
     * return - the timezone offset
     */
    function getTimezoneOffset(date) {
        if (date.hasOwnProperty(TIMEZONE_OFFSET_PROPERTY_NAME)) {
            return date.timezoneOffsetInMinutes;
        }
        return date.getTimezoneOffset();
    }
    signature(getTimezoneOffset, Number, Date);
    method(CERNY.js.Date, "getTimezoneOffset", getTimezoneOffset);

    /**
     * Set the timezone offset on a date. This does not affect outcome
     * of date.getTimezoneOffset().
     *
     * date - the date to set the timezone offset for
     * timezoneOffset - the timezone offset to set on the date
     */
    function setTimezoneOffset(date, timezoneOffset) {
        date[TIMEZONE_OFFSET_PROPERTY_NAME] = timezoneOffset;
    }
    signature(setTimezoneOffset, "undefined", Date, Number);
    method(CERNY.js.Date, "setTimezoneOffset", setTimezoneOffset);

    /**
     * Convert a date with or without a mutable timezone offset
     * property to a date in the current timezone.
     *
     * date - the date to convert
     * return - the converted date
     */
    function convertToLocalTime(date) {
        var currentTimezoneOffset = new Date().getTimezoneOffset();
        var dateTimezoneOffset = CERNY.js.Date.getTimezoneOffset(date);
        var differenceInMin = currentTimezoneOffset - dateTimezoneOffset;
        return new Date(date.getTime() + differenceInMin * 60 * 1000);
    }
    signature(convertToLocalTime, Date, Date);
    method(CERNY.js.Date, "convertToLocalTime", convertToLocalTime);

    /**
     * Parse a date fragment into a value.
     *
     * str - the string containing the date fragment
     * max - the maximum the value can reach
     * _default - the default value as a string
     */
    function parseDateFragment(str, max, _default) {
        str = str || _default;
        var n = new Number(str);
        if (n >= 0 && n <= max) {
            return n;
        }
        throw new Error("Could not parse date fragment: '" + str + "'.");
    }
    signature(parseDateFragment, "string", "number", ["undefined", "string"]);
    method(CERNY.js.Date, "parseDateFragment", parseDateFragment);

    /**
     * Extract the time zone designator from a string.
     * It returns "Z", "-10:00", "+11:00", ...
     *
     * str - the string which might contain a timezone designator
     * return - the timezone designator string
     */
    function extractTimezoneDesignator(str) {
        return getFirstMatch(str.match(/Z|[+-][0-9][0-9]:[0-9][0-9]/));
    }
    signature(extractTimezoneDesignator, ["undefined", "string"], "string");
    method(CERNY.js.Date, "extractTimezoneDesignator", extractTimezoneDesignator);

    /**
     * Extract the time from a string.
     *
     * str - the string which might contain a time
     * return - the time string
     */
    function extractTime(str) {
        return getFirstMatch(str.match(/^[0-9:]+/));
    }
    signature(extractTime, ["undefined", "string"], "string");
    method(CERNY.js.Date, "extractTime", extractTime);

    /**
     * Extract the am/pm from a string.
     * Recognizes: am,pm,a.m.,p.m.
     *
     * str - the string which might contain a am/pm
     * return - the am/pm string
     */
    function extractAmPm(timeStr) {
        return getFirstMatch(timeStr.match(/am|pm|a\.m\.|p\.m\./));
    }
    signature(extractAmPm, ["undefined", "string"], "string");
    method(CERNY.js.Date, "extractAmPm", extractAmPm);

    function isInLocalTimezone(date) {
        return CERNY.js.Date.getTimezoneOffset(date) == LOCAL_TIMEZONE_OFFSET;
    }
    signature(isInLocalTimezone, ["boolean"], Date);
    method(CERNY.js.Date, "isInLocalTimezone", isInLocalTimezone);

    function getFirstMatch(matchResult) {
        if (matchResult) {
            return matchResult[0];
        }
    }

})();
/**
 * Filename    : TimezoneFormat.js
 * Author      : Robert Cerny
 * Created     : 2008-08-01
 * Last Change : 2008-08-02
 */

CERNY.require("CERNY.text.TimezoneFormat",
              "CERNY.util",
              "CERNY.js.Date");

(function() {

    CERNY.text.TimezoneFormat = TimezoneFormat;

    var fillNumber = CERNY.util.fillNumber;
    var parseDateFragment = CERNY.js.Date.parseDateFragment;
    var signature = CERNY.signature;

    var logger = CERNY.Logger("CERNY.text.TimezoneFormat");

    /**
     * Create a time format.
     *
     * separators - the separators character, default is ":"
     * ampm - true, if it is an ampm hour format, default is false
     * return - an object representing the time format
     */
    function TimezoneFormat() {
        var self = CERNY.object({});
        self.logger = logger;
        return self;
    };
    signature(TimezoneFormat, "object");

    function formatIso(timezoneOffset) {
        if (timezoneOffset == 0) {
            return "Z";
        }
        var i = timezoneOffset / 60;
        var tzd = "+";
        if (i > 0) {
            tzd = "-";
        }
        tzd += fillNumber(Math.abs(i)) + ":00";
        return tzd;
    }
    signature(formatIso, "string", "number");

    /**
     * Parse a timezone designator string into  the timezone offset in minutes.
     * (e.g. "+01:00", "-06:00").
     *
     * tzd - the time zone designator
     * return - the timezone offset in minutes
     */
    function parseIso(tzd) {
        if (tzd == "Z") {
            return 0;
        }

        if (tzd.length < 2) {
            throw new Error("Time zone designator is too short.");
        }

        var sign = tzd.substr(0, 1);
        if (sign != "+" && sign != "-") {
            throw new Error("Time zone designator must have a + or - in the beginning.");
        }
        var rest = tzd.substr(1);
        var segments = rest.split(":");
        var hours = parseDateFragment(segments[0], 12);
        var minutes = parseDateFragment(segments[1], 59, "0");
        var total = hours * 60 + minutes;
        if (sign == "+") {
            return total * (-1);
        }
        return total;
    }
    signature(parseIso, "number", "string");

    // ISO: Z, +01:00, -04:00
    TimezoneFormat.ISO = TimezoneFormat();
    TimezoneFormat.ISO.format = formatIso;
    TimezoneFormat.ISO.parse = parseIso;

})();
/**
 * Filename    : TimeFormat.js
 * Author      : Robert Cerny
 * Created     : 2008-07-29
 * Last Change : 2009-06-24
 *
 * Description:
 *   This script provides a constructor to produce time formats. The
 *   constructor has attached some popular time formats.
 *
 * History:
 *   2008-07-29 Created.
 */

CERNY.require("CERNY.text.TimeFormat",
              "CERNY.text.TimezoneFormat",
              "CERNY.util",
              "CERNY.js.Date",
              "CERNY.js.String");

(function() {

    CERNY.text.TimeFormat = TimeFormat;

    var extractAmPm = CERNY.js.Date.extractAmPm;
    var extractTime = CERNY.js.Date.extractTime;
    var extractTimezoneDesignator = CERNY.js.Date.extractTimezoneDesignator;
    var fillNumber = CERNY.util.fillNumber;
    var parseDateFragment = CERNY.js.Date.parseDateFragment;
    var signature = CERNY.signature;
    var TimezoneFormat = CERNY.text.TimezoneFormat;

    var logger = CERNY.Logger("CERNY.text.TimeFormat");

    var CURRENT_TIMEZONE_OFFSET = new Date().getTimezoneOffset();

    /**
     * Create a time format.
     *
     * separators - the separators character, default is ":"
     * ampm - true, if it is an ampm hour format, default is false
     * return - an object representing the time format
     */
    function TimeFormat(separator, ampm) {
        var self = CERNY.object({});
        self.separator = separator || ":";
        self.ampm = ampm || false;
        self.logger = logger;

        self.format = format;
        self.formatHours = formatHoursFill;
        self.formatMinutes = formatMinutes;
        self.formatSeconds = formatSeconds;
        self.formatAmPm = formatAmPm;
        self.parse = parseEurope;
        return self;
    };
    signature(TimeFormat, "object", ["undefined", "string"], ["undefined", "boolean"]);

    function format(date) {
        var timeStr = this.formatHours(date.getHours());
        timeStr += this.formatMinutes(date.getMinutes());
        timeStr += this.formatSeconds(date.getSeconds());
        timeStr += this.formatAmPm(date.getHours(), this.ampm);
        return timeStr;
    }

    function adjustHour(hour, ampm) {
        if (hour > 12 && ampm) {
            return hour - 12;
        }
        return hour;
    }

    function formatHoursFill(hour) {
        return fillNumber(adjustHour(hour, this.ampm));
    }

    function formatHoursDonotFill(hour) {
        return adjustHour(hour, this.ampm);
    }

    function formatMinutes(minutes) {
        return this.separator + fillNumber(minutes);
    }

    function formatSeconds(seconds) {
        return this.separator + fillNumber(seconds);
    }

    function formatSecondsIfNotZero(seconds) {
        if (seconds == 0) {
            return "";
        }
        return this.separator + fillNumber(seconds);
    }

    function formatAmPm(hour, ampm) {
        if (!ampm) {
            return "";
        }
        if (hour > 12) {
            return " p.m.";
        }
        return " a.m.";
    }

    function parseEurope(str, date) {
        return parseTime(this, str, date, false);
    }

    function parseUs(str, date) {
        return parseTime(this, str, date, true);
    }

    function parseTime(t, str, date, us) {
        date = date || new Date();

        str = str.trim();

        // Extract the components
        var timeStr = extractTime(str);
        var tzdStr = extractTimezoneDesignator(str);
        var pm, appStr;
        if (us) {
            appStr = extractAmPm(str);
            if (!appStr) {
                throw new Error("a.m. or p.m. must be present.");
            }
            pm = (appStr.indexOf("p") == 0);
        }

        // Check if there is anything else but the components
        var restStr = str.replace(timeStr, "").replace(tzdStr,"");
        if (appStr) {
            restStr = restStr.replace(appStr, "");
        }
        if (restStr.match(/\S/)) {
            throw Error("Unkown component in time string.");
        }

        // Parse the time
        var segments = timeStr.split(t.separator);
        var hour;
        if (us) {
            if (pm) {
                hour = parseDateFragment(segments[0], 11);
                hour += 12;
            } else {
                hour = parseDateFragment(segments[0], 12);
            }
        } else {
            hour = parseDateFragment(segments[0], 23);
        }
        date.setHours(hour);
        date.setMinutes(parseDateFragment(segments[1], 59, "0"));
        date.setSeconds(parseDateFragment(segments[2], 59, "0"));

        // Parse the timezone offset
        var offset = new Date().getTimezoneOffset();
        try {
            offset = TimezoneFormat.ISO.parse(tzdStr);
        } catch (e) {
            logger.debug("e: " + CERNY.dump(e));
        } finally {
            CERNY.js.Date.setTimezoneOffset(date, offset);
        }
        return date;
    }

    function dontFormat() {
        return "";
    }

    // 04:13:00
    TimeFormat.DE = TimeFormat();

    // 4:13 or 4:13:12
    TimeFormat.DE1 = TimeFormat();
    TimeFormat.DE1.formatHours = formatHoursDonotFill;
    TimeFormat.DE1.formatSeconds = formatSecondsIfNotZero;

    // 4:13
    TimeFormat.DE2 = TimeFormat();
    TimeFormat.DE2.formatHours = formatHoursDonotFill;
    TimeFormat.DE2.formatSeconds = dontFormat;

    // 04:13:00 a.m.
    TimeFormat.US = TimeFormat(":", true);
    TimeFormat.US.parse = parseUs;

    // 4:13 a.m. or 4:13:12 a.m.
    TimeFormat.US1 = TimeFormat(":", true);
    TimeFormat.US1.formatHours = formatHoursDonotFill;
    TimeFormat.US1.formatSeconds = formatSecondsIfNotZero;
    TimeFormat.US1.parse = parseUs;

    // 4:13 a.m.
    TimeFormat.US2 = TimeFormat(":", true);
    TimeFormat.US2.formatHours = formatHoursDonotFill;
    TimeFormat.US2.formatSeconds = dontFormat;
    TimeFormat.US2.parse = parseUs;

    // 04:13:00+02:00
    TimeFormat.ISO = TimeFormat(":");

})();
/**
 * Filename    : Locale.js
 * Author      : Robert Cerny
 * Created     : 2008-07-30
 * Last Change : 2009-06-24
 *
 * History:
 *   2009-06-24 Added timeShort
 */

CERNY.require("CERNY.util.Locale",
              "CERNY.util",
              "CERNY.text.DateFormat",
              "CERNY.text.TimezoneFormat",
              "CERNY.text.TimeFormat");

(function() {

    CERNY.util.Locale = Locale;
    CERNY.util.FormatsMap = FormatsMap;

    var signature = CERNY.signature;
    var method = CERNY.method;

    var logger = CERNY.Logger("CERNY.util.Locale");

    function Locale(language, country, formatsMap) {
        formatsMap = formatsMap || FormatsMap.DEFAULT;
        this.language = language;
        this.country = country;
        this.formats = formatsMap.getFormats(country);
    }
    // signature(Locale, Locale, "string", "string", ["undefined", "object"]);

    function FormatsMap(formatsMap) {
        var self = CERNY.object(formatsMap);
        method(self, "getFormats", getFormats);
        return self;
    }
    // signature(FormatsMap, FormatsMap, "string", "string");

    function getFormats(country) {
        if (this[country]) {
            return this[country];
        }
        return this["_default"];
    }
    signature(getFormats, "undefined", "string");

    FormatsMap.DEFAULT = FormatsMap({
            "_default": {
                date: CERNY.text.DateFormat.DE,
                time: CERNY.text.TimeFormat.DE1,
                timeShort: CERNY.text.TimeFormat.DE2,
                timezone: CERNY.text.TimezoneFormat.ISO
            },
            "DE": {
                date: CERNY.text.DateFormat.DE,
                time: CERNY.text.TimeFormat.DE1,
                timeShort: CERNY.text.TimeFormat.DE2,
                timezone: CERNY.text.TimezoneFormat.ISO
            },
            "US": {
                date: CERNY.text.DateFormat.US,
                time: CERNY.text.TimeFormat.US1,
                timeShort: CERNY.text.TimeFormat.US2,
                timezone: CERNY.text.TimezoneFormat.ISO
            }});

})();
/**
 * Filename    : locale.js
 * Author      : Robert Cerny
 * Created     : 30.07.2008
 * Last Change : 2008-08-02
 *
 * Copyright 2008 Robert Cerny
 */

CERNY.require("TOPINCS.locale",
              "CERNY.util.Locale",
              "CERNY.text.TimeFormat",
              "CERNY.text.DateFormat");

(function() {

    TOPINCS.namespace("locale");

    var Locale = CERNY.util.Locale;

    function getLocale() {
        var browserLocale = window.navigator.language;
        browserLocale = browserLocale || window.navigator.userLanguage;
        browserLocale = browserLocale || "en_US";

        var country;
        var language = browserLocale.substr(0,2);
        if (browserLocale.length == 5) {
            country = browserLocale.substr(3,2);
        } else {
            country = language.toUpperCase();
        }
        return new Locale(language, country);
    }
    // signature(getLocale, Locale);
    CERNY.method(TOPINCS, "getLocale", getLocale);

})();
/**
 * Filename    : dict.js
 * Author      : Robert Cerny
 * Created     : 2008-04-05
 * Last Change : 2009-11-03
 */

CERNY.require("TOPINCS.dict");

(function() {

    TOPINCS.dict = {};

    var method = CERNY.method;
    var logger = CERNY.Logger("TOPINCS.dict");

    function getDictionary(symbol) {
        var lang = TOPINCS.UI_LANGUAGE || "en";
        var dictLocation = CERNY.Catalog.lookup(symbol);
        var dictionaryLocation = dictLocation.replace(/dict\.js$/, lang + ".json");
        return CERNY.getResource(dictionaryLocation);
    }
    method(TOPINCS.dict, "getDictionary", getDictionary);

    function get(key, replacements, count) {
        if (typeof count === "number") {
            key = getKeyNoneSgPl(key, count);
        }
        var value = this[key];
        if (value && replacements) {
            var i = 1;
            replacements.map(function(replacement) {
                value = value.replace(new RegExp("%" + i, "g"), replacement);
                i += 1;
            });
        }
        return value;
    }
    // signature(get, "string", "string", Array, ["undefined", "number"]);
    method(TOPINCS.dict, "get", get);

    function getKeyNoneSgPl(key, count) {
        if (count > 1) {
            return key + "_pl";
        }
        if (count == 1) {
            return key + "_sg";
        }
        return key + "_none";
    }
    // signature(getKeyNoneSgPl, "string", "string", "number");




})();
/**
 * Filename    : dict.js
 * Author      : Robert Cerny
 * Created     : 2008-04-05
 * Last Change : 2009-10-31
 */

CERNY.require("DICT",
              "TOPINCS.dict");

(function() {

    eval("DICT = " + TOPINCS.dict.getDictionary("DICT") + ";");

})();
/**
 * Filename    : cons.js
 * Author      : Robert Cerny
 * Created     : 30.11.2005
 * Last Change : 2009-11-28
 *
 * Copyright 2005 Robert Cerny
 */

CERNY.require("TOPINCS.cons",
              "CERNY.util");

if (!TOPINCS.cons) {
    TOPINCS.namespace("cons");
}

(function () {
    var info = CERNY.util.parseUri(document.URL);

    TOPINCS.BASE = getBase();
    TOPINCS.HOST = info.scheme + "://" + info.host;
    if (info.port) {
        TOPINCS.HOST += ":" + info.port;
    }

    TOPINCS.UI_LANGUAGE = TOPINCS.UI_LANGUAGE || "en";

    /*
     * Returns the "base" of the application. The base in this particular
     * context is understood as all path segments of the URI, except for
     * the last one.
     *
     * Examples:
     *     DOCUMENT URI                                 BASE
     *     http://some.host.com/topincs/                "/topincs"
     *     http://some.host.com/                        ""
     *     http://some.farm.com:123/some_user/topincs/  "/some_user/topincs"
     *     http://some.host.com/topincs/index.php       "/topincs"
     */
    function getBase() {
        var base = "";

        for (var i = 0; i < info.path_segments.length - 1 ; i++) {
            base += "/" + info.path_segments[i];
        }

        if (typeof REMOVE_FROM_BASE_DIR == "string") {
            base = base.replace(REMOVE_FROM_BASE_DIR, "");
        }

        return base;
    }
})();

var MAPS = "topicmaps/";

var LOGIN_URL = ".login";

// MEDIA_TYPE_CORE_TOPIC_IDS
var CORE_TOPICS_URL = "3.6.1/.core-topics";
var CORE_TOPICS_URL_NO_CACHED = ".core-topics";

// MEDIA_TYPE_TOPIC_PROXY_ARRAY
var ROLES_URL = "associations/.roles";

// MEDIA_TYPE_ROLE_TYPE_PROXY_ARRAY
var POSSIBLE_ROLE_TYPES_URL = "roles/.possible-types";

// MEDIA_TYPE_TOPIC_PROXY_ARRAY
var POSSIBLE_OCCURRENCE_TYPES_URL = "occurrences/.possible-types";

// MEDIA_TYPE_TOPIC_PROXY_ARRAY
var POSSIBLE_NAME_TYPES_URL = "names/.possible-types";

// MEDIA_TYPE_TOPIC_PROXY_ARRAY
var POSSIBLE_PLAYERS_URL = "roles/.possible-players";

// MEDIA_TYPE_TOPINCS_TOOL_ARRAY
var TOOLS_URL = ".tools";

// MEDIA_TYPE_STORE_SEARCH_RESULT, for InputCompleter still old format
var TOPIC_SEARCH_URL = "topics/.search";

var WIKI_SEARCH_URL = "wiki/.search";

// MEDIA_TYPE_RECENT_CHANGES
var WIKI_CHANGES_URL = "wiki/.changes";

/**
 * Get the label (value of a name) of a topic.
 *
 * system_id - the system id of the topic for which the name is wanted
 * scope (optional) - a comma separated list of system ids of the scope the name should be in
 * return - the label of the topic with the specified system_id
 */
var TOPIC_LABEL_URL = "topics/.label";

var TOPIC_DESCRIPTION_URL = "topics/.description";

// MEDIA_TYPE_DATATYPE_ARRAY
var DATATYPES_URL = "occurrences/.datatypes";

// MEDIA_TYPE_ROLE_PROXY_ARRAY
var ROLES_SEARCH_URL = "roles/.search";

// MEDIA_TYPE_NODE
var TOPICMAPS_CONTENT_URL = "topicmaps/.content";

var TOPIC_LOCATE_URL = "topics/.locate";
var TOPIC_USAGE_URL = "topics/.usage";
var JOURNAL_URL = ".journal";

// MEDIA_TYPE_ITEM_META_INFORMATION
var META_URL = ".meta";

// MEDIA_TYPE_TOPIC_PROXY_ARRAY
var POSSIBLE_SCOPING_TOPINCS_URL = ".possible-scoping-topics";

var USERS_URL = TOPINCS.BASE + "/users/";

var INCLUDE_URL = "wiki/.include";

var ACCEPT_SCOPE = "";
var USCOPE = "uc";
var ASCOPE = "*";

var TOPIC_SELF_REFERENCE = "_self_";

var DT_SCHEMA = "http://www.w3.org/2001/XMLSchema#";

var DT_STRING = DT_SCHEMA + "string";
var DT_NORMALIZEDSTRING = DT_SCHEMA + "normalizedString";
var DT_TOKEN = DT_SCHEMA + "token";
var DT_BASE64BINARY = DT_SCHEMA + "base64Binary";
var DT_HEXBINARY = DT_SCHEMA + "hexBinary";
var DT_INTEGER = DT_SCHEMA + "integer";
var DT_POSITIVEINTEGER = DT_SCHEMA + "positiveInteger";
var DT_NEGATIVEINTEGER = DT_SCHEMA + "negativeInteger";
var DT_NONNEGATIVEINTEGER = DT_SCHEMA + "nonNegativeInteger";
var DT_NONPOSITIVEINTEGER = DT_SCHEMA + "nonPositiveInteger";
var DT_LONG = DT_SCHEMA + "long";
var DT_UNSIGNEDLONG = DT_SCHEMA + "unsignedLong";
var DT_INT = DT_SCHEMA + "int";
var DT_UNSIGNEDINT = DT_SCHEMA + "unsignedInt";
var DT_SHORT = DT_SCHEMA + "short";
var DT_UNSIGNEDSHORT = DT_SCHEMA + "unsignedShort";
var DT_BYTE = DT_SCHEMA + "byte";
var DT_UNSIGNEDBYTE = DT_SCHEMA + "unsignedByte";
var DT_DECIMAL = DT_SCHEMA + "decimal";
var DT_FLOAT = DT_SCHEMA + "float";
var DT_DOUBLE = DT_SCHEMA + "double";
var DT_BOOLEAN = DT_SCHEMA + "boolean";
var DT_DURATION = DT_SCHEMA + "duration";
var DT_DATETIME = DT_SCHEMA + "dateTime";
var DT_DATE = DT_SCHEMA + "date";
var DT_TIME = DT_SCHEMA + "time";
var DT_GYEAR = DT_SCHEMA + "gYear";
var DT_GYEARMONTH = DT_SCHEMA + "gYearMonth";
var DT_GMONTH = DT_SCHEMA + "gMonth";
var DT_GMONTHDAY = DT_SCHEMA + "gMonthDay";
var DT_GDAY = DT_SCHEMA + "gDay";
var DT_NAME = DT_SCHEMA + "Name";
var DT_QNAME = DT_SCHEMA + "QName";
var DT_NCNAME = DT_SCHEMA + "NCName";
var DT_ANYURI = DT_SCHEMA + "anyURI";
var DT_LANGUAGE = DT_SCHEMA + "language";
var DT_ID = DT_SCHEMA + "ID";
var DT_IDREF = DT_SCHEMA + "IDREF";
var DT_IDREFS = DT_SCHEMA + "IDREFS";
var DT_ENTITY = DT_SCHEMA + "ENTITY";
var DT_ENTITIES = DT_SCHEMA + "ENTITIES";
var DT_NOTATION = DT_SCHEMA + "NOTATION";
var DT_NMTOKEN = DT_SCHEMA + "NMTOKEN";
var DT_NMTOKENS = DT_SCHEMA + "NMTOKENS";
var DT_ANYTYPE = DT_SCHEMA + "anyType";

var DT_WIKIMARKUP = "http://tmwiki.org/psi/wiki-markup";

var MEDIA_TYPE_JSON = "application/json";
var MEDIA_TYPE_XTM = "application/xtm+xml;1.0";
var MEDIA_TYPE_XTM_2_0 = "application/xtm+xml;2.0";
var MEDIA_TYPE_TOPIC_PROXY_ARRAY = "application/topicproxyarray+topincs+json";
var MEDIA_TYPE_ROLE_TYPE_PROXY_ARRAY = "application/roletypeproxyarray+topincs+json";
var MEDIA_TYPE_ROLE_PROXY_ARRAY = "application/roleproxyarray+topincs+json";
var MEDIA_TYPE_TOPINCS_TOOL_ARRAY = "application/topincstoolarray+topincs+json";
var MEDIA_TYPE_STORE_SEARCH_RESULT = "application/storesearchresult+topincs+json";
var MEDIA_TYPE_STORE_SEARCH_RESULT_V2 = "application/storesearchresult+topincs+json;v2";
var MEDIA_TYPE_CORE_TOPIC_PROXY_MAP = "application/coretopicproxymap+topincs+json";
var MEDIA_TYPE_DATATYPE_ARRAY = "application/datatypearray+topincs+json";
var MEDIA_TYPE_RECENT_CHANGES = "application/recentchanges+topincs+json";
var MEDIA_TYPE_ITEM_META_INFORMATION = "application/itemmetainformation+topincs+json";
var MEDIA_TYPE_NODE = "application/node+topincs+json";
var MEDIA_TYPE_JTM = "application/jtm+json";
var MEDIA_TYPE_JTM_1_0 = "application/jtm+json";

// Format that apply to whole map. These types can be sent as a value of
// the type parameter to an URL of a map
var FORMAT_XTM_1_0 = "xtm-1.0";
var FORMAT_XTM_2_0 = "xtm-2.0";
var FORMAT_JTM_1_0 = "jtm-1.0";

var IMPORT_SOURCE_URL = "URL";
var IMPORT_SOURCE_FILE = "File";

var COOKIE_CONFIGURATION = "topincs.editor.conf";

var HREF_VOID = "javascript:void(null)";

var PSI_TYPE_INSTANCE = "http://psi.topicmaps.org/iso13250/model/type-instance";
var PSI_INSTANCE = "http://psi.topicmaps.org/iso13250/model/instance";
var PSI_TYPE = "http://psi.topicmaps.org/iso13250/model/type";
var PSI_TOPIC_TYPE = "http://psi.topincs.com/iso13250/topic-type";

var PSI_LANG_BASE = "http://www.topicmaps.org/xtm/1.0/language.xtm#";
/**
 * Filename    : dict.js
 * Author      : Robert Cerny
 * Created     : 2009-10-31
 * Last Change : 2009-10-31
 */

CERNY.require("TOPINCS.widgets.DICT",
              "TOPINCS.dict");

(function() {

    eval("TOPINCS.widgets.DICT = " + TOPINCS.dict.getDictionary("TOPINCS.widgets.DICT") + ";");
    TOPINCS.widgets.DICT.get = TOPINCS.dict.get;

})();
/**
 * Filename    : Response.js
 * Author      : Robert Cerny
 * Created     : 2007-12-08
 * Last Change : 2007-12-08
 *
 * Description:
 *  Provides a wrapper around a HTTP response.
 *
 * History:
 *   2007-12-08 Created.
 */

CERNY.require("CERNY.http.Response");

(function() {

    var signature = CERNY.signature;
    var method = CERNY.method;

    CERNY.http.Response = Response;

    var logger = CERNY.Logger("CERNY.http.Response");

    /**
     * This class represents the HTTP response. A response must have a
     * status.
     *
     * request - the request that belongs to this response
     * return - an instance of this class
     */
    function Response(request) {

        /**
         * The request that issued this response.
         */
        this.request = request;

        /**
         * The body of this response.
         */
        this.body = request.responseText;

        /**
         * The status code of this response.
         */
        this.status = request.status;
    }
    // signature(Response, "object", CERNY.http.Request);

    Response.prototype.logger = logger;

    /**
     * Return the status of this response.
     *
     * return - the response status
     */
    function getStatus() {
        return this.status;
    }
    signature(getStatus, "number");
    method(Response.prototype, "getStatus", getStatus);

    /**
     * Return the body of this response.
     *
     * return - the response body
     */
    function getBody() {
        return this.body;
    }
    signature(getBody, "string");
    method(Response.prototype, "getBody", getBody);

    /**
     * Return a header of the response.
     *
     * name - the name of the header to return
     * return - the value of the response header
     */
    function getHeader(name) {
        return this.request.getResponseHeader(name);
    }
    signature(getHeader, "string", "string");
    method(Response.prototype, "getHeader", getHeader);

    /**
     * Interpret the body of the response as a JSON document and
     * return the evaluation result.
     *
     * return - the value of the JSON document in the body
     */
    function getValue() {
        eval("var o = " + this.body);
        return o;
    }
    signature(getValue, "any");
    method(Response.prototype, "getValue", getValue);

})();
/**
 * Filename    : Request.js
 * Author      : Robert Cerny
 * Created     : 2007-06-18
 * Last Change : 2008-12-23
 *
 * Description:
 *  This script provides Ajax functionality to send HTTP requests to a
 *  server.
 *
 * History:
 *   2008-12-23 Filtering empty strings before setting request parameter headers.
 *   2008-10-06 Added method setNoCacheHeaders.
 *   2007-12-08 Split into two scripts, Request and Response.
 *   2007-07-07 Fixed bug caused by json.js when setting request headers.
 *   2007-06-18 Created.
 */

CERNY.require("CERNY.http.Request",
              "CERNY.http.Response");

(function() {

    var signature = CERNY.signature;
    var method = CERNY.method;
    var Response = CERNY.http.Response;

    CERNY.http.Request = Request;

    var logger = CERNY.Logger("CERNY.http.Request");

    /**
     * This class represents the HTTP request. This is a wrapper to add
     * some convenience and avoid the word XML.
     *
     * method - the method of the request
     * url - the URL of the request
     * return - an instance of this class
     */
    function Request(method, url) {

        /**
         * The method (verb) of this HTTP request. Valid values are
         * all methods defined in RFC 2616.
         */
        this.method = method;

        /**
         * The URL of this HTTP request. Only URLs within the current
         * domain can be processed, due to browser security.
         */
        this.url = url;

        /**
         * The headers that should be sent with this request. The
         * browser will add some more.
         */
        this.headers = {};

        /**
         * The body of this request.
         */
        this.body = null;

        /**
         * The content type of the body of this request. If present
         * this header will be set automatically before sending the
         * request.
         */
        this.contentType = null;
    }
    // signature(Request, "object", "string", "string");

    Request.prototype.logger = logger;

    // See http://www.w3.org/TR/XMLRequest/
    Request.UNSENT = "0";
    Request.OPEN = "1";
    Request.SENT = "2";
    Request.LOADING = "3";
    Request.DONE = "4";

    /**
     * Set the body of the request, optionally pass the content type
     * of the body. It is recommended to pass the content type.
     *
     * body - the body the request should transport
     * contentType - the content type of the body
     */
    function setBody(body, contentType) {
        this.body = body;
        this.contentType = contentType;
    }
    signature(setBody, "undefined", "string", ["undefined", "string"]);
    method(Request.prototype, "setBody", setBody);

    /**
     * Set a header of the request.
     *
     * name - the name of the header
     * value - the value of the header
     */
    function setHeader(name, value) {
        this.headers[name] = value;
    }
    signature(setHeader, "undefined", "string", "string");
    method(Request.prototype, "setHeader", setHeader);

    /**
     * Send this request synchronously. The browser will wait for the
     * response with further execution.
     *
     * return - the response of the server
     */
    function sendSynch() {
        this.request = new XMLHttpRequest();
        this.request.open(this.method, this.url, false);
        setHeaders(this, this.request);
        this.request.send(this.body);
        return new Response(this.request);
    }
    signature(sendSynch, CERNY.http.Response);
    method(Request.prototype, "sendSynch", sendSynch);

    /**
     * Send this request asynchronously. The browser will continue to
     * execute the script without waiting for the response.
     *
     * The parameter <code>callback</code> is an object that may
     * contain a function for each phases of the request. The name of
     * the property is the number of the phase, so UNSET is "0", OPEN
     * is "1", SENT is "2", LOADING is "3" and DONE is "4". If a
     * function is passed instead of an object, it is interpreted as a
     * callback when the request is done (complete, the response has
     * arrived, a status is available).
     *
     * The callbacks receive the request as their only parameter.
     *
     * callback - handler(s) for the request processing phases
     */
    function sendAsynch(callback) {
        var handler = callback;
        if (isFunction(callback)) {
            handler = {};
            handler[Request.DONE] = callback;
        }
        this.request = new XMLHttpRequest();
        this.request.open(this.method, this.url, true);
        setHeaders(this, this.request);
        var req = this.request;
        this.request.onreadystatechange = function () {
            if (isFunction(handler["" + req.readyState])) {
                handler["" + req.readyState](req);
            }
        }
        this.request.send(this.body);
    }
    signature(sendAsynch, "undefined", ["function", "object"]);
    method(Request.prototype, "sendAsynch", sendAsynch);

    /**
     * Set headers for this request, so that the response must come
     * from the origin server.
     */
    function setNoCacheHeaders() {
        this.setHeader("Pragma", "no-cache");
        this.setHeader("Cache-Control", "no-cache");

        // While the browsers do not honor the no-cache directive on
        // XMLHttpRequests [1], add a random query parameter.
        if (this.url.indexOf("?") < 0) {
            this.url += "?";
        } else {
            this.url += "&";
        }
        this.url += "cernyjsnocache=" + Math.random().toString().replace(".", "");
    }
    signature(setNoCacheHeaders, "undefined", ["function", "object"]);
    method(Request.prototype, "setNoCacheHeaders", setNoCacheHeaders);

    /*
     * Set the headers for the request.
     */
    function setHeaders(t, request) {
        if (t.contentType) {
            request.setRequestHeader("Content-Type", t.contentType);
        }
        for (var name in t.headers) {
            // Check for own property, because otherwise toJSONString
            // is considered as well.
            if (t.headers.hasOwnProperty(name)) {

                // Google Chrome does not like empty strings as header
                // parameter values.
                var value = t.headers[name];
                if (typeof value == "string" && value.length > 0) {
                    request.setRequestHeader(name, t.headers[name]);
                }
            }
        }
    }

})();

// [1] http://www.mnot.net/javascript/xmlhttprequest/cache.html
/**
 * Filename    : dom.js
 * Author      : Robert Cerny
 * Created     : 2006-11-11
 * Last Change : 2007-04-10
 */

CERNY.require("CERNY.dom");

CERNY.namespace("dom");
CERNY.dom.logger = CERNY.Logger("CERNY.dom");

function isNode(a) {
    return isObject(a) && isNumber(a.nodeType);
}

function isElement(a) {
    return isNode(a) && a.nodeType == 1;
}

function isTextNode(a) {
    return isNode(a) && a.nodeType == 3;
}
/**
 * Filename    : Node.js
 * Author      : Robert Cerny
 * Created     : 2004-10-27
 * Last Change : 2009-10-12
 *
 * Description:
 *   Provides a handle for a DOM node.
 *
 * History:
 *   2007-04-12 Completly refactored.
 *   2004-10-27 Created.
 */

CERNY.require("CERNY.dom.Node",
              "CERNY.dom");

(function() {

    var method = CERNY.method;
    var signature = CERNY.signature;
    var pre = CERNY.pre;
    var post = CERNY.post;
    var check = CERNY.check;

    /**
     * Create a handle for an existing DOM node. The constructor can
     * be called without arguments to satisfy CERNY.inherit.
     *
     * nodeOrId - a node id or a node
     * return - a handle for a DOM node
     */
    CERNY.dom.Node = function(nodeOrId) {
        if (isUndefined(nodeOrId)) {
            return this;
        }
        if (nodeOrId instanceof CERNY.dom.Node) {
            return nodeOrId;
        }
        var node = nodeOrId;
        var id = nodeOrId;
        if (isString(id)) {
            node = document.getElementById(id);
            if (node === null) {
                throw new Error("Document does not contain element with id '" + id + "'");
            }
        }
        if (isNode(node)) {
            // if (node.cernydomnode) {
            //     return node.cernydomnode;
            // }
            // node.cernydomnode = this;
            this.node = node;
            return this;
        }
        throw new Error("No node");
    };
    signature(CERNY.dom.Node, "object", ["string", "object", CERNY.dom.Node, "undefined"], ["boolean", "undefined"]);
    CERNY.intercept(CERNY.dom, "Node");

    CERNY.dom.Node.prototype.logger = CERNY.Logger("CERNY.dom.Node");

    /**
     * Get all children that fulfill predicate.
     *
     * predicate - a function taking a node and returning true or false, defaults to isNode
     * return - all child nodes that fulfill predicate in original order
     */
    var getChildren = function(predicate) {
        if (!predicate) {
            predicate = isNode;
        }

        var result = [];

        var children = this.node.childNodes;
        for (var i = 0; i < children.length; i++) {
            if (predicate(children[i])) {
                result.push(children[i]);
            }
        }

        return result;
    };
    signature(getChildren, Array, ["function", "undefined"]);
    method(CERNY.dom.Node.prototype, "getChildren", getChildren);

    /**
     * Delete all children of this node that fulfill predicate.
     *
     * predicate - the predicate that children must fulfill, defaults to isNode
     * return - the number of deleted children
     */
    var deleteChildren = function(predicate) {
        if (!predicate) {
            predicate = isNode;
        }

        var children = this.node.childNodes;
        var count = 0;
        for (var i = children.length; i >= 0; i--) {
            if (predicate(children[i])) {
                this.node.removeChild(children[i]);
                count += 1;
            }
        }
        return count;
    };
    signature(deleteChildren, "number", ["function", "undefined"]);
    CERNY.pre(deleteChildren, function(predicate) {
        CERNY.check(isObject(this.node), "this.node must be present");
    });
    method(CERNY.dom.Node.prototype, "deleteChildren", deleteChildren);

    /**
     * Count the children, that fulfill predicate.
     *
     * predicate - the predicate for the nodes to be counted, defaults to isNode
     * number - the number of matching children
     */
    var countChildren = function(predicate) {
        return this.getChildren(predicate).length;
    };
    signature(countChildren, "number", ["function", "undefined"]);
    method(CERNY.dom.Node.prototype, "countChildren", countChildren);


    /**
     * Append a node to this node.
     *
     * node - the node to append
     */
    var appendChild = function(node) {
        if (isNode(node)) {
            this.node.appendChild(node);
        } else if (isNode(node.node)) {
            this.node.appendChild(node.node);
        }
    };
    signature(appendChild, "undefined", [CERNY.dom.Node, "object"]);
    method(CERNY.dom.Node.prototype, "appendChild", appendChild);

    /**
     * Append nodes to this node.
     *
     * arguments - the nodes to append
     */
    var appendChildren = function() {
        for (var i = 0; i < arguments.length; i++) {
            this.appendChild(arguments[i]);
        }
    };
    signature(appendChildren, "undefined", [CERNY.dom.Node, "object"]);
    method(CERNY.dom.Node.prototype, "appendChildren", appendChildren);

    /**
     * Get all descendants of this node that fulfill predicate.
     *
     * predicate - the predicate to fulfill
     * return - all descendants that fulfill predicate in original order
     */
    function getDescendants(predicate) {
        var result = [];
        var children = this.getChildren();
        children.map(function(child) {
            if (predicate(child)) {
                result.push(child);
            }
            result.append(new CERNY.dom.Node(child).getDescendants(predicate));
        });
        return result;
    }
    signature(getDescendants, Array, ["function", "undefined"]);
    method(CERNY.dom.Node.prototype, "getDescendants", getDescendants);

    /**
     * Get the nth (next or previous) sibling that fulfills a certain
     * predicate.
     *
     * predicate - the predicate the node should fulfill, default is isNode
     * next - if true, the search is performed forward, default is true; if false
     *        search direction is backwards
     * nth - number of sibling to fetch, default is 1
     */
    var getNthSibling = function(predicate, next, nth) {
        var sibling = this.node;

        if (!isFunction(predicate)) {
            predicate = isNode;
        }

        if (!isBoolean(next)) {
            next = true;
        }

        if (!isNumber(nth)) {
            nth = 1;
        }

        var direction = "previousSibling";
        if (next) {
            direction = "nextSibling";
        }

        var matches = 0;
        while (sibling !== null && matches < nth) {
            sibling = sibling[direction];
            if (predicate(sibling)) {
                matches++;
            }
        }

        return sibling;
    };
    signature(getNthSibling, ["object", "null"], ["function", "undefined"], ["boolean", "undefined"], ["number", "undefined"]);
    method(CERNY.dom.Node.prototype, "getNthSibling", getNthSibling);

    /**
     * Return the closest sibling of this node that fulfills a certain
     * predicate.
     *
     * predicate - the predicate that must be fulfilled
     * next - direction; true - forward, false - backward
     * return - the closest sibling of predicate or null
     */
    var getClosestSibling = function(predicate, next) {
        return this.getNthSibling(predicate, next, 1);
    };
    signature(getClosestSibling, ["object", "null"], ["function", "undefined"], ["boolean", "undefined"]);
    method(CERNY.dom.Node.prototype, "getClosestSibling", getClosestSibling);

    /**
     * Return the first child of this node that fulfills predicate.
     *
     * predicate - the predicate to fulfill, default is isNode
     * return - the first matching node or null
     */
    var getFirstChild = function(predicate) {
        if (!isFunction(predicate)) {
            predicate = isNode;
        }
        var first = this.node.firstChild;
        if (first === null || predicate(first)) {
            return first;
        }
        return new CERNY.dom.Node(first).getClosestSibling(predicate);
    };
    signature(getFirstChild, ["object", "null"], ["function", "undefined"]);
    method(CERNY.dom.Node.prototype, "getFirstChild", getFirstChild);

    /**
     * Return true, if this node is a grandchild of node.
     * False, otherwise.
     *
     * node - the node who might be a grand parent
     * return - true, if node is a grandchild of this node, otherwise false
     */
    var isGrandchildOf = function(node) {
        node = new CERNY.dom.Node(node);
        var climber = this.node.parentNode;
        while (climber !== null) {
            if (climber === node.node) {
                return true;
            }
            climber = climber.parentNode;
        }
        return false;
    };
    signature(isGrandchildOf, ["boolean"], [CERNY.dom.Node, "object"]);
    method(CERNY.dom.Node.prototype, "isGrandchildOf", isGrandchildOf);

    /**
     * Return true, if this node is an ancestor of node.
     * False, otherwise.
     *
     * node - possible ancestor
     * return - true, if node is ancestor of this node, false otherwise
     */
    var isAncestorOf = function(node) {
        return new CERNY.dom.Node(node).isGrandchildOf(this.node);
    };
    signature(isAncestorOf, ["boolean"], [CERNY.dom.Node, "object"]);
    method(CERNY.dom.Node.prototype, "isAncestorOf", isAncestorOf);

    /**
     * Return an array of all ancestors to this node that fulfill
     * predicate.
     *
     * predicate - the predicate the ancestors must fulfill, default is isNode
     * return - array of all matching ancestors
     */
    var getAncestors = function(predicate) {
        if (!predicate) {
            predicate = isNode;
        }

        var result = [];

        var ancestor = this.node.parentNode;
        while (ancestor) {
            if (predicate(ancestor)) {
                result.push(ancestor);
            }
            ancestor = ancestor.parentNode;
        }

        return result;
    };
    signature(getAncestors, Array, ["function", "undefined"]);
    method(CERNY.dom.Node.prototype, "getAncestors", getAncestors);


    /**
     * Get first ancestor which fulfills predicate.
     *
     * predicate - predicate that ancestor must fulfill, default is isNode
     * return - first ancestor that matches predicate
     */
    var getFirstAncestor = function(predicate) {
        if (!predicate) {
            predicate = isNode;
        }

        var parent = this.node.parentNode;
        if (parent === null) {
            return null;
        }

        if (predicate(parent)) {
            return parent;
        } else {
            return new CERNY.dom.Node(parent).getFirstAncestor(predicate);
        }

    };
    signature(getFirstAncestor, ["object", "null"], ["function", "undefined"]);
    method(CERNY.dom.Node.prototype, "getFirstAncestor", getFirstAncestor);

    /**
     * Add event listener to node.
     *
     * type - the type of event that is listend for
     * listener - the listener
     * capture - if true event is captured, default is false (bubble)
     */
    var addEvtListener = function(type, listener, capture) {
        if (this.node.attachEvent) {
            this.node.attachEvent("on" + type, listener);
        } else {
            this.node.addEventListener(type, listener, capture);
        }
        if (!this.eventListeners) {
            this.eventListeners = [];
        }
        this.eventListeners.push(listener);
    };
    signature(addEvtListener, "undefined", "string", "function", ["boolean", "undefined"]);
    method(CERNY.dom.Node.prototype, "addEvtListener", addEvtListener);

    /**
     * Remove event listener from node.
     *
     * type - the type of event that is listend for
     * listener - the listener
     * capture - if true event is captured, default is false (bubble)
     */
    var  removeEvtListener = function(type, listener, capture) {
        if (this.node.detachEvent) {
            this.node.detachEvent("on" + type, listener);
        } else {
            this.node.removeEventListener(type, listener, capture);
        }
    };
    signature(removeEvtListener, "undefined", "string", "function", ["boolean", "undefined"]);
    method(CERNY.dom.Node.prototype, "removeEvtListener", removeEvtListener);

    /**
     * Remove all event listeners from this node.
     */
    var removeAllEvtListeners = function() {
        if (this.eventListeners) {
            this.eventListeners.map(function(listener) {
                this.node[listener] = null;
            });
            this.eventListeners = [];
        }
    };
    signature(removeAllEvtListeners, "undefined", "undefined");
    method(CERNY.dom.Node.prototype, "removeAllEvtListeners", removeAllEvtListeners);

    /**
     * Copy this node to a destination.
     *
     * destinaton - the destinaton node
     * anchor - if present, this node is inserted before anchor
     * return - the copied node
     */
    var domCopy = function(destination, anchor) {
        if (!isNode(anchor)) {
            anchor = null;
        }

        destination = new CERNY.dom.Node(destination);

        var clone = this.node.cloneNode(true);
        destination.node.insertBefore(clone, anchor);
        return clone;
    };
    signature(domCopy, "object", "object", ["object", "undefined"]);
    method(CERNY.dom.Node.prototype, "domCopy", domCopy);

    /**
     * Move this node to a destination and position it before
     * or after the anchor, depending on parameter after.
     *
     * destination - the node to move this node to
     * anchor - the node become the new sibling of this node
     *          defaults to firstChild or lastChild depenging on after
     * after - if true this node is inserted after anchor,
     *         if false it is inserted before
     *         defaults to true
     */
    var domMove = function(destination, anchor, after) {
        if (!isBoolean(after)) {
            after = true;
        }

        destination = new CERNY.dom.Node(destination);

        if (!isNode(anchor)) {
            if (after) {
                anchor = destination.lastChild;
            } else {
                anchor = destination.firstChild;
            }
        }
        if (after) {
            if (!anchor || anchor.nextSibling === null) {
                destination.appendChild(this.node);
            } else {
                destination.node.insertBefore(this.node, anchor.nextSibling);
            }
        } else {
            destination.node.insertBefore(this.node, anchor);
        }
    };
    signature(domMove, "undefined", "object", ["object", "undefined"], ["boolean", "undefined"]);
    method(CERNY.dom.Node.prototype, "domMove", domMove);

    /*
     * Move the node within the family in either direction.
     *
     * predicate - the predicate for the anchor to match, default is isNode
     * next - if true, next sibling, if false, previousSibling, default is true
     */
    var domMoveWithin = function(predicate, next) {
        if (!isBoolean(next)) {
            next = true;
        }

        if (!isFunction(predicate)) {
            predicate = isNode;
        }

        var sibling = this.getClosestSibling(predicate, next);

        if (sibling !== null) {
            this.domMove(this.node.parentNode, sibling, next);
        }
    };
    signature(domMoveWithin, "undefined", ["function", "undefined"], ["boolean", "undefined"]);
    method(CERNY.dom.Node.prototype, "domMoveWithin", domMoveWithin);

    /**
     * Move the node within the family up.
     *
     * predicate - the predicate for the anchor to match, default is isNode
     */
    var domMoveUpWithin = function(predicate) {
        this.domMoveWithin(predicate, false);
    };
    signature(domMoveUpWithin, "undefined", ["function", "undefined"]);
    method(CERNY.dom.Node.prototype, "domMoveUpWithin", domMoveUpWithin);

    /**
     * Move the node within the family down.
     *
     * predicate - the predicate for the anchor to match, default is isNode
     */
    var domMoveDownWithin = function(predicate) {
        this.domMoveWithin(predicate, true);
    };
    signature(domMoveDownWithin, "undefined", ["function", "undefined"]);
    method(CERNY.dom.Node.prototype, "domMoveDownWithin", domMoveDownWithin);


    /**
     * Replace node by byNode.
     *
     * byNode - the node by which this node is to replace
     */
    var domReplace = function(byNode) {
        if (isNode(byNode)) {
            this.node.parentNode.replaceChild(byNode, this.node);
        }
    };
    signature(domReplace, "undefined", "object");
    method(CERNY.dom.Node.prototype, "domReplace", domReplace);


    /**
     * Delete this node.
     * Altough the Node object still exists all operations will fail.
     *
     * By writing the tests, it occured to me that this method is not well
     * named, since the node is actually not deleted, it is just removed
     * from it's parent.
     */
    var domDelete = function() {
        if (this.node.parentNode) {
            this.node.parentNode.removeChild(this.node);
        }
        // For Topincs it is impossible to set this.node to null,
        // because large code parts interpret this functions in a way,
        // that afterwards the node can be operated on and integrated
        // in the DOM tree again. See also (1)
        // this.node = null;
    };
    signature(domDelete, "undefined");
    method(CERNY.dom.Node.prototype, "domDelete", domDelete);
    // (1) A postcondition to make sure that it was intentional that
    // the this.node is not set to null.
    post(domDelete, function() {
        check(isNode(this.node), "this.node must be a dom node");
    });

    /**
     * Insert node into this node before a certain child (anchor). If
     * the second paremeter is omitted node is inserted before the
     * first child into this node.
     *
     * node - the node to be inserted can be a native Node or an instance
     *        of this class
     * anchor - the node before which node should be inserted before, can
     *          be a native Node or an instance of this class, if null the
     *          first child of this node is taken instead, if there is no
     *          first node, it just inserted as the first node
     */
    var insertBefore = function(node, anchor) {
        node = new CERNY.dom.Node(node);
        if (anchor) {
            anchor = new CERNY.dom.Node(anchor);
            this.node.insertBefore(node.node, anchor.node);
        } else {
            this.node.insertBefore(node.node, this.node.firstChild);
        }
    };
    signature(insertBefore, "undefined", [CERNY.dom.Node, "object"], [CERNY.dom.Node, "object", "undefined"]);
    method(CERNY.dom.Node.prototype, "insertBefore", insertBefore);

    /**
     * Insert a node after a certain child.
     *
     * node - the node to be inserted
     * anchor - the child node after which the node should be inserted, default is last one
     */
    var insertAfter = function(node, anchor) {
        if (anchor) {
            anchor = new CERNY.dom.Node(anchor);
            if (anchor.node.nextSibling) {
                this.insertBefore(node, anchor.node.nextSibling);
                return;
            }
        }
        this.appendChild(node);
    };
    signature(insertAfter, "undefined", [CERNY.dom.Node, "object", "undefined"], [CERNY.dom.Node, "object", "undefined"]);
    method(CERNY.dom.Node.prototype, "insertAfter", insertAfter);

    /**
     * Performs a sorted insert.
     *
     * node - the node to be inserted
     * func - the comparison function (takes the acutal nodes, not
     *        the handlers) to determine the place of the insert. If
     *        undefined, the node is appended at the end.
     */
    var insert = function(node, func) {
        node = CERNY.dom.Node(node);
        if (!func) {
            this.appendChild(node);
        } else {
            var climber = this.node.firstChild;
            while (climber && func(climber, node.node) <= 0) {
                climber = climber.nextSibling;
            }
            if (climber) {
                this.insertBefore(node, climber);
            } else {
                this.appendChild(node);
            }
        }
    };
    signature(insert, "undefined", [CERNY.dom.Node, "object"], ["function", "undefined"]);
    method(CERNY.dom.Node.prototype, "insert", insert);


})();
/**
 * Filename    : Observable.js
 * Author      : Robert Cerny
 * Created     : 2007-06-13
 * Last Change : 2008-09-26
 *
 * Description:
 *   This script provides a function <code>Observable</code> to make
 *   an object call observers when events occur.
 *
 *   <code>Observable</code> should be called on the prototype of a
 *   constructor, but it can also be called on individual objects. The
 *   first option is preferable, because it is faster and only
 *   attaches the methods to the prototype and not to every single
 *   instance.
 *
 *   Observable attaches the methods <code>addObserver</code>,
 *   <code>removeObserver</code>, <code>removeObservers</code> and
 *   <code>notify</code> to the object.
 *
 *   On the first call to <code>addObserver</code> the object receives
 *   a property <code>_observableObservers</code>.
 *
 *   An observable can forward its events to other observables. Use
 *   the methods <code>addForwarding</code> and
 *   <code>removeForwarding</code> to use this feature.
 *
 * History:
 *   2008-09-26 Performance improvement and using pushUnique.
 *   2008-05-13 Added addForwarding and removeForwarding.
 *   2007-08-17 Added removeObservers.
 *   2007-06-13 Created.
 */

CERNY.require("CERNY.event.Observable",
              "CERNY.js.Array");

(function() {

    var check = CERNY.check;
    var method = CERNY.method;
    var signature = CERNY.signature;
    var pre = CERNY.pre;

    var logger = CERNY.Logger("CERNY.event.Observable");

    /**
     * Makes an object observable.
     *
     * obj - the object to make observable
     */
    function Observable(obj) {
        method(obj, "addObserver", addObserver);
        method(obj, "removeObserver", removeObserver);
        method(obj, "removeObservers", removeObservers);
        method(obj, "notify", notify);
        method(obj, "addForwarding", addForwarding);
        method(obj, "removeForwarding", removeForwarding);
    }
    signature(Observable, "undefined", "object");
    method(CERNY.event, "Observable", Observable);
    pre(Observable, function(obj) {
        check(!obj._observableObservers,
              "Observable cannot be called on object with observers.");
    });

    /**
     * Add an observer (a function) to be called when event occurs.
     *
     * event - the event that is observed
     * observer - the function that should be called on the event
     */
    function addObserver(event, observer) {
        if (!this._observableObservers) {
            this._observableObservers = {};
        }
        if (!this._observableObservers[event]) {
            this._observableObservers[event] = [];
        }
        this._observableObservers[event].pushUnique(observer);
    }
    signature(addObserver, "undefined", "string", "function");

    /**
     * Remove an observer.
     *
     * event - the event that the observer observes
     * observer - the observer to be removed
     */
    function removeObserver(event, observer) {
        if (this._observableObservers[event]) {
            this._observableObservers[event].remove(observer);
        }
    }
    signature(removeObserver, "undefined", "string", "function");

    /**
     * Remove observers. If an event is passed, only observers of that
     * event will be removed. Otherwise all observers will be removed.
     *
     * event - the event for which observers should be removed
     */
    function removeObservers(event) {
        if (event) {
            delete(this._observableObservers[event]);
        } else {
            delete(this._observableObservers);
        }
    }
    signature(removeObservers, "undefined", ["undefined", "string"]);

    /**
     * Notify all observers of event.
     *
     * event - the event that occurs
     * arguments - arguments that will be passed to the observers
     */
    function notify(event) {
        var args = [];
        for (var i = 1; i < arguments.length; i++) {
            args[i-1] = arguments[i];
        }
        if (this._observableObservers && this._observableObservers[event]) {
            var observers = this._observableObservers[event];
            for (var i = 0, l = observers.length; i < l; i++) {
                observers[i].apply(null, args);
            }
        }
        var t = this;

        if (this._observableForwardings) {
            var forwardings = this._observableForwardings;
            for (var i = 0, l = forwardings.length; i < l; i++) {
                var forward = forwardings[i];
                args.unshift(event);
                forward.notify.apply(forward, args);
            }
        }
    }
    signature(notify, "undefined", "string", "any");

    /**
     * Forward events to another observeable.
     *
     * forwarding - the observable the events should be forwarded
     */
    function addForwarding(forwarding) {
        if (!this._observableForwardings) {
            this._observableForwardings = [];
        }
        this._observableForwardings.pushUnique(forwarding);
    }
    signature(addForwarding, "undefined", "object");

    /**
     * Remove a forwarding.
     *
     * forwarding - the forwarding to be removed
     */
    function removeForwarding(forwarding) {
        if (this._observableForwardings) {
            this._observableForwardings.remove(forwarding);
        }
    }
    signature(removeForwarding, "undefined", "object");

})();
/**
 * Filename    : jsdomlib.js
 * Author      : Robert Cerny
 * Created     : 2007-04-16
 * Last Change : 2008-10-09
 *
 * Holds the rest of jsDOMlib, which was not eleminated of the first
 * migration from jsDOMlib to Cerny.js. This should be eliminated aswell.
 */

CERNY.require("JSDOMLIB");

JSDOMLIB = {};

Function.prototype.method = function(name, func) {
    this.prototype[name] = func;
    return this;
};

Function.method("inherits", function (parent) {
    var d = 0;
    var p = (this.prototype = new parent());
    this.method('uber', function uber(name) {
        var f;
        var r;
        var t = d;
        var v = parent.prototype;
        if (t) {
            while (t) {
                v = v.constructor.prototype;
                t -= 1;
            }
            f = v[name];
        } else {
            f = p[name];
            if (f == this[name]) {
                f = v[name];
            }
        }
        d += 1;
        r = f.apply(this, Array.prototype.slice.apply(arguments, [1]));
        d -= 1;
        return r;
    });
    return this;
});

Function.method('swiss', function (parent) {
    for (var i = 1; i < arguments.length; i += 1) {
        var name = arguments[i];
        this.prototype[name] = parent.prototype[name];
    }
});

/**
 * Retrieve cookie.
 *
 * name - name of the cookie to retrieve
 */
function getCookie(name) {
    var dc = document.cookie;
    var prefix = name + "=";
    var begin = dc.indexOf("; " + prefix);
    if (begin == -1) {
        begin = dc.indexOf(prefix);
        if (begin != 0) return null;
    } else
        begin += 2;
    var end = document.cookie.indexOf(";", begin);
    if (end == -1)
        end = dc.length;
    return decodeURI(dc.substring(begin + prefix.length, end));
}


/**
 * Sets a cookie.
 *
 * name - name of the cookie
 * value - value of the cookie
 * expires - expiration date of the cookie
 */
function setCookie(name, value, expires, path, domain, secure) {
    var _cookie = name + "=" + encodeURI(value) +
        ((expires) ? "; expires=" + expires.toGMTString() : "") +
        ((path) ? "; path=" + path : "") +
        ((domain) ? "; domain=" + domain : "") +
        ((secure) ? "; secure" : "");
    document.cookie = _cookie;
}
/**
 * Filename    : Element.js
 * Author      : Robert Cerny
 * Created     : 2004-10-27
 * Last Change : 2009-10-15
 *
 * Description:
 *   Provides a handle for a DOM element.
 *
 * History:
 *   2007-09-27 Added method setInnerHTML.
 *   2007-04-11 Completly refactored.
 *   2004-10-27 Created.
 */

CERNY.require("CERNY.dom.Element",
              "CERNY.dom.Node",
              "CERNY.dom",
              "CERNY.event.Observable",
              "JSDOMLIB",
              "CERNY.js.String");

(function() {

    /**
     * Create a handle for an existing DOM Element.
     *
     * elementOrId - the existing DOM element or it's id
     * return - a handle for the DOM element
     */
    CERNY.dom.Element = function(elementOrId) {
        if (elementOrId instanceof CERNY.dom.Element) {
            return elementOrId;
        }
        CERNY.dom.Node.call(this, elementOrId);
        CERNY.event.Observable(this);
        return this;
    };
    CERNY.signature(CERNY.dom.Element, "object", ["string", "object"]);
    CERNY.intercept(CERNY.dom, "Element");

    CERNY.inherit(CERNY.dom.Element, CERNY.dom.Node);

    var name = "CERNY.dom.Element";
    CERNY.dom.Element.logger = CERNY.Logger(name);
    CERNY.dom.Element.prototype.logger = CERNY.Logger(name);

    var EVT_SHOWN = name + ".EVT_SHOWN";
    var EVT_HIDDEN = name + ".EVT_HIDDEN";

    CERNY.dom.Element.EVT_SHOWN = EVT_SHOWN;
    CERNY.dom.Element.EVT_HIDDEN = EVT_HIDDEN;

    /**
     * Set an attribute for this element.
     *
     * name - name of the attribute to set
     * value - value to set the attribute to
     */
    var setAttr = function(name, value) {
        switch (name) {

            // The following are the exceptions from the default with
            // a reason why we must deviate.

            // IE does not do it
            case "style":
               this.node.style.cssText = value;
               break;

            // IE does not do it
            case "class":
               this.setCSSClass(value);
               break;

            default:
               this.node.setAttribute(name, value);
               break;
        }
    };
    CERNY.signature(setAttr, "undefined", "string", "string");
    CERNY.method(CERNY.dom.Element.prototype, "setAttr", setAttr);

    /**
     * Return the value of an attribute.
     *
     * name - name of the attribute to return the value of
     */
    var getAttr = function(name) {
        var value;
        switch (name) {

            // The following are the exceptions from the default with
            // a reason why we must deviate.

            // IE returns the object on getAttribute where as other
            // browsers return the string that defines the style.
            case "style":
                value = this.node.style.cssText;
                break;

            // IE throws on Object Error.
            case "class":
                value = this.getCSSClass();
                break;

            default:
                value = this.node.getAttribute(name);
                break;
        }

        if (value) {
            return value;
        }
        return "";
    };
    CERNY.signature(getAttr, "string", "string");
    CERNY.method(CERNY.dom.Element.prototype, "getAttr", getAttr);

    /**
     * Set the text of this element.
     *
     * text - the text to set
     */
    var setText = function(text) {
        this.deleteChildren(isTextNode);
        this.appendChild(document.createTextNode(text));
    };
    CERNY.signature(setText, "undefined", ["string", String]);
    CERNY.method(CERNY.dom.Element.prototype, "setText", setText);

    /**
     * Return the text of the element.
     *
     * return - the text of the element, or null, if there is none
     */
    var getText = function() {
        var firstTextNode = this.getFirstChild(isTextNode),
        text = null;

        if (firstTextNode) {
            text = firstTextNode.data;
        }
        return text;
    };
    CERNY.signature(getText, ["string", "null"]);
    CERNY.method(CERNY.dom.Element.prototype, "getText", getText);

    /**
     * Set the inner html of the element.
     *
     * innerHtml - the html to set
     */
    var setInnerHTML = function(html) {
        this.node.innerHTML = html;
    };
    CERNY.signature(setInnerHTML, "undefined", "string");
    CERNY.method(CERNY.dom.Element.prototype, "setInnerHTML", setInnerHTML);


    /**
     * Show the element.
     *
     */
    var show = function() {
        this.deleteCSSClass("hidden");
        this.notify(EVT_SHOWN);
    };
    CERNY.signature(show, "undefined");
    CERNY.method(CERNY.dom.Element.prototype, "show", show);

    /**
     * Hide the element.
     *
     */
    var hide = function() {
        this.addCSSClass("hidden");
        this.notify(EVT_HIDDEN);
    };
    CERNY.signature(hide, "undefined");
    CERNY.method(CERNY.dom.Element.prototype, "hide", hide);

    /**
     * Determine whether this element is visible (displayed).
     *
     * return - true, if it is visible, otherwise false
     */
    var isVisible = function() {
        return !this.isHidden();
    };
    CERNY.signature(isVisible, "boolean");
    CERNY.method(CERNY.dom.Element.prototype, "isVisible", isVisible);

    /**
     * Determine whether this element is hidden (display: none).
     *
     * return - true, if it is hidden, otherwise false
     */
    var isHidden = function() {
        return this.hasCSSClass("hidden");
    };
    CERNY.signature(isHidden, "boolean");
    CERNY.method(CERNY.dom.Element.prototype, "isHidden", isHidden);

    /**
     * Toggle the visibility of this element.
     *
     */
    var toggleVisibilty = function() {
        if (this.isVisible()) {
            this.hide();
        } else {
            this.show();
        }
    };
    CERNY.signature(toggleVisibilty, "undefined");
    CERNY.method(CERNY.dom.Element.prototype, "toggleVisibilty", toggleVisibilty);

    /**
     * Return the CSS class string of the element.
     *
     */
    var getCSSClass = function() {
        return this.node.className;
    };
    CERNY.signature(getCSSClass, "string");
    CERNY.method(CERNY.dom.Element.prototype, "getCSSClass", getCSSClass);


    /**
     * Sets the CSS class of the element.
     *
     * cssClass - the cssClass to set the element to
     */
    var setCSSClass = function(cssClass) {
        cssClass = cssClass.trim();
        // not more than one whitespace in the middle
        // cssClass = cssClass.replace(/\s{2,}/g, " ");
        this.node.className = cssClass;
    };
    CERNY.signature(setCSSClass, "undefined", "string");
    CERNY.method(CERNY.dom.Element.prototype, "setCSSClass", setCSSClass);

    /**
     * Determine whether this element has a certain css class.
     *
     * cssClass - the css class to check for
     */
    var hasCSSClass = function(cssClass) {
        cssClass = cssClass.trim();
        var regexp = new RegExp("(\\s|^)" + cssClass + "(\\s|$)");
        return this.getCSSClass().match(regexp) !== null;
    };
    CERNY.signature(hasCSSClass, "boolean", "string");
    CERNY.method(CERNY.dom.Element.prototype, "hasCSSClass", hasCSSClass);

    /**
     * Add a class to the element, by default to the end. Avoids
     * duplication of classes.
     *
     * cssClass - the class to add to the element
     */
    var addCSSClass = function(cssClass) {
        if (!this.hasCSSClass(cssClass)) {
            this.setCSSClass(this.getCSSClass() + " " + cssClass);
        }
    };
    CERNY.signature(addCSSClass, "undefined", "string");
    CERNY.method(CERNY.dom.Element.prototype, "addCSSClass", addCSSClass);

    /**
     * Replace a CSS class by another.
     *
     * cssClassOld - the name of the class to replace
     * cssClassNew - the name of the replacing class
     * force - add cssClassNew, if cssClassOld is not occuring
     */
    var replaceCSSClass = function(cssClassOld, cssClassNew, force) {
        if (!isBoolean(force)) {
            force = false;
        }

        var currentCssClass = this.getCSSClass();

        var regexp = "/(\\s|^)" + cssClassOld + "(\\s|$)/g";
        var newClass = currentCssClass.replace(new RegExp(eval(regexp)), " " + cssClassNew + " ");
        this.setCSSClass(newClass);
        if (force && !this.hasCSSClass(cssClassNew)) {
            this.addCSSClass(cssClassNew);
        }
    };
    CERNY.signature(replaceCSSClass, "undefined", "string", "string", ["boolean", "undefined"]);
    CERNY.method(CERNY.dom.Element.prototype, "replaceCSSClass", replaceCSSClass);

    /**
     * Delete a css class from the class attribute of element.
     *
     * cssClass - name of the class to delete
     */
    var deleteCSSClass = function(cssClass) {
        this.replaceCSSClass(cssClass, "");
    };
    CERNY.signature(deleteCSSClass, "undefined", "string");
    CERNY.method(CERNY.dom.Element.prototype, "deleteCSSClass", deleteCSSClass);

    /**
     * Remove stlye from this element.
     */
    var removeStyle = function() {
        this.setAttr("style", "");
    };
    CERNY.signature(removeStyle, "undefined");
    CERNY.method(CERNY.dom.Element.prototype, "removeStyle", removeStyle);

    function getAbsolute(element, property) {
        var r = element[property];
        var parent = element.offsetParent;
        while (parent !== null) {
            r += parent[property];
            parent = parent.offsetParent;
        }
        return r;
    }

    /**
     * Return the absolute x coordinate of this element.
     *
     * return - the absolute x coordinate
     */
    var getAbsoluteX = function () {
        return getAbsolute(this.node, "offsetLeft");
    };
    CERNY.signature(getAbsoluteX, "number");
    CERNY.method(CERNY.dom.Element.prototype, "getAbsoluteX", getAbsoluteX);

    /**
     * Return the absolute y coordinate of this element.
     *
     * return - the absolute y coordinate
     */
    var getAbsoluteY = function () {
        return getAbsolute(this.node, "offsetTop");
    };
    CERNY.signature(getAbsoluteY, "number");
    CERNY.method(CERNY.dom.Element.prototype, "getAbsoluteY", getAbsoluteY);

    var moveTo = function(x,y) {
        this.setAttr("style", "position: absolute; " +
                     "top: " + y + "px; " +
                     "left: " + x + "px;");
    };
    CERNY.signature(moveTo, "undefined", "number", "number");
    CERNY.method(CERNY.dom.Element.prototype, "moveTo", moveTo);

    /**
     * Move this element over target.
     *
     * 0 visibility percentage means, target is covered completly on respective axis
     * 1 visibility percentage means, target is completly visible on respective axis
     *
     * target - the target node over which to move this Element
     * dX - percentage of visibility of target on X after moving [0,1]
     * dY - percentage of visibility of target on Y after moving [0,1]
     */
    var moveOver = function(target, dX, dY) {
        target = new CERNY.dom.Element(target);

        var x = target.getAbsoluteX() + target.node.offsetWidth * dX;
        var y = target.getAbsoluteY() + target.node.offsetHeight * dY;

        this.moveTo(x,y);
    };
    CERNY.signature(moveOver, "undefined", [CERNY.dom.Element, "object"], "number", "number");
    CERNY.method(CERNY.dom.Element.prototype, "moveOver", moveOver);

    /**
     * Determine whether this element is over certain coordinates.
     *
     * x - the x coordinate
     * y - the y coordinate
     * return - true, if this element is over (x,y), otherwise false
     */
    var isOver = function(x, y) {
        var tlX = this.getAbsoluteX();
        var tlY = this.getAbsoluteY();
        var brX = this.getAbsoluteX() + this.node.offsetWidth;
        var brY = this.getAbsoluteY() + this.node.offsetHeight;
        return (tlX <= x && x <= brX) && (tlY <= y && y <= brY);
    };
    CERNY.signature(isOver, "boolean", "number", "number");
    CERNY.method(CERNY.dom.Element.prototype, "isOver", isOver);

    /**
     * Sort children of this element matching a certain
     * predicate. Delete children and append them.
     *
     * comparator - the function to be used for comparison, defualt is Element.compareContent
     * predicate - the predicate to decide which elements to sort, default is isElement
     */
    var sortChildren = function(comparator, predicate) {
        if (!comparator) {
            comparator = CERNY.dom.Element.compareContent;
        }
        if (!predicate) {
            predicate = isElement;
        }
        var children = this.getChildren(predicate).sort(comparator);
        this.deleteChildren(predicate);
        for (var i = 0; i < children.length; i++) {
            this.appendChild(children[i]);
        }
    };
    CERNY.signature(sortChildren, "undefined", ["function", "undefined"], ["function", "undefined"]);
    CERNY.method(CERNY.dom.Element.prototype, "sortChildren", sortChildren);

    /**
     * Compare the content of two elements.
     * Static.
     *
     * e1 - the first element to compare
     * e2 - the second element to compare
     */
    var compareContent = function(e1, e2) {
        e1 = new CERNY.dom.Element(e1);
        e2 = new CERNY.dom.Element(e2);
        var t1 = e1.getText();
        var t2 = e2.getText();
        if (!t1 || !t2) {
            return 0;
        }

        t1 = t1.toLowerCase();
        t2 = t2.toLowerCase();
        if (t1 == t2) {
            return 0;
        }
        if (t1 < t2) {
            return -1;
        }
        if (t1 > t2) {
            return 1;
        }
    };
    CERNY.signature(compareContent, "number", "object", "object");
    CERNY.method(CERNY.dom.Element, "compareContent", compareContent);

    /**
     * Create a element in the document and returns it.
     * Has one advantage over document.createElement: text can be in the element.
     *
     * tagName - the tagName of the element to create
     * text - the text of the element to create
     * arguments - unlimited number of strings of the form 'attributeName=attributeValue'
     */
    var create = function(tagName, text) {
        var element = new CERNY.dom.Element(document.createElement(tagName));
        if (text) {
            element.setText(text);
        }

        for (var i = 2; i < arguments.length; ++i) {
            var next = arguments[i];
            if (next !== null) {
                var position = next.indexOf("=");
                var attributeName = "";
                var attributeValue = "";
                if (position > 0) {
                    attributeName = next.substring(0, position);
                    attributeValue = next.substring(position + 1, next.length);
                }
            }
            element.setAttr(attributeName, attributeValue);
        }
        return element;
    };
    CERNY.signature(create, CERNY.dom.Element, "string", ["string", "null", "undefined"], ["string", "undefined"]);
    CERNY.method(CERNY.dom.Element, "create", create);

    /**
     * Determine whether an element has a certain css class.
     *
     * element - the element to inspect
     * cssClass - the css class to look for
     * return - true, if element has css class, otherwise false
     */
    var cssFilter = function(element, cssClass) {
        if (isElement(element)) {
            return new CERNY.dom.Element(element).hasCSSClass(cssClass);
        }
        return false;
    };
    CERNY.signature(cssFilter, "boolean", "object", "string");
    CERNY.method(CERNY.dom.Element, "cssFilter", cssFilter);


})();
/**
 * Filename    : util.js
 * Author      : Robert Cerny
 * Created     : 01.12.2005
 * Last Change : 2009-11-30
 *
 * Copyright 2005 Robert Cerny
 */

CERNY.require("TOPINCS.util",
              "TOPINCS.cons",
              "CERNY.http.Request",
              "CERNY.http.Response",
              "CERNY.dom.Element",
              "CERNY.util");

(function () {

    var method = CERNY.method;
    var signature = CERNY.signature;

    var Element = CERNY.dom.Element;
    var Request = CERNY.http.Request;
    var Response = CERNY.http.Response;
    var fillNumber = CERNY.util.fillNumber;

    var logger = CERNY.Logger("TOPINCS.util");
    var util = {};
    util.logger = logger;
    TOPINCS.util = util;

    var EL_UI_BLOCKER = Element.create("div", null, "id=uiblocker");

    function getResult(url, accept, nocache, options) {
        var result;
        accept = accept || MEDIA_TYPE_JSON;
        nocache = nocache || false;
        options = options || { "X-Topincs-Options": "mind_name=1",
                               "X-Topincs-Accept-Scope": ACCEPT_SCOPE};

        var request = new Request("GET", url);

        // Make sure the display names are sent for referenced topics
        for (var key in options) {
            if (options.hasOwnProperty(key)) {
                request.setHeader(key, options[key]);
            }
        }
        request.setHeader("Accept", accept);
        if (nocache) {
            request.setNoCacheHeaders();
        }

        var response = request.sendSynch();
        switch (response.getStatus()) {

        case 404:
            throw new Error("Resource '" + request.url + "' does not exist.");
            break;

        case 500:
            TOPINCS.util.fatalError("Server error: " + response.getBody());
            break;

        default:
            try {
                result = response.getValue();
            } catch (e) {
                if (e instanceof SyntaxError) {
                    throw new Error("Response is not a JSON document: \n" + response.getBody());
                }
                throw e;
            }
        }

        return result;
    };
    signature(getResult, "object", "string", ["undefined", "string"]);
    method(util, "getResult", getResult);

    function fatalError(message) {
        TOPINCS.util.showMessage(message);
        throw new Error(message);
    }
    signature(fatalError, "undefined", "string");
    method(util, "fatalError", fatalError);


    function getAssociations(query) {
        return TOPINCS.util.getResult(ROLES_SEARCH_URL + "?" + query, MEDIA_TYPE_ROLE_PROXY_ARRAY);
    }
    signature(getAssociations, Array, "string");
    method(util, "getAssociations", getAssociations);

    /**
     * Return the datatypes for the occurrence type.
     *
     * typeId - the occurrence type id
     */
    function getDatatypes(typeId) {
        var url = DATATYPES_URL;
        if (typeId) {
            url += "?ot=id:" + typeId;
        }
        return TOPINCS.util.getResult(url, MEDIA_TYPE_DATATYPE_ARRAY).sort();
    }
    signature(getDatatypes, Array, ["undefined", "string"]);
    method(util, "getDatatypes", getDatatypes);

    function abortOpenRequests() {

        // First copy the requests into a new array, then empty the
        // passed array and then abort all pending requests. This way the
        // check for abortion for a request (absence in the passed array)
        // will immedialty kick in
        var requests = [];
        OPEN_REQUESTS.map(function(req) {
            requests.push(req);
        });
        OPEN_REQUESTS = [];
        requests.map(function(req) {
            req.abort();
        });

    }
    signature(abortOpenRequests, "undefined");
    method(util, "abortOpenRequests", abortOpenRequests);

    /**
     * Simple comparator for sorting topic proxies by name.
     */
    function compareTopicProxiesByName(x,y) {
        return (x.label.toLowerCase() < y.label.toLowerCase()) ? -1 : 1;
    }
    signature(compareTopicProxiesByName, "number", "object", "object");
    method(util, "compareTopicProxiesByName", compareTopicProxiesByName);

    /**
     * Simple comparator for sorting topic proxies by id.
     */
    function compareTopicProxiesById(x,y) {
        return (Number(x.id) < Number(y.id)) ? -1 : 1;
    }
    signature(compareTopicProxiesById, "number", "object", "object");
    method(util, "compareTopicProxiesById", compareTopicProxiesById);

    function getMetaInfo(item) {
        return TOPINCS.util.getResult(META_URL + "?item_type=" + item.itemType + "&system_id=" + item.id);
    }
    signature(getMetaInfo, "object", "string");
    method(util, "getMetaInfo", getMetaInfo);

    function meta(_item) {
        var meta, append, iis, date, creation_ts, parts, time;

        var metaInfo = getMetaInfo(_item);

        try {
            meta = '<table class="meta" cellpadding="0" cellspacing="0">';
            append = function (_field, _value) {
                if (_value.indexOf("://") > 0 || _value.indexOf("wiki") == 0) {
                    _value = '<a href="' + _value + '">' + _value + '</a>';
                }
                meta = meta + '<tr>'
                + '<td class="field">' + _field + '</td>'
                + '<td class="value">' + _value + '</td>'
                + '</tr>';
            }

            append(DICT.lab_item_identifers, _item.getAbsoluteURL());
            // Item identifiers
            iis = _item.item_identifiers.slice(1, _item.item_identifiers.length);
            iis.map(function(_ii) {
                append("", _ii);
            });

            if (_item.parent) {
                append(DICT.lab_parent, _item.parent);
            }
            append(DICT.lab_meta_creation_tag, metaInfo.creation_tag);

            parts = metaInfo.creation_ts.split(" ");
            date = parts[0];
            time = parts[1];
            creation_ts = '<span><a href="javascript:TOPINCS.editor.Editor.showJournal(' + "'" +  date + "'" + ');"'
                + ' title="' + DICT.lab_jump_to_journal + '">'
                + date + "</a> " + time + "</span>";

            append(DICT.lab_meta_created, creation_ts);
            append(DICT.lab_meta_by, metaInfo.creation_user);
            append(DICT.lab_meta_modified, metaInfo.modification_ts);
            append(DICT.lab_meta_by, metaInfo.modification_user);
            if (_item.itemType == "Topic") {
                append(DICT.lab_wiki_url, createWikiUri(_item.id));
            }

            meta += '</table>';

            return meta;
        } catch (_e) {
            logger.error("Exception when generating info: " + _e.message);
            return DICT.msg_no_information;
        }
    }
    signature(meta, "string", "object");
    method(util, "meta", meta);

    function updateAcceptScope() {
        var scope = CONF.scope;
        ACCEPT_SCOPE = "";

        var first = true;
        scope.map(function (_s) {
            if (first) {
                first = false;
            } else {
                ACCEPT_SCOPE += ",";
            }
            ACCEPT_SCOPE += _s.id;
        });
    }
    signature(updateAcceptScope, "undefined");
    method(util, "updateAcceptScope", updateAcceptScope);

    function showMessage(message, error) {
        alert(message);
        if (error) {
            alert(error);
        }
    }
    signature(showMessage, "undefined", "string");
    method(util, "showMessage", showMessage);

    function showConfirmation(message) {
        return confirm(message);
    }
    signature(showConfirmation, "boolean", "string");
    method(util, "showConfirmation", showConfirmation);

    function getTopics(substring, type, map, limit) {
        var url = TOPIC_SEARCH_URL + "?";
        if (substring) {
            url += "&string=" + encodeURIComponent(substring);
        }
        if (type) {
            url += "&type=" + type;
        }
        if (map) {
            url += "&map=" + map;
        }
        if (limit) {
            url += "&limit=" + limit;
        }

        var request = new Request("GET", url);
        request.setHeader("Accept", MEDIA_TYPE_STORE_SEARCH_RESULT_V2);
        var response = request.sendSynch();
        return response.getValue();
    }
    signature(getTopics, "object", "string", ["undefined", "string"], ["undefined", "string"]);
    method(util, "getTopics", getTopics);

    function createWikiUri(topicId, base) {
        base = base || "";
        if (isNumber(Number(topicId))) {
            topicId = "id:" + topicId;
            return base + "wiki/" + topicId;
        }
    }
    signature(createWikiUri, "string", ["string", "undefined"]);
    method(util, "createWikiUri", createWikiUri);

    function extractSystemIdFromWikiUri(wikiUri) {
        var matches = wikiUri.match(/\d+$/);
        if (isArray(matches)) {
            return matches[0];
        }
    }
    signature(extractSystemIdFromWikiUri, ["string", "undefined"], "string");
    method(util, "extractSystemIdFromWikiUri", extractSystemIdFromWikiUri);

    function compareById(a,b) {
        return a.id === b.id;
    }
    signature(compareById, "boolean", "object", "object");
    method(util, "compareById", compareById);

    function isMultiline(str) {
        return str.indexOf("\r") >= 0 || str.indexOf("\n") >= 0;
    }
    signature(isMultiline, "boolean", "string");
    method(util, "isMultiline", isMultiline);

    function isCode(str) {
        var frequencies = getCharacterFrequencies(str);
        var lotsOfBraces = frequencies.relative("(",")","{","}","[","]","=") >= 0.02;
        var dotAtTheEnd = str.match(/\.\s*$/) !== null;
        return lotsOfBraces && !dotAtTheEnd;
    }
    signature(isCode, "boolean", "string");
    method(util, "isCode", isCode);

    function getCharacterFrequencies(str, max) {
        max = max || str.length;
        if (max > str.length) {
            max = str.length;
        }

        var result = {};
        for (var i = 0; i < max; i++) {
            var charCode = str.charCodeAt(i);
            if (isUndefined(result[charCode])) {
                result[charCode] = 0;
            }
            result[charCode] += 1;
        }
        method(result, "relative", function () {
            var total = 0;
            for (var i = 0; i < arguments.length; i++) {
                var freq = this[arguments[i].charCodeAt(0)];
                if (freq) {
                    total +=  freq / max;
                }
            }
            return total;
        });

        return result;
    }
    signature(getCharacterFrequencies, "object", "string", ["number", "undefined"]);
    method(util, "getCharacterFrequencies", getCharacterFrequencies);

    function countLines(str) {
        var count = str.split("\n").length;
        if (count < 2) {
            count = str.split("\r").length;
        }
        return count - 1;
    }
    signature(countLines, "number", "string");
    method(util, "countLines", countLines);

    // ie has problems with setting relative locations
    function setLocation(url) {
        var baseUri = getBaseUri();
        if (baseUri) {
            url = baseUri + url;
        }
        document.location = url;
    }
    signature(setLocation, "undefined", "string");
    method(util, "setLocation", setLocation);

    function getJournal(start, end) {
        function format(date) {
            function fill(value) {
                return value < 10 ? "0" + value : value;
            }
            return "" + date.getFullYear() +
                fill(date.getMonth() + 1) + fill(date.getDate()) +
                fill(date.getHours()) + fill(date.getMinutes()) + fill(date.getSeconds());
        }

        var query =  "start=" + format(start) + "&end=" + format(end);
        return TOPINCS.util.getResult(JOURNAL_URL + "?" + query);
    }
    signature(getJournal, Array, Date, Date);
    method(util, "getJournal", getJournal);

    function cache(object, methodName) {
        var func = object[methodName];
        if (!isFunction(func)) {
            throw new Error("Function '" + methodName + "' not found on object.");
        }
        var cache = {};

        function cachedFunction() {
            var key = argumentsToArray(arguments).join("-");
            var value = cache[key];
            if (!value) {
                value = func.apply(object, arguments);
                cache[key] = value;
            }
            return value;
        }

        method(object, methodName, cachedFunction);
    }
    signature(cache, "undefined", "object", "string", "function");
    method(util, "cache", cache);

    function blockUi() {
        var el = EL_UI_BLOCKER.node;
        document.body.appendChild(el);
        el.style.visibility = "visible";
    }
    signature(blockUi, "undefined");
    method(util, "blockUi", blockUi);

    function releaseUi() {
        EL_UI_BLOCKER.node.style.visibility = "hidden";
    }
    signature(releaseUi, "undefined");
    method(util, "releaseUi", releaseUi);

    function sendRequest(request, callback, onComplete) {
        if (callback) {
            if (onComplete) {
                callback = CERNY.joinFunctions(function(request) {
                    onComplete(new Response(request));
                }, callback);
            }
            request.sendAsynch(callback);
        } else {
            var response = request.sendSynch();
            if (onComplete) {
                onComplete(response);
            }
            return response;
        }
    }
    signature(sendRequest, ["undefined", Response], Request, "function", ["undefined", "function"]);
    method(util, "sendRequest", sendRequest);

    function getBaseUri() {
        return document.baseURI || document.getElementsByTagName("base")[0].href;
    }
    signature(getBaseUri, ["string", "undefined"]);
    method(util, "getBaseUri", getBaseUri);

    function isLocalLocator(locator) {
        return locator.indexOf(getBaseUri()) === 0;
    }
    signature(isLocalLocator, "boolean", "string");
    method(util, "isLocalLocator", isLocalLocator);

    function isDynamicLocator(locator) {
        if (isLocalLocator(locator)) {
            var relUri = locator.replace(getBaseUri(), "");
            return relUri.match(/^((topics|names|roles|occurrences|associations)\/)?[1-9][0-9]*$/) !== null;
        }
        return false;
    }
    signature(isDynamicLocator, "boolean", "string");
    method(util, "isDynamicLocator", isDynamicLocator);

    function isRelativeLocator(locator) {
        return isLocalLocator(locator) && !isDynamicLocator(locator);
    }
    signature(isRelativeLocator, "boolean", "string");
    method(util, "isRelativeLocator", isRelativeLocator);

    function localizeToolCode(code) {
        var newCode = "javascript:(" + code + ")();";
        newCode = newCode.replace(/BASE/, TOPINCS.HOST + TOPINCS.BASE);
        newCode = newCode.replace(new RegExp(" +", "g"), " ");
        return newCode;
    }
    signature(localizeToolCode, "string", "string");
    method(util, "localizeToolCode", localizeToolCode);

    function argumentsToArray(a) {
        var result = [];
        for (var i = 0; i < a.length; i++) {
            result.push(a[i]);
        }
        return result;
    }

})();
/**
 * Filename    : ValueViewer.js
 * Author      : Robert Cerny
 * Created     : 2007-06-11
 * Last Change : 2009-11-24
 */

CERNY.require("TOPINCS.widgets.ValueViewer",
              "TOPINCS.cons",
              "TOPINCS.widgets.DICT",
              "TOPINCS.util",
              "CERNY.util",

              "CERNY.text.DateFormat",
              "CERNY.js.Date",
              "CERNY.text.TimeFormat",

              // Has to be avoided for deployment reasons
              // See http://www.topincs.com/issues/wiki/id:171
              // "Wiky",
              "CERNY.dom.Element");

(function() {

    var DICT = TOPINCS.widgets.DICT;
    var Element = CERNY.dom.Element;
    var method = CERNY.method;
    var signature = CERNY.signature;
    var Logger = CERNY.Logger;
    var isMultiline = TOPINCS.util.isMultiline;
    var isCode = TOPINCS.util.isCode;
    var countLines = TOPINCS.util.countLines;

    TOPINCS.widgets.ValueViewer = ValueViewer;

    var logger = Logger("TOPINCS.widgets.ValueViewer");

    function ValueViewer(value, datatype, locale) {
        var cons = ValueViewer[datatype];
        if (!cons) {
            cons = ValueViewer._default;
        }
        var viewer = new cons(value, datatype, locale);
        return viewer;
    }
    ValueViewer.prototype.logger = logger;

    function init(t, value, datatype, locale) {
        t.value = value;
        t.datatype = datatype;
        t.locale = locale;
    }

    (function() {
        ValueViewer[DT_ANYURI] = AnyUriViewer;

        function AnyUriViewer(value, datatype, locale) {
            init(this, value, datatype, locale);
            this.el = Element.create("a");
        }

        function render() {
            this.el.setText(this.value);
            this.el.setAttr("href", this.value);
            this.el.addCSSClass("external");
            return this.el;
        }
        signature("render", CERNY.dom.Element);
        method(AnyUriViewer.prototype, "render", render);

    })();


    (function() {
        ValueViewer[DT_STRING] = StringViewer;
        ValueViewer._default = StringViewer;

        function StringViewer(value, datatype, locale) {
            init(this, value, datatype, locale);
            if (isMultiline(value)) {
                this.el = Element.create("div");
            } else {
                this.el = Element.create("span");
            }
        }

        function render() {
            if (this.value == "") {
                this.el.setText(DICT.lab_empty_string);
                this.el.addCSSClass("message");
            } else {
                var nodes = [document.createTextNode(this.value)];
                if (isMultiline(this.value)) {

                    // Split up the string into parapraphs
                    // http://www.topincs.com/issues/wiki/id:367
                    nodes = [];
                    var paragraphs = this.value.split("\n");
                    for (var j = 0, l = paragraphs.length; j < l; j++) {
                        nodes.push(Element.create("p", paragraphs[j]));
                    }
                    this.el.addCSSClass("multiline");
                }
                if (isCode(this.value)) {
                    this.el.addCSSClass("code");
                }
                // Append the nodes that display the string
                for (var i = 0, l = nodes.length; i < l; i++) {
                    this.el.appendChild(nodes[i]);
                }
            }

            return this.el;
        }
        signature("render", CERNY.dom.Element);
        method(StringViewer.prototype, "render", render);

    })();

    (function() {
        ValueViewer[DT_DATE] = DateViewer;

        function DateViewer(value, datatype, locale) {
            init(this, value, datatype, locale);
            this.el = Element.create("span");
        }

        function render() {
            var value = this.value;
            var t = this;
            var el;
            var date = Date.parseDate(value, CERNY.text.DateFormat.ISO);
            if (date) {
                el = formatDateWithLocalTime(date, function (_date) {
                    var timezoneFormat;
                    if (!CERNY.js.Date.isInLocalTimezone(_date)) {
                        timezoneFormat = t.locale.formats.timezone;
                    }
                    return date.formatDate(t.locale.formats.date, " ", timezoneFormat)
                });
            }
            this.el.appendChild(el);
            return this.el;
        }
        signature("render", CERNY.dom.Element);
        method(DateViewer.prototype, "render", render);

    })();

    (function() {
        ValueViewer[DT_BOOLEAN] = BooleanViewer;

        function BooleanViewer(value, datatype, locale) {
            init(this, value, datatype, locale);
            this.el = Element.create("span");
        }

        function render() {
            if (this.value === "1") {
                this.el.setText(" " + DICT.lab_yes);
            } else {
                this.el.setText(" " + DICT.lab_no);
            }
            return this.el;
        }
        signature("render", CERNY.dom.Element);
        method(BooleanViewer.prototype, "render", render);

    })();

    (function() {
        ValueViewer[DT_WIKIMARKUP] = WikiMarkupViewer;

        function WikiMarkupViewer(value, datatype, locale) {
            init(this, value, datatype, locale);
            this.el = Element.create("div", null, "class=wikimarkupviewer");
        }

        function render() {
            var html;
            try {
                html = Wiky.toHtml(CERNY.util.escapeHtml(this.value));
            } catch (e) {
                logger.debug("e: " + CERNY.dump(e));
                html = this.value;
            }
            this.el.node.innerHTML = html;
            return this.el;
        }
        signature("render", CERNY.dom.Element);
        method(WikiMarkupViewer.prototype, "render", render);

    })();

    (function() {
        ValueViewer[DT_DATETIME] = DateTimeViewer;

        function DateTimeViewer(value, datatype, locale) {
            init(this, value, datatype, locale);
            this.el = Element.create("span");
        }

        function render() {
            var date, el, t = this;
            try {
                var dateStr = this.value.substr(0, 10);
                var timeStr = this.value.substr(11);

                date = Date.parseDateTime(dateStr, CERNY.text.DateFormat.ISO,
                                          timeStr, CERNY.text.TimeFormat.ISO);

                el = formatDateWithLocalTime(date, function (_dateTime) {
                    var timezoneFormat;
                    if (!CERNY.js.Date.isInLocalTimezone(_dateTime)) {
                        timezoneFormat = t.locale.formats.timezone;
                    }
                    return _dateTime.formatDateTime(t.locale.formats.date, " ", t.locale.formats.time, " ", timezoneFormat);
                });

            } catch (e) {
                logger.debug("e: " + e);
                el = Element.create("span", this.value);
            }
            this.el.appendChild(el);
            return this.el;
        }
        signature("render", CERNY.dom.Element);
        method(DateTimeViewer.prototype, "render", render);

    })();

    (function() {
        ValueViewer[DT_TIME] = TimeViewer;

        function TimeViewer(value, datatype, locale) {
            init(this, value, datatype, locale);
            this.el = Element.create("span");
        }

        function render() {
            var time, el, t = this;
            try {
                time = Date.parseTime(this.value, CERNY.text.TimeFormat.ISO);
                el = formatDateWithLocalTime(time, function(_time) {
                    var timezoneFormat;
                    if (!CERNY.js.Date.isInLocalTimezone(_time)) {
                        timezoneFormat = t.locale.formats.timezone;
                    }
                    return _time.formatTime(t.locale.formats.time, " ", timezoneFormat);
                });
            } catch (e) {
                logger.debug("e: " + e);
                el = Element.create("span", this.value);
            }
            this.el.appendChild(el);
            return this.el;
        }
        signature("render", CERNY.dom.Element);
        method(TimeViewer.prototype, "render", render);

    })();

    function formatDateWithLocalTime(date, f) {
        var localDate = CERNY.js.Date.convertToLocalTime(date);
        var el = Element.create("span", f(date));

        if (date.getTime() != localDate.getTime()) {
            el.setAttr("title", DICT.lab_local_time + ": " + f(localDate));
        }
        return el;
    }

})();
/*
 * jQuery JavaScript Library v1.3.2
 * http://jquery.com/
 *
 * Copyright (c) 2009 John Resig
 * Dual licensed under the MIT and GPL licenses.
 * http://docs.jquery.com/License
 *
 * Date: 2009-02-19 17:34:21 -0500 (Thu, 19 Feb 2009)
 * Revision: 6246
 */
(function(){var l=this,g,y=l.jQuery,p=l.$,o=l.jQuery=l.$=function(E,F){return new o.fn.init(E,F)},D=/^[^<]*(<(.|\s)+>)[^>]*$|^#([\w-]+)$/,f=/^.[^:#\[\.,]*$/;o.fn=o.prototype={init:function(E,H){E=E||document;if(E.nodeType){this[0]=E;this.length=1;this.context=E;return this}if(typeof E==="string"){var G=D.exec(E);if(G&&(G[1]||!H)){if(G[1]){E=o.clean([G[1]],H)}else{var I=document.getElementById(G[3]);if(I&&I.id!=G[3]){return o().find(E)}var F=o(I||[]);F.context=document;F.selector=E;return F}}else{return o(H).find(E)}}else{if(o.isFunction(E)){return o(document).ready(E)}}if(E.selector&&E.context){this.selector=E.selector;this.context=E.context}return this.setArray(o.isArray(E)?E:o.makeArray(E))},selector:"",jquery:"1.3.2",size:function(){return this.length},get:function(E){return E===g?Array.prototype.slice.call(this):this[E]},pushStack:function(F,H,E){var G=o(F);G.prevObject=this;G.context=this.context;if(H==="find"){G.selector=this.selector+(this.selector?" ":"")+E}else{if(H){G.selector=this.selector+"."+H+"("+E+")"}}return G},setArray:function(E){this.length=0;Array.prototype.push.apply(this,E);return this},each:function(F,E){return o.each(this,F,E)},index:function(E){return o.inArray(E&&E.jquery?E[0]:E,this)},attr:function(F,H,G){var E=F;if(typeof F==="string"){if(H===g){return this[0]&&o[G||"attr"](this[0],F)}else{E={};E[F]=H}}return this.each(function(I){for(F in E){o.attr(G?this.style:this,F,o.prop(this,E[F],G,I,F))}})},css:function(E,F){if((E=="width"||E=="height")&&parseFloat(F)<0){F=g}return this.attr(E,F,"curCSS")},text:function(F){if(typeof F!=="object"&&F!=null){return this.empty().append((this[0]&&this[0].ownerDocument||document).createTextNode(F))}var E="";o.each(F||this,function(){o.each(this.childNodes,function(){if(this.nodeType!=8){E+=this.nodeType!=1?this.nodeValue:o.fn.text([this])}})});return E},wrapAll:function(E){if(this[0]){var F=o(E,this[0].ownerDocument).clone();if(this[0].parentNode){F.insertBefore(this[0])}F.map(function(){var G=this;while(G.firstChild){G=G.firstChild}return G}).append(this)}return this},wrapInner:function(E){return this.each(function(){o(this).contents().wrapAll(E)})},wrap:function(E){return this.each(function(){o(this).wrapAll(E)})},append:function(){return this.domManip(arguments,true,function(E){if(this.nodeType==1){this.appendChild(E)}})},prepend:function(){return this.domManip(arguments,true,function(E){if(this.nodeType==1){this.insertBefore(E,this.firstChild)}})},before:function(){return this.domManip(arguments,false,function(E){this.parentNode.insertBefore(E,this)})},after:function(){return this.domManip(arguments,false,function(E){this.parentNode.insertBefore(E,this.nextSibling)})},end:function(){return this.prevObject||o([])},push:[].push,sort:[].sort,splice:[].splice,find:function(E){if(this.length===1){var F=this.pushStack([],"find",E);F.length=0;o.find(E,this[0],F);return F}else{return this.pushStack(o.unique(o.map(this,function(G){return o.find(E,G)})),"find",E)}},clone:function(G){var E=this.map(function(){if(!o.support.noCloneEvent&&!o.isXMLDoc(this)){var I=this.outerHTML;if(!I){var J=this.ownerDocument.createElement("div");J.appendChild(this.cloneNode(true));I=J.innerHTML}return o.clean([I.replace(/ jQuery\d+="(?:\d+|null)"/g,"").replace(/^\s*/,"")])[0]}else{return this.cloneNode(true)}});if(G===true){var H=this.find("*").andSelf(),F=0;E.find("*").andSelf().each(function(){if(this.nodeName!==H[F].nodeName){return}var I=o.data(H[F],"events");for(var K in I){for(var J in I[K]){o.event.add(this,K,I[K][J],I[K][J].data)}}F++})}return E},filter:function(E){return this.pushStack(o.isFunction(E)&&o.grep(this,function(G,F){return E.call(G,F)})||o.multiFilter(E,o.grep(this,function(F){return F.nodeType===1})),"filter",E)},closest:function(E){var G=o.expr.match.POS.test(E)?o(E):null,F=0;return this.map(function(){var H=this;while(H&&H.ownerDocument){if(G?G.index(H)>-1:o(H).is(E)){o.data(H,"closest",F);return H}H=H.parentNode;F++}})},not:function(E){if(typeof E==="string"){if(f.test(E)){return this.pushStack(o.multiFilter(E,this,true),"not",E)}else{E=o.multiFilter(E,this)}}var F=E.length&&E[E.length-1]!==g&&!E.nodeType;return this.filter(function(){return F?o.inArray(this,E)<0:this!=E})},add:function(E){return this.pushStack(o.unique(o.merge(this.get(),typeof E==="string"?o(E):o.makeArray(E))))},is:function(E){return !!E&&o.multiFilter(E,this).length>0},hasClass:function(E){return !!E&&this.is("."+E)},val:function(K){if(K===g){var E=this[0];if(E){if(o.nodeName(E,"option")){return(E.attributes.value||{}).specified?E.value:E.text}if(o.nodeName(E,"select")){var I=E.selectedIndex,L=[],M=E.options,H=E.type=="select-one";if(I<0){return null}for(var F=H?I:0,J=H?I+1:M.length;F<J;F++){var G=M[F];if(G.selected){K=o(G).val();if(H){return K}L.push(K)}}return L}return(E.value||"").replace(/\r/g,"")}return g}if(typeof K==="number"){K+=""}return this.each(function(){if(this.nodeType!=1){return}if(o.isArray(K)&&/radio|checkbox/.test(this.type)){this.checked=(o.inArray(this.value,K)>=0||o.inArray(this.name,K)>=0)}else{if(o.nodeName(this,"select")){var N=o.makeArray(K);o("option",this).each(function(){this.selected=(o.inArray(this.value,N)>=0||o.inArray(this.text,N)>=0)});if(!N.length){this.selectedIndex=-1}}else{this.value=K}}})},html:function(E){return E===g?(this[0]?this[0].innerHTML.replace(/ jQuery\d+="(?:\d+|null)"/g,""):null):this.empty().append(E)},replaceWith:function(E){return this.after(E).remove()},eq:function(E){return this.slice(E,+E+1)},slice:function(){return this.pushStack(Array.prototype.slice.apply(this,arguments),"slice",Array.prototype.slice.call(arguments).join(","))},map:function(E){return this.pushStack(o.map(this,function(G,F){return E.call(G,F,G)}))},andSelf:function(){return this.add(this.prevObject)},domManip:function(J,M,L){if(this[0]){var I=(this[0].ownerDocument||this[0]).createDocumentFragment(),F=o.clean(J,(this[0].ownerDocument||this[0]),I),H=I.firstChild;if(H){for(var G=0,E=this.length;G<E;G++){L.call(K(this[G],H),this.length>1||G>0?I.cloneNode(true):I)}}if(F){o.each(F,z)}}return this;function K(N,O){return M&&o.nodeName(N,"table")&&o.nodeName(O,"tr")?(N.getElementsByTagName("tbody")[0]||N.appendChild(N.ownerDocument.createElement("tbody"))):N}}};o.fn.init.prototype=o.fn;function z(E,F){if(F.src){o.ajax({url:F.src,async:false,dataType:"script"})}else{o.globalEval(F.text||F.textContent||F.innerHTML||"")}if(F.parentNode){F.parentNode.removeChild(F)}}function e(){return +new Date}o.extend=o.fn.extend=function(){var J=arguments[0]||{},H=1,I=arguments.length,E=false,G;if(typeof J==="boolean"){E=J;J=arguments[1]||{};H=2}if(typeof J!=="object"&&!o.isFunction(J)){J={}}if(I==H){J=this;--H}for(;H<I;H++){if((G=arguments[H])!=null){for(var F in G){var K=J[F],L=G[F];if(J===L){continue}if(E&&L&&typeof L==="object"&&!L.nodeType){J[F]=o.extend(E,K||(L.length!=null?[]:{}),L)}else{if(L!==g){J[F]=L}}}}}return J};var b=/z-?index|font-?weight|opacity|zoom|line-?height/i,q=document.defaultView||{},s=Object.prototype.toString;o.extend({noConflict:function(E){l.$=p;if(E){l.jQuery=y}return o},isFunction:function(E){return s.call(E)==="[object Function]"},isArray:function(E){return s.call(E)==="[object Array]"},isXMLDoc:function(E){return E.nodeType===9&&E.documentElement.nodeName!=="HTML"||!!E.ownerDocument&&o.isXMLDoc(E.ownerDocument)},globalEval:function(G){if(G&&/\S/.test(G)){var F=document.getElementsByTagName("head")[0]||document.documentElement,E=document.createElement("script");E.type="text/javascript";if(o.support.scriptEval){E.appendChild(document.createTextNode(G))}else{E.text=G}F.insertBefore(E,F.firstChild);F.removeChild(E)}},nodeName:function(F,E){return F.nodeName&&F.nodeName.toUpperCase()==E.toUpperCase()},each:function(G,K,F){var E,H=0,I=G.length;if(F){if(I===g){for(E in G){if(K.apply(G[E],F)===false){break}}}else{for(;H<I;){if(K.apply(G[H++],F)===false){break}}}}else{if(I===g){for(E in G){if(K.call(G[E],E,G[E])===false){break}}}else{for(var J=G[0];H<I&&K.call(J,H,J)!==false;J=G[++H]){}}}return G},prop:function(H,I,G,F,E){if(o.isFunction(I)){I=I.call(H,F)}return typeof I==="number"&&G=="curCSS"&&!b.test(E)?I+"px":I},className:{add:function(E,F){o.each((F||"").split(/\s+/),function(G,H){if(E.nodeType==1&&!o.className.has(E.className,H)){E.className+=(E.className?" ":"")+H}})},remove:function(E,F){if(E.nodeType==1){E.className=F!==g?o.grep(E.className.split(/\s+/),function(G){return !o.className.has(F,G)}).join(" "):""}},has:function(F,E){return F&&o.inArray(E,(F.className||F).toString().split(/\s+/))>-1}},swap:function(H,G,I){var E={};for(var F in G){E[F]=H.style[F];H.style[F]=G[F]}I.call(H);for(var F in G){H.style[F]=E[F]}},css:function(H,F,J,E){if(F=="width"||F=="height"){var L,G={position:"absolute",visibility:"hidden",display:"block"},K=F=="width"?["Left","Right"]:["Top","Bottom"];function I(){L=F=="width"?H.offsetWidth:H.offsetHeight;if(E==="border"){return}o.each(K,function(){if(!E){L-=parseFloat(o.curCSS(H,"padding"+this,true))||0}if(E==="margin"){L+=parseFloat(o.curCSS(H,"margin"+this,true))||0}else{L-=parseFloat(o.curCSS(H,"border"+this+"Width",true))||0}})}if(H.offsetWidth!==0){I()}else{o.swap(H,G,I)}return Math.max(0,Math.round(L))}return o.curCSS(H,F,J)},curCSS:function(I,F,G){var L,E=I.style;if(F=="opacity"&&!o.support.opacity){L=o.attr(E,"opacity");return L==""?"1":L}if(F.match(/float/i)){F=w}if(!G&&E&&E[F]){L=E[F]}else{if(q.getComputedStyle){if(F.match(/float/i)){F="float"}F=F.replace(/([A-Z])/g,"-$1").toLowerCase();var M=q.getComputedStyle(I,null);if(M){L=M.getPropertyValue(F)}if(F=="opacity"&&L==""){L="1"}}else{if(I.currentStyle){var J=F.replace(/\-(\w)/g,function(N,O){return O.toUpperCase()});L=I.currentStyle[F]||I.currentStyle[J];if(!/^\d+(px)?$/i.test(L)&&/^\d/.test(L)){var H=E.left,K=I.runtimeStyle.left;I.runtimeStyle.left=I.currentStyle.left;E.left=L||0;L=E.pixelLeft+"px";E.left=H;I.runtimeStyle.left=K}}}}return L},clean:function(F,K,I){K=K||document;if(typeof K.createElement==="undefined"){K=K.ownerDocument||K[0]&&K[0].ownerDocument||document}if(!I&&F.length===1&&typeof F[0]==="string"){var H=/^<(\w+)\s*\/?>$/.exec(F[0]);if(H){return[K.createElement(H[1])]}}var G=[],E=[],L=K.createElement("div");o.each(F,function(P,S){if(typeof S==="number"){S+=""}if(!S){return}if(typeof S==="string"){S=S.replace(/(<(\w+)[^>]*?)\/>/g,function(U,V,T){return T.match(/^(abbr|br|col|img|input|link|meta|param|hr|area|embed)$/i)?U:V+"></"+T+">"});var O=S.replace(/^\s+/,"").substring(0,10).toLowerCase();var Q=!O.indexOf("<opt")&&[1,"<select multiple='multiple'>","</select>"]||!O.indexOf("<leg")&&[1,"<fieldset>","</fieldset>"]||O.match(/^<(thead|tbody|tfoot|colg|cap)/)&&[1,"<table>","</table>"]||!O.indexOf("<tr")&&[2,"<table><tbody>","</tbody></table>"]||(!O.indexOf("<td")||!O.indexOf("<th"))&&[3,"<table><tbody><tr>","</tr></tbody></table>"]||!O.indexOf("<col")&&[2,"<table><tbody></tbody><colgroup>","</colgroup></table>"]||!o.support.htmlSerialize&&[1,"div<div>","</div>"]||[0,"",""];L.innerHTML=Q[1]+S+Q[2];while(Q[0]--){L=L.lastChild}if(!o.support.tbody){var R=/<tbody/i.test(S),N=!O.indexOf("<table")&&!R?L.firstChild&&L.firstChild.childNodes:Q[1]=="<table>"&&!R?L.childNodes:[];for(var M=N.length-1;M>=0;--M){if(o.nodeName(N[M],"tbody")&&!N[M].childNodes.length){N[M].parentNode.removeChild(N[M])}}}if(!o.support.leadingWhitespace&&/^\s/.test(S)){L.insertBefore(K.createTextNode(S.match(/^\s*/)[0]),L.firstChild)}S=o.makeArray(L.childNodes)}if(S.nodeType){G.push(S)}else{G=o.merge(G,S)}});if(I){for(var J=0;G[J];J++){if(o.nodeName(G[J],"script")&&(!G[J].type||G[J].type.toLowerCase()==="text/javascript")){E.push(G[J].parentNode?G[J].parentNode.removeChild(G[J]):G[J])}else{if(G[J].nodeType===1){G.splice.apply(G,[J+1,0].concat(o.makeArray(G[J].getElementsByTagName("script"))))}I.appendChild(G[J])}}return E}return G},attr:function(J,G,K){if(!J||J.nodeType==3||J.nodeType==8){return g}var H=!o.isXMLDoc(J),L=K!==g;G=H&&o.props[G]||G;if(J.tagName){var F=/href|src|style/.test(G);if(G=="selected"&&J.parentNode){J.parentNode.selectedIndex}if(G in J&&H&&!F){if(L){if(G=="type"&&o.nodeName(J,"input")&&J.parentNode){throw"type property can't be changed"}J[G]=K}if(o.nodeName(J,"form")&&J.getAttributeNode(G)){return J.getAttributeNode(G).nodeValue}if(G=="tabIndex"){var I=J.getAttributeNode("tabIndex");return I&&I.specified?I.value:J.nodeName.match(/(button|input|object|select|textarea)/i)?0:J.nodeName.match(/^(a|area)$/i)&&J.href?0:g}return J[G]}if(!o.support.style&&H&&G=="style"){return o.attr(J.style,"cssText",K)}if(L){J.setAttribute(G,""+K)}var E=!o.support.hrefNormalized&&H&&F?J.getAttribute(G,2):J.getAttribute(G);return E===null?g:E}if(!o.support.opacity&&G=="opacity"){if(L){J.zoom=1;J.filter=(J.filter||"").replace(/alpha\([^)]*\)/,"")+(parseInt(K)+""=="NaN"?"":"alpha(opacity="+K*100+")")}return J.filter&&J.filter.indexOf("opacity=")>=0?(parseFloat(J.filter.match(/opacity=([^)]*)/)[1])/100)+"":""}G=G.replace(/-([a-z])/ig,function(M,N){return N.toUpperCase()});if(L){J[G]=K}return J[G]},trim:function(E){return(E||"").replace(/^\s+|\s+$/g,"")},makeArray:function(G){var E=[];if(G!=null){var F=G.length;if(F==null||typeof G==="string"||o.isFunction(G)||G.setInterval){E[0]=G}else{while(F){E[--F]=G[F]}}}return E},inArray:function(G,H){for(var E=0,F=H.length;E<F;E++){if(H[E]===G){return E}}return -1},merge:function(H,E){var F=0,G,I=H.length;if(!o.support.getAll){while((G=E[F++])!=null){if(G.nodeType!=8){H[I++]=G}}}else{while((G=E[F++])!=null){H[I++]=G}}return H},unique:function(K){var F=[],E={};try{for(var G=0,H=K.length;G<H;G++){var J=o.data(K[G]);if(!E[J]){E[J]=true;F.push(K[G])}}}catch(I){F=K}return F},grep:function(F,J,E){var G=[];for(var H=0,I=F.length;H<I;H++){if(!E!=!J(F[H],H)){G.push(F[H])}}return G},map:function(E,J){var F=[];for(var G=0,H=E.length;G<H;G++){var I=J(E[G],G);if(I!=null){F[F.length]=I}}return F.concat.apply([],F)}});var C=navigator.userAgent.toLowerCase();o.browser={version:(C.match(/.+(?:rv|it|ra|ie)[\/: ]([\d.]+)/)||[0,"0"])[1],safari:/webkit/.test(C),opera:/opera/.test(C),msie:/msie/.test(C)&&!/opera/.test(C),mozilla:/mozilla/.test(C)&&!/(compatible|webkit)/.test(C)};o.each({parent:function(E){return E.parentNode},parents:function(E){return o.dir(E,"parentNode")},next:function(E){return o.nth(E,2,"nextSibling")},prev:function(E){return o.nth(E,2,"previousSibling")},nextAll:function(E){return o.dir(E,"nextSibling")},prevAll:function(E){return o.dir(E,"previousSibling")},siblings:function(E){return o.sibling(E.parentNode.firstChild,E)},children:function(E){return o.sibling(E.firstChild)},contents:function(E){return o.nodeName(E,"iframe")?E.contentDocument||E.contentWindow.document:o.makeArray(E.childNodes)}},function(E,F){o.fn[E]=function(G){var H=o.map(this,F);if(G&&typeof G=="string"){H=o.multiFilter(G,H)}return this.pushStack(o.unique(H),E,G)}});o.each({appendTo:"append",prependTo:"prepend",insertBefore:"before",insertAfter:"after",replaceAll:"replaceWith"},function(E,F){o.fn[E]=function(G){var J=[],L=o(G);for(var K=0,H=L.length;K<H;K++){var I=(K>0?this.clone(true):this).get();o.fn[F].apply(o(L[K]),I);J=J.concat(I)}return this.pushStack(J,E,G)}});o.each({removeAttr:function(E){o.attr(this,E,"");if(this.nodeType==1){this.removeAttribute(E)}},addClass:function(E){o.className.add(this,E)},removeClass:function(E){o.className.remove(this,E)},toggleClass:function(F,E){if(typeof E!=="boolean"){E=!o.className.has(this,F)}o.className[E?"add":"remove"](this,F)},remove:function(E){if(!E||o.filter(E,[this]).length){o("*",this).add([this]).each(function(){o.event.remove(this);o.removeData(this)});if(this.parentNode){this.parentNode.removeChild(this)}}},empty:function(){o(this).children().remove();while(this.firstChild){this.removeChild(this.firstChild)}}},function(E,F){o.fn[E]=function(){return this.each(F,arguments)}});function j(E,F){return E[0]&&parseInt(o.curCSS(E[0],F,true),10)||0}var h="jQuery"+e(),v=0,A={};o.extend({cache:{},data:function(F,E,G){F=F==l?A:F;var H=F[h];if(!H){H=F[h]=++v}if(E&&!o.cache[H]){o.cache[H]={}}if(G!==g){o.cache[H][E]=G}return E?o.cache[H][E]:H},removeData:function(F,E){F=F==l?A:F;var H=F[h];if(E){if(o.cache[H]){delete o.cache[H][E];E="";for(E in o.cache[H]){break}if(!E){o.removeData(F)}}}else{try{delete F[h]}catch(G){if(F.removeAttribute){F.removeAttribute(h)}}delete o.cache[H]}},queue:function(F,E,H){if(F){E=(E||"fx")+"queue";var G=o.data(F,E);if(!G||o.isArray(H)){G=o.data(F,E,o.makeArray(H))}else{if(H){G.push(H)}}}return G},dequeue:function(H,G){var E=o.queue(H,G),F=E.shift();if(!G||G==="fx"){F=E[0]}if(F!==g){F.call(H)}}});o.fn.extend({data:function(E,G){var H=E.split(".");H[1]=H[1]?"."+H[1]:"";if(G===g){var F=this.triggerHandler("getData"+H[1]+"!",[H[0]]);if(F===g&&this.length){F=o.data(this[0],E)}return F===g&&H[1]?this.data(H[0]):F}else{return this.trigger("setData"+H[1]+"!",[H[0],G]).each(function(){o.data(this,E,G)})}},removeData:function(E){return this.each(function(){o.removeData(this,E)})},queue:function(E,F){if(typeof E!=="string"){F=E;E="fx"}if(F===g){return o.queue(this[0],E)}return this.each(function(){var G=o.queue(this,E,F);if(E=="fx"&&G.length==1){G[0].call(this)}})},dequeue:function(E){return this.each(function(){o.dequeue(this,E)})}});
/*
 * Sizzle CSS Selector Engine - v0.9.3
 *  Copyright 2009, The Dojo Foundation
 *  Released under the MIT, BSD, and GPL Licenses.
 *  More information: http://sizzlejs.com/
 */
(function(){var R=/((?:\((?:\([^()]+\)|[^()]+)+\)|\[(?:\[[^[\]]*\]|['"][^'"]*['"]|[^[\]'"]+)+\]|\\.|[^ >+~,(\[\\]+)+|[>+~])(\s*,\s*)?/g,L=0,H=Object.prototype.toString;var F=function(Y,U,ab,ac){ab=ab||[];U=U||document;if(U.nodeType!==1&&U.nodeType!==9){return[]}if(!Y||typeof Y!=="string"){return ab}var Z=[],W,af,ai,T,ad,V,X=true;R.lastIndex=0;while((W=R.exec(Y))!==null){Z.push(W[1]);if(W[2]){V=RegExp.rightContext;break}}if(Z.length>1&&M.exec(Y)){if(Z.length===2&&I.relative[Z[0]]){af=J(Z[0]+Z[1],U)}else{af=I.relative[Z[0]]?[U]:F(Z.shift(),U);while(Z.length){Y=Z.shift();if(I.relative[Y]){Y+=Z.shift()}af=J(Y,af)}}}else{var ae=ac?{expr:Z.pop(),set:E(ac)}:F.find(Z.pop(),Z.length===1&&U.parentNode?U.parentNode:U,Q(U));af=F.filter(ae.expr,ae.set);if(Z.length>0){ai=E(af)}else{X=false}while(Z.length){var ah=Z.pop(),ag=ah;if(!I.relative[ah]){ah=""}else{ag=Z.pop()}if(ag==null){ag=U}I.relative[ah](ai,ag,Q(U))}}if(!ai){ai=af}if(!ai){throw"Syntax error, unrecognized expression: "+(ah||Y)}if(H.call(ai)==="[object Array]"){if(!X){ab.push.apply(ab,ai)}else{if(U.nodeType===1){for(var aa=0;ai[aa]!=null;aa++){if(ai[aa]&&(ai[aa]===true||ai[aa].nodeType===1&&K(U,ai[aa]))){ab.push(af[aa])}}}else{for(var aa=0;ai[aa]!=null;aa++){if(ai[aa]&&ai[aa].nodeType===1){ab.push(af[aa])}}}}}else{E(ai,ab)}if(V){F(V,U,ab,ac);if(G){hasDuplicate=false;ab.sort(G);if(hasDuplicate){for(var aa=1;aa<ab.length;aa++){if(ab[aa]===ab[aa-1]){ab.splice(aa--,1)}}}}}return ab};F.matches=function(T,U){return F(T,null,null,U)};F.find=function(aa,T,ab){var Z,X;if(!aa){return[]}for(var W=0,V=I.order.length;W<V;W++){var Y=I.order[W],X;if((X=I.match[Y].exec(aa))){var U=RegExp.leftContext;if(U.substr(U.length-1)!=="\\"){X[1]=(X[1]||"").replace(/\\/g,"");Z=I.find[Y](X,T,ab);if(Z!=null){aa=aa.replace(I.match[Y],"");break}}}}if(!Z){Z=T.getElementsByTagName("*")}return{set:Z,expr:aa}};F.filter=function(ad,ac,ag,W){var V=ad,ai=[],aa=ac,Y,T,Z=ac&&ac[0]&&Q(ac[0]);while(ad&&ac.length){for(var ab in I.filter){if((Y=I.match[ab].exec(ad))!=null){var U=I.filter[ab],ah,af;T=false;if(aa==ai){ai=[]}if(I.preFilter[ab]){Y=I.preFilter[ab](Y,aa,ag,ai,W,Z);if(!Y){T=ah=true}else{if(Y===true){continue}}}if(Y){for(var X=0;(af=aa[X])!=null;X++){if(af){ah=U(af,Y,X,aa);var ae=W^!!ah;if(ag&&ah!=null){if(ae){T=true}else{aa[X]=false}}else{if(ae){ai.push(af);T=true}}}}}if(ah!==g){if(!ag){aa=ai}ad=ad.replace(I.match[ab],"");if(!T){return[]}break}}}if(ad==V){if(T==null){throw"Syntax error, unrecognized expression: "+ad}else{break}}V=ad}return aa};var I=F.selectors={order:["ID","NAME","TAG"],match:{ID:/#((?:[\w\u00c0-\uFFFF_-]|\\.)+)/,CLASS:/\.((?:[\w\u00c0-\uFFFF_-]|\\.)+)/,NAME:/\[name=['"]*((?:[\w\u00c0-\uFFFF_-]|\\.)+)['"]*\]/,ATTR:/\[\s*((?:[\w\u00c0-\uFFFF_-]|\\.)+)\s*(?:(\S?=)\s*(['"]*)(.*?)\3|)\s*\]/,TAG:/^((?:[\w\u00c0-\uFFFF\*_-]|\\.)+)/,CHILD:/:(only|nth|last|first)-child(?:\((even|odd|[\dn+-]*)\))?/,POS:/:(nth|eq|gt|lt|first|last|even|odd)(?:\((\d*)\))?(?=[^-]|$)/,PSEUDO:/:((?:[\w\u00c0-\uFFFF_-]|\\.)+)(?:\((['"]*)((?:\([^\)]+\)|[^\2\(\)]*)+)\2\))?/},attrMap:{"class":"className","for":"htmlFor"},attrHandle:{href:function(T){return T.getAttribute("href")}},relative:{"+":function(aa,T,Z){var X=typeof T==="string",ab=X&&!/\W/.test(T),Y=X&&!ab;if(ab&&!Z){T=T.toUpperCase()}for(var W=0,V=aa.length,U;W<V;W++){if((U=aa[W])){while((U=U.previousSibling)&&U.nodeType!==1){}aa[W]=Y||U&&U.nodeName===T?U||false:U===T}}if(Y){F.filter(T,aa,true)}},">":function(Z,U,aa){var X=typeof U==="string";if(X&&!/\W/.test(U)){U=aa?U:U.toUpperCase();for(var V=0,T=Z.length;V<T;V++){var Y=Z[V];if(Y){var W=Y.parentNode;Z[V]=W.nodeName===U?W:false}}}else{for(var V=0,T=Z.length;V<T;V++){var Y=Z[V];if(Y){Z[V]=X?Y.parentNode:Y.parentNode===U}}if(X){F.filter(U,Z,true)}}},"":function(W,U,Y){var V=L++,T=S;if(!U.match(/\W/)){var X=U=Y?U:U.toUpperCase();T=P}T("parentNode",U,V,W,X,Y)},"~":function(W,U,Y){var V=L++,T=S;if(typeof U==="string"&&!U.match(/\W/)){var X=U=Y?U:U.toUpperCase();T=P}T("previousSibling",U,V,W,X,Y)}},find:{ID:function(U,V,W){if(typeof V.getElementById!=="undefined"&&!W){var T=V.getElementById(U[1]);return T?[T]:[]}},NAME:function(V,Y,Z){if(typeof Y.getElementsByName!=="undefined"){var U=[],X=Y.getElementsByName(V[1]);for(var W=0,T=X.length;W<T;W++){if(X[W].getAttribute("name")===V[1]){U.push(X[W])}}return U.length===0?null:U}},TAG:function(T,U){return U.getElementsByTagName(T[1])}},preFilter:{CLASS:function(W,U,V,T,Z,aa){W=" "+W[1].replace(/\\/g,"")+" ";if(aa){return W}for(var X=0,Y;(Y=U[X])!=null;X++){if(Y){if(Z^(Y.className&&(" "+Y.className+" ").indexOf(W)>=0)){if(!V){T.push(Y)}}else{if(V){U[X]=false}}}}return false},ID:function(T){return T[1].replace(/\\/g,"")},TAG:function(U,T){for(var V=0;T[V]===false;V++){}return T[V]&&Q(T[V])?U[1]:U[1].toUpperCase()},CHILD:function(T){if(T[1]=="nth"){var U=/(-?)(\d*)n((?:\+|-)?\d*)/.exec(T[2]=="even"&&"2n"||T[2]=="odd"&&"2n+1"||!/\D/.test(T[2])&&"0n+"+T[2]||T[2]);T[2]=(U[1]+(U[2]||1))-0;T[3]=U[3]-0}T[0]=L++;return T},ATTR:function(X,U,V,T,Y,Z){var W=X[1].replace(/\\/g,"");if(!Z&&I.attrMap[W]){X[1]=I.attrMap[W]}if(X[2]==="~="){X[4]=" "+X[4]+" "}return X},PSEUDO:function(X,U,V,T,Y){if(X[1]==="not"){if(X[3].match(R).length>1||/^\w/.test(X[3])){X[3]=F(X[3],null,null,U)}else{var W=F.filter(X[3],U,V,true^Y);if(!V){T.push.apply(T,W)}return false}}else{if(I.match.POS.test(X[0])||I.match.CHILD.test(X[0])){return true}}return X},POS:function(T){T.unshift(true);return T}},filters:{enabled:function(T){return T.disabled===false&&T.type!=="hidden"},disabled:function(T){return T.disabled===true},checked:function(T){return T.checked===true},selected:function(T){T.parentNode.selectedIndex;return T.selected===true},parent:function(T){return !!T.firstChild},empty:function(T){return !T.firstChild},has:function(V,U,T){return !!F(T[3],V).length},header:function(T){return/h\d/i.test(T.nodeName)},text:function(T){return"text"===T.type},radio:function(T){return"radio"===T.type},checkbox:function(T){return"checkbox"===T.type},file:function(T){return"file"===T.type},password:function(T){return"password"===T.type},submit:function(T){return"submit"===T.type},image:function(T){return"image"===T.type},reset:function(T){return"reset"===T.type},button:function(T){return"button"===T.type||T.nodeName.toUpperCase()==="BUTTON"},input:function(T){return/input|select|textarea|button/i.test(T.nodeName)}},setFilters:{first:function(U,T){return T===0},last:function(V,U,T,W){return U===W.length-1},even:function(U,T){return T%2===0},odd:function(U,T){return T%2===1},lt:function(V,U,T){return U<T[3]-0},gt:function(V,U,T){return U>T[3]-0},nth:function(V,U,T){return T[3]-0==U},eq:function(V,U,T){return T[3]-0==U}},filter:{PSEUDO:function(Z,V,W,aa){var U=V[1],X=I.filters[U];if(X){return X(Z,W,V,aa)}else{if(U==="contains"){return(Z.textContent||Z.innerText||"").indexOf(V[3])>=0}else{if(U==="not"){var Y=V[3];for(var W=0,T=Y.length;W<T;W++){if(Y[W]===Z){return false}}return true}}}},CHILD:function(T,W){var Z=W[1],U=T;switch(Z){case"only":case"first":while(U=U.previousSibling){if(U.nodeType===1){return false}}if(Z=="first"){return true}U=T;case"last":while(U=U.nextSibling){if(U.nodeType===1){return false}}return true;case"nth":var V=W[2],ac=W[3];if(V==1&&ac==0){return true}var Y=W[0],ab=T.parentNode;if(ab&&(ab.sizcache!==Y||!T.nodeIndex)){var X=0;for(U=ab.firstChild;U;U=U.nextSibling){if(U.nodeType===1){U.nodeIndex=++X}}ab.sizcache=Y}var aa=T.nodeIndex-ac;if(V==0){return aa==0}else{return(aa%V==0&&aa/V>=0)}}},ID:function(U,T){return U.nodeType===1&&U.getAttribute("id")===T},TAG:function(U,T){return(T==="*"&&U.nodeType===1)||U.nodeName===T},CLASS:function(U,T){return(" "+(U.className||U.getAttribute("class"))+" ").indexOf(T)>-1},ATTR:function(Y,W){var V=W[1],T=I.attrHandle[V]?I.attrHandle[V](Y):Y[V]!=null?Y[V]:Y.getAttribute(V),Z=T+"",X=W[2],U=W[4];return T==null?X==="!=":X==="="?Z===U:X==="*="?Z.indexOf(U)>=0:X==="~="?(" "+Z+" ").indexOf(U)>=0:!U?Z&&T!==false:X==="!="?Z!=U:X==="^="?Z.indexOf(U)===0:X==="$="?Z.substr(Z.length-U.length)===U:X==="|="?Z===U||Z.substr(0,U.length+1)===U+"-":false},POS:function(X,U,V,Y){var T=U[2],W=I.setFilters[T];if(W){return W(X,V,U,Y)}}}};var M=I.match.POS;for(var O in I.match){I.match[O]=RegExp(I.match[O].source+/(?![^\[]*\])(?![^\(]*\))/.source)}var E=function(U,T){U=Array.prototype.slice.call(U);if(T){T.push.apply(T,U);return T}return U};try{Array.prototype.slice.call(document.documentElement.childNodes)}catch(N){E=function(X,W){var U=W||[];if(H.call(X)==="[object Array]"){Array.prototype.push.apply(U,X)}else{if(typeof X.length==="number"){for(var V=0,T=X.length;V<T;V++){U.push(X[V])}}else{for(var V=0;X[V];V++){U.push(X[V])}}}return U}}var G;if(document.documentElement.compareDocumentPosition){G=function(U,T){var V=U.compareDocumentPosition(T)&4?-1:U===T?0:1;if(V===0){hasDuplicate=true}return V}}else{if("sourceIndex" in document.documentElement){G=function(U,T){var V=U.sourceIndex-T.sourceIndex;if(V===0){hasDuplicate=true}return V}}else{if(document.createRange){G=function(W,U){var V=W.ownerDocument.createRange(),T=U.ownerDocument.createRange();V.selectNode(W);V.collapse(true);T.selectNode(U);T.collapse(true);var X=V.compareBoundaryPoints(Range.START_TO_END,T);if(X===0){hasDuplicate=true}return X}}}}(function(){var U=document.createElement("form"),V="script"+(new Date).getTime();U.innerHTML="<input name='"+V+"'/>";var T=document.documentElement;T.insertBefore(U,T.firstChild);if(!!document.getElementById(V)){I.find.ID=function(X,Y,Z){if(typeof Y.getElementById!=="undefined"&&!Z){var W=Y.getElementById(X[1]);return W?W.id===X[1]||typeof W.getAttributeNode!=="undefined"&&W.getAttributeNode("id").nodeValue===X[1]?[W]:g:[]}};I.filter.ID=function(Y,W){var X=typeof Y.getAttributeNode!=="undefined"&&Y.getAttributeNode("id");return Y.nodeType===1&&X&&X.nodeValue===W}}T.removeChild(U)})();(function(){var T=document.createElement("div");T.appendChild(document.createComment(""));if(T.getElementsByTagName("*").length>0){I.find.TAG=function(U,Y){var X=Y.getElementsByTagName(U[1]);if(U[1]==="*"){var W=[];for(var V=0;X[V];V++){if(X[V].nodeType===1){W.push(X[V])}}X=W}return X}}T.innerHTML="<a href='#'></a>";if(T.firstChild&&typeof T.firstChild.getAttribute!=="undefined"&&T.firstChild.getAttribute("href")!=="#"){I.attrHandle.href=function(U){return U.getAttribute("href",2)}}})();if(document.querySelectorAll){(function(){var T=F,U=document.createElement("div");U.innerHTML="<p class='TEST'></p>";if(U.querySelectorAll&&U.querySelectorAll(".TEST").length===0){return}F=function(Y,X,V,W){X=X||document;if(!W&&X.nodeType===9&&!Q(X)){try{return E(X.querySelectorAll(Y),V)}catch(Z){}}return T(Y,X,V,W)};F.find=T.find;F.filter=T.filter;F.selectors=T.selectors;F.matches=T.matches})()}if(document.getElementsByClassName&&document.documentElement.getElementsByClassName){(function(){var T=document.createElement("div");T.innerHTML="<div class='test e'></div><div class='test'></div>";if(T.getElementsByClassName("e").length===0){return}T.lastChild.className="e";if(T.getElementsByClassName("e").length===1){return}I.order.splice(1,0,"CLASS");I.find.CLASS=function(U,V,W){if(typeof V.getElementsByClassName!=="undefined"&&!W){return V.getElementsByClassName(U[1])}}})()}function P(U,Z,Y,ad,aa,ac){var ab=U=="previousSibling"&&!ac;for(var W=0,V=ad.length;W<V;W++){var T=ad[W];if(T){if(ab&&T.nodeType===1){T.sizcache=Y;T.sizset=W}T=T[U];var X=false;while(T){if(T.sizcache===Y){X=ad[T.sizset];break}if(T.nodeType===1&&!ac){T.sizcache=Y;T.sizset=W}if(T.nodeName===Z){X=T;break}T=T[U]}ad[W]=X}}}function S(U,Z,Y,ad,aa,ac){var ab=U=="previousSibling"&&!ac;for(var W=0,V=ad.length;W<V;W++){var T=ad[W];if(T){if(ab&&T.nodeType===1){T.sizcache=Y;T.sizset=W}T=T[U];var X=false;while(T){if(T.sizcache===Y){X=ad[T.sizset];break}if(T.nodeType===1){if(!ac){T.sizcache=Y;T.sizset=W}if(typeof Z!=="string"){if(T===Z){X=true;break}}else{if(F.filter(Z,[T]).length>0){X=T;break}}}T=T[U]}ad[W]=X}}}var K=document.compareDocumentPosition?function(U,T){return U.compareDocumentPosition(T)&16}:function(U,T){return U!==T&&(U.contains?U.contains(T):true)};var Q=function(T){return T.nodeType===9&&T.documentElement.nodeName!=="HTML"||!!T.ownerDocument&&Q(T.ownerDocument)};var J=function(T,aa){var W=[],X="",Y,V=aa.nodeType?[aa]:aa;while((Y=I.match.PSEUDO.exec(T))){X+=Y[0];T=T.replace(I.match.PSEUDO,"")}T=I.relative[T]?T+"*":T;for(var Z=0,U=V.length;Z<U;Z++){F(T,V[Z],W)}return F.filter(X,W)};o.find=F;o.filter=F.filter;o.expr=F.selectors;o.expr[":"]=o.expr.filters;F.selectors.filters.hidden=function(T){return T.offsetWidth===0||T.offsetHeight===0};F.selectors.filters.visible=function(T){return T.offsetWidth>0||T.offsetHeight>0};F.selectors.filters.animated=function(T){return o.grep(o.timers,function(U){return T===U.elem}).length};o.multiFilter=function(V,T,U){if(U){V=":not("+V+")"}return F.matches(V,T)};o.dir=function(V,U){var T=[],W=V[U];while(W&&W!=document){if(W.nodeType==1){T.push(W)}W=W[U]}return T};o.nth=function(X,T,V,W){T=T||1;var U=0;for(;X;X=X[V]){if(X.nodeType==1&&++U==T){break}}return X};o.sibling=function(V,U){var T=[];for(;V;V=V.nextSibling){if(V.nodeType==1&&V!=U){T.push(V)}}return T};return;l.Sizzle=F})();o.event={add:function(I,F,H,K){if(I.nodeType==3||I.nodeType==8){return}if(I.setInterval&&I!=l){I=l}if(!H.guid){H.guid=this.guid++}if(K!==g){var G=H;H=this.proxy(G);H.data=K}var E=o.data(I,"events")||o.data(I,"events",{}),J=o.data(I,"handle")||o.data(I,"handle",function(){return typeof o!=="undefined"&&!o.event.triggered?o.event.handle.apply(arguments.callee.elem,arguments):g});J.elem=I;o.each(F.split(/\s+/),function(M,N){var O=N.split(".");N=O.shift();H.type=O.slice().sort().join(".");var L=E[N];if(o.event.specialAll[N]){o.event.specialAll[N].setup.call(I,K,O)}if(!L){L=E[N]={};if(!o.event.special[N]||o.event.special[N].setup.call(I,K,O)===false){if(I.addEventListener){I.addEventListener(N,J,false)}else{if(I.attachEvent){I.attachEvent("on"+N,J)}}}}L[H.guid]=H;o.event.global[N]=true});I=null},guid:1,global:{},remove:function(K,H,J){if(K.nodeType==3||K.nodeType==8){return}var G=o.data(K,"events"),F,E;if(G){if(H===g||(typeof H==="string"&&H.charAt(0)==".")){for(var I in G){this.remove(K,I+(H||""))}}else{if(H.type){J=H.handler;H=H.type}o.each(H.split(/\s+/),function(M,O){var Q=O.split(".");O=Q.shift();var N=RegExp("(^|\\.)"+Q.slice().sort().join(".*\\.")+"(\\.|$)");if(G[O]){if(J){delete G[O][J.guid]}else{for(var P in G[O]){if(N.test(G[O][P].type)){delete G[O][P]}}}if(o.event.specialAll[O]){o.event.specialAll[O].teardown.call(K,Q)}for(F in G[O]){break}if(!F){if(!o.event.special[O]||o.event.special[O].teardown.call(K,Q)===false){if(K.removeEventListener){K.removeEventListener(O,o.data(K,"handle"),false)}else{if(K.detachEvent){K.detachEvent("on"+O,o.data(K,"handle"))}}}F=null;delete G[O]}}})}for(F in G){break}if(!F){var L=o.data(K,"handle");if(L){L.elem=null}o.removeData(K,"events");o.removeData(K,"handle")}}},trigger:function(I,K,H,E){var G=I.type||I;if(!E){I=typeof I==="object"?I[h]?I:o.extend(o.Event(G),I):o.Event(G);if(G.indexOf("!")>=0){I.type=G=G.slice(0,-1);I.exclusive=true}if(!H){I.stopPropagation();if(this.global[G]){o.each(o.cache,function(){if(this.events&&this.events[G]){o.event.trigger(I,K,this.handle.elem)}})}}if(!H||H.nodeType==3||H.nodeType==8){return g}I.result=g;I.target=H;K=o.makeArray(K);K.unshift(I)}I.currentTarget=H;var J=o.data(H,"handle");if(J){J.apply(H,K)}if((!H[G]||(o.nodeName(H,"a")&&G=="click"))&&H["on"+G]&&H["on"+G].apply(H,K)===false){I.result=false}if(!E&&H[G]&&!I.isDefaultPrevented()&&!(o.nodeName(H,"a")&&G=="click")){this.triggered=true;try{H[G]()}catch(L){}}this.triggered=false;if(!I.isPropagationStopped()){var F=H.parentNode||H.ownerDocument;if(F){o.event.trigger(I,K,F,true)}}},handle:function(K){var J,E;K=arguments[0]=o.event.fix(K||l.event);K.currentTarget=this;var L=K.type.split(".");K.type=L.shift();J=!L.length&&!K.exclusive;var I=RegExp("(^|\\.)"+L.slice().sort().join(".*\\.")+"(\\.|$)");E=(o.data(this,"events")||{})[K.type];for(var G in E){var H=E[G];if(J||I.test(H.type)){K.handler=H;K.data=H.data;var F=H.apply(this,arguments);if(F!==g){K.result=F;if(F===false){K.preventDefault();K.stopPropagation()}}if(K.isImmediatePropagationStopped()){break}}}},props:"altKey attrChange attrName bubbles button cancelable charCode clientX clientY ctrlKey currentTarget data detail eventPhase fromElement handler keyCode metaKey newValue originalTarget pageX pageY prevValue relatedNode relatedTarget screenX screenY shiftKey srcElement target toElement view wheelDelta which".split(" "),fix:function(H){if(H[h]){return H}var F=H;H=o.Event(F);for(var G=this.props.length,J;G;){J=this.props[--G];H[J]=F[J]}if(!H.target){H.target=H.srcElement||document}if(H.target.nodeType==3){H.target=H.target.parentNode}if(!H.relatedTarget&&H.fromElement){H.relatedTarget=H.fromElement==H.target?H.toElement:H.fromElement}if(H.pageX==null&&H.clientX!=null){var I=document.documentElement,E=document.body;H.pageX=H.clientX+(I&&I.scrollLeft||E&&E.scrollLeft||0)-(I.clientLeft||0);H.pageY=H.clientY+(I&&I.scrollTop||E&&E.scrollTop||0)-(I.clientTop||0)}if(!H.which&&((H.charCode||H.charCode===0)?H.charCode:H.keyCode)){H.which=H.charCode||H.keyCode}if(!H.metaKey&&H.ctrlKey){H.metaKey=H.ctrlKey}if(!H.which&&H.button){H.which=(H.button&1?1:(H.button&2?3:(H.button&4?2:0)))}return H},proxy:function(F,E){E=E||function(){return F.apply(this,arguments)};E.guid=F.guid=F.guid||E.guid||this.guid++;return E},special:{ready:{setup:B,teardown:function(){}}},specialAll:{live:{setup:function(E,F){o.event.add(this,F[0],c)},teardown:function(G){if(G.length){var E=0,F=RegExp("(^|\\.)"+G[0]+"(\\.|$)");o.each((o.data(this,"events").live||{}),function(){if(F.test(this.type)){E++}});if(E<1){o.event.remove(this,G[0],c)}}}}}};o.Event=function(E){if(!this.preventDefault){return new o.Event(E)}if(E&&E.type){this.originalEvent=E;this.type=E.type}else{this.type=E}this.timeStamp=e();this[h]=true};function k(){return false}function u(){return true}o.Event.prototype={preventDefault:function(){this.isDefaultPrevented=u;var E=this.originalEvent;if(!E){return}if(E.preventDefault){E.preventDefault()}E.returnValue=false},stopPropagation:function(){this.isPropagationStopped=u;var E=this.originalEvent;if(!E){return}if(E.stopPropagation){E.stopPropagation()}E.cancelBubble=true},stopImmediatePropagation:function(){this.isImmediatePropagationStopped=u;this.stopPropagation()},isDefaultPrevented:k,isPropagationStopped:k,isImmediatePropagationStopped:k};var a=function(F){var E=F.relatedTarget;while(E&&E!=this){try{E=E.parentNode}catch(G){E=this}}if(E!=this){F.type=F.data;o.event.handle.apply(this,arguments)}};o.each({mouseover:"mouseenter",mouseout:"mouseleave"},function(F,E){o.event.special[E]={setup:function(){o.event.add(this,F,a,E)},teardown:function(){o.event.remove(this,F,a)}}});o.fn.extend({bind:function(F,G,E){return F=="unload"?this.one(F,G,E):this.each(function(){o.event.add(this,F,E||G,E&&G)})},one:function(G,H,F){var E=o.event.proxy(F||H,function(I){o(this).unbind(I,E);return(F||H).apply(this,arguments)});return this.each(function(){o.event.add(this,G,E,F&&H)})},unbind:function(F,E){return this.each(function(){o.event.remove(this,F,E)})},trigger:function(E,F){return this.each(function(){o.event.trigger(E,F,this)})},triggerHandler:function(E,G){if(this[0]){var F=o.Event(E);F.preventDefault();F.stopPropagation();o.event.trigger(F,G,this[0]);return F.result}},toggle:function(G){var E=arguments,F=1;while(F<E.length){o.event.proxy(G,E[F++])}return this.click(o.event.proxy(G,function(H){this.lastToggle=(this.lastToggle||0)%F;H.preventDefault();return E[this.lastToggle++].apply(this,arguments)||false}))},hover:function(E,F){return this.mouseenter(E).mouseleave(F)},ready:function(E){B();if(o.isReady){E.call(document,o)}else{o.readyList.push(E)}return this},live:function(G,F){var E=o.event.proxy(F);E.guid+=this.selector+G;o(document).bind(i(G,this.selector),this.selector,E);return this},die:function(F,E){o(document).unbind(i(F,this.selector),E?{guid:E.guid+this.selector+F}:null);return this}});function c(H){var E=RegExp("(^|\\.)"+H.type+"(\\.|$)"),G=true,F=[];o.each(o.data(this,"events").live||[],function(I,J){if(E.test(J.type)){var K=o(H.target).closest(J.data)[0];if(K){F.push({elem:K,fn:J})}}});F.sort(function(J,I){return o.data(J.elem,"closest")-o.data(I.elem,"closest")});o.each(F,function(){if(this.fn.call(this.elem,H,this.fn.data)===false){return(G=false)}});return G}function i(F,E){return["live",F,E.replace(/\./g,"`").replace(/ /g,"|")].join(".")}o.extend({isReady:false,readyList:[],ready:function(){if(!o.isReady){o.isReady=true;if(o.readyList){o.each(o.readyList,function(){this.call(document,o)});o.readyList=null}o(document).triggerHandler("ready")}}});var x=false;function B(){if(x){return}x=true;if(document.addEventListener){document.addEventListener("DOMContentLoaded",function(){document.removeEventListener("DOMContentLoaded",arguments.callee,false);o.ready()},false)}else{if(document.attachEvent){document.attachEvent("onreadystatechange",function(){if(document.readyState==="complete"){document.detachEvent("onreadystatechange",arguments.callee);o.ready()}});if(document.documentElement.doScroll&&l==l.top){(function(){if(o.isReady){return}try{document.documentElement.doScroll("left")}catch(E){setTimeout(arguments.callee,0);return}o.ready()})()}}}o.event.add(l,"load",o.ready)}o.each(("blur,focus,load,resize,scroll,unload,click,dblclick,mousedown,mouseup,mousemove,mouseover,mouseout,mouseenter,mouseleave,change,select,submit,keydown,keypress,keyup,error").split(","),function(F,E){o.fn[E]=function(G){return G?this.bind(E,G):this.trigger(E)}});o(l).bind("unload",function(){for(var E in o.cache){if(E!=1&&o.cache[E].handle){o.event.remove(o.cache[E].handle.elem)}}});(function(){o.support={};var F=document.documentElement,G=document.createElement("script"),K=document.createElement("div"),J="script"+(new Date).getTime();K.style.display="none";K.innerHTML='   <link/><table></table><a href="/a" style="color:red;float:left;opacity:.5;">a</a><select><option>text</option></select><object><param/></object>';var H=K.getElementsByTagName("*"),E=K.getElementsByTagName("a")[0];if(!H||!H.length||!E){return}o.support={leadingWhitespace:K.firstChild.nodeType==3,tbody:!K.getElementsByTagName("tbody").length,objectAll:!!K.getElementsByTagName("object")[0].getElementsByTagName("*").length,htmlSerialize:!!K.getElementsByTagName("link").length,style:/red/.test(E.getAttribute("style")),hrefNormalized:E.getAttribute("href")==="/a",opacity:E.style.opacity==="0.5",cssFloat:!!E.style.cssFloat,scriptEval:false,noCloneEvent:true,boxModel:null};G.type="text/javascript";try{G.appendChild(document.createTextNode("window."+J+"=1;"))}catch(I){}F.insertBefore(G,F.firstChild);if(l[J]){o.support.scriptEval=true;delete l[J]}F.removeChild(G);if(K.attachEvent&&K.fireEvent){K.attachEvent("onclick",function(){o.support.noCloneEvent=false;K.detachEvent("onclick",arguments.callee)});K.cloneNode(true).fireEvent("onclick")}o(function(){var L=document.createElement("div");L.style.width=L.style.paddingLeft="1px";document.body.appendChild(L);o.boxModel=o.support.boxModel=L.offsetWidth===2;document.body.removeChild(L).style.display="none"})})();var w=o.support.cssFloat?"cssFloat":"styleFloat";o.props={"for":"htmlFor","class":"className","float":w,cssFloat:w,styleFloat:w,readonly:"readOnly",maxlength:"maxLength",cellspacing:"cellSpacing",rowspan:"rowSpan",tabindex:"tabIndex"};o.fn.extend({_load:o.fn.load,load:function(G,J,K){if(typeof G!=="string"){return this._load(G)}var I=G.indexOf(" ");if(I>=0){var E=G.slice(I,G.length);G=G.slice(0,I)}var H="GET";if(J){if(o.isFunction(J)){K=J;J=null}else{if(typeof J==="object"){J=o.param(J);H="POST"}}}var F=this;o.ajax({url:G,type:H,dataType:"html",data:J,complete:function(M,L){if(L=="success"||L=="notmodified"){F.html(E?o("<div/>").append(M.responseText.replace(/<script(.|\s)*?\/script>/g,"")).find(E):M.responseText)}if(K){F.each(K,[M.responseText,L,M])}}});return this},serialize:function(){return o.param(this.serializeArray())},serializeArray:function(){return this.map(function(){return this.elements?o.makeArray(this.elements):this}).filter(function(){return this.name&&!this.disabled&&(this.checked||/select|textarea/i.test(this.nodeName)||/text|hidden|password|search/i.test(this.type))}).map(function(E,F){var G=o(this).val();return G==null?null:o.isArray(G)?o.map(G,function(I,H){return{name:F.name,value:I}}):{name:F.name,value:G}}).get()}});o.each("ajaxStart,ajaxStop,ajaxComplete,ajaxError,ajaxSuccess,ajaxSend".split(","),function(E,F){o.fn[F]=function(G){return this.bind(F,G)}});var r=e();o.extend({get:function(E,G,H,F){if(o.isFunction(G)){H=G;G=null}return o.ajax({type:"GET",url:E,data:G,success:H,dataType:F})},getScript:function(E,F){return o.get(E,null,F,"script")},getJSON:function(E,F,G){return o.get(E,F,G,"json")},post:function(E,G,H,F){if(o.isFunction(G)){H=G;G={}}return o.ajax({type:"POST",url:E,data:G,success:H,dataType:F})},ajaxSetup:function(E){o.extend(o.ajaxSettings,E)},ajaxSettings:{url:location.href,global:true,type:"GET",contentType:"application/x-www-form-urlencoded",processData:true,async:true,xhr:function(){return l.ActiveXObject?new ActiveXObject("Microsoft.XMLHTTP"):new XMLHttpRequest()},accepts:{xml:"application/xml, text/xml",html:"text/html",script:"text/javascript, application/javascript",json:"application/json, text/javascript",text:"text/plain",_default:"*/*"}},lastModified:{},ajax:function(M){M=o.extend(true,M,o.extend(true,{},o.ajaxSettings,M));var W,F=/=\?(&|$)/g,R,V,G=M.type.toUpperCase();if(M.data&&M.processData&&typeof M.data!=="string"){M.data=o.param(M.data)}if(M.dataType=="jsonp"){if(G=="GET"){if(!M.url.match(F)){M.url+=(M.url.match(/\?/)?"&":"?")+(M.jsonp||"callback")+"=?"}}else{if(!M.data||!M.data.match(F)){M.data=(M.data?M.data+"&":"")+(M.jsonp||"callback")+"=?"}}M.dataType="json"}if(M.dataType=="json"&&(M.data&&M.data.match(F)||M.url.match(F))){W="jsonp"+r++;if(M.data){M.data=(M.data+"").replace(F,"="+W+"$1")}M.url=M.url.replace(F,"="+W+"$1");M.dataType="script";l[W]=function(X){V=X;I();L();l[W]=g;try{delete l[W]}catch(Y){}if(H){H.removeChild(T)}}}if(M.dataType=="script"&&M.cache==null){M.cache=false}if(M.cache===false&&G=="GET"){var E=e();var U=M.url.replace(/(\?|&)_=.*?(&|$)/,"$1_="+E+"$2");M.url=U+((U==M.url)?(M.url.match(/\?/)?"&":"?")+"_="+E:"")}if(M.data&&G=="GET"){M.url+=(M.url.match(/\?/)?"&":"?")+M.data;M.data=null}if(M.global&&!o.active++){o.event.trigger("ajaxStart")}var Q=/^(\w+:)?\/\/([^\/?#]+)/.exec(M.url);if(M.dataType=="script"&&G=="GET"&&Q&&(Q[1]&&Q[1]!=location.protocol||Q[2]!=location.host)){var H=document.getElementsByTagName("head")[0];var T=document.createElement("script");T.src=M.url;if(M.scriptCharset){T.charset=M.scriptCharset}if(!W){var O=false;T.onload=T.onreadystatechange=function(){if(!O&&(!this.readyState||this.readyState=="loaded"||this.readyState=="complete")){O=true;I();L();T.onload=T.onreadystatechange=null;H.removeChild(T)}}}H.appendChild(T);return g}var K=false;var J=M.xhr();if(M.username){J.open(G,M.url,M.async,M.username,M.password)}else{J.open(G,M.url,M.async)}try{if(M.data){J.setRequestHeader("Content-Type",M.contentType)}if(M.ifModified){J.setRequestHeader("If-Modified-Since",o.lastModified[M.url]||"Thu, 01 Jan 1970 00:00:00 GMT")}J.setRequestHeader("X-Requested-With","XMLHttpRequest");J.setRequestHeader("Accept",M.dataType&&M.accepts[M.dataType]?M.accepts[M.dataType]+", */*":M.accepts._default)}catch(S){}if(M.beforeSend&&M.beforeSend(J,M)===false){if(M.global&&!--o.active){o.event.trigger("ajaxStop")}J.abort();return false}if(M.global){o.event.trigger("ajaxSend",[J,M])}var N=function(X){if(J.readyState==0){if(P){clearInterval(P);P=null;if(M.global&&!--o.active){o.event.trigger("ajaxStop")}}}else{if(!K&&J&&(J.readyState==4||X=="timeout")){K=true;if(P){clearInterval(P);P=null}R=X=="timeout"?"timeout":!o.httpSuccess(J)?"error":M.ifModified&&o.httpNotModified(J,M.url)?"notmodified":"success";if(R=="success"){try{V=o.httpData(J,M.dataType,M)}catch(Z){R="parsererror"}}if(R=="success"){var Y;try{Y=J.getResponseHeader("Last-Modified")}catch(Z){}if(M.ifModified&&Y){o.lastModified[M.url]=Y}if(!W){I()}}else{o.handleError(M,J,R)}L();if(X){J.abort()}if(M.async){J=null}}}};if(M.async){var P=setInterval(N,13);if(M.timeout>0){setTimeout(function(){if(J&&!K){N("timeout")}},M.timeout)}}try{J.send(M.data)}catch(S){o.handleError(M,J,null,S)}if(!M.async){N()}function I(){if(M.success){M.success(V,R)}if(M.global){o.event.trigger("ajaxSuccess",[J,M])}}function L(){if(M.complete){M.complete(J,R)}if(M.global){o.event.trigger("ajaxComplete",[J,M])}if(M.global&&!--o.active){o.event.trigger("ajaxStop")}}return J},handleError:function(F,H,E,G){if(F.error){F.error(H,E,G)}if(F.global){o.event.trigger("ajaxError",[H,F,G])}},active:0,httpSuccess:function(F){try{return !F.status&&location.protocol=="file:"||(F.status>=200&&F.status<300)||F.status==304||F.status==1223}catch(E){}return false},httpNotModified:function(G,E){try{var H=G.getResponseHeader("Last-Modified");return G.status==304||H==o.lastModified[E]}catch(F){}return false},httpData:function(J,H,G){var F=J.getResponseHeader("content-type"),E=H=="xml"||!H&&F&&F.indexOf("xml")>=0,I=E?J.responseXML:J.responseText;if(E&&I.documentElement.tagName=="parsererror"){throw"parsererror"}if(G&&G.dataFilter){I=G.dataFilter(I,H)}if(typeof I==="string"){if(H=="script"){o.globalEval(I)}if(H=="json"){I=l["eval"]("("+I+")")}}return I},param:function(E){var G=[];function H(I,J){G[G.length]=encodeURIComponent(I)+"="+encodeURIComponent(J)}if(o.isArray(E)||E.jquery){o.each(E,function(){H(this.name,this.value)})}else{for(var F in E){if(o.isArray(E[F])){o.each(E[F],function(){H(F,this)})}else{H(F,o.isFunction(E[F])?E[F]():E[F])}}}return G.join("&").replace(/%20/g,"+")}});var m={},n,d=[["height","marginTop","marginBottom","paddingTop","paddingBottom"],["width","marginLeft","marginRight","paddingLeft","paddingRight"],["opacity"]];function t(F,E){var G={};o.each(d.concat.apply([],d.slice(0,E)),function(){G[this]=F});return G}o.fn.extend({show:function(J,L){if(J){return this.animate(t("show",3),J,L)}else{for(var H=0,F=this.length;H<F;H++){var E=o.data(this[H],"olddisplay");this[H].style.display=E||"";if(o.css(this[H],"display")==="none"){var G=this[H].tagName,K;if(m[G]){K=m[G]}else{var I=o("<"+G+" />").appendTo("body");K=I.css("display");if(K==="none"){K="block"}I.remove();m[G]=K}o.data(this[H],"olddisplay",K)}}for(var H=0,F=this.length;H<F;H++){this[H].style.display=o.data(this[H],"olddisplay")||""}return this}},hide:function(H,I){if(H){return this.animate(t("hide",3),H,I)}else{for(var G=0,F=this.length;G<F;G++){var E=o.data(this[G],"olddisplay");if(!E&&E!=="none"){o.data(this[G],"olddisplay",o.css(this[G],"display"))}}for(var G=0,F=this.length;G<F;G++){this[G].style.display="none"}return this}},_toggle:o.fn.toggle,toggle:function(G,F){var E=typeof G==="boolean";return o.isFunction(G)&&o.isFunction(F)?this._toggle.apply(this,arguments):G==null||E?this.each(function(){var H=E?G:o(this).is(":hidden");o(this)[H?"show":"hide"]()}):this.animate(t("toggle",3),G,F)},fadeTo:function(E,G,F){return this.animate({opacity:G},E,F)},animate:function(I,F,H,G){var E=o.speed(F,H,G);return this[E.queue===false?"each":"queue"](function(){var K=o.extend({},E),M,L=this.nodeType==1&&o(this).is(":hidden"),J=this;for(M in I){if(I[M]=="hide"&&L||I[M]=="show"&&!L){return K.complete.call(this)}if((M=="height"||M=="width")&&this.style){K.display=o.css(this,"display");K.overflow=this.style.overflow}}if(K.overflow!=null){this.style.overflow="hidden"}K.curAnim=o.extend({},I);o.each(I,function(O,S){var R=new o.fx(J,K,O);if(/toggle|show|hide/.test(S)){R[S=="toggle"?L?"show":"hide":S](I)}else{var Q=S.toString().match(/^([+-]=)?([\d+-.]+)(.*)$/),T=R.cur(true)||0;if(Q){var N=parseFloat(Q[2]),P=Q[3]||"px";if(P!="px"){J.style[O]=(N||1)+P;T=((N||1)/R.cur(true))*T;J.style[O]=T+P}if(Q[1]){N=((Q[1]=="-="?-1:1)*N)+T}R.custom(T,N,P)}else{R.custom(T,S,"")}}});return true})},stop:function(F,E){var G=o.timers;if(F){this.queue([])}this.each(function(){for(var H=G.length-1;H>=0;H--){if(G[H].elem==this){if(E){G[H](true)}G.splice(H,1)}}});if(!E){this.dequeue()}return this}});o.each({slideDown:t("show",1),slideUp:t("hide",1),slideToggle:t("toggle",1),fadeIn:{opacity:"show"},fadeOut:{opacity:"hide"}},function(E,F){o.fn[E]=function(G,H){return this.animate(F,G,H)}});o.extend({speed:function(G,H,F){var E=typeof G==="object"?G:{complete:F||!F&&H||o.isFunction(G)&&G,duration:G,easing:F&&H||H&&!o.isFunction(H)&&H};E.duration=o.fx.off?0:typeof E.duration==="number"?E.duration:o.fx.speeds[E.duration]||o.fx.speeds._default;E.old=E.complete;E.complete=function(){if(E.queue!==false){o(this).dequeue()}if(o.isFunction(E.old)){E.old.call(this)}};return E},easing:{linear:function(G,H,E,F){return E+F*G},swing:function(G,H,E,F){return((-Math.cos(G*Math.PI)/2)+0.5)*F+E}},timers:[],fx:function(F,E,G){this.options=E;this.elem=F;this.prop=G;if(!E.orig){E.orig={}}}});o.fx.prototype={update:function(){if(this.options.step){this.options.step.call(this.elem,this.now,this)}(o.fx.step[this.prop]||o.fx.step._default)(this);if((this.prop=="height"||this.prop=="width")&&this.elem.style){this.elem.style.display="block"}},cur:function(F){if(this.elem[this.prop]!=null&&(!this.elem.style||this.elem.style[this.prop]==null)){return this.elem[this.prop]}var E=parseFloat(o.css(this.elem,this.prop,F));return E&&E>-10000?E:parseFloat(o.curCSS(this.elem,this.prop))||0},custom:function(I,H,G){this.startTime=e();this.start=I;this.end=H;this.unit=G||this.unit||"px";this.now=this.start;this.pos=this.state=0;var E=this;function F(J){return E.step(J)}F.elem=this.elem;if(F()&&o.timers.push(F)&&!n){n=setInterval(function(){var K=o.timers;for(var J=0;J<K.length;J++){if(!K[J]()){K.splice(J--,1)}}if(!K.length){clearInterval(n);n=g}},13)}},show:function(){this.options.orig[this.prop]=o.attr(this.elem.style,this.prop);this.options.show=true;this.custom(this.prop=="width"||this.prop=="height"?1:0,this.cur());o(this.elem).show()},hide:function(){this.options.orig[this.prop]=o.attr(this.elem.style,this.prop);this.options.hide=true;this.custom(this.cur(),0)},step:function(H){var G=e();if(H||G>=this.options.duration+this.startTime){this.now=this.end;this.pos=this.state=1;this.update();this.options.curAnim[this.prop]=true;var E=true;for(var F in this.options.curAnim){if(this.options.curAnim[F]!==true){E=false}}if(E){if(this.options.display!=null){this.elem.style.overflow=this.options.overflow;this.elem.style.display=this.options.display;if(o.css(this.elem,"display")=="none"){this.elem.style.display="block"}}if(this.options.hide){o(this.elem).hide()}if(this.options.hide||this.options.show){for(var I in this.options.curAnim){o.attr(this.elem.style,I,this.options.orig[I])}}this.options.complete.call(this.elem)}return false}else{var J=G-this.startTime;this.state=J/this.options.duration;this.pos=o.easing[this.options.easing||(o.easing.swing?"swing":"linear")](this.state,J,0,1,this.options.duration);this.now=this.start+((this.end-this.start)*this.pos);this.update()}return true}};o.extend(o.fx,{speeds:{slow:600,fast:200,_default:400},step:{opacity:function(E){o.attr(E.elem.style,"opacity",E.now)},_default:function(E){if(E.elem.style&&E.elem.style[E.prop]!=null){E.elem.style[E.prop]=E.now+E.unit}else{E.elem[E.prop]=E.now}}}});if(document.documentElement.getBoundingClientRect){o.fn.offset=function(){if(!this[0]){return{top:0,left:0}}if(this[0]===this[0].ownerDocument.body){return o.offset.bodyOffset(this[0])}var G=this[0].getBoundingClientRect(),J=this[0].ownerDocument,F=J.body,E=J.documentElement,L=E.clientTop||F.clientTop||0,K=E.clientLeft||F.clientLeft||0,I=G.top+(self.pageYOffset||o.boxModel&&E.scrollTop||F.scrollTop)-L,H=G.left+(self.pageXOffset||o.boxModel&&E.scrollLeft||F.scrollLeft)-K;return{top:I,left:H}}}else{o.fn.offset=function(){if(!this[0]){return{top:0,left:0}}if(this[0]===this[0].ownerDocument.body){return o.offset.bodyOffset(this[0])}o.offset.initialized||o.offset.initialize();var J=this[0],G=J.offsetParent,F=J,O=J.ownerDocument,M,H=O.documentElement,K=O.body,L=O.defaultView,E=L.getComputedStyle(J,null),N=J.offsetTop,I=J.offsetLeft;while((J=J.parentNode)&&J!==K&&J!==H){M=L.getComputedStyle(J,null);N-=J.scrollTop,I-=J.scrollLeft;if(J===G){N+=J.offsetTop,I+=J.offsetLeft;if(o.offset.doesNotAddBorder&&!(o.offset.doesAddBorderForTableAndCells&&/^t(able|d|h)$/i.test(J.tagName))){N+=parseInt(M.borderTopWidth,10)||0,I+=parseInt(M.borderLeftWidth,10)||0}F=G,G=J.offsetParent}if(o.offset.subtractsBorderForOverflowNotVisible&&M.overflow!=="visible"){N+=parseInt(M.borderTopWidth,10)||0,I+=parseInt(M.borderLeftWidth,10)||0}E=M}if(E.position==="relative"||E.position==="static"){N+=K.offsetTop,I+=K.offsetLeft}if(E.position==="fixed"){N+=Math.max(H.scrollTop,K.scrollTop),I+=Math.max(H.scrollLeft,K.scrollLeft)}return{top:N,left:I}}}o.offset={initialize:function(){if(this.initialized){return}var L=document.body,F=document.createElement("div"),H,G,N,I,M,E,J=L.style.marginTop,K='<div style="position:absolute;top:0;left:0;margin:0;border:5px solid #000;padding:0;width:1px;height:1px;"><div></div></div><table style="position:absolute;top:0;left:0;margin:0;border:5px solid #000;padding:0;width:1px;height:1px;" cellpadding="0" cellspacing="0"><tr><td></td></tr></table>';M={position:"absolute",top:0,left:0,margin:0,border:0,width:"1px",height:"1px",visibility:"hidden"};for(E in M){F.style[E]=M[E]}F.innerHTML=K;L.insertBefore(F,L.firstChild);H=F.firstChild,G=H.firstChild,I=H.nextSibling.firstChild.firstChild;this.doesNotAddBorder=(G.offsetTop!==5);this.doesAddBorderForTableAndCells=(I.offsetTop===5);H.style.overflow="hidden",H.style.position="relative";this.subtractsBorderForOverflowNotVisible=(G.offsetTop===-5);L.style.marginTop="1px";this.doesNotIncludeMarginInBodyOffset=(L.offsetTop===0);L.style.marginTop=J;L.removeChild(F);this.initialized=true},bodyOffset:function(E){o.offset.initialized||o.offset.initialize();var G=E.offsetTop,F=E.offsetLeft;if(o.offset.doesNotIncludeMarginInBodyOffset){G+=parseInt(o.curCSS(E,"marginTop",true),10)||0,F+=parseInt(o.curCSS(E,"marginLeft",true),10)||0}return{top:G,left:F}}};o.fn.extend({position:function(){var I=0,H=0,F;if(this[0]){var G=this.offsetParent(),J=this.offset(),E=/^body|html$/i.test(G[0].tagName)?{top:0,left:0}:G.offset();J.top-=j(this,"marginTop");J.left-=j(this,"marginLeft");E.top+=j(G,"borderTopWidth");E.left+=j(G,"borderLeftWidth");F={top:J.top-E.top,left:J.left-E.left}}return F},offsetParent:function(){var E=this[0].offsetParent||document.body;while(E&&(!/^body|html$/i.test(E.tagName)&&o.css(E,"position")=="static")){E=E.offsetParent}return o(E)}});o.each(["Left","Top"],function(F,E){var G="scroll"+E;o.fn[G]=function(H){if(!this[0]){return null}return H!==g?this.each(function(){this==l||this==document?l.scrollTo(!F?H:o(l).scrollLeft(),F?H:o(l).scrollTop()):this[G]=H}):this[0]==l||this[0]==document?self[F?"pageYOffset":"pageXOffset"]||o.boxModel&&document.documentElement[G]||document.body[G]:this[0][G]}});o.each(["Height","Width"],function(I,G){var E=I?"Left":"Top",H=I?"Right":"Bottom",F=G.toLowerCase();o.fn["inner"+G]=function(){return this[0]?o.css(this[0],F,false,"padding"):null};o.fn["outer"+G]=function(K){return this[0]?o.css(this[0],F,false,K?"margin":"border"):null};var J=G.toLowerCase();o.fn[J]=function(K){return this[0]==l?document.compatMode=="CSS1Compat"&&document.documentElement["client"+G]||document.body["client"+G]:this[0]==document?Math.max(document.documentElement["client"+G],document.body["scroll"+G],document.documentElement["scroll"+G],document.body["offset"+G],document.documentElement["offset"+G]):K===g?(this.length?o.css(this[0],J):null):this.css(J,typeof K==="string"?K:K+"px")}})})();/**
 * Filename    : Describer.js
 * Author      : Robert Cerny
 * Created     : 2009-11-19
 * Last Change : 2009-12-07
 */

CERNY.require("TOPINCS.misc.Describer",
              "TOPINCS.cons",
              "DICT",
              "CERNY.http.Request",
              "jQuery",
              "CERNY.http.Response");

(function () {
    TOPINCS.misc.Describer = {};
    var Describer = TOPINCS.misc.Describer;

    var method = CERNY.method;
    var signature = CERNY.signature;

    var timeoutId = null;
    var waitingTime = 2000;
    var cache = {};

    $(document.body).append("<div id='tooltip' class='hidden tooltip'></div>");

    function displayDescription(topicref, displayFunc) {
        if (cache[topicref]) {
            displayFunc(cache[topicref]);
            return;
        }

        var url = TOPIC_DESCRIPTION_URL + "?t=" + topicref,
            description,
            request = new CERNY.http.Request("GET", url);

        request.sendAsynch(function(req) {
            var description,
                response = new CERNY.http.Response(req);
            if (response.getStatus() < 400) {
                description = response.getBody();
                if (!isNonEmptyString(description)) {
                    description = DICT.msg_no_description;
                }
            } else {
                description = DICT.msg_description_loading_error;
            }
            cache[topicref] = description;
            displayFunc(description);
        });
    }
    signature(displayDescription, "undefined", "string", "function");
    method(Describer, "displayDescription", displayDescription);

    function describe(el) {
        timeoutId = window.setTimeout(function() {
            displayDescription("si:" + el.href, function (desc) {
                showTooltip(desc, el);
            });
        }, waitingTime);
    }
    signature(describe, "undefined", "object");
    method(Describer, "describe", describe);


    function install(el) {
        $(el).hover(function() {
            describe(el);
        }, function() {
            clearTimeout(timeoutId);
            $("#tooltip").fadeOut(300);
        });
    }
    signature(install, "undefined", "object");
    method(Describer, "install", install);

    function showTooltip(text, el) {
        var tooltipEl = $("#tooltip");
        tooltipEl.text(text);
        positionOver(tooltipEl, $(el));
        tooltipEl.removeClass("hidden");
        tooltipEl.fadeIn(300);
    }

    function positionOver(tooltipEl, targetEl) {
        var p = targetEl.position();
        tooltipEl.css("left", p.left + 30);
        tooltipEl.css("top", p.top + 30);
        tooltipEl.css("position", "absolute");
    }


})();
/**
 * Filename    : topic.js
 * Author      : Robert Cerny
 * Created     : 2009-06-02
 * Last Change : 2009-11-19
 */

CERNY.require("TOPINCS.web.Topic",
              "jQuery",
              "TOPINCS.locale",
              "DICT",
              "TOPINCS.widgets.ValueViewer",
              "TOPINCS.misc.Describer");

(function() {

    initViewers(TOPINCS.getLocale());
    initStatements();
    installDescriber();
    createWikiLink(TOPINCS.PAGE_SUBJECT_ID, DICT.lab_open_in_wiki);
    showContent();
    handleHash();

    var isPopupOpen = false;

    function initViewers(locale) {
        $("[datatype]").each(function() {
            var el = $(this);
            var viewer = new TOPINCS.widgets.ValueViewer(el.text(), el.attr("datatype"), locale);
            el.replaceWith(viewer.render().node);
        });
    }

    function handleHash() {
        var hash = document.location.hash;
        if (hash) {
            var markedStatementEl = $(hash);
            if (markedStatementEl) {
                mark(markedStatementEl);
            }
        }
    }

    function initStatements() {
        $("div.statement").each(function() {
            var el = $(this);
            var detailsEl = $("div.details",this);
            var buttonEl = $("button.open-details",this);
            buttonEl.click(function() {
                isPopupOpen = true;
                el.addClass("statement-hl");
                detailsEl.show();
                position(detailsEl, el);
            });

            var closeButtonEl = $("button.close-details",this);
            closeButtonEl.click(function() {
                el.removeClass("statement-hl");
                detailsEl.hide();
                isPopupOpen = false;
            });

            el.mouseenter(function() {
                if (!isPopupOpen) {
                    position(buttonEl, el);
                    buttonEl.show();
                }
            });

            el.mouseleave(function() {
                buttonEl.hide();
            });

            var aEl = $("a.statement-link", detailsEl);
            aEl.click(function() {
                mark(el);
            });
        });
    }

    function showContent() {
        $("#content").removeClass("hidden");
    }

    function mark(el) {
        var p = el.position();
        var mEl = $("#marker");
        mEl.css("left", p.left - 23);
        mEl.css("top", p.top);
        mEl.css("position", "absolute");
        mEl.show();
    }

    function position(el, targetEl) {
        // var top = 0 + (targetEl.outerHeight() / 2) - (el.outerHeight() / 3);
        var offset = targetEl.offset();
        var top = offset.top;
        var left = offset.left + targetEl.outerWidth() - el.outerWidth();
        el.css("position", "absolute").css("left", left + "px").css("top", top + "px");
    }

    function createWikiLink(systemId, label) {
        $("#footer").append("<a href='wiki/id:" + systemId + "'>" + label + "</a>");
    }

    function installDescriber() {
        $("span.topic-link a").each(function() {
            TOPINCS.misc.Describer.install(this);
        });
    }

})();
