
String.prototype.contains = function(value) {
    return this.indexOf(value) > -1;
};
String.prototype.startsWith = function(value) {
    return this.indexOf(value) == 0;
};
String.prototype.endsWith = function(value) {
    var searchFrom = this.length - value.length;
    return this.indexOf(value, searchFrom) == searchFrom;
};
String.prototype.each = function(handler) {
    for (var i = 0; i < this.length; i++) {
        handler(this.charAt(i), i);
    }
};
String.prototype.trim = function() {
    return this.replace(/^\s+|\s+$/g, "");
};
String.empty = "";
String.prototype.isEmpty = function() {
    return this == String.empty;
};
String.prototype.isNotEmpty = function() {
    return ! this.isEmpty();
};
if (typeof(Array.prototype.indexOf) == "undefined") {
    Array.prototype.indexOf = function(item) {
        for (var i = 0; i < this.length; i++) {
            if (this[i] == item) {
                return i;
            }
        }
        return - 1;
    };
}
Array.prototype.add = function(item) {
    this.push(item);
    return this;
};
Array.prototype.remove = function(item) {
    var i = this.indexOf(item);
    while (i != -1) {
        this.splice(i, 1);
        i = this.indexOf(item);
    }
};
Array.prototype.contains = function(value) {
    return this.indexOf(value) > -1;
};
Array.prototype.last = function() {
    return this[this.length - 1];
};
Array.each = function(items, handler) {
    for (var i = 0; i < items.length; i++) {
        handler(items[i], i);
    }
};
Array.prototype.each = function(handler) {
    return Array.each(this, handler);
};
Array.filter = function(items, handler) {
    var results = [];
    Array.each(items,
    function(item) {
        if (handler(item)) {
            results.add(item);
        }
    });
    return results;
};
if (typeof(Array.prototype.filter) == "undefined") {
    Array.prototype.filter = function(handler) {
        return Array.filter(this, handler);
    };
}
Array.map = function(items, handler) {
    var results = [];
    Array.each(items,
    function(item, index) {
        results.add(handler(item, index));
    });
    return results;
};
if (typeof(Array.prototype.map) == "undefined") {
    Array.prototype.map = function(handler) {
        return Array.map(this, handler);
    };
}
function StringBuilder() {
    this.buffer = [];
}
StringBuilder.prototype.append = function(value) {
    this.buffer.add(value);
    return this;
};
StringBuilder.prototype.toString = function(separator) {
    return this.buffer.join(separator || "");
};
function Path() {}
Path.extractFilename = function(path) {
    if (path.contains("\\")) {
        return path.split("\\").last();
    } else {
        if (path.contains("/")) {
            return path.split("/").last();
        }
    }
    return path;
};
Function.importIntoScope = function(functionToImport) {
    self.eval(functionToImport.toString());
};
Object.each = function(object, handler) {
    for (var property in object) {
        handler(property, object[property]);
    }
};
function Map() {
    this.pairs = [];
}
Map.Pair = function(key, value) {
    this.key = key;
    this.value = value;
};
Map.prototype.set = function(key, value) {
    this.remove(key);
    this.pairs.add(new Map.Pair(key, value));
    return this;
};
Map.prototype.remove = function(key) {
    this.pairs.remove(this.get(key));
};
Map.prototype.contains = function(key) {
    return this.get(key) != null;
};
Map.prototype.get = function(key) {
    var value = null;
    this.each(function(pair) {
        if (pair.key == key) {
            value = pair.value;
        }
    });
    return value;
};
Map.prototype.each = function(handler) {
    this.pairs.each(handler);
};
Map.prototype.merge = function(map) {
    map.each(function(pair) {
        this.set(pair.key, pair.value);
    });
};
Boolean.parse = function(value) {
    return value.toLowerCase() == "true";
};
function BrowserEvent(event) {
    this.event = event;
}
BrowserEvent.prototype.htmlTarget = function() {
    var target;
    var event = this.event;
    if (!event) {
        var event = window.event;
    }
    if (event.target) {
        target = event.target;
    } else {
        if (event.srcElement) {
            target = event.srcElement;
        }
    }
    if (target.nodeType == 3) {
        target = target.parentNode;
    }
    return target;
};
function RequestMessage(method, url) {
    this.method = method;
    this.url = url;
    this.httpDriver = RequestMessage.createHttpDriver();
}
RequestMessage.createHttpDriver = function() {
    if (typeof(XMLHttpRequest) == "function" || typeof(XMLHttpRequest) == "object") {
        return new XMLHttpRequest();
    } else {
        if (typeof(ActiveXObject) == "function") {
            return new ActiveXObject("MSXML2.XMLHTTP.3.0");
        } else {
            alert("No XML callback facility found!");
        }
    }
};
RequestMessage.prototype.asyncSend = function(parameters, callback) {
    this.callback = callback;
    var self = this;
    this.httpDriver.onreadystatechange = function() {
        self.responseRecieved();
    };
    if (this.getMethod() == "POST") {
        this.httpDriver.open(this.getMethod(), this.getFullyQualifiedUrl(), true);
        this.httpDriver.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
        this.httpDriver.send(parameters.toString());
    } else {
        if (this.getMethod() == "GET") {
            var urlWithParameters = this.appendParameters(this.getFullyQualifiedUrl(), parameters);
            this.httpDriver.open(this.getMethod(), urlWithParameters, true);
            this.httpDriver.send(null);
        }
    }
};
RequestMessage.prototype.send = function(parameters) {
    if (this.getMethod() == "POST") {
        this.httpDriver.open(this.getMethod(), this.getFullyQualifiedUrl(), false);
        this.httpDriver.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
        this.httpDriver.send(parameters.toString());
    } else {
        if (this.getMethod() == "GET") {
            var urlWithParameters = this.appendParameters(this.getFullyQualifiedUrl(), parameters);
            this.httpDriver.open(this.getMethod(), urlWithParameters, false);
            this.httpDriver.send(null);
        }
    }
    return new ResponseMessage(this.httpDriver);
};
RequestMessage.prototype.appendParameters = function(url, parameters) {
    if (url.contains("?") && !url.endsWith("&")) {
        url += "&";
    } else {
        url += "?";
    }
    url += parameters.toString();
    return url;
};
RequestMessage.prototype.responseRecieved = function() {
    if (this.httpDriver.readyState == 4) {
        this.callback(new ResponseMessage(this.httpDriver));
    }
};
RequestMessage.prototype.getMethod = function() {
    return this.method.toUpperCase();
};
RequestMessage.prototype.getFullyQualifiedUrl = function() {
    return new UrlQualifier(window.location).qualify(this.url);
};
function ResponseMessage(httpDriver) {
    this.httpDriver = httpDriver;
}
ResponseMessage.prototype.getText = function() {
    return this.httpDriver.responseText;
};
ResponseMessage.prototype.getXml = function() {
    return this.httpDriver.responseXml;
};
ResponseMessage.prototype.isSuccess = function() {
    return this.httpDriver.status == 200;
};
function UrlQualifier(location) {
    this.location = location;
}
UrlQualifier.prototype.qualify = function(url) {
    if (url.contains(":")) {
        return url;
    } else {
        if (url.startsWith("?")) {
            return this.location.href.split("?")[0] + url;
        } else {
            if (url.startsWith("/")) {
                return this.location.protocol + "//" + this.location.host + url;
            } else {
                var parts = url.split("/");
                parts[parts.length - 1] = url;
                return parts.join("/");
            }
        }
    }
};
function Meta() {}
Meta.getContent = function(name, optionalDoc) {
    var doc = optionalDoc || document;
    var content = "";
    var metas = doc.getElementsByTagName("meta");
    Array.each(metas,
    function(element) {
        if (name == element.getAttribute("name")) {
            content = element.getAttribute("content");
        }
    });
    return content;
};
function Script(src) {
    this.src = src;
}
Script.prototype.load = function(callback) {
    var html = '<script type="text/javascript" src="' + this.src + '"><\/script>';
    if (!callback) {
        document.writeln(html);
    } else {
        var script = Elements.create(html);
        script.addEventListener("load", callback, false);
        Elements.addToHead(script);
    }
};
function ClassName(element) {
    this.element = element;
}
ClassName.prototype.ClassSeperator = " ";
ClassName.prototype.addClass = function(name) {
    var classNames = this.getNames();
    if (!classNames.contains(name)) {
        classNames.add(name);
        this.setNames(classNames);
    }
};
ClassName.prototype.removeClass = function(name) {
    var classNames = this.getNames();
    classNames.remove(name);
    this.setNames(classNames);
};
ClassName.prototype.contains = function(name) {
    return this.getNames().contains(name);
};
ClassName.prototype.getNames = function() {
    if (this.element.className) {
        return this.element.className.split(this.ClassSeperator);
    }
    return [];
};
ClassName.prototype.setNames = function(classNames) {
    this.element.className = classNames.join(this.ClassSeperator);
};
if (typeof(Node) == "undefined") {
    function Node() {}
}
if (typeof(Node.ELEMENT_NODE) == "undefined") {
    Node.ELEMENT_NODE = 1;
}
function Elements() {}
Elements.replaceContent = function(referenceElement, newContent) {
    Elements.clearContent(referenceElement);
    referenceElement.appendChild(newContent);
};
Elements.clearContent = function(element) {
    element.innerHTML = "";
};
Elements.getSwfObject = function(swfName, definingProperty) {
    var possibleLocations = [window[swfName], document[swfName], Elements.getElementById(swfName)];
    return possibleLocations.filter(function(item) {
        return typeof(item) != "undefined" && typeof(item[definingProperty]) == "function";
    })[0];
};
Elements.addToHead = function(element) {
    document.getElementsByTagName("head")[0].appendChild(element);
};
Elements.getElementById = function(id) {
    var element = document.getElementById(id);
    return Elements.fix(element);
};
Elements.fixAll = function(elements) {
    return Array.map(elements, Elements.fix);
};
Elements.fix = function(element) {
    if (element == null) {
        return element;
    }
    if (typeof(element.addEventListener) != "function") {
        element.addEventListener = function(type, listener, useCapture) {
            element.attachEvent("on" + type,
            function() {
                if (element.tagName && element.tagName.toLowerCase() == "iframe") {
                    element = Frames.fix(element);
                }
                var wrapper = {
                    preventDefault: function() {
                        window.event.returnValue = false;
                    }
                };
                listener(wrapper);
            });
        };
    }
    if (typeof(element.isBlank) != "isBlank") {
        if (element.type == "text" || element.type == "textarea" || element.type == "hidden") {
            element.isBlank = function() {
                return element.value.length == 0;
            };
        } else {
            if (element.type == "checkbox") {
                element.isBlank = function() {
                    return ! element.checked;
                };
            } else {
                if (element.type == "select") {
                    element.isBlank = function() {
                        return ! element.selected;
                    };
                } else {
                    element.isBlank = function() {
                        return false;
                    };
                }
            }
        }
    }
    return element;
};
Elements.remove = function(element) {
    if (element) {
        var parent = element.parentNode;
        parent.removeChild(element);
    }
};
Elements.replace = function(elementToReplace, newElement) {
    if (typeof(newElement) == "string") {
        newElement = Elements.createFragment(newElement);
    }
    if (newElement.outerHTML) {
        newElement = Elements.createFragment(newElement.outerHTML);
    }
    var parent = elementToReplace.parentNode;
    parent.replaceChild(newElement, elementToReplace);
};
Elements.create = function(html) {
    var temp = document.createElement("div");
    temp.innerHTML = html;
    return Elements.fix(temp.firstChild);
};
Elements.createFragment = function(html) {
    var temp = document.createElement("div");
    temp.innerHTML = html;
    var fragment = document.createDocumentFragment();
    Elements.moveChildren(temp, fragment);
    return fragment;
};
Elements.moveChildren = function(from, to) {
    while (from.childNodes.length > 0) {
        var child = from.removeChild(from.firstChild);
        to.appendChild(child);
    }
};
Elements.insertBefore = function(referenceElement, newElement) {
    var parent = referenceElement.parentNode;
    parent.insertBefore(newElement, referenceElement);
};
Elements.insertAfter = function(referenceElement, newElement) {
    var nextSibling = referenceElement.nextSibling;
    var parent = referenceElement.parentNode;
    parent.insertBefore(newElement, nextSibling);
};
Elements.forEachTagName = function(element, tagNames, handler) {
    for (var t = 0; t < tagNames.length; ++t) {
        var elements = element.getElementsByTagName(tagNames[t]);
        for (var e = 0; e < elements.length; e++) {
            handler(elements[e]);
        }
    }
};
Elements.getDescendentsByName = function(parent, name) {
    var result = [];
    Elements.forEachTagName(parent, ["*"],
    function(element) {
        if (element.name == name) {
            result.add(element);
        }
    });
    return result;
};
Elements.classesFor = function(element) {
    return element.className.split(" ");
};
Elements.getElementsByClassName = function(parent, name) {
    var result = [];
    Elements.forEachTagName(parent, ["*"],
    function(element) {
        var classes = new ClassName(element);
        if (classes.contains(name)) {
            result.add(element);
        }
    });
    return result;
};
Elements.getChildByClass = function(element, className) {
    for (var i = 0; i < element.childNodes.length; i++) {
        var childElement = element.childNodes[i];
        if (childElement.className != null) {
            if (Elements.classesFor(childElement).contains(className)) {
                return childElement;
            }
        }
    }
    return null;
};
Elements.getChildByTagName = function(element, tagName) {
    for (var i = 0; i < element.childNodes.length; i++) {
        var childElement = element.childNodes[i];
        if (childElement.tagName == tagName) {
            return childElement;
        }
    }
    return null;
};
Elements.getElementByIdFrom = function(element, id) {
    var children = element.getElementsByTagName("*");
    for (var i = 0; children != undefined && i < children.length; i++) {
        if (children[i].id == id) {
            return children[i];
        }
    }
    return element.id == id ? element: null;
};
function Size(width, height) {
    this.setWidth(width || 0);
    this.setHeight(height || 0);
}
Size.prototype.setWidth = function(width) {
    this.width = parseInt(width);
};
Size.prototype.setHeight = function(height) {
    this.height = parseInt(height);
};
Size.prototype.isZero = function() {
    return this.width == 0 && this.height == 0;
};
Elements.findLargestSize = function(element) {
    var largest = new Size();
    Elements.forEachTagName(element, ["*"],
    function(child) {
        if (child.width > largest.width && child.height > largest.height) {
            largest.setWidth(child.width);
            largest.setHeight(child.height);
        } else {
            if (child.scrollWidth > largest.width && child.scrollHeight > largest.height) {
                largest.setWidth(child.scrollWidth);
                largest.setHeight(child.scrollHeight);
            }
        }
    });
    return largest;
};
function Html() {}
Html.Form = function(element, parameters) {
    this.element = element;
    this.parameters = parameters || new Parameters();
};
Html.Form.prototype.submit = function(callBack) {
    var parameters = this.getParameters();
    var requestMessage = new RequestMessage(this.getMethod(), this.getAction());
    requestMessage.asyncSend(parameters, callBack);
};
Html.Form.prototype.getParameters = function() {
    var parameters = this.parameters;
    Array.each(this.element.elements,
    function(element) {
        if (element.type == "text" || element.type == "textarea" || element.type == "hidden") {
            parameters.add(element.name, element.value);
        } else {
            if (element.type == "checkbox" && element.checked) {
                parameters.add(element.name, element.value);
            }
        }
    });
    return parameters;
};
Html.Form.prototype.getMethod = function() {
    return this.element.method;
};
Html.Form.prototype.getAction = function() {
    return this.element.action;
};
function Parameters() {
    this.params = {};
}
Parameters.forBody = function() {
    var parameters = new Parameters();
    parameters.add("decorator", "body");
    return parameters;
};
Parameters.prototype.add = function(name, value) {
    this.params[name] = value;
    return this;
};
Parameters.prototype.toString = function() {
    var result = new StringBuilder();
    for (var name in this.params) {
        result.append(name).append("=").append(encodeURIComponent(this.params[name])).append("&");
    }
    return result.toString();
};
Parameters.prototype.contains = function(key) {
    return this.params[key] != null;
};
function Frames() {}
Frames.fix = function(frame) {
    if (frame.contentDocument != frame.contentWindow.document) {
        frame.contentDocument = frame.contentWindow.document;
    }
    return frame;
};
Frames.sizeToContent = function(frame) {
    frame = Frames.fix(frame);
    frame.style.width = 0;
    frame.style.height = 0;
    frame.style.width = frame.contentDocument.body.scrollWidth + "px";
    frame.style.height = frame.contentDocument.body.scrollHeight + "px";
};
Frames.sizeToParent = function(frame) {
    frame = Frames.fix(frame);
    frame.style.width = "100%";
    frame.style.height = "100%";
    frame.contentDocument.body.style.width = frame.scrollWidth + "px";
    frame.contentDocument.body.style.height = frame.scrollHeight + "px";
};
window.location.getHash = function() {
    var result = window.location.hash;
    return result.split("#")[1];
};
function Cookies(document) {
    this.document = document || self.document;
}
Cookies.Seperator = ";";
Cookies.prototype.get = function(key) {
    var map = this.parse();
    return map.get(key);
};
Cookies.prototype.set = function(key, value) {
    document.cookie = new Cookies.Cookie(key, value).toString();
};
Cookies.prototype.parse = function() {
    var map = new Map();
    this.document.cookie.split(Cookies.Seperator).each(function(raw) {
        var cookie = Cookies.Cookie.parse(raw);
        map.set(cookie.key, cookie.value);
    });
    return map;
};
Cookies.Cookie = function(key, value, path) {
    this.key = key;
    this.value = value;
    this.path = path || "/";
};
Cookies.Cookie.prototype.toString = function() {
    var result = new StringBuilder();
    result.append(this.key).append(Cookies.Cookie.Seperator).append(encodeURIComponent(this.value)).append(";path=").append(this.path);
    return result.toString();
};
Cookies.Cookie.Seperator = "=";
Cookies.Cookie.parse = function(value) {
    var pair = value.trim().split(Cookies.Cookie.Seperator);
    return new Cookies.Cookie(pair[0], pair[1]);
};
var Behaviour = {
    list: new Array,
    executedList: new Array,
    register: function(sheet) {
        var bindingsToAdd = {};
        for (var selector in sheet) {
            if (!this.isAlreadyRegistered(selector, sheet[selector])) {
                bindingsToAdd[selector] = sheet[selector];
            }
        }
        Behaviour.list.push(bindingsToAdd);
    },
    start: function() {
        Behaviour.addLoadEvent(function() {
            Behaviour.apply();
        });
    },
    isAlreadyRegistered: function(selectorToFind, functionToFind) {
        var result = false;
        for (var h = 0; sheet = Behaviour.list[h]; h++) {
            for (selector in sheet) {
                var funct = sheet[selector];
                var functComp = (String(funct) == String(functionToFind));
                if (selector == selectorToFind && functComp) {
                    result = true;
                    break;
                }
            }
        }
        return result;
    },
    apply: function() {
        for (h = 0; sheet = Behaviour.list[h]; h++) {
            for (selector in sheet) {
                list = document.getElementsBySelector(selector);
                if (!list) {
                    continue;
                }
                var executedFuncts = "";
                for (var i = 0; element = list[i]; i++) {
                    var funct = sheet[selector];
                    if (!this.hasFunctionBeenExecuted(element, funct)) {
                        executedFuncts += "\n" + funct;
                        element = Elements.fix(element);
                        try {
                            funct(element);
                        } catch(e) {
                            window.console.error(e);
                        }
                        this.addExecutedFunction(element, funct);
                    }
                }
            }
        }
    },
    reapply: function() {
        setTimeout(function() {
            Behaviour.apply();
        },
        50);
    },
    addLoadEvent: function(func) {
        var oldonload = window.onload;
        if (typeof window.onload != "function") {
            window.onload = func;
        } else {
            window.onload = function() {
                oldonload();
                func();
            };
        }
    },
    addExecutedFunction: function(element, funct) {
        var index = this.findExecutedIndex(element);
        if (!this.executedList[index]) {
            index = this.executedList.length;
            this.executedList[index] = new Array();
            this.executedList[index]["element"] = element;
            this.executedList[index]["executedFunctions"] = new Array();
        }
        var executedFunctions = this.executedList[index]["executedFunctions"];
        executedFunctions[executedFunctions.length] = funct;
    },
    hasFunctionBeenExecuted: function(element, funct) {
        var result = false;
        var index = this.findExecutedIndex(element);
        if (this.executedList[index]) {
            for (var i = 0; i < this.executedList[index]["executedFunctions"].length; ++i) {
                var executedFunct = this.executedList[index]["executedFunctions"][i];
                if (executedFunct == funct) {
                    result = true;
                    break;
                }
            }
        }
        return result;
    },
    findExecutedIndex: function(element) {
        var index = -1;
        for (var i = 0; i < this.executedList.length; ++i) {
            if (this.executedList[i]["element"] === element) {
                index = i;
                break;
            }
        }
        return index;
    }
};
Behaviour.start();
function getAllChildren(e) {
    return e.all ? e.all: e.getElementsByTagName("*");
}
document.getElementsBySelector = function(selector) {
    if (!document.getElementsByTagName) {
        return new Array();
    }
    var tokens = selector.split(" ");
    var currentContext = new Array(document);
    for (var i = 0; i < tokens.length; i++) {
        token = tokens[i].replace(/^\s+/, "").replace(/\s+$/, "");
        if (token.indexOf("#") > -1) {
            var bits = token.split("#");
            var tagName = bits[0];
            var id = bits[1];
            var element = document.getElementById(id);
            if (element == null) {
                return new Array();
            }
            if (tagName && element.nodeName.toLowerCase() != tagName) {
                return new Array();
            }
            currentContext = new Array(element);
            continue;
        }
        if (token.indexOf(".") > -1) {
            var bits = token.split(".");
            var tagName = bits[0];
            var className = bits[1];
            if (!tagName) {
                tagName = "*";
            }
            var found = new Array;
            var foundCount = 0;
            for (var h = 0; h < currentContext.length; h++) {
                var elements;
                if (tagName == "*") {
                    elements = getAllChildren(currentContext[h]);
                } else {
                    elements = currentContext[h].getElementsByTagName(tagName);
                }
                for (var j = 0; j < elements.length; j++) {
                    found[foundCount++] = elements[j];
                }
            }
            currentContext = new Array;
            var currentContextIndex = 0;
            for (var k = 0; k < found.length; k++) {
                if (found[k].className && found[k].className.match(new RegExp("\\b" + className + "\\b"))) {
                    currentContext[currentContextIndex++] = found[k];
                }
            }
            continue;
        }
        if (token.match(/^(\w*)\[(\w+)([=~\|\^\$\*]?)=?"?([^\]"]*)"?\]$/)) {
            var tagName = RegExp.$1;
            var attrName = RegExp.$2;
            var attrOperator = RegExp.$3;
            var attrValue = RegExp.$4;
            if (!tagName) {
                tagName = "*";
            }
            var found = new Array;
            var foundCount = 0;
            for (var h = 0; h < currentContext.length; h++) {
                var elements;
                if (tagName == "*") {
                    elements = getAllChildren(currentContext[h]);
                } else {
                    elements = currentContext[h].getElementsByTagName(tagName);
                }
                for (var j = 0; j < elements.length; j++) {
                    found[foundCount++] = elements[j];
                }
            }
            currentContext = new Array;
            var currentContextIndex = 0;
            var checkFunction;
            switch (attrOperator) {
            case "=":
                checkFunction = function(e) {
                    return (e.getAttribute(attrName) == attrValue);
                };
                break;
            case "~":
                checkFunction = function(e) {
                    return (e.getAttribute(attrName).match(new RegExp("\\b" + attrValue + "\\b")));
                };
                break;
            case "|":
                checkFunction = function(e) {
                    return (e.getAttribute(attrName).match(new RegExp("^" + attrValue + "-?")));
                };
                break;
            case "^":
                checkFunction = function(e) {
                    return (e.getAttribute(attrName).indexOf(attrValue) == 0);
                };
                break;
            case "$":
                checkFunction = function(e) {
                    return (e.getAttribute(attrName).lastIndexOf(attrValue) == e.getAttribute(attrName).length - attrValue.length);
                };
                break;
            case "*":
                checkFunction = function(e) {
                    return (e.getAttribute(attrName).indexOf(attrValue) > -1);
                };
                break;
            default:
                checkFunction = function(e) {
                    return e.getAttribute(attrName);
                };
            }
            currentContext = new Array;
            var currentContextIndex = 0;
            for (var k = 0; k < found.length; k++) {
                if (checkFunction(found[k])) {
                    currentContext[currentContextIndex++] = found[k];
                }
            }
            continue;
        }
        if (!currentContext[0]) {
            return;
        }
        tagName = token;
        var found = new Array;
        var foundCount = 0;
        for (var h = 0; h < currentContext.length; h++) {
            var elements = currentContext[h].getElementsByTagName(tagName);
            for (var j = 0; j < elements.length; j++) {
                found[foundCount++] = elements[j];
            }
        }
        currentContext = found;
    }
    return currentContext;
};
function CompleteRedirect() {}
CompleteRedirect.prototype.handle = function(progress) {
    var url = progress.iframe.contentWindow.location.href;
    if (url != "" || !(url.startsWith("about:"))) {
        window.location.href = url;
    }
};
function CompleteOverlay() {}
CompleteOverlay.prototype.handle = function(progress) {
    var progressDocument = progress.iframe.contentDocument;
    var overlay = Elements.getElementById("overlay");
    var div = progressDocument.getElementById("complete");
    if (div == null) {
        var redirect = new CompleteRedirect();
        redirect.handle(progress);
    } else {
        overlay.innerHTML = (new CSSScrubber()).prepareStylesForOverlay(div.innerHTML);
        Tracking.track(progressDocument);
    }
};
function Progress(element, completeHandler) {
    this.element = element;
    this.completeHandler = completeHandler;
    this.attachToEvents();
    this.url = "/progress.e4";
}
Progress.prototype.attachToEvents = function() {
    var formElements = this.element.elements;
    var url = formElements["form-action"].value;
    var self = this;
    this.element.onsubmit = function() {
        self.createIframe();
        self.setFormTarget();
        self.showProgress();
        Progress.monitorUpload(url);
    };
};
Progress.prototype.createIframe = function() {
    this.iframe = Elements.create('<iframe name="progress" class="progress"></iframe>');
    Elements.insertBefore(this.element, this.iframe);
    var self = this;
    this.iframe.addEventListener("load",
    function() {
        self.completeHandler.handle(self);
    },
    false);
};
Progress.prototype.setFormTarget = function() {
    this.element.setAttribute("target", this.iframe.getAttribute("name"));
};
Progress.prototype.showProgress = function() {
    this.overlay = new UrlOverlay(this.url, "small", false);
    var self = this;
    this.overlay.setDisplayHandler(function() {
        self.addFilenames();
    });
    this.overlay.setCloseHandler(function() {
        self.cancel();
    });
    this.overlay.show();
};
Progress.prototype.addFilenames = function() {
    var filenamesContainer = Elements.getElementById("upload-filenames");
    filenamesContainer.innerHTML = this.convertFilesToList();
};
Progress.prototype.convertFilesToList = function() {
    var builder = new StringBuilder();
    builder.append("<ul>");
    Array.each(this.element.elements,
    function(item) {
        if (item.type == "file") {
            builder.append("<li>").append(Path.extractFilename(item.value)).append("</li>");
        }
    });
    builder.append("</ul>");
    return builder.toString();
};
Progress.prototype.cancel = function() {
    Elements.remove(this.iframe);
};
Progress.monitorUpload = function(url) {
    window.setTimeout("Progress.checkUploadProgress('" + url + "')", 5000);
};
Progress.checkUploadProgress = function(url) {
    var parameters = new Parameters();
    parameters.add("decorator", "none");
    parameters.add("resourceReference", url);
    var request = new RequestMessage("GET", "/upload/progress.e4");
    request.asyncSend(parameters,
    function(responseContent) {
        var responseText = responseContent.getText();
        Progress.updateUploadProgress(url, responseText);
    });
};
Progress.updateUploadProgress = function(url, responseText) {
    var status = Elements.getElementById("upload-status");
    if (status) {
        var index = responseText.indexOf("/");
        if (index > 0) {
            var uploaded = parseFloat(responseText.substring(0, index));
            var total = parseFloat(responseText.substring(index + 1, responseText.length));
            var percentage = Math.round(uploaded / total * 100);
            responseText = "Upload " + percentage + "% complete";
            status.innerHTML = responseText;
            Progress.monitorUpload(url);
        } else {
            if (responseText == "Failed") {
                window.location.reload();
            } else {
                status.innerHTML = responseText;
            }
        }
    }
};
function Overlay(size, displayClose) {
    this.size = size || "small";
    this.displayClose = typeof(displayClose) == "boolean" ? displayClose: true;
    this.displayHandler = function() {};
    this.closeHandler = function() {};
}
Overlay.prototype.show = function(html) {
    this.close();
    this.hideSelectElementsBehindOverlay();
    this.createOverlay((new CSSScrubber()).prepareStylesForOverlay(html));
    this.addClose();
    this.createOverlaid();
    this.displayHandler();
};
Overlay.prototype.hideSelectElementsBehindOverlay = function() {};
Overlay.prototype.createOverlay = function(html) {
    var overlayHtml = new StringBuilder();
    overlayHtml.append('<div id="overlay" class="overlay overlay-').append(this.size).append('">');
    overlayHtml.append('<div id="overlay-head" class="overlay-head" ></div>');
    overlayHtml.append('<div id="overlay-content" >');
    overlayHtml.append(html);
    overlayHtml.append("</div>");
    overlayHtml.append('<div class="overlay-foot" ></div></div>');
    this.overlayDiv = Elements.create(overlayHtml.toString());
    document.body.appendChild(this.overlayDiv);
    this.overlayDiv.style.marginTop = "-" + (this.overlayDiv.clientHeight / 2) + "px";
};
Overlay.prototype.createOverlaid = function() {
    this.overlaidDiv = Elements.create('<div id="overlaid" class="overlaid"></div>');
    document.body.appendChild(this.overlaidDiv);
    this.overlaidDiv.style.height = document.body.scrollHeight;
};
Overlay.prototype.addClose = function() {
    if (this.displayClose) {
        var head = Elements.getElementById("overlay-head");
        var closeLink = Elements.create('<a id="overlay-close" href="">Close</a>');
        head.appendChild(closeLink);
        var self = this;
        closeLink.addEventListener("click",
        function(event) {
            self.close();
            self.closeHandler();
            event.preventDefault();
        },
        false);
    }
};
Overlay.prototype.close = function() {
    Elements.remove(Elements.getElementById("overlay"));
    Elements.remove(Elements.getElementById("overlaid"));
};
Overlay.prototype.setDisplayHandler = function(handler) {
    this.displayHandler = handler;
};
Overlay.prototype.setCloseHandler = function(handler) {
    this.closeHandler = handler;
};
function OverlayMixins() {}
OverlayMixins.setDisplayHandler = function(handler) {
    this.overlay.setDisplayHandler(handler);
};
OverlayMixins.setCloseHandler = function(handler) {
    this.overlay.setCloseHandler(handler);
};
OverlayMixins.attachToEvent = function(type) {
    var self = this;
    this.element.addEventListener(type,
    function(event) {
        self.show();
        event.preventDefault();
    },
    false);
};
OverlayMixins.close = function() {
    this.overlay.close();
};
function UrlOverlay(url, size, displayClose) {
    this.url = url;
    this.overlay = new Overlay(size, displayClose);
}
UrlOverlay.prototype.show = function() {
    var request = new RequestMessage("get", this.url);
    var self = this;
    request.asyncSend(this.getParameters(),
    function(responseContent) {
        self.overlay.show(responseContent.getText());
    });
};
UrlOverlay.prototype.setDisplayHandler = OverlayMixins.setDisplayHandler;
UrlOverlay.prototype.setCloseHandler = OverlayMixins.setCloseHandler;
UrlOverlay.prototype.getParameters = Parameters.forBody;
UrlOverlay.prototype.close = OverlayMixins.close;
function LinkOverlay(element, size, displayClose) {
    this.element = element;
    this.overlay = new UrlOverlay(this.element.href, size, displayClose);
    this.attachToEvent("click");
}
LinkOverlay.prototype.show = function() {
    this.overlay.show();
};
LinkOverlay.prototype.attachToEvent = OverlayMixins.attachToEvent;
LinkOverlay.prototype.getParameters = Parameters.forBody;
LinkOverlay.prototype.setDisplayHandler = OverlayMixins.setDisplayHandler;
LinkOverlay.prototype.setCloseHandler = OverlayMixins.setCloseHandler;
LinkOverlay.prototype.close = OverlayMixins.close;
function FormOverlay(element, size, displayClose) {
    this.element = element;
    this.overlay = new Overlay(size, displayClose);
    this.attachToAllSubmitButtons();
}
FormOverlay.prototype.show = function(submit) {
    var params = this.getParameters();
    params.add(submit.name, submit.value);
    var form = new Html.Form(this.element, params);
    var self = this;
    form.submit(function(responseMessage) {
        self.overlay.show(responseMessage.getText());
    });
};
FormOverlay.prototype.attachToAllSubmitButtons = function() {
    var submits = Array.filter(this.element.elements,
    function(input) {
        return input.type == "submit";
    });
    submits = Elements.fixAll(submits);
    var self = this;
    submits.each(function(submit) {
        submit.addEventListener("click",
        function(event) {
            self.show(submit);
            event.preventDefault();
        },
        false);
    });
};
FormOverlay.prototype.getParameters = Parameters.forBody;
FormOverlay.prototype.setDisplayHandler = OverlayMixins.setDisplayHandler;
FormOverlay.prototype.setCloseHandler = OverlayMixins.setCloseHandler;
FormOverlay.prototype.close = OverlayMixins.close;
function Include(element, withHead) {
    this.element = element;
    if (withHead) {
        this.includeHead();
    }
    this.include();
}
Include.prototype.include = function() {
    var parts = this.element.href.split("#");
    var url = parts[0];
    var id = parts[1];
    var request = new RequestMessage("get", url);
    var parameters = new Parameters();
    if (id) {
        parameters.add("decorator", "extractor").add("decorator.property-name", "div." + id);
    } else {
        parameters.add("decorator", "body");
    }
    parameters.add("success", asRelative(window.location));
    parameters.add("failure", asRelative(window.location));
    var self = this;
    request.asyncSend(parameters,
    function(responseMessage) {
        if (responseMessage.isSuccess()) {
            var elementText = responseMessage.getText();
            self.showResponse(elementText);
        }
    });
};
Include.prototype.includeHead = function() {
    var parts = this.element.href.split("#");
    var url = parts[0];
    var request = new RequestMessage("get", url);
    var parameters = new Parameters();
    parameters.add("decorator", "head");
    parameters.add("success", asRelative(window.location));
    parameters.add("failure", asRelative(window.location));
    request.asyncSend(parameters,
    function(responseMessage) {
        var elementText = responseMessage.getText();
        Elements.addToHead(Elements.createFragment(elementText));
    });
};
function asRelative(location) {
    var href = location.href;
    var toRemove = location.protocol + "://" + location.host;
    return href.substr(toRemove.length - 1);
}
Include.prototype.showResponse = function(html) {
    Elements.replace(this.element, html);
    Behaviour.reapply();
};
function Focuser(element) {
    this.element = element;
    this.errors = [];
    this.warnings = [];
    this.infos = [];
    this.focusElements = [];
    this.focusFirstElement();
}
Focuser.prototype.focusFirstElement = function() {
    var self = this;
    Elements.forEachTagName(this.element, ["*"],
    function(element) {
        var classes = new ClassName(element);
        if (element.tabIndex == -1) {
            return;
        }
        if (classes.contains("focusElement")) {
            self.focusElements.add(element);
        }
        if (classes.contains("error")) {
            self.errors.add(element);
        }
        if (classes.contains("warning")) {
            self.warnings.add(element);
        }
        if (classes.contains("info")) {
            self.infos.add(element);
        }
    });
    this.focusFirst(this.focusElements.concat(this.errors.concat(this.warnings).concat(this.infos)));
};
Focuser.prototype.focusFirst = function(items) {
    for (var i = 0; i < items.length; i++) {
        var item = items[i];
        try {
            item.focus();
            break;
        } catch(e) {}
    }
};
function InputValidator(element, id) {
    this.element = element;
    this.id = id;
}
InputValidator.prototype.validate = function() {
    var parameters = new Parameters();
    parameters.add("decorator", "extractor").add("decorator.property-name", "div." + this.id);
    var self = this;
    new Html.Form(this.element.form, parameters).submit(function(responseMessage) {
        self.showResponse(responseMessage);
    });
};
InputValidator.prototype.showResponse = function(responseMessage) {
    var elementToReplace = Elements.getElementById(this.id);
    Elements.replace(elementToReplace, responseMessage.getText());
    Behaviour.apply();
};
function FieldValidator(element, id) {
    InputValidator.apply(this, arguments);
    this.attachToEvent();
}
FieldValidator.prototype = new InputValidator();
FieldValidator.prototype.attachToEvent = function() {
    var self = this;
    this.element.onblur = function() {
        self.validate();
    };
};
function ButtonValidator(element, id, label) {
    InputValidator.apply(this, arguments);
    this.createButton(label);
}
ButtonValidator.prototype = new InputValidator();
ButtonValidator.prototype.createButton = function(label) {
    var button = Elements.create("<input type='button' value='" + label + "'/>");
    Elements.insertAfter(this.element, button);
    var self = this;
    button.onclick = function() {
        self.validate();
    };
};
function ElementDisabler(element, id) {
    this.element = element;
    this.id = id;
    if (this.element.checked != undefined && !this.element.checked) {
        this.toggleElementsInContainer();
    }
    this.attachToEvents();
}
ElementDisabler.prototype.attachToEvents = function() {
    var self = this;
    this.element.addEventListener("click",
    function() {
        self.toggleElementsInContainer();
    },
    false);
};
ElementDisabler.prototype.toggleElementsInContainer = function() {
    var target = Elements.getElementById(this.id);
    var self = this;
    Elements.forEachTagName(target, ["*"],
    function(element) {
        self.toggle(element);
    });
};
ElementDisabler.prototype.toggle = function(element) {
    if (element.nodeType == Node.ELEMENT_NODE) {
        this.toggleClassName(element);
        this.toggleDisabled(element);
    }
};
ElementDisabler.prototype.toggleDisabled = function(element) {
    if (typeof(element.disabled) == "boolean") {
        element.disabled = !element.disabled;
    }
};
ElementDisabler.prototype.toggleClassName = function(element) {
    var classes = new ClassName(element);
    if (classes.contains("disabled")) {
        classes.removeClass("disabled");
    } else {
        classes.addClass("disabled");
    }
};
function LimitTextSize(element, maxCharacters) {
    this.element = element;
    this.maxCharacters = maxCharacters;
    this.attachToEvent();
}
LimitTextSize.prototype.attachToEvent = function() {
    var self = this;
    if (this.element.onkeyup) {
        this.nextOnKeyUp = this.element.onkeyup;
    }
    this.element.onkeyup = function() {
        self.checkLimitAndForward();
    };
};
LimitTextSize.prototype.checkLimitAndForward = function() {
    if (this.element.value.length > this.maxCharacters) {
        this.element.value = this.element.value.substring(0, this.maxCharacters);
        return false;
    }
    if (this.nextOnKeyUp) {
        this.nextOnKeyUp();
    }
};
function CharacterCounter(element, maxCharacters) {
    this.element = element;
    this.maxCharacters = maxCharacters;
    this.targetId = "characters-remaining-count" + this.element.getAttribute("id");
    this.addCharacterCounterDisplay();
    this.attachToEvent();
}
CharacterCounter.prototype.addCharacterCounterDisplay = function() {
    var label = Elements.create('<p class="character_count"><span id="' + this.targetId + '">' + this.getRemainingCharacters() + "</span> characters remaining. </p>   ");
    Elements.insertAfter(this.element, label);
};
CharacterCounter.prototype.getRemainingCharacters = function() {
    if (this.element.value.length > this.maxCharacters) {
        this.element.value = this.element.value.substring(0, this.maxCharacters);
    }
    return this.maxCharacters - this.element.value.length;
};
CharacterCounter.prototype.attachToEvent = function() {
    var self = this;
    this.element.onkeyup = function() {
        self.updateDisplay();
    };
};
CharacterCounter.prototype.updateDisplay = function() {
    var target = Elements.getElementById(this.targetId);
    target.innerHTML = this.getRemainingCharacters();
};
function TextAreaResizer(element) {
    this.element = element;
    this.minRows = element.rows;
    this.maxRows = 60;
    this.updateDisplay();
    this.attachToEvent();
}
TextAreaResizer.prototype.attachToEvent = function() {
    var self = this;
    this.element.onkeyup = function() {
        self.updateDisplay();
    };
};
TextAreaResizer.prototype.updateDisplay = function() {
    var lines = this.element.value.split("\n");
    var rows = 0;
    for (var x = 0; x < lines.length; x++) {
        if (lines[x].length >= this.element.cols) {
            rows += Math.floor(lines[x].length / this.element.cols);
        }
    }
    rows += lines.length;
    this.element.rows = Math.min(this.maxRows, Math.max(rows, this.minRows));
};
function DeleteConfirmationOverlay(element) {
    this.element = element;
    this.size = "small";
    this.overlay = new LinkOverlay(this.element, this.size, false);
}
function SendToFriend(element) {
    this.element = element;
    this.size = "large";
    this.overlay = new LinkOverlay(this.element, this.size);
    this.setDisplayHandler();
}
SendToFriend.prototype.setDisplayHandler = function() {
    var self = this;
    this.overlay.setDisplayHandler(function() {
        self.attachToFormOrLink();
    });
};
SendToFriend.prototype.attachToFormOrLink = function() {
    this.attachToForm();
    this.attachToLink();
    this.setDisplayHandler();
};
SendToFriend.prototype.attachToForm = function() {
    var form = Elements.getElementById("sendToFriendForm");
    if (form != null) {
        this.overlay = new FormOverlay(form, this.size);
    }
};
SendToFriend.prototype.attachToLink = function() {
    var shareAgainLink = Elements.getElementById("share-again");
    if (shareAgainLink != null) {
        this.overlay = new LinkOverlay(shareAgainLink, this.size);
    }
};
function LoginLinkOverLay(element) {
    this.element = element;
    this.formId = "login-overlay";
    this.size = "large";
    this.targetName = "login-overlay-target";
    this.loginLinkOverlay = new LinkOverlay(element, this.size, true);
    this.loginLinkOverlay.overlay.getParameters = function() {
        return Parameters.forBody().add("decorator.overlay", "true");
    };
    this.attachToOverLay();
}
LoginLinkOverLay.prototype.getParameters = Parameters.forBody;
LoginLinkOverLay.prototype.setDisplayHandler = OverlayMixins.setDisplayHandler;
LoginLinkOverLay.prototype.attachToOverLay = function() {
    var self = this;
    this.loginLinkOverlay.setDisplayHandler(function() {
        self.attachToLinkLoginForm();
    });
};
LoginLinkOverLay.prototype.attachToLinkLoginForm = function() {
    this.createTargetIFrame();
    this.setupForm();
};
LoginLinkOverLay.prototype.createTargetIFrame = function() {
    var self = this;
    var iframe = Elements.create('<iframe name="' + this.targetName + '" ></iframe>');
    Elements.addToHead(iframe);
    iframe.addEventListener("load",
    function() {
        self.handleResult(iframe);
    },
    false);
};
LoginLinkOverLay.prototype.handleResult = function(iframe) {
    var url = iframe.contentWindow.location.href;
    if (url != "" && !(url.startsWith("about:"))) {
        if (url.contains("/login.e4")) {
            this.overlay = new Overlay(this.size);
            this.overlay.show(iframe.contentDocument.body.innerHTML);
            this.setupForm();
        } else {
            window.location.href = url;
        }
    }
};
LoginLinkOverLay.prototype.setupForm = function() {
    var form = Elements.getElementById(this.formId);
    form.appendChild(Elements.create('<input type="hidden" name="decorator" value="none" />'));
    form.appendChild(Elements.create('<input type="hidden" name="decorator.overlay" value="true" />'));
    form.setAttribute("target", this.targetName);
};
function LoginOverlay(element) {
    this.size = "large";
    this.formId = "login-overlay";
    this.targetName = "login-overlay-target";
    if (!User.isLoggedIn()) {
        this.attachToInitalForm(element);
    }
}
LoginOverlay.prototype.attachToInitalForm = function(form) {
    this.overlay = new FormOverlay(form, this.size);
    this.overlay.getParameters = function() {
        return Parameters.forBody().add("decorator.overlay", "true");
    };
    var self = this;
    this.overlay.setDisplayHandler(function() {
        self.attachToLoginForm();
    });
};
LoginOverlay.prototype.attachToLoginForm = function() {
    this.createTargetIFrame();
    this.setupForm();
};
LoginOverlay.prototype.createTargetIFrame = function() {
    var self = this;
    var iframe = Elements.create('<iframe name="' + this.targetName + '" ></iframe>');
    Elements.addToHead(iframe);
    iframe.addEventListener("load",
    function() {
        self.handleResult(iframe);
    },
    false);
};
LoginOverlay.prototype.handleResult = function(iframe) {
    var url = iframe.contentWindow.location.href;
    if (url != "" && !(url.startsWith("about:"))) {
        if (url.contains("/login.e4")) {
            this.overlay = new Overlay(this.size);
            this.overlay.show(iframe.contentDocument.body.innerHTML);
            this.setupForm();
        } else {
            window.location.href = url;
        }
    }
};
LoginOverlay.prototype.setupForm = function() {
    var form = Elements.getElementById(this.formId);
    form.appendChild(Elements.create('<input type="hidden" name="decorator" value="none" />'));
    form.appendChild(Elements.create('<input type="hidden" name="decorator.overlay" value="true" />'));
    form.setAttribute("target", this.targetName);
};
function User() {}
User.isLoggedIn = function() {
    var request = new RequestMessage("GET", "/login-status.txt");
    var response = request.send(new Parameters());
    return Boolean.parse(response.getText());
};
function RemoveChallengeEntryField(element) {
    this.element = element;
    this.attachToEvent();
}
RemoveChallengeEntryField.prototype.attachToEvent = function() {
    var self = this;
    this.element.onclick = function(e) {
        if (confirm("Do you want to delete this field?")) {
            self.updateHiddenRemoveField();
            new BrowserEvent(e).htmlTarget().form.submit();
        }
    };
};
RemoveChallengeEntryField.prototype.updateHiddenRemoveField = function() {
    Elements.getElementById("removeFieldIdentity").value = this.element.name;
};
function CSSScrubber() {}
CSSScrubber.prototype.prepareStylesForOverlay = function(innerHtml) {
    html = innerHtml || "";
    return html.replace(/purple-white-btn/g, "purple-btn").replace(/purple-white-action/g, "purple-action");
};
function ClickableContainer(targetLink, clickableDomElement) {
    this.targetAnchorDomElement = targetLink;
    this.clickableDomElement = Elements.fix(clickableDomElement);
    this.attachEvents();
}
ClickableContainer.prototype.attachEvents = function() {
    var self = this;
    this.clickableDomElement.addEventListener("click",
    function(e) {
        self.targetAnchorDomElement.click();
    },
    false);
};
function Adverts() {}
Adverts.map = new Map().set("top", "Top").set("mpu", "Middle1").set("skyscraper", "x07").set("video", "x69");
Adverts.load = function() {
    var content = Meta.getContent("nonexpandable-advert");
    if (content.isNotEmpty()) {
        var iframe = Elements.create('<iframe id="advertiframescript" name="advertiframescript" src="' + Adverts.getUrl() + '"></iframe>');
        Elements.addToHead(iframe);
        iframe.addEventListener("load", Adverts.scriptLoaded, false);
    }
};
Adverts.getUrl = function() {
    var url = new StringBuilder();
    url.append("/advert/script.e4?decorator=none&path=");
    url.append(encodeURIComponent(Adverts.getRealMediaPath()));
    return url.toString();
};
Adverts.getRealMediaPath = function() {
    var realmediaPath = new StringBuilder();
    realmediaPath.append(Adverts.getHostName());
    realmediaPath.append(Adverts.getPath());
    realmediaPath.append(Adverts.getRandom());
    realmediaPath.append("@").append(Adverts.getTypes());
    var optional = Adverts.getOptionalParameters();
    if (optional.isNotEmpty()) {
        realmediaPath.append("?").append(optional).append("&").append(Adverts.getRevSci());
    } else {
        realmediaPath.append("?").append(Adverts.getRevSci());
    }
    return realmediaPath.toString();
};
Adverts.getRevSci = function() {
    var segQS = "";
    if (typeof rsinetsegs != "undefined") {
        segQS = rsinetsegs.length > 0 ? "s=" + rsinetsegs[0] : "";
        for (var segQSi = 1; segQSi < rsinetsegs.length; segQSi++) {
            segQS += ("&s=" + rsinetsegs[segQSi]);
        }
    }
    return segQS;
};
Adverts.scriptLoaded = function() {
    Adverts.create("top");
    Adverts.create("mpu");
    Adverts.create("skyscraper");
    Adverts.create("video");
};
Adverts.create = function(type) {
    var iframe = document.getElementById("advertiframe" + type);
    if (iframe) {
        iframe.contentWindow.location.reload();
    } else {
        document.getElementsBySelector("div.advert-" + type).each(function(element) {
            new Advert(element, type);
        });
    }
};
Adverts.getOptionalParameters = function() {
    var result = new Parameters(); ["from-name", "challenge-identity"].each(function(name) {
        var content = Meta.getContent(name);
        if (content.isNotEmpty()) {
            result.add(name, content);
        }
    });
    return result.toString();
};
Adverts.getHostName = function() {
    if (location.hostname == "www.e4.com" || location.hostname == "e4.com" || location.hostname == "uat.e4.com") {
        return "www.e4.com";
    } else {
        if (location.hostname == "stage.e4.com") {
            return "stage.e4.com";
        }
    }
    return "twdev.e4.com";
};
Adverts.getPath = function() {
    var pathname = location.pathname;
    if (pathname.endsWith("/")) {
        pathname += "index.html/";
    } else {
        pathname += "/";
    }
    return pathname;
};
Adverts.getRandom = function() {
    return "1" + Math.random() * 100000000000000000;
};
Adverts.getTypes = function() {
    var list = new StringBuilder();
    Adverts.required.each(function(name) {
        list.append(Adverts.convertToRealMediaType(name)).append(",");
    });
    return list;
};
Adverts.required = new Array();
Adverts.write = function(type) {
    if (!Adverts.required.contains(type)) {
        Adverts.required.add(type);
    }
};
Adverts.isRequiredType = function(type) {
    return Adverts.required.contains(type);
};
Adverts.convertToRealMediaType = function(type) {
    return Adverts.map.get(type);
};
Adverts.reload = function() {
    var iframe = Elements.getElementById("advertiframescript");
    if (iframe != null) {
        iframe.contentWindow.location.href = Adverts.getUrl();
    }
};
Adverts.listeners = new Map();
Adverts.setLoadListener = function(type, handler) {
    Adverts.listeners.set(type, handler);
};
Adverts.getLoadListener = function(type) {
    if (Adverts.listeners.contains(type)) {
        return Adverts.listeners.get(type);
    }
    return function() {};
};
function Advert(element, type) {
    this.element = element;
    this.type = type;
    this.id = "advertiframe" + this.type;
    this.createIframe();
}
Advert.prototype.createIframe = function() {
    this.iframe = Elements.create('<iframe id="' + this.id + '" name="' + this.id + '" class="advert" src="/components/adverts/advert.htm?decorator=none" scrolling="no" frameborder="0" allowtransparency="true"></iframe>');
    this.iframe.realMediaType = Adverts.convertToRealMediaType(this.type);
    var me = this;
    this.iframe.addEventListener("load",
    function() {
        Adverts.getLoadListener(me.type)(me.iframe);
    },
    false);
    this.element.appendChild(this.iframe);
};
Behaviour.register(
{
    'body': function(element) {
        Adverts.load();
    }
});
function Tracking(overrides) {
    this.properties = this.getProperties();
    if (overrides) {
        this.properties.merge(overrides);
    }
}
Tracking.getAccount = function() {
    if (location.hostname == "www.e4.com" || location.hostname == "e4.com" || location.hostname == "uat.e4.com" || location.hostname == "stage.e4.com" || location.hostname == 'misfits.e4.com') {
        return "channel4e4com";
    }
    return "channel4e4comtest";
};
Tracking.prototype.execute = function() {
    if (self.s != null && this.notInFrame()) {
        Tracking.trackLastEvent();
        this.setProperties();
        this.write();
    }
};
Tracking.prototype.notInFrame = function() {
    return window.frameElement == null;
};
Tracking.fields = ["tracking.area", "tracking.brand", "tracking.subsection", "tracking.pagetype", "tracking.sortorder", "tracking.upload.type", "tracking.search.terms", "tracking.search.results", "tracking.events", "keywords", "DC.date"];
Tracking.prototype.getProperties = function() {
    var properties = new Map();
    Tracking.fields.each(function(item) {
        properties.set(item, Meta.getContent(item));
    });
    return properties;
};
Tracking.prototype.setProperties = function() {
    self.s.prop1 = this.properties.get("tracking.area");
    self.s.prop2 = this.properties.get("tracking.brand");
    self.s.prop5 = this.properties.get("tracking.subsection");
    self.s.prop6 = this.properties.get("tracking.pagetype");
    self.s.prop31 = this.properties.get("tracking.sortorder");
    this.setEvent();
    this.setUploadType();
    this.setSearch();
    this.setTags();
    this.setPublishedDate();
    this.setLoggedIn();
};
Tracking.EventType = new Map().set("Participate", 1).set("Comment", 2).set("Rate", 3).set("Login", 4).set("Registration", 5).set("Upload", 6).set("Newsletter signup", 9);
Tracking.prototype.setEvent = function() {
    var eventNames = this.properties.get("tracking.events");
    self.s.events = Tracking.convertToCodes(eventNames);
    self.s.prop3 = eventNames;
};
Tracking.convertToCodes = function(eventNames) {
    var eventCodes = new StringBuilder();
    eventNames.split(",").each(function(item) {
        var eventType = item.trim();
        if (eventType != "") {
            eventCodes.append("event").append(Tracking.EventType.get(eventType)).append(",");
        }
    });
    return eventCodes.toString();
};
Tracking.prototype.setUploadType = function() {
    self.s.prop7 = this.properties.get("tracking.upload.type");
};
Tracking.prototype.setSearch = function() {
    self.s.prop8 = this.properties.get("tracking.search.terms");
    self.s.prop9 = this.properties.get("tracking.search.results");
};
Tracking.prototype.setTags = function() {
    self.s.prop13 = this.properties.get("keywords").toLowerCase();
};
Tracking.prototype.setPublishedDate = function() {
    self.s.prop26 = this.properties.get("DC.date");
};
Tracking.prototype.setLoggedIn = function() {
    if (User.isLoggedIn()) {
        self.s.prop15 = "Logged in";
    }
};
Tracking.prototype.write = function() {
    var code = self.s.t();
    if (code) {
        document.write(code);
    }
};
Tracking.track = function(doc) {
    var events = Meta.getContent("tracking.events", doc);
    var uploadType = Meta.getContent("tracking.upload.type", doc);
    Tracking.trackEvents(events, uploadType);
};
Tracking.trackEvents = function(eventNames, uploadType) {
    self.s = s_gi(Tracking.getAccount());
    self.s.trackingServer = "st.e4.com";
    var propertiesBeingSent = ["prop3", "eVar3", "events"];
    if (uploadType != null || uploadType != "") {
        propertiesBeingSent.add("prop7").add("eVar7");
        self.s.prop7 = uploadType;
        self.s.eVar7 = uploadType;
    }
    self.s.linkTrackVars = propertiesBeingSent.join(",");
    var eventsCodes = Tracking.convertToCodes(eventNames);
    self.s.linkTrackEvents = eventsCodes;
    self.s.events = eventsCodes;
    self.s.prop3 = eventNames;
    self.s.eVar3 = eventNames;
    var trackingLink = Elements.create('<a href="">trackingLink</a>');
    Elements.addToHead(trackingLink);
    self.s.pageURL = "http://www.e4.com/dummyTrackingLink";
    try {
        self.s.tl(trackingLink, "o", eventNames);
    } catch(e) {
        window.console.error(e);
    }
};
Tracking.CookieKey = "e4.tracking.last.event";
Tracking.trackLastEvent = function() {
    var lastEvent = Tracking.getLastEvent();
    if (lastEvent && lastEvent.isNotEmpty()) {
        Tracking.trackEvents(lastEvent);
        Tracking.setLastEvent(String.empty);
    }
};
Tracking.setLastEvent = function(eventType) {
    new Cookies().set(Tracking.CookieKey, eventType);
};
Tracking.getLastEvent = function() {
    return new Cookies().get(Tracking.CookieKey);
};
function FormTracker(element, eventType) {
    this.element = element;
    this.eventType = eventType;
    this.attachEvent();
}
FormTracker.prototype.attachEvent = function() {
    var self = this;
    this.element.addEventListener("submit",
    function() {
        self.track();
    },
    false);
};
FormTracker.prototype.track = function() {
    Tracking.setLastEvent(this.eventType);
};
Behaviour.register(
{
    'form.comment-create': function(element) {
        new FormTracker(element, "Comment");
    }
}
);
Behaviour.register({
    "body.focus": function(element) {
        new Focuser(Elements.getElementById("page"));
    },
    "a.include": function(element) {
        new Include(element);
    },
    "a.includeWithHead": function(element) {
        new Include(element, true);
    },
    "form.progress-redirect": function(element) {
        new Progress(element, new CompleteRedirect());
    },
    "form.progress-overlay": function(element) {
        new Progress(element, new CompleteOverlay());
    },
    "a.confirmation-overlay": function(element) {
        new DeleteConfirmationOverlay(element);
    },
    "a.sendToFriend": function(element) {
        new SendToFriend(element);
    },
    "form#create-comment-form": function(element) {
        new LoginOverlay(element);
    },
    "textarea.autosizeme": function(element) {
        new TextAreaResizer(element);
    },
    "form#challenge-entry-terms": function(element) {
        new LoginOverlay(element);
    },
    "a#logInLink": function(element) {
        new LoginLinkOverLay(element);
    }
});
if (typeof deconcept == "undefined") {
    var deconcept = new Object();
}
if (typeof deconcept.util == "undefined") {
    deconcept.util = new Object();
}
if (typeof deconcept.SWFObjectUtil == "undefined") {
    deconcept.SWFObjectUtil = new Object();
}
deconcept.SWFObject = function(_1, id, w, h, _5, c, _7, _8, _9, _a) {
    if (!document.getElementById) {
        return;
    }
    this.DETECT_KEY = _a ? _a: "detectflash";
    this.skipDetect = deconcept.util.getRequestParameter(this.DETECT_KEY);
    this.params = new Object();
    this.variables = new Object();
    this.attributes = new Array();
    if (_1) {
        this.setAttribute("swf", _1);
    }
    if (id) {
        this.setAttribute("id", id);
    }
    if (w) {
        this.setAttribute("width", w);
    }
    if (h) {
        this.setAttribute("height", h);
    }
    if (_5) {
        this.setAttribute("version", new deconcept.PlayerVersion(_5.toString().split(".")));
    }
    this.installedVer = deconcept.SWFObjectUtil.getPlayerVersion();
    if (!window.opera && document.all && this.installedVer.major > 7) {
        deconcept.SWFObject.doPrepUnload = true;
    }
    if (c) {
        this.addParam("bgcolor", c);
    }
    var q = _7 ? _7: "high";
    this.addParam("quality", q);
    this.setAttribute("useExpressInstall", false);
    this.setAttribute("doExpressInstall", false);
    var _c = (_8) ? _8: window.location;
    this.setAttribute("xiRedirectUrl", _c);
    this.setAttribute("redirectUrl", "");
    if (_9) {
        this.setAttribute("redirectUrl", _9);
    }
};
deconcept.SWFObject.prototype = {
    useExpressInstall: function(_d) {
        this.xiSWFPath = !_d ? "expressinstall.swf": _d;
        this.setAttribute("useExpressInstall", true);
    },
    setAttribute: function(_e, _f) {
        this.attributes[_e] = _f;
    },
    getAttribute: function(_10) {
        return this.attributes[_10];
    },
    addParam: function(_11, _12) {
        this.params[_11] = _12;
    },
    getParams: function() {
        return this.params;
    },
    addVariable: function(_13, _14) {
        this.variables[_13] = _14;
    },
    getVariable: function(_15) {
        return this.variables[_15];
    },
    getVariables: function() {
        return this.variables;
    },
    getVariablePairs: function() {
        var _16 = new Array();
        var key;
        var _18 = this.getVariables();
        for (key in _18) {
            _16[_16.length] = key + "=" + _18[key];
        }
        return _16;
    },
    getSWFHTML: function() {
        var _19 = "";
        if (navigator.plugins && navigator.mimeTypes && navigator.mimeTypes.length) {
            if (this.getAttribute("doExpressInstall")) {
                this.addVariable("MMplayerType", "PlugIn");
                this.setAttribute("swf", this.xiSWFPath);
            }
            _19 = '<embed type="application/x-shockwave-flash" src="' + this.getAttribute("swf") + '" width="' + this.getAttribute("width") + '" height="' + this.getAttribute("height") + '" style="' + this.getAttribute("style") + '"';
            _19 += ' id="' + this.getAttribute("id") + '" name="' + this.getAttribute("id") + '" ';
            var _1a = this.getParams();
            for (var key in _1a) {
                _19 += [key] + '="' + _1a[key] + '" ';
            }
            var _1c = this.getVariablePairs().join("&");
            if (_1c.length > 0) {
                _19 += 'flashvars="' + _1c + '"';
            }
            _19 += "/>";
        } else {
            if (this.getAttribute("doExpressInstall")) {
                this.addVariable("MMplayerType", "ActiveX");
                this.setAttribute("swf", this.xiSWFPath);
            }
            _19 = '<object id="' + this.getAttribute("id") + '" classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000" width="' + this.getAttribute("width") + '" height="' + this.getAttribute("height") + '" style="' + this.getAttribute("style") + '">';
            _19 += '<param name="movie" value="' + this.getAttribute("swf") + '" />';
            var _1d = this.getParams();
            for (var key in _1d) {
                _19 += '<param name="' + key + '" value="' + _1d[key] + '" />';
            }
            var _1f = this.getVariablePairs().join("&");
            if (_1f.length > 0) {
                _19 += '<param name="flashvars" value="' + _1f + '" />';
            }
            _19 += "</object>";
        }
        return _19;
    },
    write: function(_20) {
        if (this.getAttribute("useExpressInstall")) {
            var _21 = new deconcept.PlayerVersion([6, 0, 65]);
            if (this.installedVer.versionIsValid(_21) && !this.installedVer.versionIsValid(this.getAttribute("version"))) {
                this.setAttribute("doExpressInstall", true);
                this.addVariable("MMredirectURL", escape(this.getAttribute("xiRedirectUrl")));
                document.title = document.title.slice(0, 47) + " - Flash Player Installation";
                this.addVariable("MMdoctitle", document.title);
            }
        }
        if (this.skipDetect || this.getAttribute("doExpressInstall") || this.installedVer.versionIsValid(this.getAttribute("version"))) {
            var n = (typeof _20 == "string") ? document.getElementById(_20) : _20;
            n.innerHTML = this.getSWFHTML();
            return true;
        } else {
            if (this.getAttribute("redirectUrl") != "") {
                document.location.replace(this.getAttribute("redirectUrl"));
            }
        }
        return false;
    }
};
deconcept.SWFObjectUtil.getPlayerVersion = function() {
    var _23 = new deconcept.PlayerVersion([0, 0, 0]);
    if (navigator.plugins && navigator.mimeTypes.length) {
        var x = navigator.plugins["Shockwave Flash"];
        if (x && x.description) {
            _23 = new deconcept.PlayerVersion(x.description.replace(/([a-zA-Z]|\s)+/, "").replace(/(\s+r|\s+b[0-9]+)/, ".").split("."));
        }
    } else {
        if (navigator.userAgent && navigator.userAgent.indexOf("Windows CE") >= 0) {
            var axo = 1;
            var _26 = 3;
            while (axo) {
                try {
                    _26++;
                    axo = new ActiveXObject("ShockwaveFlash.ShockwaveFlash." + _26);
                    _23 = new deconcept.PlayerVersion([_26, 0, 0]);
                } catch(e) {
                    axo = null;
                }
            }
        } else {
            try {
                var axo = new ActiveXObject("ShockwaveFlash.ShockwaveFlash.7");
            } catch(e) {
                try {
                    var axo = new ActiveXObject("ShockwaveFlash.ShockwaveFlash.6");
                    _23 = new deconcept.PlayerVersion([6, 0, 21]);
                    axo.AllowScriptAccess = "always";
                } catch(e) {
                    if (_23.major == 6) {
                        return _23;
                    }
                }
                try {
                    axo = new ActiveXObject("ShockwaveFlash.ShockwaveFlash");
                } catch(e) {}
            }
            if (axo != null) {
                _23 = new deconcept.PlayerVersion(axo.GetVariable("$version").split(" ")[1].split(","));
            }
        }
    }
    return _23;
};
deconcept.PlayerVersion = function(_29) {
    this.major = _29[0] != null ? parseInt(_29[0]) : 0;
    this.minor = _29[1] != null ? parseInt(_29[1]) : 0;
    this.rev = _29[2] != null ? parseInt(_29[2]) : 0;
};
deconcept.PlayerVersion.prototype.versionIsValid = function(fv) {
    if (this.major < fv.major) {
        return false;
    }
    if (this.major > fv.major) {
        return true;
    }
    if (this.minor < fv.minor) {
        return false;
    }
    if (this.minor > fv.minor) {
        return true;
    }
    if (this.rev < fv.rev) {
        return false;
    }
    return true;
};
deconcept.util = {
    getRequestParameter: function(_2b) {
        var q = document.location.search || document.location.hash;
        if (_2b == null) {
            return q;
        }
        if (q) {
            var _2d = q.substring(1).split("&");
            for (var i = 0; i < _2d.length; i++) {
                if (_2d[i].substring(0, _2d[i].indexOf("=")) == _2b) {
                    return _2d[i].substring((_2d[i].indexOf("=") + 1));
                }
            }
        }
        return "";
    }
};
deconcept.SWFObjectUtil.cleanupSWFs = function() {
    var _2f = document.getElementsByTagName("OBJECT");
    for (var i = _2f.length - 1; i >= 0; i--) {
        _2f[i].style.display = "none";
        for (var x in _2f[i]) {
            if (typeof _2f[i][x] == "function") {
                _2f[i][x] = function() {};
            }
        }
    }
};
if (deconcept.SWFObject.doPrepUnload) {
    if (!deconcept.unloadSet) {
        deconcept.SWFObjectUtil.prepUnload = function() {
            __flash_unloadHandler = function() {};
            __flash_savedUnloadHandler = function() {};
            window.attachEvent("onunload", deconcept.SWFObjectUtil.cleanupSWFs);
        };
        window.attachEvent("onbeforeunload", deconcept.SWFObjectUtil.prepUnload);
        deconcept.unloadSet = true;
    }
}
if (!document.getElementById && document.all) {
    document.getElementById = function(id) {
        return document.all[id];
    };
}
var getQueryParamValue = deconcept.util.getRequestParameter;
var FlashObject = deconcept.SWFObject;
var SWFObject = deconcept.SWFObject;

