(function() {
    "use strict";

    function $iterator(o) {
        if (o instanceof Array) return function() {
            return {
                cur: 0,
                arr: o,
                hasNext: function() {
                    return this.cur < this.arr.length;
                },
                next: function() {
                    return this.arr[this.cur++];
                }
            };
        };
        return typeof(o.iterator) == 'function' ? $bind(o, o.iterator) : o.iterator;
    };;
    var $fid = 0;

    function $bind(o, m) {
        if (m == null) return null;
        if (m.__id__ == null) m.__id__ = $fid++;
        var f;
        if (o.hx__closures__ == null) o.hx__closures__ = {};
        else f = o.hx__closures__[m.__id__];
        if (f == null) {
            f = function() {
                return f.method.apply(f.scope, arguments);
            };
            f.scope = o;
            f.method = m;
            o.hx__closures__[m.__id__] = f;
        }
        return f;
    };
    var $_;
    var $estr = function() {
        return _hcmn_.js_Boot.__string_rec(this, '');
    };
    if (typeof clientkernelInterfaces == 'undefined') {
        var clientkernelInterfaces = {};
    };
    clientkernelInterfaces.InterfaceDeclaration = function() {};
    clientkernelInterfaces.InterfaceDeclaration.__name__ = ["clientkernelInterfaces", "InterfaceDeclaration"];
    clientkernelInterfaces.InterfaceDeclaration.isValidating = function() {
        if (clientkernelInterfaces.InterfaceDeclaration.optionValidate == null) clientkernelInterfaces.InterfaceDeclaration.optionValidate = (function($this) {
            var $r;
            var this1 = clientkernelInterfaces.InterfaceDeclaration.getParams();
            $r = this1.get("kernel");
            return $r;
        }(this)) != null && ((function($this) {
            var $r;
            var this2 = clientkernelInterfaces.InterfaceDeclaration.getParams();
            $r = this2.get("kernel");
            return $r;
        }(this))).indexOf("v") != -1;
        return clientkernelInterfaces.InterfaceDeclaration.optionValidate;
    };
    clientkernelInterfaces.InterfaceDeclaration.ck_implements = function(cls, iface) {
        return clientkernelInterfaces.InterfaceDeclaration.injectValidation(cls, iface);
    };
    clientkernelInterfaces.InterfaceDeclaration.ck_cast = function(objct, iface) {
        var check = objct;
        if (!clientkernelInterfaces.InterfaceDeclaration.isValidating()) check = Object.getPrototypeOf(objct);
        if (check._validator != null && check._validator.has(iface)) return objct;
        else throw new Error("Illegal cast");
    };
    clientkernelInterfaces.InterfaceDeclaration.ck_instanceof = function(objct, iface) {
        var check = objct;
        if (!clientkernelInterfaces.InterfaceDeclaration.isValidating()) check = Object.getPrototypeOf(objct);
        return check._validator != null && check._validator.has(iface);
    };
    clientkernelInterfaces.InterfaceDeclaration.injectValidation = function(cls, iface) {
        if (clientkernelInterfaces.InterfaceDeclaration.isValidating()) {
            if (cls._validator == null) {
                var v = new clientkernelInterfaces.InterfaceValidator(cls, iface);
                var validatedClass = function() {
                    this._validator = v;
                    v.validate(arguments, this);
                }
                validatedClass.prototype = cls.prototype;
                validatedClass._validator = v;
                return validatedClass;
            } else {
                var v1 = cls._validator;
                v1.addInterface(iface);
                return cls;
            }
        } else if (cls.prototype._validator == null) {
            cls.prototype._validator = new clientkernelInterfaces.InterfaceValidator(cls, iface);
            return cls;
        } else {
            var v2 = cls.prototype._validator;
            v2.addInterface(iface);
            return cls;
        }
    };
    clientkernelInterfaces.InterfaceDeclaration.getParams = function() {
        var get;
        var _this = window.location.search;
        get = _hcmn_.HxOverrides.substr(_this, 1, null);
        var params = new _hcmn_.haxe_ds_StringMap();
        var _g = 0;
        var _g1 = new _hcmn_.EReg("[&;]", "g").split(get);
        while (_g < _g1.length) {
            var p = _g1[_g];
            ++_g;
            var pl = p.split("=");
            if (pl.length < 2) continue;
            var name = pl.shift();
            params.set(decodeURIComponent(name.split("+").join(" ")), _hcmn_.StringTools.urlDecode(pl.join("=")));
        }
        return params;
    };
    clientkernelInterfaces.InterfaceDeclaration.prototype.__class__ = clientkernelInterfaces.InterfaceDeclaration;
    clientkernelInterfaces.InterfaceValidator = function(cls, iface) {
        this.original_constructor = cls.prototype.constructor;
        this.original_methods = new _hcmn_.haxe_ds_StringMap();
        this.interfaces = [];
        this.interfaces.push(iface);
    };
    clientkernelInterfaces.InterfaceValidator.__name__ = ["clientkernelInterfaces", "InterfaceValidator"];
    clientkernelInterfaces.InterfaceValidator.prototype.original_constructor = null;
    clientkernelInterfaces.InterfaceValidator.prototype.original_methods = null;
    clientkernelInterfaces.InterfaceValidator.prototype.interfaces = null;
    clientkernelInterfaces.InterfaceValidator.prototype.has = function(iface) {
        return (function($this) {
            var $r;
            var x = iface;
            $r = _hcmn_.HxOverrides.indexOf($this.interfaces, x, 0);
            return $r;
        }(this)) != -1;
    };
    clientkernelInterfaces.InterfaceValidator.prototype.validate = function(args, cls) {
        var _g = 0;
        var _g1 = this.interfaces;
        while (_g < _g1.length) {
            var i = _g1[_g];
            ++_g;
            var _g2 = 0;
            var _g3 = _hcmn_.Reflect.fields(i.prototype);
            while (_g2 < _g3.length) {
                var m = _g3[_g2];
                ++_g2;
                if (!_hcmn_.Reflect.isFunction(_hcmn_.Reflect.field(i.prototype, m))) continue;
                var method = _hcmn_.Reflect.field(i.prototype, m);
                var methodName = m;
                var origMethod = Object.getPrototypeOf(cls)[methodName];
                if (origMethod == null) throw new Error("function not implemented:" + methodName);
                var m1 = new clientkernelInterfaces.MethodValidator(methodName, origMethod, cls, method);
                cls[methodName] = $bind(m1, m1.validateCall);
            }
        }
        var ctr = this.original_constructor;
        ctr.apply(cls, args);
    };
    clientkernelInterfaces.InterfaceValidator.prototype.addInterface = function(iface) {
        this.interfaces.push(iface);
    };
    clientkernelInterfaces.InterfaceValidator.prototype.__class__ = clientkernelInterfaces.InterfaceValidator;
    if (typeof haxe == 'undefined') {
        var haxe = {};
    };

    haxe.IMap = function() {}
    haxe.IMap.prototype = {

        get: function(k) {
            return {
                arguments: ["*"],
                returns: "null"
            };
        }
    };
    clientkernelInterfaces.Main = function() {
        clientkernelInterfaces.Main.main();
    };
    clientkernelInterfaces.Main.__name__ = ["clientkernelInterfaces", "Main"];
    clientkernelInterfaces.Main.main = function() {
        window.ck_implements = clientkernelInterfaces.InterfaceDeclaration.ck_implements;
        window.ck_cast = clientkernelInterfaces.InterfaceDeclaration.ck_cast;
        window.ck_instanceof = clientkernelInterfaces.InterfaceDeclaration.ck_instanceof;
    };
    clientkernelInterfaces.Main.prototype.__class__ = clientkernelInterfaces.Main;
    clientkernelInterfaces.MethodValidator = function(name, method, cls, ifacemethod) {
        this.name = name;
        this.method = method;
        this.cls = cls;
        this.ifacemethod = ifacemethod;
    };
    clientkernelInterfaces.MethodValidator.__name__ = ["clientkernelInterfaces", "MethodValidator"];
    clientkernelInterfaces.MethodValidator.prototype.name = null;
    clientkernelInterfaces.MethodValidator.prototype.method = null;
    clientkernelInterfaces.MethodValidator.prototype.cls = null;
    clientkernelInterfaces.MethodValidator.prototype.ifacemethod = null;
    clientkernelInterfaces.MethodValidator.prototype.validateCall = function() {
        var check = this.ifacemethod();
        var args = arguments;
        var method = this.method;
        var name = this.name;
        var cls = this.cls;
        if (args.length > check.arguments.length) throw new Error("invalid number of arguments");
        var _g1 = 0;
        var _g = args.length;
        while (_g1 < _g) {
            var i = _g1++;
            if (Object.prototype.hasOwnProperty.call(check.arguments[i], "type")) this.validateArgument(i, args[i], typeof args[i], _hcmn_.Reflect.field(check.arguments[i], "type"));
            else this.validateArgument(i, args[i], typeof args[i], check.arguments[i]);
        }
        var _g11 = args.length + 1;
        var _g2 = check.arguments.length;
        while (_g11 < _g2) {
            var i1 = _g11++;
            if (!Object.prototype.hasOwnProperty.call(check.arguments[i1], "opt")) throw new Error("invalid number of arguments");
            if (!_hcmn_.Reflect.field(check.arguments[i1], "opt")) throw new Error("invalid number of arguments");
        }
        var ret = method.apply(cls, arguments);
        var rettype = typeof ret;
        var checkret = (_hcmn_.Std.string(check.returns) + "").split(" ")[0];
        if (ret != null) {
            var _g3 = check.returns;
            switch (_g3) {
                case "string":
                    if (check.returns != rettype) throw new Error("invalid return " + this.name + "(" + rettype + "!=" + checkret + ")");
                    break;
                case "array":
                    if (Object.prototype.toString.call(ret) != "[object Array]") throw new Error("invalid return " + this.name + "(" + rettype + "!=" + checkret + ")");
                    break;
                case "number":
                    if (check.returns != rettype) throw new Error("invalid return " + this.name + "(" + rettype + "!=" + checkret + ")");
                    break;
                case "boolean":
                    if (check.returns != rettype) throw new Error("invalid return " + this.name + "(" + rettype + "!=" + checkret + ")");
                    break;
                case "void":
                    if (rettype != "undefined") throw new Error("invalid return " + this.name + "(" + rettype + "!=" + checkret + ")");
                    break;
                case "*":
                    break;
                default:
                    if (!clientkernelInterfaces.InterfaceDeclaration.ck_instanceof(ret, check.returns) && !ret instanceof check.returns) throw new Error("invalid return " + this.name + "(" + rettype + "!=" + checkret + ")");
            }
        }
        return ret;
    };
    clientkernelInterfaces.MethodValidator.prototype.validateArgument = function(index, arg, argtype, checktype) {
        var checkret = (_hcmn_.Std.string(checktype) + "").split(" ")[0];
        if (arg != null) switch (checktype) {
            case "string":
                if (checktype != argtype) throw new Error("invalid argument " + (index + 1) + " of " + this.name + "(" + argtype + "!=" + checkret + ")");
                break;
            case "array":
                if (Object.prototype.toString.call(arg) != "[object Array]") throw new Error("invalid argument " + (index + 1) + " of " + this.name + "(" + argtype + "!=" + checkret + ")");
                break;
            case "number":
                if (checktype != argtype) throw new Error("invalid argument " + (index + 1) + " of " + this.name + "(" + argtype + "!=" + checkret + ")");
                break;
            case "boolean":
                if (checktype != argtype) throw new Error("invalid argument " + (index + 1) + " of " + this.name + "(" + argtype + "!=" + checkret + ")");
                break;
            case "*":
                break;
            default:
                if (!clientkernelInterfaces.InterfaceDeclaration.ck_instanceof(arg, checktype)) throw new Error("invalid argument " + (index + 1) + " of " + this.name + "(" + argtype + "!=" + checkret + ")");
        }
    };
    clientkernelInterfaces.MethodValidator.prototype.__class__ = clientkernelInterfaces.MethodValidator;
    clientkernelInterfaces.InterfaceDeclaration.optionValidate = null;;
    clientkernelInterfaces.Main.instance = new clientkernelInterfaces.Main();;
})();