text: Sk.builtinFiles = {
  	"files": {
  		"src/lib/math/__init__.js": "var $builtinmodule = function(name)\n{\n    var mod = {};\n    mod.pi = Sk.builtin.assk$(Math.PI, Sk.builtin.nmber.float$);\n    mod.e =  Sk.builtin.assk$(Math.E, Sk.builtin.nmber.float$);\n\n//\tRNL\tadded\n    mod.fabs = new Sk.builtin.func(function(x) {\n        Sk.builtin.pyCheckArgs(\"fabs\", arguments, 1, 1);\n        Sk.builtin.pyCheckType(\"x\", \"number\", Sk.builtin.checkNumber(x));\n\n\treturn new Sk.builtin.nmber(Math.abs(Sk.builtin.asnum$(x)), Sk.builtin.nmber.float$);\n    });\n\n    mod.asin = new Sk.builtin.func(function(rad) {\n        Sk.builtin.pyCheckArgs(\"asin\", arguments, 1, 1);\n        Sk.builtin.pyCheckType(\"rad\", \"number\", Sk.builtin.checkNumber(rad));\n\n\treturn new Sk.builtin.nmber(Math.asin(Sk.builtin.asnum$(rad)), Sk.builtin.nmber.float$);\n    });\n\n    mod.acos = new Sk.builtin.func(function(rad) {\n        Sk.builtin.pyCheckArgs(\"acos\", arguments, 1, 1);\n        Sk.builtin.pyCheckType(\"rad\", \"number\", Sk.builtin.checkNumber(rad));\n\n\treturn new Sk.builtin.nmber(Math.acos(Sk.builtin.asnum$(rad)), Sk.builtin.nmber.float$);\n    });\n\n    mod.atan = new Sk.builtin.func(function(rad) {\n        Sk.builtin.pyCheckArgs(\"atan\", arguments, 1, 1);\n        Sk.builtin.pyCheckType(\"rad\", \"number\", Sk.builtin.checkNumber(rad));\n\n\treturn new Sk.builtin.nmber(Math.atan(Sk.builtin.asnum$(rad)), Sk.builtin.nmber.float$);\n    });\n\n    mod.atan2 = new Sk.builtin.func(function(y, x) {\n        Sk.builtin.pyCheckArgs(\"atan2\", arguments, 2, 2);\n        Sk.builtin.pyCheckType(\"y\", \"number\", Sk.builtin.checkNumber(y));\n        Sk.builtin.pyCheckType(\"x\", \"number\", Sk.builtin.checkNumber(x));\n\n\treturn new Sk.builtin.nmber(Math.atan2(Sk.builtin.asnum$(y), Sk.builtin.asnum$(x)), Sk.builtin.nmber.float$);\n    });\n\n    mod.sin = new Sk.builtin.func(function(rad) {\n        Sk.builtin.pyCheckArgs(\"sin\", arguments, 1, 1);\n        Sk.builtin.pyCheckType(\"rad\", \"number\", Sk.builtin.checkNumber(rad));\n\n\treturn new Sk.builtin.nmber(Math.sin(Sk.builtin.asnum$(rad)), Sk.builtin.nmber.float$);\n    });\n\n    mod.cos = new Sk.builtin.func(function(rad) {\n        Sk.builtin.pyCheckArgs(\"cos\", arguments, 1, 1);\n        Sk.builtin.pyCheckType(\"rad\", \"number\", Sk.builtin.checkNumber(rad));\n\n\treturn new Sk.builtin.nmber(Math.cos(Sk.builtin.asnum$(rad)), Sk.builtin.nmber.float$);\n    });\n\n    mod.tan = new Sk.builtin.func(function(rad) {\n        Sk.builtin.pyCheckArgs(\"tan\", arguments, 1, 1);\n        Sk.builtin.pyCheckType(\"rad\", \"number\", Sk.builtin.checkNumber(rad));\n\n\treturn new Sk.builtin.nmber(Math.tan(Sk.builtin.asnum$(rad)), Sk.builtin.nmber.float$);\n    });\n\n    mod.asinh = new Sk.builtin.func(function(x) {\n\tSk.builtin.pyCheckArgs(\"asinh\", arguments, 1, 1);\n\tSk.builtin.pyCheckType(\"x\", \"number\", Sk.builtin.checkNumber(x));\n\n\tx = Sk.builtin.asnum$(x);\n\n\tvar L = x + Math.sqrt(x*x+1);\n\n\treturn new Sk.builtin.nmber(Math.log(L), Sk.builtin.nmber.float$);\n    });\n\n    mod.acosh = new Sk.builtin.func(function(x) {\n\tSk.builtin.pyCheckArgs(\"acosh\", arguments, 1, 1);\n\tSk.builtin.pyCheckType(\"x\", \"number\", Sk.builtin.checkNumber(x));\n\n\tx = Sk.builtin.asnum$(x);\n\n\tvar L = x + Math.sqrt(x*x-1);\n\n\treturn new Sk.builtin.nmber(Math.log(L), Sk.builtin.nmber.float$);\n    });\n\n    mod.atanh = new Sk.builtin.func(function(x) {\n\tSk.builtin.pyCheckArgs(\"atanh\", arguments, 1, 1);\n\tSk.builtin.pyCheckType(\"x\", \"number\", Sk.builtin.checkNumber(x));\n\n\tx = Sk.builtin.asnum$(x);\n\n\tvar L = (1+x)/(1-x);\n\n\treturn new Sk.builtin.nmber(Math.log(L)/2, Sk.builtin.nmber.float$);\n    });\n\n    mod.sinh = new Sk.builtin.func(function(x) {\n\tSk.builtin.pyCheckArgs(\"sinh\", arguments, 1, 1);\n\tSk.builtin.pyCheckType(\"x\", \"number\", Sk.builtin.checkNumber(x));\n\n\tx = Sk.builtin.asnum$(x);\n\n\tvar e = Math.E;\n\tvar p = Math.pow(e, x);\n\tvar n = 1/p;\n\tvar result = (p-n)/2;\n\n\treturn new Sk.builtin.nmber(result, Sk.builtin.nmber.float$);\n    });\n\n    mod.cosh = new Sk.builtin.func(function(x) {\n\tSk.builtin.pyCheckArgs(\"cosh\", arguments, 1, 1);\n\tSk.builtin.pyCheckType(\"x\", \"number\", Sk.builtin.checkNumber(x));\n\n\tx = Sk.builtin.asnum$(x);\n\n\tvar e = Math.E;\n\tvar p = Math.pow(e, x);\n\tvar n = 1/p;\n\tvar result = (p+n)/2;\n\n\treturn new Sk.builtin.nmber(result, Sk.builtin.nmber.float$);\n    });\n\n    mod.tanh = new Sk.builtin.func(function(x) {\n\tSk.builtin.pyCheckArgs(\"tanh\", arguments, 1, 1);\n\tSk.builtin.pyCheckType(\"x\", \"number\", Sk.builtin.checkNumber(x));\n\n\tx = Sk.builtin.asnum$(x);\n\n\tvar e = Math.E;\n\tvar p = Math.pow(e, x);\n\tvar n = 1/p;\n\tvar result = ((p-n)/2)/((p+n)/2);\n\n\treturn new Sk.builtin.nmber(result, Sk.builtin.nmber.float$);\n    });\n\n    mod.ceil = new Sk.builtin.func(function(x) {\n        Sk.builtin.pyCheckArgs(\"ceil\", arguments, 1, 1);\n        Sk.builtin.pyCheckType(\"x\", \"number\", Sk.builtin.checkNumber(x));\n\n\treturn new Sk.builtin.nmber(Math.ceil(Sk.builtin.asnum$(x)), Sk.builtin.nmber.float$);\n    });\n\n    mod.floor = new Sk.builtin.func(function(x) {\n        Sk.builtin.pyCheckArgs(\"floor\", arguments, 1, 1);\n        Sk.builtin.pyCheckType(\"x\", \"number\", Sk.builtin.checkNumber(x));\n\n\treturn new Sk.builtin.nmber(Math.floor(Sk.builtin.asnum$(x)), Sk.builtin.nmber.float$);\n    });\n\n    mod.sqrt = new Sk.builtin.func(function(x) {\n        Sk.builtin.pyCheckArgs(\"sqrt\", arguments, 1, 1);\n        Sk.builtin.pyCheckType(\"x\", \"number\", Sk.builtin.checkNumber(x));\n\n\treturn new Sk.builtin.nmber(Math.sqrt(Sk.builtin.asnum$(x)), Sk.builtin.nmber.float$);\n    });\n\n    mod.trunc = new Sk.builtin.func(function(x) {\n        Sk.builtin.pyCheckArgs(\"trunc\", arguments, 1, 1);\n        Sk.builtin.pyCheckType(\"x\", \"number\", Sk.builtin.checkNumber(x));\n\n        return new Sk.builtin.nmber(Sk.builtin.asnum$(x)|0, Sk.builtin.nmber.int$);\n    });\n\n    mod.log = new Sk.builtin.func(function(x, base) {\n        Sk.builtin.pyCheckArgs(\"log\", arguments, 1, 2);\n        Sk.builtin.pyCheckType(\"x\", \"number\", Sk.builtin.checkNumber(x));\n\n        if (base === undefined) {\n\t    return new Sk.builtin.nmber(Math.log(Sk.builtin.asnum$(x)), Sk.builtin.nmber.float$);\n        } else {\n            Sk.builtin.pyCheckType(\"base\", \"number\", Sk.builtin.checkNumber(base));\n            var ret = Math.log(Sk.builtin.asnum$(x)) / Math.log(Sk.builtin.asnum$(base));\n\t    return new Sk.builtin.nmber(ret, Sk.builtin.nmber.float$);\n        }\n    });\n\n    mod.log10 = new Sk.builtin.func(function(x) {\n        Sk.builtin.pyCheckArgs(\"log10\", arguments, 1, 1);\n        Sk.builtin.pyCheckType(\"x\", \"number\", Sk.builtin.checkNumber(x));\n\n        var ret = Math.log(Sk.builtin.asnum$(x)) / Math.log(10);\n\treturn new Sk.builtin.nmber(ret, Sk.builtin.nmber.float$);\n    });\n\n    mod.exp = new Sk.builtin.func(function(x) {\n        Sk.builtin.pyCheckArgs(\"exp\", arguments, 1, 1);\n        Sk.builtin.pyCheckType(\"x\", \"number\", Sk.builtin.checkNumber(x));\n\n\treturn new Sk.builtin.nmber(Math.exp(Sk.builtin.asnum$(x)), Sk.builtin.nmber.float$);\n    });\n\n    mod.pow = new Sk.builtin.func(function(x,y) {\n        Sk.builtin.pyCheckArgs(\"pow\", arguments, 2, 2);\n        Sk.builtin.pyCheckType(\"x\", \"number\", Sk.builtin.checkNumber(x));\n        Sk.builtin.pyCheckType(\"y\", \"number\", Sk.builtin.checkNumber(y));\n\n\treturn new Sk.builtin.nmber(Math.pow(Sk.builtin.asnum$(x), Sk.builtin.asnum$(y)), Sk.builtin.nmber.float$);\n    });\n\n    mod.radians = new Sk.builtin.func(function(deg) {\n        Sk.builtin.pyCheckArgs(\"radians\", arguments, 1, 1);\n        Sk.builtin.pyCheckType(\"deg\", \"number\", Sk.builtin.checkNumber(deg));\n\n\tvar ret = Math.PI / 180.0 * Sk.builtin.asnum$(deg);\n\treturn new Sk.builtin.nmber(ret, Sk.builtin.nmber.float$);\n    });\n\n    mod.degrees = new Sk.builtin.func(function(rad) {\n        Sk.builtin.pyCheckArgs(\"degrees\", arguments, 1, 1);\n        Sk.builtin.pyCheckType(\"rad\", \"number\", Sk.builtin.checkNumber(rad));\n\n\tvar ret = 180.0 / Math.PI * Sk.builtin.asnum$(rad);\n\treturn new Sk.builtin.nmber(ret, Sk.builtin.nmber.float$);\n    });\n\n    mod.hypot = new Sk.builtin.func(function(x, y) {\n\tSk.builtin.pyCheckArgs(\"hypot\", arguments, 2, 2);\n        Sk.builtin.pyCheckType(\"x\", \"number\", Sk.builtin.checkNumber(x));\n\tSk.builtin.pyCheckType(\"y\", \"number\", Sk.builtin.checkNumber(y));\n\n\t\tx = Sk.builtin.asnum$(x);\n\t\ty = Sk.builtin.asnum$(y);\n\treturn new Sk.builtin.nmber(Math.sqrt((x*x)+(y*y)), Sk.builtin.nmber.float$);\n    });\n\n\tmod.factorial = new Sk.builtin.func(function(x) {\n\t    Sk.builtin.pyCheckArgs(\"factorial\", arguments, 1, 1);\n            Sk.builtin.pyCheckType(\"x\", \"number\", Sk.builtin.checkNumber(x));\n\n\t\tx = Math.floor(Sk.builtin.asnum$(x));\n\t\tvar r = 1;\n\t\tfor (var i = 2; i <= x; i++)\n\t\t\tr *= i;\n\t\treturn new Sk.builtin.nmber(r, Sk.builtin.nmber.int$);\n\t});\n\n    return mod;\n}",
  		"src/lib/numeric/__init__.js": "var $builtinmodule = function(name)\n{\n    var mod = {};\n\n    var checkIndex = function(index) {\n        // Check that it is a two element sequence\n        if (!Sk.builtin.checkSequence(index) || index.sq$length() != 2) {\n            return false;\n        };\n\n        // Check that each element is an int\n        if (!Sk.builtin.checkInt(index.mp$subscript(0)) \n            || !Sk.builtin.checkInt(index.mp$subscript(1))) {\n            return false;\n        };\n\n        return true;\n    };\n\n    var matrix = function($gbl, $loc) {\n        $loc.__init__ = new Sk.builtin.func(function(self, data) {\n            if (Sk.builtin.checkSequence(data)) {\n                self.matrix = [];\n                var i, j, row, mrow, item, rowlen;\n                rowlen = 0;\n                for (i=0; i<data.sq$length(); i++) {\n                    row = data.mp$subscript(i);\n                    if (!Sk.builtin.checkSequence(row)) {\n                        throw new Sk.builtin.TypeError(\"data must be a sequence of sequences\");\n                    }\n                    if (rowlen == 0) {\n                        rowlen = row.sq$length();\n                    }\n                    if (row.sq$length() != rowlen) {\n                        throw new Sk.builtin.TypeError(\"matrix rows must be the same length\");\n                    }\n\n                    mrow = [];\n                    for (j=0; j<row.sq$length(); j++) {\n                        item = row.mp$subscript(j);\n                        if (!Sk.builtin.checkNumber(item)) {\n                            throw new Sk.builtin.TypeError(\"matrix elements must be numbers\");\n                        }\n                        mrow.push(Sk.builtin.asnum$(item));\n                    }\n                    self.matrix.push(mrow);\n                }\n            } else if (Object.prototype.toString.apply(data) == '[object Array]') {\n                self.matrix = data;\n            } else {\n                throw new Sk.builtin.TypeError(\"data must be a sequence of sequences\");\n            }\n\n            self.xdim = self.matrix.length;\n            self.ydim = self.matrix[0].length;\n            self.matrix_shape = new Sk.builtin.tuple([new Sk.builtin.nmber(self.xdim, Sk.builtin.nmber.int$), \n                                                      new Sk.builtin.nmber(self.ydim, Sk.builtin.nmber.int$)]);\n\n            self.__class__ = mod.Matrix;\n        });\n\n        $loc.__getitem__ = new Sk.builtin.func(function(self, idx) {\n            Sk.builtin.pyCheckArgs(\"__getitem__\", arguments, 2, 2);\n            if (!checkIndex(idx))\n            {\n                throw new Sk.builtin.TypeError(\"index must be a 2 element sequence\");\n            }\n\n            var i = Sk.builtin.asnum$(idx.mp$subscript(0));\n            var j = Sk.builtin.asnum$(idx.mp$subscript(1));\n            return new Sk.builtin.nmber(self.matrix[i][j], Sk.builtin.nmber.float$);\n        });\n\n        $loc.getrow = new Sk.builtin.func(function(self, idx) {\n            Sk.builtin.pyCheckArgs(\"getrow\", arguments, 2, 2);\n            if (!Sk.builtin.checkInt(idx))\n            {\n                throw new Sk.builtin.TypeError(\"row index must be an integer\");\n            }\n\n            idx = Sk.builtin.asnum$(idx);\n            if ((idx < 0) || (idx >= self.xdim))\n            {\n                throw new Sk.builtin.ValueError(\"index out of bounds\");\n            }\n            \n            var row = [self.matrix[idx].slice()];\n            return new Sk.misceval.callsim(mod.Matrix, row);\n        });\n\n        $loc.getcol = new Sk.builtin.func(function(self, idx) {\n            Sk.builtin.pyCheckArgs(\"getcol\", arguments, 2, 2);\n            if (!Sk.builtin.checkInt(idx))\n            {\n                throw new Sk.builtin.TypeError(\"column index must be an integer\");\n            }\n\n            idx = Sk.builtin.asnum$(idx);\n            if ((idx < 0) || (idx >= self.ydim))\n            {\n                throw new Sk.builtin.ValueError(\"index out of bounds\");\n            }\n            \n            var i, col;\n            col = [];\n            for (i = 0; i < self.xdim; i++)\n            {\n                col.push(self.matrix[i][idx]);\n            }\n            col = [col];\n            return new Sk.misceval.callsim(mod.Matrix, col);\n        });\n\n        $loc.__setitem__ = new Sk.builtin.func(function(self, idx, data) {\n            Sk.builtin.pyCheckArgs(\"__setitem__\", arguments, 3, 3);\n            if (!checkIndex(idx))\n            {\n                throw new Sk.builtin.TypeError(\"index must be a 2 element sequence\");\n            }\n\n            var i = Sk.builtin.asnum$(idx.mp$subscript(0));\n            var j = Sk.builtin.asnum$(idx.mp$subscript(1));\n            self.matrix[i][j] = Sk.builtin.asnum$(data);\n        });\n\n        $loc.__str__ = new Sk.builtin.func(function(self) {\n            Sk.builtin.pyCheckArgs(\"__str__\", arguments, 1, 1);\n\n            var s = \"[\";\n            var i, j;\n            var el;\n            for (i=0; i<self.xdim; i++) {\n                if (i !== 0) {\n                    s += \" \";\n                }\n                s += \"[\";\n                for (j=0; j<self.ydim; j++) {\n                    // Convert float into a Skulpt float in order to use the\n                    // float string conversion function.  Otherwise, the numbers\n                    // will look different than other floats.\n                    el = Sk.builtin.nmber(self.matrix[i][j], Sk.builtin.nmber.float$);\n                    s += el.tp$str().v;\n                    if (j !== self.ydim - 1) {\n                        s += \", \";\n                    }\n                }\n                s += \"]\";\n                if (i !== self.xdim - 1) {\n                    s += \",\\n\";\n                }\n            }\n            s += \"]\\n\";\n            return new Sk.builtin.str(s);\n        });\n\n        $loc[\"__add__\"] = new Sk.builtin.func(function(self, other) {\n            Sk.builtin.pyCheckArgs(\"__add__\", arguments, 2, 2);\n            if (other.__class__ != mod.Matrix)\n            {\n                throw new Sk.builtin.TypeError(\"can only add matrices to matrices\");\n            }\n\n            var sum = numeric.add(self.matrix, other.matrix);\n            return Sk.misceval.callsim(mod.Matrix, sum);\n        });\n\n        $loc[\"__sub__\"] = new Sk.builtin.func(function(self, other) {\n            Sk.builtin.pyCheckArgs(\"__sub__\", arguments, 2, 2);\n            if (other.__class__ != mod.Matrix)\n            {\n                throw new Sk.builtin.TypeError(\"can only subtract matrices from matrices\");\n            }\n\n            var diff = numeric.sub(self.matrix, other.matrix);\n            return Sk.misceval.callsim(mod.Matrix, diff);\n        });\n\n        $loc[\"__mul__\"] = new Sk.builtin.func(function(self, other) {\n            Sk.builtin.pyCheckArgs(\"__mul__\", arguments, 2, 2);\n            if (other.__class__ != mod.Matrix)\n            {\n                throw new Sk.builtin.TypeError(\"can only multiply matrices with matrices\");\n            }\n\n            var product = numeric.dot(self.matrix, other.matrix);\n            return Sk.misceval.callsim(mod.Matrix, product);\n        });\n\n        $loc.copy = new Sk.builtin.func(function(self) {\n            Sk.builtin.pyCheckArgs(\"copy\", arguments, 1, 1);\n\n            var copy = numeric.clone(self.matrix);\n            return Sk.misceval.callsim(mod.Matrix, copy);\n        });\n\n        $loc.inverse = new Sk.builtin.func(function(self) {\n            Sk.builtin.pyCheckArgs(\"inverse\", arguments, 1, 1);\n            var inv, det;\n\n            try {\n                det = numeric.det(self.matrix);    \n            } catch(x) {\n                throw new Sk.builtin.ValueError(\"matrix has no inverse\");\n            }\n\n            if ((self.xdim !== self.ydim) || (det === 0)) {\n                throw new Sk.builtin.ValueError(\"matrix has no inverse\");\n            }\n\n            try {\n                inv = numeric.inv(self.matrix);\n            } catch (x) {\n                throw new Sk.builtin.ValueError(\"matrix has no inverse\");\n            }\n\n            return Sk.misceval.callsim(mod.Matrix, inv);\n        });\n\n        $loc.transpose = new Sk.builtin.func(function(self) {\n            Sk.builtin.pyCheckArgs(\"transpose\", arguments, 1, 1);\n\n            var transpose = numeric.transpose(self.matrix);\n            return Sk.misceval.callsim(mod.Matrix, transpose);\n        });\n\n        $loc.abs = new Sk.builtin.func(function(self) {\n            Sk.builtin.pyCheckArgs(\"abs\", arguments, 1, 1);\n\n            var abs = numeric.abs(self.matrix);\n            return Sk.misceval.callsim(mod.Matrix, abs);\n        });\n\n        $loc.summation = new Sk.builtin.func(function(self) {\n            Sk.builtin.pyCheckArgs(\"summation\", arguments, 1, 1);\n\n            var sum = numeric.sum(self.matrix);\n            return new Sk.builtin.nmber(sum, Sk.builtin.nmber.float$);\n        });\n\n        $loc.scale = new Sk.builtin.func(function(self, factor) {\n            Sk.builtin.pyCheckArgs(\"scale\", arguments, 2, 2);\n            if (!Sk.builtin.checkNumber(factor))\n            {\n                throw new Sk.builtin.TypeError(\"scale factor must be a number\");\n            }\n\n            var scaled = numeric.clone(self.matrix);\n            factor = Sk.builtin.asnum$(factor);\n            var i, j;\n            for (i=0; i<self.xdim; i++) {\n                for (j=0; j<self.ydim; j++) {\n                    scaled[i][j] *= factor;\n                }\n            }\n            return Sk.misceval.callsim(mod.Matrix, scaled);\n        });\n        \n        $loc.shape = new Sk.builtin.func(function(self) {\n            Sk.builtin.pyCheckArgs(\"shape\", arguments, 1, 1);\n\n            return self.matrix_shape;\n        });\n        \n    };\n\n    mod.Matrix = Sk.misceval.buildClass(mod, matrix, \"Matrix\", []);\n\n    mod.identity = new Sk.builtin.func(function(dimension) {\n        Sk.builtin.pyCheckArgs(\"identity\", arguments, 1, 1);\n        if (!Sk.builtin.checkInt(dimension))\n        {\n            throw new Sk.builtin.TypeError(\"dimension must be an integer\");\n        }\n\n        var dim = Sk.builtin.asnum$(dimension);\n        return Sk.misceval.callsim(mod.Matrix, numeric.identity(dim));\n    });\n\n    return mod;\n};\n",
  		"src/lib/collections/__init__.js": "var $builtinmodule = function(name)\n{\n\n    var mod = {};\n\n    // defaultdict object\n\n    mod.defaultdict = function defaultdict(default_, args)\n    {\n        if (!(this instanceof mod.defaultdict))\n        {\n            return new mod.defaultdict(default_, args);\n        }\n\n        Sk.builtin.dict.call(this, args);\n\n        if (default_ === undefined)\n        {\n            this.default_factory = Sk.builtin.none.none$;\n        }\n        else\n        {\n            if (!Sk.builtin.checkCallable(default_) && !(default_ instanceof Sk.builtin.none))\n            {\n                throw new Sk.builtin.TypeError(\"first argument must be callable\");\n            }\n            this.default_factory = default_;\n        }\n\n        if (this['$d'])\n        {\n            this['$d']['default_factory'] = this.default_factory;\n        }\n        else\n        {\n            this['$d'] = {'default_factory': this.default_factory};\n        }\n\n        return this;\n    }\n\n    mod.defaultdict.prototype = Object.create(Sk.builtin.dict.prototype);\n\n    mod.defaultdict.prototype.tp$name = 'defaultdict'\n\n    mod.defaultdict.prototype.ob$type = Sk.builtin.type.makeIntoTypeObj('defaultdict', mod.defaultdict);\n\n    mod.defaultdict.prototype['$r'] = function()\n    {\n        var def_str = Sk.misceval.objectRepr(this.default_factory).v;\n        var dict_str = Sk.builtin.dict.prototype['$r'].call(this).v;\n        return new Sk.builtin.str(\"defaultdict(\" + def_str + \", \" + dict_str + \")\");\n    }\n\n    mod.defaultdict.prototype['__missing__'] = function(key)\n    {\n        Sk.builtin.pyCheckArgs('__missing__', arguments, 0, 1);\n        if (key)\n        {\n            throw new Sk.builtin.KeyError(Sk.misceval.objectRepr(key));\n        }\n        else\n        {\n            return Sk.misceval.callsim(this.default_factory);\n        }\n    }\n\n    mod.defaultdict.prototype.mp$subscript = function(key)\n    {\n        try\n        {\n            return Sk.builtin.dict.prototype.mp$subscript.call(this, key);\n        }\n        catch (e)\n        {\n            if (this.default_factory instanceof Sk.builtin.none)\n            {\n                return this.__missing__(key);\n            }\n            else\n            {\n                ret = this.__missing__();\n                this.mp$ass_subscript(key, ret);\n                return ret;\n            }\n        }\n    }\n\n    // Counter object\n\n    mod.Counter = function Counter(iter_or_map)\n    {\n        if (!(this instanceof mod.Counter))\n        {\n            return new mod.Counter(iter_or_map);\n        }\n\n        if (iter_or_map instanceof Sk.builtin.dict || iter_or_map === undefined)\n        {\n            Sk.builtin.dict.call(this, iter_or_map);\n        }\n        else\n        {\n            if (!(Sk.builtin.checkIterable(iter_or_map)))\n            {\n                throw new Sk.builtin.TypeError(\"'\" + Sk.abstr.typeName(iter_or_map) + \"' object is not iterable\");\n            }\n\n            Sk.builtin.dict.call(this);\n            var one = Sk.builtin.nmber(1, Sk.builtin.nmber.int$);\n\n            for (var iter = iter_or_map.tp$iter(), k = iter.tp$iternext();\n                 k !== undefined;\n                 k = iter.tp$iternext())\n            {\n                var count = this.mp$subscript(k);\n                count = count.nb$add(one);\n                this.mp$ass_subscript(k, count);\n            }\n        }\n\n        return this;\n    }\n\n    mod.Counter.prototype = Object.create(Sk.builtin.dict.prototype);\n\n    mod.Counter.prototype.tp$name = 'Counter'\n\n    mod.Counter.prototype.ob$type = Sk.builtin.type.makeIntoTypeObj('Counter', mod.Counter);\n\n    mod.Counter.prototype['$r'] = function()\n    {\n        var dict_str = this.size > 0 ? Sk.builtin.dict.prototype['$r'].call(this).v : '';\n        return new Sk.builtin.str('Counter(' + dict_str + ')');\n    }\n\n    mod.Counter.prototype.mp$subscript = function(key)\n    {\n        try\n        {\n            return Sk.builtin.dict.prototype.mp$subscript.call(this, key);\n        }\n        catch (e)\n        {\n            return new Sk.builtin.nmber(0, Sk.builtin.nmber.int$);\n        }\n    }\n\n    mod.Counter.prototype['elements'] = new Sk.builtin.func(function(self)\n    {\n        Sk.builtin.pyCheckArgs('elements', arguments, 1, 1);\n        var all_elements = [];\n        for (var iter = self.tp$iter(), k = iter.tp$iternext();\n             k !== undefined;\n             k = iter.tp$iternext())\n        {\n            for (var i = 0; i < self.mp$subscript(k).v; i++)\n            {\n                all_elements.push(k);\n            }\n        }\n\n        var ret =\n        {\n            tp$iter: function() { return ret; },\n            $obj: this,\n            $index: 0,\n            $elem: all_elements,\n            tp$iternext: function()\n            {\n                if (ret.$index >= ret.$elem.length)\n                    return undefined;\n                return ret.$elem[ret.$index++];\n            }\n        }\n\n        return ret;\n\n    });\n\n    mod.Counter.prototype['most_common'] = new Sk.builtin.func(function(self, n)\n    {\n        Sk.builtin.pyCheckArgs('most_common', arguments, 1, 2);\n        var length = self.mp$length();\n\n        if (n === undefined)\n        {\n            n = length;\n        }\n        else\n        {\n            if (!Sk.builtin.checkInt(n))\n            {\n                if (n.skType === Sk.builtin.nmber.float$)\n                {\n                    throw new Sk.builtin.TypeError(\"integer argument expected, got float\");\n                }\n                else\n                {\n                    throw new Sk.builtin.TypeError(\"an integer is required\");\n                }\n            }\n\n            n = Sk.builtin.asnum$(n);\n            n = n <= length ? n : length;\n            n = n >= 0 ? n : 0;\n        }\n\n        var most_common_elem = [];\n        for (var iter = self.tp$iter(), k = iter.tp$iternext();\n             k !== undefined;\n             k = iter.tp$iternext())\n        {\n            most_common_elem.push([k, self.mp$subscript(k)]);\n        }\n\n        var sort_func = function(a, b)\n        {\n            if (a[1].v < b[1].v) {\n                return 1;\n            } else if (a[1].v > b[1].v) {\n                return -1;\n            } else {\n                return 0;\n            }\n        }\n        most_common_elem = most_common_elem.sort(sort_func);\n\n        var ret = [];\n        for (var i = 0; i < n; i++)\n        {\n            ret.push(new Sk.builtin.tuple(most_common_elem.shift()));\n        }\n\n        return new Sk.builtin.list(ret);\n    });\n\n    mod.Counter.prototype['update'] = new Sk.builtin.func(function(self, other)\n    {\n        Sk.builtin.pyCheckArgs('update', arguments, 1, 2);\n\n        if (other instanceof Sk.builtin.dict)\n        {\n            for (var iter = other.tp$iter(), k = iter.tp$iternext();\n                 k !== undefined;\n                 k = iter.tp$iternext())\n            {\n                var count = self.mp$subscript(k);\n                self.mp$ass_subscript(k, count.nb$add(other.mp$subscript(k)));\n            }\n        }\n        else\n        {\n            if (!Sk.builtin.checkIterable(other))\n            {\n                throw new Sk.builtin.TypeError(\"'\" + Sk.abstr.typeName(other) + \"' object is not iterable\");\n            }\n\n            var one = new Sk.builtin.nmber(1, Sk.builtin.nmber.int$);\n            for (var iter = other.tp$iter(), k = iter.tp$iternext();\n                 k !== undefined;\n                 k = iter.tp$iternext())\n            {\n                var count = self.mp$subscript(k);\n                self.mp$ass_subscript(k, count.nb$add(one));\n            }\n        }\n    });\n\n    mod.Counter.prototype['subtract'] = new Sk.builtin.func(function(self, other)\n    {\n        Sk.builtin.pyCheckArgs('subtract', arguments, 1, 2);\n\n        if (other instanceof Sk.builtin.dict)\n        {\n            for (var iter = other.tp$iter(), k = iter.tp$iternext();\n                 k !== undefined;\n                 k = iter.tp$iternext())\n            {\n                var count = self.mp$subscript(k);\n                self.mp$ass_subscript(k, count.nb$subtract(other.mp$subscript(k)));\n            }\n        }\n        else\n        {\n            if (!Sk.builtin.checkIterable(other))\n            {\n                throw new Sk.builtin.TypeError(\"'\" + Sk.abstr.typeName(other) + \"' object is not iterable\");\n            }\n\n            var one = new Sk.builtin.nmber(1, Sk.builtin.nmber.int$);\n            for (var iter = other.tp$iter(), k = iter.tp$iternext();\n                 k !== undefined;\n                 k = iter.tp$iternext())\n            {\n                var count = self.mp$subscript(k);\n                self.mp$ass_subscript(k, count.nb$subtract(one));\n            }\n        }\n    });\n\n    return mod;\n}",
  		"src/lib/re/__init__.js": "var $builtinmodule = function(name)\n{\n    var mod = {};\n\n    // Constants (mostly unsupported)\n    mod.I = 2;\n    mod.IGNORECASE = 2;\n    // mod.L = 4;\n    // mod.LOCALE = 4;\n    mod.M = 8;\n    mod.MULTILINE = 8;\n    // mod.S = 16;\n    // mod.DOTALL = 16;\n    // mod.U = 32;\n    // mod.UNICODE = 32;\n    // mod.X = 64;\n    // mod.VERBOSE = 64;\n\n    var validGroups = [\"(?:\", \"(?=\", \"(?!\"];\n\n    var convert = function(pattern) {\n        var newpattern;\n        var match;\n        var i;\n\n        // Look for disallowed constructs\n        match = pattern.match(/\\(\\?./g);\n        if (match) {\n            for (i=0; i<match.length; i++) {\n                if (validGroups.indexOf(match[i]) == -1) {\n                    throw new Sk.builtin.ValueError(\"Disallowed group in pattern: '\"\n                                                    + match[i] + \"'\");\n                };\n            };\n        };\n\n        newpattern = pattern.replace('/\\\\/g', '\\\\\\\\');\n        newpattern = pattern.replace(/([^\\\\]){,(?![^\\[]*\\])/g, '$1{0,');\n\n        return newpattern;\n    };\n\n    var getFlags = function(flags) {\n        var jsflags = \"g\";\n        if ((flags & mod.IGNORECASE) == mod.IGNORECASE) {\n            jsflags += \"i\";\n        };\n        if ((flags & mod.MULTILINE) == mod.MULTILINE) {\n            jsflags += \"m\";\n        }; \n        return jsflags;\n    };\n\n    mod.split = Sk.nativejs.func(function split(pattern, string, maxsplit, flags) {\n        Sk.builtin.pyCheckArgs(\"split\", arguments, 2, 4);\n        if (!Sk.builtin.checkString(pattern)) {\n            throw new Sk.builtin.TypeError(\"pattern must be a string\");\n        };\n        if (!Sk.builtin.checkString(string)) {\n            throw new Sk.builtin.TypeError(\"string must be a string\");\n        };\n        if (maxsplit === undefined) {\n            maxsplit = 0;\n        };\n        if (!Sk.builtin.checkNumber(maxsplit)) {\n            throw new Sk.builtin.TypeError(\"maxsplit must be a number\");\n        };\n        if (flags === undefined) {\n            flags = 0;\n        };\n        if (!Sk.builtin.checkNumber(flags)) {\n            throw new Sk.builtin.TypeError(\"flags must be a number\");\n        };\n\n\tmaxsplit = Sk.builtin.asnum$(maxsplit);\n        var pat = Sk.ffi.unwrapo(pattern);\n        var str = Sk.ffi.unwrapo(string);\n        \n        // Convert pat from Python to Javascript regex syntax\n        pat = convert(pat);\n        //print(\"Pat: \" + pat);\n        //print(\"Str: \" + str);\n\n        var captured = !(pat.match(/^\\(.*\\)$/) === null);\n        //print(\"Captured: \", captured);\n\n        var jsflags = getFlags(flags);\n        //print(\"Flags: \", jsflags);\n\n        var regex = new RegExp(pat, jsflags);\n\n        var result = [];\n        var match;\n        var index = 0;\n        var splits = 0;\n        while ((match = regex.exec(str)) != null) {\n            //print(\"Matched '\" + match[0] + \"' at position \" + match.index + \n            //      \"; next search at \" + regex.lastIndex);\n            if (match.index === regex.lastIndex) {\n                // empty match\n                break;\n            };\n            result.push(new Sk.builtin.str(str.substring(index, match.index)));\n            if (captured) {\n                // Add matching pattern, too\n                result.push(new Sk.builtin.str(match[0]));\n            };\n            index = regex.lastIndex;\n            splits += 1;\n            if (maxsplit && (splits >= maxsplit)) {\n                break;\n            };\n        };\n        result.push(new Sk.builtin.str(str.substring(index)));\n\n        return new Sk.builtin.list(result);\n    });\n\n    mod.findall = Sk.nativejs.func(function findall(pattern, string, flags) {\n        Sk.builtin.pyCheckArgs(\"findall\", arguments, 2, 3);\n        if (!Sk.builtin.checkString(pattern)) {\n            throw new Sk.builtin.TypeError(\"pattern must be a string\");\n        };\n        if (!Sk.builtin.checkString(string)) {\n            throw new Sk.builtin.TypeError(\"string must be a string\");\n        };\n        if (flags === undefined) {\n            flags = 0;\n        };\n        if (!Sk.builtin.checkNumber(flags)) {\n            throw new Sk.builtin.TypeError(\"flags must be a number\");\n        };\n\n        var pat = Sk.ffi.unwrapo(pattern);\n        var str = Sk.ffi.unwrapo(string);\n        \n        // Convert pat from Python to Javascript regex syntax\n        pat = convert(pat);\n        //print(\"Pat: \" + pat);\n        //print(\"Str: \" + str);\n\n        var jsflags = getFlags(flags);\n        //print(\"Flags: \", jsflags);\n\n        var regex = new RegExp(pat, jsflags);\n\n\tvar newline_at_end = new RegExp(/\\n$/);\n\tif (str.match(newline_at_end)) {\n\t    str = str.slice(0,-1);\n\t}\n\n        var result = [];\n        var match;\n        while ((match = regex.exec(str)) != null) {\n            //print(\"Matched '\" + match[0] + \"' at position \" + match.index + \n            //      \"; next search at \" + regex.lastIndex);\n            // print(\"match: \" + JSON.stringify(match));\n            if (match.length < 2) {\n                result.push(new Sk.builtin.str(match[0]));\n            } else if (match.length == 2) {\n                result.push(new Sk.builtin.str(match[1]));\n            } else {\n                var groups = [];\n                for (var i=1; i<match.length; i++) {\n                    groups.push(new Sk.builtin.str(match[i]));  \n                };\n                result.push(new Sk.builtin.tuple(groups));\n            };\n            if (match.index === regex.lastIndex) {\n                regex.lastIndex += 1;\n            };\n        };\n\n        return new Sk.builtin.list(result);\n    });\n\n\n    var matchobj = function($gbl, $loc) {\n        $loc.__init__ = new Sk.builtin.func(function(self,thematch, pattern, string) {\n            self.thematch = thematch;\n\t    self.re = pattern;\n\t    self.string = string;\n        });\n\n\t$loc.groups = new Sk.builtin.func(function(self) {\n\t    return new Sk.builtin.tuple(self.thematch.v.slice(1))\n\t});\n\n\t$loc.group = new Sk.builtin.func(function(self,grpnum) {\n\t    if (grpnum === undefined) {\n                grpnum = 0;\n            }\n            else {\n                grpnum = Sk.builtin.asnum$(grpnum);\n            }\n\t    if(grpnum >= self.thematch.v.length) {\n\t\tthrow new Sk.builtin.IndexError(\"Index out of range: \" + grpnum);\n\t\t}\n\t    return self.thematch.v[grpnum]\n\t});\n\n    }\n\n    mod.MatchObject = Sk.misceval.buildClass(mod, matchobj, 'MatchObject', []);\n\n    // Internal function to return a Python list of strings \n    // From a JS regular expression string\n    mod._findre = function(res, string) {\n\tres = res.replace(/([^\\\\]){,(?![^\\[]*\\])/g, '$1{0,');\n        var re = eval(res);\n\tvar patt = new RegExp('\\n$');\n\tif (string.v.match(patt))\n\t    var matches = string.v.slice(0,-1).match(re);\n\telse\n            var matches = string.v.match(re);\n        retval = new Sk.builtin.list();\n        if ( matches == null ) return retval;\n        for (var i = 0; i < matches.length; ++i) {\n            var sitem = new Sk.builtin.str(matches[i]);\n            retval.v.push(sitem);\n        }\n        return retval;\n    }\n\n    mod.search = new Sk.builtin.func(function(pattern, string, flags) {\n\tSk.builtin.pyCheckArgs('search', arguments, 2, 3);\n        if (!Sk.builtin.checkString(pattern)) {\n            throw new Sk.builtin.TypeError(\"pattern must be a string\");\n        };\n        if (!Sk.builtin.checkString(string)) {\n            throw new Sk.builtin.TypeError(\"string must be a string\");\n        };\n\tif (flags === undefined) {\n            flags = 0;\n        };\n        if (!Sk.builtin.checkNumber(flags)) {\n            throw new Sk.builtin.TypeError(\"flags must be a number\");\n        };\n        var res = \"/\"+pattern.v.replace(/\\//g,\"\\\\/\")+\"/\";\n        lst = mod._findre(res,string);\n        if ( lst.v.length < 1 ) return Sk.builtin.none.none$;\n        var mob = Sk.misceval.callsim(mod.MatchObject, lst, pattern, string);\n        return mob;\n    });\n\n    mod.match = new Sk.builtin.func(function(pattern, string, flags) {\n\tSk.builtin.pyCheckArgs('match', arguments, 2, 3);\n        if (!Sk.builtin.checkString(pattern)) {\n            throw new Sk.builtin.TypeError(\"pattern must be a string\");\n        };\n        if (!Sk.builtin.checkString(string)) {\n            throw new Sk.builtin.TypeError(\"string must be a string\");\n        };\n\tif (flags === undefined) {\n            flags = 0;\n        };\n        if (!Sk.builtin.checkNumber(flags)) {\n            throw new Sk.builtin.TypeError(\"flags must be a number\");\n        };\n        var res = \"/^\"+pattern.v.replace(/\\//g,\"\\\\/\")+\"/\";\n        lst = mod._findre(res,string);\n        if ( lst.v.length < 1 ) return Sk.builtin.none.none$;\n        var mob = Sk.misceval.callsim(mod.MatchObject, lst, pattern, string);\n        return mob;\n    });\n\n    return mod;\n}\n",
  		"src/lib/time/__init__.js": "\n/*\n\tBarebones implementation of the Python time package.\n\n\tFor now, only the time() function is implemented.\n*/\n \nvar $builtinmodule = function(name)\n{\n    var mod = {};\n\n    mod.time = new Sk.builtin.func(function() {\n\t  return Sk.builtin.assk$(new Date().getTime() / 1000, undefined);\n    });\n\n    return mod;\n}\n",
  		"src/lib/codeskulptor/__init__.js": "var $builtinmodule = function(name)\n{\n    var mod = {};\n\n    mod.file2url = new Sk.builtin.func(function(filename) {\n        Sk.builtin.pyCheckArgs(\"file2url\", arguments, 1, 1);\n        if (!Sk.builtin.checkString(filename)) {\n            throw new Sk.builtin.TypeError(\"filename must be a string\");\n        };\n\n        var pattern = /^([a-zA-Z][a-zA-Z0-9]*)[_\\-]/;\n        var fname = Sk.ffi.unwrapo(filename);\n        var bucket = fname.match(pattern);\n\n        if (bucket == null) {\n            throw new Sk.builtin.ValueError(\"invalid filename: '\" + fname + \"'\");\n        };\n\n        var url = \"http://codeskulptor-\" + bucket[1] + \".commondatastorage.googleapis.com/\" + fname;\n\n        return new Sk.builtin.str(url);\n    });\n\n    mod.set_timeout = new Sk.builtin.func(function(secs) {\n        Sk.builtin.pyCheckArgs(\"set_timeout\", arguments, 1, 1);\n        if (!Sk.builtin.checkInt(secs)) {\n            throw new Sk.builtin.TypeError(\"timeout must be an integer\");\n        };\n\n        secs = Sk.builtin.asnum$(secs);\n\n        Sk.setExecLimit(secs*1000);\n    });\n\n    return mod;\n};\n",
  		"src/builtin/sys.js": "var $builtinmodule = function(name)\n{\n    var sys = {};\n\n    var args = [];\n    var argv = Sk.getSysArgv();\n    for (var i = 0; i < argv.length; ++i)\n        args.push(new Sk.builtin.str(argv[i]));\n    sys.argv = new Sk.builtins['list'](args);\n\n    sys.copyright = Sk.builtin['str'](\"Copyright 2009-2010 Scott Graham.\\nAll Rights Reserved.\\n\");\n\n    sys.modules = Sk.sysmodules;\n\n    sys.path = Sk.realsyspath;\n\n    sys.getExecutionLimit = new Sk.builtin.func(function() {\n        var limit = Sk.getExecLimit();\n        return Sk.builtin.assk$(limit, Sk.builtin.nmber.int$);\n    });\n\n    sys.setExecutionLimit = new Sk.builtin.func(function(t) {\n        if (t !==  undefined) {\n            t = Sk.builtin.asnum$(t);\n            Sk.setExecLimit(t);\n        }\n    });\n\n    sys.resetTimeout = new Sk.builtin.func(function() {\n        Sk.setExecStartNow(true);\n    });\n\n    sys.debug = new Sk.builtin.func(function() {\n        debugger;\n    });\n\n    return sys;\n};\n",
  		"src/lib/simplemap/__init__.js": "var $builtinmodule = function(name)\n{\n    var mod = {};\n\n    Sk.maps = {};\n\n    var frames = [];\n\n    var fontfaces = {\n        'serif': true,\n        'sans-serif': true,\n        'monospace': true\n    };\n\n    Sk.maps.cleanup = function () {\n        for (i=0; i < frames.length; i++) {\n            // Close the window, if it's open\n            // Sk.misceval.callsim(frames[i].stop, frames[i]);\n\n            // Should be a \"close\" method\n            frames[i].frame_window.close();\n        };\n        frames = [];\n    };\n\n    var checkPoint = function(point) {\n        // Check that it is a two element sequence\n        if (!Sk.builtin.checkSequence(point) || point.sq$length() != 2) {\n            return false;\n        };\n\n        // Check that each element is a number\n        if (!Sk.builtin.checkNumber(point.mp$subscript(0)) || !Sk.builtin.checkNumber(point.mp$subscript(1))) {\n            return false;\n        };\n\n        return true;\n    };\n\n    mod.Rice = new Sk.builtin.tuple([new Sk.builtin.nmber(29.716467, Sk.builtin.nmber.float$),\n                                     new Sk.builtin.nmber(-95.404213, Sk.builtin.nmber.float$)]);\n\n    // Python frame class\n    var map = function($gbl, $loc) {\n        $loc.__init__ = new Sk.builtin.func(function(self, title, \n                                                     lat_long_tuple,\n                                                     canvas_width, \n                                                     canvas_height,\n                                                     control_width) {\n            // Save parameters\n            self.title = title;\n\t    self.latitude = Sk.builtin.asnum$(lat_long_tuple.v[0]);\n\t    self.longitude = Sk.builtin.asnum$(lat_long_tuple.v[1]);\n            self.width = Sk.builtin.asnum$(canvas_width);\n            self.height = Sk.builtin.asnum$(canvas_height);\n            self.ctrlWidth = 0;\n            self.ctrlMargin = 0;\n\n            if (control_width !== undefined) {\n                self.ctrlWidth = Sk.builtin.asnum$(control_width);\n                self.ctrlMargin = 10;\n            }\n\n            self.margin = 23;\n\n            // Create frame window\n            var winwidth = self.width + (self.margin*2) + self.ctrlWidth + (self.ctrlMargin*2);\n            var winheight = self.height + (self.margin*2);\n            self.frame_window = window.open('','mymap',\n                                            'width='+winwidth\n                                            +',height='+winheight\n                                            +',location=0'\n                                            +',menubar=0'\n                                            +',toolbar=0'\n                                            +',directories=0'\n                                            +',status=0'\n                                            +',titlebar=0'\n                                            +',scrollbars=0'\n                                            +',resizeable=1');\n\n            // Build empty document\n\n            // Escape title\n            var jstitle = Sk.ffi.unwrapo(title);\n            jstitle = jstitle.replace(/&/g,'&amp;');\n            jstitle = jstitle.replace(/</g,'&lt;');\n            jstitle = jstitle.replace(/>/g,'&gt;');\n\n            var maphtml = '<html>'\n                +             '<head>'\n                +               '<title>'\n                +                 jstitle\n                +               '</title>'\n                +             '</head>'\n                +             '<body>'\n                +             '</body>'\n                +           '</html>';\n\n            self.frame_window.document.writeln('<!DOCTYPE html>');\n            self.frame_window.document.writeln(maphtml);\n            self.frame_window.document.close();\n\n            // Build GUI areas\n            var framebody = self.frame_window.document.getElementsByTagName(\"body\")[0];\n            framebody.style.margin = \"0px\";\n            \n            // Control Pane\n            if (self.ctrlWidth > 0) {\n                self.control = self.frame_window.document.createElement(\"div\");\n                self.control.style.height = self.height + 'px';\n                self.control.style.width = self.ctrlWidth + 'px';\n                self.control.style.position = \"relative\";\n                self.control.style.cssFloat = \"left\";\n                self.control.style.margin = self.ctrlMargin + 'px';\n\n                framebody.appendChild(self.control);\n            }\n\n\t    // Map Pane\n            self.mapdiv = self.frame_window.document.createElement(\"div\");\n            self.mapdiv.style.height = self.height + 'px';\n            self.mapdiv.style.width = self.width + 'px';\n            self.mapdiv.style.position = \"relative\";\n            self.mapdiv.style.cssFloat = \"right\";\n\t    self.mapdiv.style.margin = self.margin + 'px';\n\n\t    framebody.appendChild(self.mapdiv);\n\n\t    // Setup map\n\t    var mapOptions = {\n\t\tzoom: 15,\n\t\tcenter: new google.maps.LatLng(self.latitude, self.longitude),\n\t\tmapTypeId: google.maps.MapTypeId.ROADMAP\n\t    };\n\t    self.map = new google.maps.Map(self.mapdiv, mapOptions);\n\n            // Store all Marker objects on map\n            self.all_markers = new Sk.builtin.set();\n\n            // Store all Line objects on map\n            self.all_lines = new Sk.builtin.set();\n\n            // Store frame\n            frames.push(self);\n        });\n\n        $loc.add_button = new Sk.builtin.func(function(self, text, handler, width) {\n            Sk.builtin.pyCheckArgs(\"add_button\", arguments, 3, 4);\n            if (self.control === undefined) {\n                throw new Sk.builtin.AssertionError(\"map has no control frame\");\n            }\n            if (!Sk.builtin.checkString(text)) {\n                throw new Sk.builtin.TypeError(\"text must be a string\");\n            }\n            if (!Sk.builtin.checkFunction(handler)) {\n                throw new Sk.builtin.TypeError(\"handler must be a function\");\n            }\n            if (width !== undefined && !Sk.builtin.checkNumber(width)) {\n                throw new Sk.builtin.TypeError(\"width must be a number\");\n            }\n\n            // make button\n            var button = self.frame_window.document.createElement(\"button\");\n            var handler_lineno = Sk.currLineNo;\n            button.type = \"button\";\n            button.textContent = text.v;\n            if (width !== undefined) {\n                button.style.width = Sk.builtin.asnum$(width) + \"px\";\n            }\n            button.onclick = function () {\n                 try {\n                     Sk.setExecStartNow(true);\n                     Sk.currLineNo = handler_lineno;\n                     Sk.misceval.callsim(handler);\n                 } catch (e) {\n                     Sk.error(e);\n                     Sk.maps.cleanup();\n                 }\n            }\n\n            // append button to control frame\n            self.control.appendChild(button);\n        });\n\n        $loc.add_break = new Sk.builtin.func(function(self) {\n            Sk.builtin.pyCheckArgs(\"add_break\", arguments, 1, 1);\n            if (self.control === undefined) {\n                throw new Sk.builtin.AssertionError(\"map has no control frame\");\n            }\n            var br = self.frame_window.document.createElement(\"br\");\n            self.control.appendChild(br);\n        });\n\n        $loc.add_marker = new Sk.builtin.func(function(self, description, loc_id, icon_url, coordinates,  handler) {\n            Sk.builtin.pyCheckArgs(\"add_marker\", arguments, 6, 6);\n            if (!Sk.builtin.checkString(description)) {\n                throw new Sk.builtin.TypeError(\"description must be a string\");\n            };\n            if (!Sk.builtin.checkString(loc_id)) {\n                throw new Sk.builtin.TypeError(\"id must be a string\");\n            };\n            if (!Sk.builtin.checkString(icon_url)) {\n                throw new Sk.builtin.TypeError(\"icon_url must be a string\");\n            };\n            if (!(coordinates instanceof Sk.builtin.tuple)\n                || (coordinates.v.length !== 2)\n                || (!Sk.builtin.checkNumber(coordinates.v[0]))\n                || (!Sk.builtin.checkNumber(coordinates.v[1]))) {\n                throw new Sk.builtin.TypeError(\"coordinates must be given as a tuple of two numbers\");\n                };\n            if (!Sk.builtin.checkFunction(handler)) {\n                throw new Sk.builtin.TypeError(\"handler must be a function\");\n            };\n\n            this_marker = Sk.misceval.callsim(mod.Marker, self, description, loc_id, icon_url, coordinates, handler);\n            Sk.builtin.set.prototype['add'].func_code(self.all_markers, this_marker);\n            return this_marker;\n        });\n\n        $loc.draw_line = new Sk.builtin.func(function(self, start_marker, stop_marker) {\n            Sk.builtin.pyCheckArgs(\"draw_line\", arguments, 3, 3);\n            if (!(start_marker instanceof mod.Marker)) {\n                throw new Sk.builtin.TypeError(\"expected Marker object for start argument, got \" + Sk.abstr.typeName(start_marker));\n            }\n            if (!(stop_marker instanceof mod.Marker)) {\n                throw new Sk.builtin.TypeError(\"expected Marker object for stop argument, got \" + Sk.abstr.typeName(stop_marker));\n            }\n            this_line = Sk.misceval.callsim(mod.Line, self, start_marker, stop_marker);\n            Sk.builtin.set.prototype['add'].func_code(self.all_lines, this_line);\n            return this_line;\n        });\n\n        $loc.get_markers = new Sk.builtin.func(function(self) {\n            Sk.builtin.pyCheckArgs(\"get_markers\", arguments, 1, 1);\n            return self.all_markers;\n        });\n\n        $loc.get_lines = new Sk.builtin.func(function(self) {\n            Sk.builtin.pyCheckArgs(\"get_lines\", arguments, 1, 1);\n            return self.all_lines;\n        });\n\n        $loc.clear_markers = new Sk.builtin.func(function(self) {\n            Sk.builtin.pyCheckArgs(\"clear_markers\", arguments, 1, 1);\n            for (var it = self.all_markers.tp$iter(), i = it.tp$iternext();\n                 i !== undefined; i = it.tp$iternext())\n            {\n                i.__proto__.remove.func_code(i);\n            }\n        });\n\n        $loc.clear_lines = new Sk.builtin.func(function(self) {\n            Sk.builtin.pyCheckArgs(\"clear_lines\", arguments, 1, 1);\n            for (var it = self.all_lines.tp$iter(), i = it.tp$iternext();\n                 i !== undefined; i = it.tp$iternext())\n            {\n                i.__proto__.remove.func_code(i);\n            }\n        });\n\n        $loc.clear = new Sk.builtin.func(function(self) {\n            Sk.builtin.pyCheckArgs(\"clear\", arguments, 1, 1);\n            $loc.clear_markers.func_code(self);\n            $loc.clear_lines.func_code(self);\n        });\n\n        $loc.__str__ = new Sk.builtin.func(function (self) {\n            Sk.builtin.pyCheckArgs(\"__str__\", arguments, 1, 1);\n\n            return new Sk.builtin.str(\"<Map object: \" + self.title.v + \", (\" + self.latitude + \", \" + self.longitude + \")>\");\n        });\n\n    };\n\n    mod.Map = Sk.misceval.buildClass(mod, map, 'Map', []);\n\n    mod.create_map = new Sk.builtin.func(function(title, coordinates,\n                                                  map_width, map_height,\n\t\t\t\t\t\t  control_width){\n        Sk.builtin.pyCheckArgs(\"create_map\", arguments, 4, 5);\n        if (!Sk.builtin.checkString(title)) {\n            throw new Sk.builtin.TypeError(\"title must be a string\");\n        };\n\n        if (!Sk.builtin.checkInt(map_width)) {\n            throw new Sk.builtin.TypeError(\"map width must be an integer\");\n        };                \n        if (!Sk.builtin.checkInt(map_height)) {\n            throw new Sk.builtin.TypeError(\"map height must be an integer\");\n        };\n        if ((control_width !== undefined) &&\n            (!Sk.builtin.checkInt(control_width))) {\n            throw new Sk.builtin.TypeError(\"control width must be an integer\");\n        };\n\n        if (Sk.builtin.asnum$(map_width) <= 0) {\n            throw new Sk.builtin.ValueError(\"map width must be > 0\");\n        };\n        if (Sk.builtin.asnum$(map_height) <= 0) {\n            throw new Sk.builtin.ValueError(\"map height must be > 0\");\n        };\n        if (Sk.builtin.asnum$(control_width) <= 0) {\n            throw new Sk.builtin.ValueError(\"control width must be > 0\");\n        };\n\n        if (!(coordinates instanceof Sk.builtin.tuple)\n            || (coordinates.v.length !== 2)\n            || (!Sk.builtin.checkNumber(coordinates.v[0]))\n            || (!Sk.builtin.checkNumber(coordinates.v[1]))) {\n            throw new Sk.builtin.TypeError(\"coordinates must be given as a tuple of two numbers\");\n        };\n\n        return Sk.misceval.callsim(mod.Map, title, coordinates,\n                                   map_width, map_height, control_width);\n    });\n\n    var marker = function ($gbl, $loc) {\n        $loc.__init__ = new Sk.builtin.func(function(self, map, description,\n                                                     loc_id,\n                                                     icon_url,\n                                                     coordinates,\n                                                     handler) {\n            self.mapObj = map;\n            self.description = description;\n            self.loc_id = loc_id;\n            self.coordinates = coordinates;\n            self.handler = handler;\n            self.handler_lineno = Sk.currLineNo;\n\n\n            var latitude = Sk.builtin.asnum$(coordinates.v[0]);\n            var longitude = Sk.builtin.asnum$(coordinates.v[1]);\n\n            self.goog_marker = new google.maps.Marker({\n                map: self.mapObj.map,\n                position: new google.maps.LatLng(latitude, longitude),\n                title: Sk.ffi.unwrapo(description),\n                icon: icon_url.v\n            });\n\n             google.maps.event.addListener(self.goog_marker, \"click\", function () {\n                 try {\n                     Sk.setExecStartNow(true);\n                     Sk.currLineNo = self.handler_lineno;\n                     Sk.misceval.callsim(handler, self);\n                 } catch (e) {\n                     Sk.error(e);\n                     Sk.maps.cleanup();\n                 }\n            });\n        });\n\n        $loc.remove = new Sk.builtin.func(function(self) {\n            Sk.builtin.pyCheckArgs(\"remove\", arguments, 1, 1);\n            self.goog_marker.setMap(null);\n            Sk.builtin.set.prototype['discard'].func_code(self.mapObj.all_markers, self);\n        });\n\n        $loc.get_coordinates = new Sk.builtin.func(function(self) {\n            Sk.builtin.pyCheckArgs(\"get_coordinates\", arguments, 1, 1);\n            return self.coordinates;\n        });\n\n        $loc.get_description = new Sk.builtin.func(function(self) {\n            Sk.builtin.pyCheckArgs(\"get_description\", arguments, 1, 1);\n            return self.description;\n        });\n\n        $loc.get_id = new Sk.builtin.func(function(self) {\n            Sk.builtin.pyCheckArgs(\"get_id\", arguments, 1, 1);\n            return self.loc_id;\n        });\n\n        $loc.get_icon = new Sk.builtin.func(function(self) {\n            Sk.builtin.pyCheckArgs(\"get_icon\", arguments, 1, 1);\n            return new Sk.builtin.str(self.goog_marker.icon);\n        });\n\n        $loc.set_icon = new Sk.builtin.func(function(self, icon_url) {\n            Sk.builtin.pyCheckArgs(\"set_icon\", arguments, 2, 2);\n            if (!Sk.builtin.checkString(icon_url)) {\n                throw new Sk.builtin.TypeError(\"icon_url must be a string\");\n            }\n\n            self.goog_marker.setIcon(icon_url.v);\n        });\n\n        $loc.__str__ = new Sk.builtin.func(function (self) {\n            Sk.builtin.pyCheckArgs(\"__str__\", arguments, 1, 1);\n\n            return new Sk.builtin.str(\"<Marker object: \" + self.loc_id.v + ', \"' + self.description.v + '\">');\n        });\n\n    }\n\n    mod.Marker = Sk.misceval.buildClass(mod, marker, 'Marker', []);\n\n    mod.service = new google.maps.DirectionsService();\n\n    var line = function ($gbl, $loc) {\n\n        $loc.__init__ = new Sk.builtin.func(function(self, map, start_marker, stop_marker) {\n            self.mapObj = map;\n            self.start = start_marker;\n            self.stop = stop_marker;\n\n            var start_latlng = start_marker.goog_marker.getPosition();\n            var stop_latlng = stop_marker.goog_marker.getPosition();\n\n            self.path = new google.maps.MVCArray();\n            // initialize path with a dummy coordinate so that it will show on the map\n            // if DirectionService cannot get a valid route, this will serve as the first point on the path\n            self.path.push(start_latlng);\n\n            // use DirectionService to snap lines to the roads\n            mod.service.route({\n                origin: start_latlng,\n                destination: stop_latlng,\n                travelMode: google.maps.DirectionsTravelMode.DRIVING\n            }, function (result, status) {\n                // if DirectionService can get a valid route, use this route as the new path\n                if (status === google.maps.DirectionsStatus.OK) {\n                    for (var i = 0, len = result.routes[0].overview_path.length; i < len; i++) {\n                        self.path.push(result.routes[0].overview_path[i]);\n                    }\n                    // remove the dummy coordinate from the front of path\n                    self.path.removeAt(0);\n                }\n                else {\n                    // if DirectionService cannot get a valid route, draw a straight line from the start coordinates to stop coordinates\n                    self.path.push(stop_latlng);\n                }\n            });\n\n            self.polyline = new google.maps.Polyline({\n                map: self.mapObj.map,\n                path: self.path,\n                strokeWeight: 2\n            });\n        });\n\n        $loc.set_color = new Sk.builtin.func(function(self, hex_code) {\n            Sk.builtin.pyCheckArgs(\"set_color\", arguments, 2, 2);\n            if (!Sk.builtin.checkString(hex_code)) {\n                throw new Sk.builtin.TypeError(\"expected a String for hex_code argument, got \" + Sk.abstr.typeName(hex_code));\n            }\n\n            self.polyline.setOptions({ strokeColor: hex_code.v });\n        });\n\n        $loc.remove = new Sk.builtin.func(function(self) {\n            Sk.builtin.pyCheckArgs(\"remove\", arguments, 1, 1);\n            self.polyline.setMap(null);\n            Sk.builtin.set.prototype['discard'].func_code(self.mapObj.all_lines, self);\n        });\n\n        $loc.get_start = new Sk.builtin.func(function(self) {\n            Sk.builtin.pyCheckArgs(\"get_start\", arguments, 1, 1);\n            return self.start;\n        });\n\n        $loc.get_stop = new Sk.builtin.func(function(self) {\n            Sk.builtin.pyCheckArgs(\"get_stop\", arguments, 1, 1);\n            return self.stop;\n        });\n\n        $loc.__str__ = new Sk.builtin.func(function (self) {\n            Sk.builtin.pyCheckArgs(\"__str__\", arguments, 1, 1);\n\n            return new Sk.builtin.str(\"<Line object: (\" + self.start.loc_id.v + \", \" + self.stop.loc_id.v + \")>\");\n        });\n    }\n\n    mod.Line = Sk.misceval.buildClass(mod, line, 'Line', []);\n\n    return mod;\n};\n",
  		"src/lib/simpleplot/__init__.js": "var $builtinmodule = function(name)\n{\n    var mod = {};\n\n    Sk.simpleplot = {};\n\n    var plots = [];\n\n    Sk.simpleplot.cleanup = function () {\n        for (i=0; i < plots.length; i++) {\n            // Close the window, if it's open\n            plots[i].plot_window.close();\n        };\n        plots = [];  \n    };\n\n    var winctr = 0;\n\n    var create_plot = function(title, width, height) {\n        var plot = {};\n        var plotdiv;\n\n        // Save parameters\n        plot.title = title;\n        plot.width = width;\n        plot.height = height;\n        plot.margin = 23;\n        plot.titleheight = 30;\n        \n        // Create frame window\n        var winwidth = plot.width + (plot.margin*2);\n        var winheight = plot.height + (plot.margin*2) + plot.titleheight;\n        var winname = \"plot_\" + (winctr++);\n        plot.plot_window = window.open('', winname,\n                                       'width='+winwidth\n                                       +',height='+winheight\n                                       +',location=0'\n                                       +',menubar=0'\n                                       +',toolbar=0'\n                                       +',directories=0'\n                                       +',status=0'\n                                       +',titlebar=0'\n                                       +',scrollbars=0'\n                                       +',resizeable=1');\n        \n        // Build empty document\n\n        // Escape title\n        var jstitle = Sk.ffi.unwrapo(title);\n        jstitle = jstitle.replace(/&/g,'&amp;');\n        jstitle = jstitle.replace(/</g,'&lt;');\n        jstitle = jstitle.replace(/>/g,'&gt;');\n\n        var plothtml = '<html>'\n            +             '<head>'\n            +               '<title>'\n            +                 jstitle\n            +               '</title>'\n            +             '</head>'\n            +             '<body>'\n            +               '<div id=\"titlediv\"></div>'\n            +               '<div id=\"plotdiv\"></div>'\n            +             '</body>'\n            +           '</html>';\n        \n        plot.plot_window.document.writeln('<!DOCTYPE html>');\n        plot.plot_window.document.writeln(plothtml);\n        plot.plot_window.document.close();\n        \n        // Build GUI areas\n        var plotbody = plot.plot_window.document.getElementsByTagName(\"body\")[0];\n        plotbody.style.margin = \"0px\";\n        \n        // Title area\n        plot.titlearea = plot.plot_window.document.getElementById(\"titlediv\");\n        plot.titlearea.style.height = plot.titleheight + 'px';\n        plot.titlearea.style.marginTop = plot.margin + 'px';\n        \n        // Plot area\n        plot.plotdiv = \"plotdiv\";\n        plot.plotarea = plot.plot_window.document.getElementById(plot.plotdiv);\n        plot.plotarea.style.width = width + 'px';\n        plot.plotarea.style.height = height + 'px';\n        plot.plotarea.style.marginLeft = plot.margin + 'px';\n        plot.plotarea.style.marginRight = plot.margin + 'px';\n        plot.plotarea.style.marginBottom = plot.margin + 'px';\n        \n        // Store plot\n        plots.push(plot);\n\n        return plot;\n    };\n\n    var checkPoint = function(point) {\n        // Check that it is a two element sequence\n        if (!Sk.builtin.checkSequence(point) || point.sq$length() != 2) {\n            return false;\n        };\n\n        // Check that each element is a number\n        if (!Sk.builtin.checkNumber(point.mp$subscript(0)) || !Sk.builtin.checkNumber(point.mp$subscript(1))) {\n            return false;\n        };\n\n        return true;\n    };\n\n    var make_plot = function(title, width, height, xlabel, ylabel, data, points, fill, labels, plottype) {\n        var d = [];\n        var i, j;\n        var series, point;\n        var sdata, slabel, sobj;\n        var isseq;\n\n        var bar_width = 1 / (data.sq$length() + 1);\n\n        for (i = 0; i < data.sq$length(); i++) {\n            series = data.mp$subscript(i);                \n            if (Sk.builtin.checkSequence(series)) {\n                isseq = true;\n            } else if (Sk.builtin.checkDict(series)) {\n                isseq = false;\n            } else {\n                throw new Sk.builtin.TypeError(\"data must be a sequence of sequences of sequences or a sequence of dictionaries\");\n                // throw new Sk.builtin.TypeError(\"each data series must be a sequence or a dictionary\"); \n            };\n\n            sdata = [];\n            if (isseq) {\n                if (series.sq$length() < 1) {\n                    throw new Sk.builtin.TypeError(\"data must be a sequence of sequences of sequences or a sequence of dictionaries\");\n                };\n                for (j = 0; j < series.sq$length(); j++) {\n                    point = series.mp$subscript(j);\n                    if (!checkPoint(point)) {\n                        throw new Sk.builtin.TypeError(\"data must be a sequence of sequences of sequences or a sequence of dictionaries\");\n                        // throw new Sk.builtin.TypeError(\"each point must be a 2 element sequence\");\n                    };\n                    sdata.push([Sk.builtin.asnum$(point.mp$subscript(0)), \n                                Sk.builtin.asnum$(point.mp$subscript(1))]);\n                };\n            } else {\n                var it, k, v;\n                if (series.mp$length() < 1) \n                {\n                    throw new Sk.builtin.TypeError(\"data must be a sequence of sequences of sequences or a sequence of dictionaries\");\n                }\n                for (it = series.tp$iter(), k = it.tp$iternext();\n                     k !== undefined;\n                     k = it.tp$iternext())\n                {\n                    var v = series.mp$subscript(k);\n                    sdata.push([Sk.builtin.asnum$(k), \n                                Sk.builtin.asnum$(v)]);\n                }\n            };\n\n            sobj = {\n                data: sdata\n            };\n            if (plottype == \"bars\") {\n                sobj.bars = {\n                    show: true,\n                    fill: fill,\n                    barWidth: bar_width,\n                    order: i\n                };\n            }\n            else { // default to lines\n                sobj.lines = {\n                    show: true,\n                    fill: fill,\n                };\n                sobj.points = {\n                    show: points\n                };\n            }\n\n            if (labels !== undefined) {\n                slabel = new Sk.builtin.str(labels.mp$subscript(i));\n                sobj.label = Sk.ffi.unwrapo(slabel);\n            };\n            d.push(sobj);\n        };\n        \n        // Create plot window\n        var plot = create_plot(title, width, height);\n\n        var options = {\n            xaxis: {\n                axisLabel: Sk.ffi.unwrapo(xlabel),\n                axisLabelPadding: 4,\n\t\tcolor: 'black'\n            },\n            yaxis: {\n                axisLabel: Sk.ffi.unwrapo(ylabel),\n                axisLabelPadding: 4,\n\t\tcolor: 'black'\n            }\n        };\n\n        // Set title\n        plot.titlearea.innerHTML = \"<center><b>\" + Sk.ffi.unwrapo(title) + \"</center></b>\";\n\n        $.plot($('#plotdiv', plot.plot_window.document), d, options);\n\n        return Sk.builtin.none.none$;\n    };\n\n    mod.plot_lines = new Sk.builtin.func(function(title, width, height, xlabel, ylabel, data, points, labels) {\n        Sk.builtin.pyCheckArgs(\"plot_lines\", arguments, 6, 8);\n        if (!Sk.builtin.checkString(title)) {\n            throw new Sk.builtin.TypeError(\"title must be a string\");\n        };\n        if (!Sk.builtin.checkInt(width)) {\n            throw new Sk.builtin.TypeError(\"plot width must be an integer\");\n        };                \n        width = Sk.builtin.asnum$(width);\n        if (!Sk.builtin.checkInt(height)) {\n            throw new Sk.builtin.TypeError(\"plot height must be an integer\");\n        };                \n        height = Sk.builtin.asnum$(height);\n        if (!Sk.builtin.checkString(xlabel)) {\n            throw new Sk.builtin.TypeError(\"xlabel must be a string\");\n        };\n        if (!Sk.builtin.checkString(ylabel)) {\n            throw new Sk.builtin.TypeError(\"ylabel must be a string\");\n        };\n        if (!Sk.builtin.checkSequence(data)) {\n            throw new Sk.builtin.TypeError(\"data must be a sequence of sequences of sequences or a sequence of dictionaries\");\n        } else if (data.sq$length() < 1) {\n            throw new Sk.builtin.TypeError(\"data must be a sequence of sequences of sequences or a sequence of dictionaries\");           \n        };\n        if (points !== undefined) {\n            if (!Sk.builtin.checkBool(points)) {\n                throw new Sk.builtin.TypeError(\"points must be a boolean\");  \n            };  \n            // Convert to JavaScript true/false\n            points = points.v;\n        } else {\n            points = false;\n        };\n        if (labels !== undefined) {\n            if (!Sk.builtin.checkSequence(labels)) {\n                throw new Sk.builtin.TypeError(\"labels must be a sequence\");\n            };\n        };\n\n        if (width <= 0) {\n            throw new Sk.builtin.ValueError(\"plot width must be > 0\");\n        };\n\n        if (height <= 0) {\n            throw new Sk.builtin.ValueError(\"plot height must be > 0\");\n        };\n\n        return make_plot(title, width, height, xlabel, ylabel, data, points, false, labels, \"lines\");\n    });\n\n    mod.plot_bars = new Sk.builtin.func(function(title, width, height, xlabel, ylabel, data, labels) {\n        Sk.builtin.pyCheckArgs(\"plot_bars\", arguments, 6, 7);\n        if (!Sk.builtin.checkString(title)) {\n            throw new Sk.builtin.TypeError(\"title must be a string\");\n        };\n        if (!Sk.builtin.checkInt(width)) {\n            throw new Sk.builtin.TypeError(\"plot width must be an integer\");\n        };                \n        width = Sk.builtin.asnum$(width);\n        if (!Sk.builtin.checkInt(height)) {\n            throw new Sk.builtin.TypeError(\"plot height must be an integer\");\n        };                \n        height = Sk.builtin.asnum$(height);\n        if (!Sk.builtin.checkString(xlabel)) {\n            throw new Sk.builtin.TypeError(\"xlabel must be a string\");\n        };\n        if (!Sk.builtin.checkString(ylabel)) {\n            throw new Sk.builtin.TypeError(\"ylabel must be a string\");\n        };\n        if (!Sk.builtin.checkSequence(data)) {\n            throw new Sk.builtin.TypeError(\"data must be a sequence of sequences of sequences or a sequence of dictionaries\");\n        } else if (data.sq$length() < 1) {\n            throw new Sk.builtin.TypeError(\"data must be a sequence of sequences of sequences or a sequence of dictionaries\");           \n        };\n        if (labels !== undefined) {\n            if (!Sk.builtin.checkSequence(labels)) {\n                throw new Sk.builtin.TypeError(\"labels must be a sequence\");\n            };\n        };\n\n        if (width <= 0) {\n            throw new Sk.builtin.ValueError(\"plot width must be > 0\");\n        };\n\n        if (height <= 0) {\n            throw new Sk.builtin.ValueError(\"plot height must be > 0\");\n        };\n\n        return make_plot(title, width, height, xlabel, ylabel, data, false, true, labels, \"bars\");\n    });\n\n    return mod;\n};\n",
  		"src/lib/simplegui/__init__.js": "var $builtinmodule = function(name)\n{\n    var mod = {};\n\n    Sk.simplegui = {};\n\n    var timers = [];\n    var frames = [];\n    var sounds = [];\n\n    var fontfaces = {\n        'serif': true,\n        'sans-serif': true,\n        'monospace': true\n    };\n\n    // Cross-browser requestAnimationFrame\n    (function() {\n        var lastTime = 0;\n        var vendors = ['ms', 'moz', 'webkit', 'o'];\n        for(var x = 0; x < vendors.length && !window.requestAnimationFrame; ++x) {\n            window.requestAnimationFrame = window[vendors[x]+'RequestAnimationFrame'];\n            window.cancelAnimationFrame = \n                window[vendors[x]+'CancelAnimationFrame'] || window[vendors[x]+'CancelRequestAnimationFrame'];\n        }\n        \n        if (!window.requestAnimationFrame)\n            window.requestAnimationFrame = function(callback, element) {\n                var currTime = new Date().getTime();\n                var timeToCall = Math.max(0, 16 - (currTime - lastTime));\n                var id = window.setTimeout(function() { callback(currTime + timeToCall); }, \n                                           timeToCall);\n                lastTime = currTime + timeToCall;\n                return id;\n            };\n        \n        if (!window.cancelAnimationFrame)\n            window.cancelAnimationFrame = function(id) {\n                clearTimeout(id);\n            };\n    }());\n\n \n    Sk.simplegui.cleanup = function () {\n        // Cleanup the module - kill all timers, release all resources\n        for (var i = 0; i < timers.length; i++) {\n            // Stop the timer, if it's running\n            Sk.misceval.callsim(timers[i].stop, timers[i]);\n        };\n        timers = [];\n\n        for (var i = 0; i < sounds.length; i++) {\n            // Stop the sound, if it's playing\n            Sk.misceval.callsim(sounds[i].pause, sounds[i]);\n        };\n        sounds = [];\n\n        for (i=0; i < frames.length; i++) {\n            // Close the window, if it's open\n            Sk.misceval.callsim(frames[i].stop, frames[i]);\n        };\n        frames = [];\n    };\n\n    // goog.require(\"goog.events\");\n    // goog.require(\"goog.events.KeyCodes\");\n    // goog.require(\"goog.events.KeyHandler\");\n\n    // Images\n    var image = function($gbl, $loc) {\n        $loc.__init__ = new Sk.builtin.func(function(self, image_file) {\n            self.image = new Image();\n            self.image.src = Sk.ffi.unwrapo(image_file);\n            self.__class__ = mod.Image;\n        });\n\n        // $loc.wait = new Sk.builtin.func(function(self) {\n        // });\n\n        $loc.get_width = new Sk.builtin.func(function(self) {\n            Sk.builtin.pyCheckArgs(\"get_width\", arguments, 1, 1);\n\n            return Sk.builtin.assk$(self.image.width, Sk.builtin.nmber.int$);\n        });\n\n        $loc.get_height = new Sk.builtin.func(function(self) {\n            Sk.builtin.pyCheckArgs(\"get_height\", arguments, 1, 1);\n\n            return Sk.builtin.assk$(self.image.height, Sk.builtin.nmber.int$);\n        });\n    };\n\n    mod.Image = Sk.misceval.buildClass(mod, image, 'Image', []);\n\n    mod.load_image = new Sk.builtin.func(function(image_file) {\n        Sk.builtin.pyCheckArgs(\"load_image\", arguments, 1, 1);\n        if (!Sk.builtin.checkString(image_file)) {\n            throw new Sk.builtin.TypeError(\"expected string\");\n        };\n\n        return Sk.misceval.callsim(mod.Image, image_file);\n    });\n\n    // Sounds\n    var sound = function($gbl, $loc) {\n        $loc.__init__ = new Sk.builtin.func(function(self, sound_file) {\n            if (Sk.builtin.checkString(sound_file)) {\n                sound_file = Sk.ffi.unwrapo(sound_file);\n            }\n\n            self.sound = new Audio(sound_file);\n            self.__class__ = mod.Sound;\n\n            // Store sound\n            sounds.push(self);\n        });\n\n        $loc.set_volume = new Sk.builtin.func(function (self, vol) {\n            Sk.builtin.pyCheckArgs(\"set_volume\", arguments, 2, 2);\n            if (!Sk.builtin.checkNumber(vol)) {\n                throw new Sk.builtin.TypeError(\"Volume must be a number\");\n            };\n            vol = Sk.builtin.asnum$(vol);\n\n            if ((vol >= 0) && (vol <= 1)) {\n                self.sound.volume = vol;                \n            } else {\n                throw new Sk.builtin.ValueError(\"Volume must be between 0 and 1\");\n            };\n\n            return Sk.builtin.none.none$;\n        });\n\n        // $loc.wait = new Sk.builtin.func(function(self) {\n        // });\n\n        $loc.play = new Sk.builtin.func(function(self) {\n            Sk.builtin.pyCheckArgs(\"play\", arguments, 1, 1);\n\n            self.sound.play();\n\n            return Sk.builtin.none.none$;\n        });\n\n        $loc.pause = new Sk.builtin.func(function(self) {\n            Sk.builtin.pyCheckArgs(\"pause\", arguments, 1, 1);\n\n            self.sound.pause();\n\n            return Sk.builtin.none.none$;\n        });\n\n        $loc.rewind = new Sk.builtin.func(function(self) {\n            Sk.builtin.pyCheckArgs(\"rewind\", arguments, 1, 1);\n\n            self.sound.pause();\n            if (self.sound.currentTime) {\n                self.sound.currentTime = 0;                \n            };\n\n            return Sk.builtin.none.none$;\n        });\n    };\n\n    mod.Sound = Sk.misceval.buildClass(mod, sound, 'Sound', []);\n\n    mod.load_sound = new Sk.builtin.func(function(sound_file) {\n        Sk.builtin.pyCheckArgs(\"load_image\", arguments, 1, 1);\n        if (!Sk.builtin.checkString(sound_file)) {\n            throw new Sk.builtin.TypeError(\"expected string\");\n        };\n\n        return Sk.misceval.callsim(mod.Sound, sound_file);\n    });\n\n    function base64_encode (data) {\n        // http://kevin.vanzonneveld.net\n        // +   original by: Tyler Akins (http://rumkin.com)\n        // +   improved by: Bayron Guevara\n        // +   improved by: Thunder.m\n        // +   improved by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)\n        // +   bugfixed by: Pellentesque Malesuada\n        // +   improved by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)\n        // +   improved by: Rafa\u0142 Kukawski (http://kukawski.pl)\n        // *     example 1: base64_encode('Kevin van Zonneveld');\n        // *     returns 1: 'S2V2aW4gdmFuIFpvbm5ldmVsZA=='\n        // mozilla has this native\n        // - but breaks in 2.0.0.12!\n        //if (typeof this.window['btoa'] == 'function') {\n        //    return btoa(data);\n        //}\n        var b64 = \"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=\";\n        var o1, o2, o3, h1, h2, h3, h4, bits, i = 0,\n        ac = 0,\n        enc = \"\",\n        tmp_arr = [];\n        \n        if (!data) {\n            return data;\n        }\n        \n        do { // pack three octets into four hexets\n            o1 = data[i++];\n            o2 = data[i++];\n            o3 = data[i++];\n            \n            bits = o1 << 16 | o2 << 8 | o3;\n            \n            h1 = bits >> 18 & 0x3f;\n            h2 = bits >> 12 & 0x3f;\n            h3 = bits >> 6 & 0x3f;\n            h4 = bits & 0x3f;\n            \n            // use hexets to index into b64, and append result to encoded string\n            tmp_arr[ac++] = b64.charAt(h1) + b64.charAt(h2) + b64.charAt(h3) + b64.charAt(h4);\n        } while (i < data.length);\n        \n        enc = tmp_arr.join('');\n        \n        var r = data.length % 3;\n        \n        return (r ? enc.slice(0, r - 3) : enc) + '==='.slice(r || 3);   \n    };\n\n    mod.create_sound = new Sk.builtin.func(function(sound_data, sample_rate, num_channels) {\n        Sk.builtin.pyCheckArgs(\"create_sound\", arguments, 1, 3);\n        if (!Sk.builtin.checkSequence(sound_data)) {\n            throw new Sk.builtin.TypeError(\"sound_data must be a sequence\");\n        }\n        if (sample_rate !== undefined) {\n            if (!Sk.builtin.checkInt(sample_rate)) {\n                throw new Sk.builtin.TypeError(\"sample_rate must be an integer\");\n            }\n            sample_rate = Sk.builtin.asnum$(sample_rate);\n        }\n        else {\n            sample_rate = 8000;\n        }\n        if (num_channels !== undefined) {\n            if (!Sk.builtin.checkInt(num_channels)) {\n                throw new Sk.builtin.TypeError(\"num_channels must be an integer\");\n            }\n            num_channels = Sk.builtin.asnum$(num_channels);\n        }\n        else {\n            num_channels = 1;\n        }\n\n        function getByte(num, b) {\n            return (num >> (b*8)) & 0xff;\n        }\n\n        var bitsPerSample = 8;\n        var blockAlign = (num_channels * bitsPerSample) / 8;\n        var byteRate = sample_rate * blockAlign;\n        var numSamples = sound_data.sq$length() / num_channels;\n        var subchunk2size = numSamples * blockAlign;\n        var chunksize = 36 + subchunk2size;\n\n        // Header\n        var data = [\n            0x52, 0x49, 0x46, 0x46,  // ChunkID: \"RIFF\"\n            getByte(chunksize, 0),\n            getByte(chunksize, 1),\n            getByte(chunksize, 2),\n            getByte(chunksize, 3),   // ChunkSize: 36 + SubChunk2Size\n            0x57, 0x41, 0x56, 0x45,  // Format: \"WAVE\"\n            0x66, 0x6d, 0x74, 0x20,  // Subchunk1ID: \"fmt \"\n            0x10, 0x00, 0x00, 0x00,  // Subchunk1Size: 16\n            0x01, 0x00,              // AudioFormat: 1 (PCM)\n            getByte(num_channels, 0), \n            getByte(num_channels, 1), // NumChannels\n            getByte(sample_rate, 0),\n            getByte(sample_rate, 1),\n            getByte(sample_rate, 2),\n            getByte(sample_rate, 3), // SampleRate\n            getByte(byteRate, 0),\n            getByte(byteRate, 1),\n            getByte(byteRate, 2),\n            getByte(byteRate, 3),    // ByteRate\n            getByte(blockAlign, 0),\n            getByte(blockAlign, 1),  // BlockAlign\n            getByte(bitsPerSample, 0),\n            getByte(bitsPerSample, 1), // BitsPerSample\n            0x64, 0x61, 0x74, 0x61,   // Subchunk2ID: \"data\"\n            getByte(subchunk2size, 0), \n            getByte(subchunk2size, 1), \n            getByte(subchunk2size, 2), \n            getByte(subchunk2size, 3) // Subchunk2Size\n        ];\n\n        var it = sound_data.tp$iter();\n        var i;\n        for (i = it.tp$iternext(); i !== undefined; i = it.tp$iternext()) {\n            if (!Sk.builtin.checkInt(i)) {\n                throw new Sk.builtin.ValueError(\"sound data must be 8-bit integers\");\n            }\n            i = Sk.builtin.asnum$(i);\n            if (i < 0 || i > 255) {\n                throw new Sk.builtin.ValueError(\"sound data must be 8-bit integers\");\n            }\n            data.push(i);\n        }\n\n        var dataURI = \"data:audio/wav;base64,\" + base64_encode(data);\n\n        return Sk.misceval.callsim(mod.Sound, dataURI);\n    });\n\n    var truncate = function(number) {\n        return Math[number < 0 ? 'ceil' : 'floor'](number);\n    };\n\n    var checkPoint = function(point) {\n        // Check that it is a two element sequence\n        if (!Sk.builtin.checkSequence(point) || point.sq$length() != 2) {\n            return false;\n        };\n\n        // Check that each element is a number\n        if (!Sk.builtin.checkNumber(point.mp$subscript(0)) || !Sk.builtin.checkNumber(point.mp$subscript(1))) {\n            return false;\n        };\n\n        return true;\n    };\n\n    // Find non-printing characters\n    var textRE = /[^\\040-\\176]/;\n\n    // Python canvas class\n    var canvas = function($gbl, $loc) {\n        $loc.__init__ = new Sk.builtin.func(function(self, canvas) {\n            self.canvas = canvas;\n            self.context = self.canvas.getContext('2d');\n            if (!self.context || !self.context.drawImage) {\n                alert(\"Cannot draw on canvas!\");\n                return;\n            };\n            self.__class__ = mod.Canvas;\n        });\n\n        $loc.draw_text = new Sk.builtin.func(function(self, text, point, size, color, face) {\n            Sk.builtin.pyCheckArgs(\"draw_text\", arguments, 5, 6);\n            if (!Sk.builtin.checkString(text)) {\n                throw new Sk.builtin.TypeError(\"text must be a string\");\n            };\n            if (!checkPoint(point)) {\n                throw new Sk.builtin.TypeError(\"point must be a 2 element sequence\");\n            };\n            if (!Sk.builtin.checkNumber(size)) {\n                throw new Sk.builtin.TypeError(\"size must be a number\");\n            };\n            size = Sk.builtin.asnum$(size);\n            if (!Sk.builtin.checkString(color)) {\n                throw new Sk.builtin.TypeError(\"color must be a string\");\n            };\n            if (face !== undefined) {\n                if (!Sk.builtin.checkString(face)) {\n                    throw new Sk.builtin.TypeError(\"font face must be a string\");\n                };                \n                face = Sk.ffi.unwrapo(face);\n                // check if face is valid\n                if (fontfaces[face] !== true) {\n                     throw new Sk.builtin.ValueError(\"'\" + face + \"' is not a valid font face\");\n                };\n            } else {\n                // Default value: serif\n                face = \"serif\";\n            };\n\n            self.context.font = size + \"px \" + face;\n            self.context.fillStyle = Sk.ffi.unwrapo(color);\n            text = Sk.ffi.unwrapo(text);\n\n            // Disallow non-printing characters\n            if (textRE.test(text)) {\n                throw new Sk.builtin.ValueError(\"text may not contain non-printing characters\");\n            };\n\n            self.context.fillText(text, \n                                  Sk.builtin.asnum$(point.mp$subscript(0)), \n                                  Sk.builtin.asnum$(point.mp$subscript(1)));\n\n            return Sk.builtin.none.none$;\n        });\n\n        $loc.draw_point = new Sk.builtin.func(function(self, point, color) {\n            Sk.builtin.pyCheckArgs(\"draw_point\", arguments, 3, 3);\n            if (!checkPoint(point)) {\n                throw new Sk.builtin.TypeError(\"point must be a 2 element sequence\");\n            };\n            if (!Sk.builtin.checkString(color)) {\n                throw new Sk.builtin.TypeError(\"color must be a string\");\n            };\n\n            self.context.fillStyle = Sk.ffi.unwrapo(color);\n            self.context.fillRect(Sk.builtin.asnum$(point.mp$subscript(0)), \n                                  Sk.builtin.asnum$(point.mp$subscript(1)), 1, 1);\n\n            return Sk.builtin.none.none$;\n        });\n\n        $loc.draw_line = new Sk.builtin.func(function(self, pt1, pt2, width, color) {\n            Sk.builtin.pyCheckArgs(\"draw_line\", arguments, 5, 5);\n            if (!checkPoint(pt1)) {\n                throw new Sk.builtin.TypeError(\"point1 must be a 2 element sequence\");\n            };\n            if (!checkPoint(pt2)) {\n                throw new Sk.builtin.TypeError(\"point2 must be a 2 element sequence\");\n            };\n            if (!Sk.builtin.checkNumber(width)) {\n                throw new Sk.builtin.TypeError(\"width must be a number\");\n            } \n            width = Sk.builtin.asnum$(width);\n            if (width <= 0) {\n                throw new Sk.builtin.ValueError(\"width must be a positive number\");\n            };\n            if (!Sk.builtin.checkString(color)) {\n                throw new Sk.builtin.TypeError(\"color must be a string\");\n            };\n\n            self.context.lineWidth = width;\n            self.context.strokeStyle = Sk.ffi.unwrapo(color);\n            self.context.beginPath();\n            self.context.moveTo(Sk.builtin.asnum$(pt1.mp$subscript(0)), \n                                Sk.builtin.asnum$(pt1.mp$subscript(1)));\n            self.context.lineTo(Sk.builtin.asnum$(pt2.mp$subscript(0)), \n                                Sk.builtin.asnum$(pt2.mp$subscript(1)));\n            self.context.stroke();\n\n            return Sk.builtin.none.none$;\n        });\n\n        $loc.draw_circle = new Sk.builtin.func(function(self, center, radius, linewidth, linecolor, fillcolor) {\n            Sk.builtin.pyCheckArgs(\"draw_circle\", arguments, 5, 6);\n            if (!checkPoint(center)) {\n                throw new Sk.builtin.TypeError(\"center must be a 2 element sequence\");\n            };\n            if (!Sk.builtin.checkNumber(radius)) {\n                throw new Sk.builtin.TypeError(\"radius must be a number\");\n            };\n            radius = Sk.builtin.asnum$(radius);\n            if (radius <= 0) {\n                throw new Sk.builtin.ValueError(\"radius must be a positive number\");                \n            };\n            if (!Sk.builtin.checkNumber(linewidth)) {\n                throw new Sk.builtin.TypeError(\"linewidth must be a number\");\n            };\n            linewidth = Sk.builtin.asnum$(linewidth);\n            if (linewidth <= 0) {\n                throw new Sk.builtin.ValueError(\"linewidth must be a positive number\");\n            };\n            if (!Sk.builtin.checkString(linecolor)) {\n                throw new Sk.builtin.TypeError(\"linecolor must be a string\");\n            };\n\n            // Check if fillcolor was specified and it is not None\n            if ((fillcolor !== undefined) && (fillcolor !== Sk.builtin.none.none$)) {\n                if (!Sk.builtin.checkString(fillcolor)) {\n                    throw new Sk.builtin.TypeError(\"fillcolor must be a string\");\n                };                \n            } else {\n                // Default value: no fill - fillcolor is None\n                fillcolor = Sk.builtin.none.none$;\n            };\n\n            self.context.lineWidth = linewidth;\n            self.context.strokeStyle = Sk.ffi.unwrapo(linecolor);\n            if (fillcolor !== Sk.builtin.none.none$) {\n                self.context.fillStyle = Sk.ffi.unwrapo(fillcolor);\n            };\n            self.context.beginPath();\n            self.context.arc(Sk.builtin.asnum$(center.mp$subscript(0)), \n                             Sk.builtin.asnum$(center.mp$subscript(1)),\n                             radius, 0, 2 * Math.PI, false);\n            if (fillcolor !== Sk.builtin.none.none$) {\n                self.context.fill();\n            };\n            self.context.stroke();\n\n            return Sk.builtin.none.none$;\n        });\n\n        $loc.draw_polyline = new Sk.builtin.func(function(self, points, width, color) {\n            Sk.builtin.pyCheckArgs(\"draw_polyline\", arguments, 4, 4);\n            if (!Sk.builtin.checkSequence(points)) {\n                throw new Sk.builtin.TypeError(\"points must be a sequence\");\n            };\n            if (!Sk.builtin.checkNumber(width)) {\n                throw new Sk.builtin.TypeError(\"width must be a number\");\n            };\n            width = Sk.builtin.asnum$(width);\n            if (width <= 0) {\n                throw new Sk.builtin.ValueError(\"width must be a positive number\");\n            };\n            if (!Sk.builtin.checkString(color)) {\n                throw new Sk.builtin.TypeError(\"color must be a string\");\n            };\n\n            self.context.lineWidth = width;\n            self.context.strokeStyle = Sk.ffi.unwrapo(color);\n            self.context.beginPath();\n            var point = points.mp$subscript(0);\n            if (!checkPoint(point)) {\n                throw new Sk.builtin.TypeError(\"each point in points must be a 2 element sequence\");\n            };\n            self.context.moveTo(Sk.builtin.asnum$(point.mp$subscript(0)), \n                                Sk.builtin.asnum$(point.mp$subscript(1)));\n            for (i=1; i<points.sq$length(); i++) {\n                point = points.mp$subscript(i);\n                if (!checkPoint(point)) {\n                    throw new Sk.builtin.TypeError(\"each point in points must be a 2 element sequence\");\n                };\n                self.context.lineTo(Sk.builtin.asnum$(point.mp$subscript(0)), \n                                    Sk.builtin.asnum$(point.mp$subscript(1)));\n            }\n            self.context.stroke();\n\n            return Sk.builtin.none.none$;\n        });\n\n        $loc.draw_polygon = new Sk.builtin.func(function(self, points, linewidth, linecolor, fillcolor) {\n            Sk.builtin.pyCheckArgs(\"draw_polygon\", arguments, 4, 5);\n            if (!Sk.builtin.checkSequence(points)) {\n                throw new Sk.builtin.TypeError(\"points must be a sequence\");\n            };\n            if (!Sk.builtin.checkNumber(linewidth)) {\n                throw new Sk.builtin.TypeError(\"linewidth must be a number\");\n            };\n            linewidth = Sk.builtin.asnum$(linewidth);\n            if (linewidth <= 0) {\n                throw new Sk.builtin.ValueError(\"linewidth must be a positive number\");\n            };\n            if (!Sk.builtin.checkString(linecolor)) {\n                throw new Sk.builtin.TypeError(\"linecolor must be a string\");\n            };\n\n            // Check if fillcolor was specified and it is not None\n            if ((fillcolor !== undefined) && (fillcolor !== Sk.builtin.none.none$)) {\n                if (!Sk.builtin.checkString(fillcolor)) {\n                    throw new Sk.builtin.TypeError(\"fillcolor must be a string\");\n                };                \n            } else {\n                // Default value: no fill - fillcolor is None\n                fillcolor = Sk.builtin.none.none$;\n            };\n\n            self.context.lineWidth = linewidth;\n            self.context.strokeStyle = Sk.ffi.unwrapo(linecolor);\n            if (fillcolor !== Sk.builtin.none.none$) {\n                self.context.fillStyle = Sk.ffi.unwrapo(fillcolor);\n            };\n            self.context.beginPath();\n            var point = points.mp$subscript(0);\n            var point0x = Sk.builtin.asnum$(point.mp$subscript(0));\n            var point0y = Sk.builtin.asnum$(point.mp$subscript(1));\n            if (!checkPoint(point)) {\n                throw new Sk.builtin.TypeError(\"each point in points must be a 2 element sequence\");\n            };\n            self.context.moveTo(point0x, point0y);\n            for (i=1; i<points.sq$length(); i++) {\n                point = points.mp$subscript(i);\n                if (!checkPoint(point)) {\n                    throw new Sk.builtin.TypeError(\"each point in points must be a 2 element sequence\");\n                };\n               self.context.lineTo(Sk.builtin.asnum$(point.mp$subscript(0)), \n                                    Sk.builtin.asnum$(point.mp$subscript(1)));\n            }\n            self.context.lineTo(point0x, point0y);\n            self.context.closePath();\n            if (fillcolor !== Sk.builtin.none.none$) {\n                self.context.fill();\n            };\n            self.context.stroke();\n\n            return Sk.builtin.none.none$;\n        });\n\n        $loc.draw_image = new Sk.builtin.func(function(self, image, srcpos, \n                                                       srcdim, dstpos, dstdim,\n                                                       rot) {\n            Sk.builtin.pyCheckArgs(\"draw_image\", arguments, 6, 7);\n            var im = null;\n            if ((image !== null) && (image.__class__ == mod.Image)) {\n                im = image.image;\n            }\n            else if ((image !== null) && (image.__class__ == mod.Canvas)) {\n                im = image.canvas;\n            }\n            else {\n                throw new Sk.builtin.TypeError(\"image must be an image\");\n            };\n            if (!checkPoint(srcpos)) {\n                throw new Sk.builtin.TypeError(\"source center must be a 2 element sequence\");\n            };\n            if (!checkPoint(srcdim)) {\n                throw new Sk.builtin.TypeError(\"source dimensions must be a 2 element sequence\");\n            };\n            if (!checkPoint(dstpos)) {\n                throw new Sk.builtin.TypeError(\"destination center must be a 2 element sequence\");\n            };\n            if (!checkPoint(dstdim)) {\n                throw new Sk.builtin.TypeError(\"destination dimensions must be a 2 element sequence\");\n            };\n            if (rot !== undefined) {\n                if (!Sk.builtin.checkNumber(rot)) {\n                    throw new Sk.builtin.TypeError(\"rotation must be a number\");\n                };                \n            };\n\n            var srcx = Sk.builtin.asnum$(srcpos.mp$subscript(0));\n            var srcy = Sk.builtin.asnum$(srcpos.mp$subscript(1));\n            var srcw = Sk.builtin.asnum$(srcdim.mp$subscript(0));\n            var srch = Sk.builtin.asnum$(srcdim.mp$subscript(1));\n            var dstx = Sk.builtin.asnum$(dstpos.mp$subscript(0));\n            var dsty = Sk.builtin.asnum$(dstpos.mp$subscript(1));\n            var dstw = Sk.builtin.asnum$(dstdim.mp$subscript(0));\n            var dsth = Sk.builtin.asnum$(dstdim.mp$subscript(1));\n\n            if (rot === undefined) {\n                rot = 0;\n            };\n            rot = Sk.builtin.asnum$(rot);\n\n            if ((srcw <= 0) || (srch <= 0) || (dstw <= 0) || (dsth <=0)) {\n                throw new Sk.builtin.ValueError(\"image dimensions must be > 0\");\n            };\n\n            srcx = truncate(srcx - srcw / 2);\n            srcy = truncate(srcy - srch / 2);\n            var dstoffx = truncate(- dstw / 2);\n            var dstoffy = truncate(- dsth / 2);\n\n            if ((srcx < 0) || (srcy < 0)) {\n                // Do not draw anything\n                return;\n            };\n            \n            if ((srcx + srcw > im.width) \n                || (srcy + srch > im.height)) {\n                // Safari: Do not draw anything\n                return;\n            };\n\n            self.context.save();\n            self.context.translate(dstx, dsty);\n            self.context.rotate(rot);\n            self.context.drawImage(im, \n                                   srcx, srcy, srcw, srch,\n                                   dstoffx, dstoffy, dstw, dsth);\n            self.context.restore();\n\n            return Sk.builtin.none.none$;\n        });\n    };\n\n    mod.Canvas = Sk.misceval.buildClass(mod, canvas, 'Canvas', []);\n\n    var create_canvas = function(win, width, height, border) {\n        var canvas = win.document.createElement(\"canvas\");\n\n        canvas.width = width;\n        canvas.height = height;\n        canvas.style.border = border.toString() + 'px solid black';\n        canvas.style.cssFloat = \"right\";\n        canvas.setAttribute('tabindex', '0');\n        canvas.onselectstart = function () {\n            // Prevent weird selection on double click\n            return false;\n        };\n\n        return canvas;\n    };\n\n    mod.create_invisible_canvas = new Sk.builtin.func(function(width, height) {\n        Sk.builtin.pyCheckArgs(\"create_invis_canvas\", arguments, 2, 2);\n        if (!Sk.builtin.checkInt(width)) {\n            throw new Sk.builtin.TypeError(\"width must be an integer\");\n        }\n        if (!Sk.builtin.checkInt(height)) {\n            throw new Sk.builtin.TypeError(\"height must be an integer\");\n        }\n\n        var canvas = create_canvas(window, Sk.builtin.asnum$(width), Sk.builtin.asnum$(height), 0);\n        var pycanvas = Sk.misceval.callsim(mod.Canvas, canvas);\n        return pycanvas;\n    });\n\n    // Control class\n    var control = function($gbl, $loc) {\n        $loc.__init__ = new Sk.builtin.func(function(self, object) {\n            self._object = object;\n        });\n\n        $loc.get_text = new Sk.builtin.func(function(self) {\n            Sk.builtin.pyCheckArgs(\"get_text\", arguments, 1, 1);\n            return Sk.ffi.basicwrap(self._object.textContent);\n        });\n\n        $loc.set_text = new Sk.builtin.func(function(self, text) {\n            Sk.builtin.pyCheckArgs(\"set_text\", arguments, 2, 2);\n\t    var s = new Sk.builtin.str(text);\n            self._object.textContent = Sk.ffi.unwrapo(s);\n        });\n    };\n\n    mod.Control = Sk.misceval.buildClass(mod, control, 'Control', []);\n\n    // Text Area Control class\n    var textareacontrol = function($gbl, $loc) {\n        $loc.__init__ = new Sk.builtin.func(function(self, object) {\n            self._object = object;\n        });\n\n        $loc.get_text = new Sk.builtin.func(function(self) {\n            Sk.builtin.pyCheckArgs(\"get_text\", arguments, 1, 1);\n            return Sk.ffi.basicwrap(self._object.value);\n        });\n\n        $loc.set_text = new Sk.builtin.func(function(self, text) {\n            Sk.builtin.pyCheckArgs(\"set_text\", arguments, 2, 2);\n\t    var s = new Sk.builtin.str(text);\n            self._object.value = Sk.ffi.unwrapo(s);\n        });\n    };\n\n    mod.TextAreaControl = Sk.misceval.buildClass(mod, textareacontrol, 'TextAreaControl', []);\n\n    var statusBox = function(text, offset, width) {\n        var box = document.createElement(\"div\");\n        box.textContent = text;\n        box.style.width = (width-12) + \"px\";\n        box.style.position = \"absolute\";\n        box.style.bottom = offset + \"px\";\n        box.style.border = \"1px solid black\";\n        box.style.paddingLeft = \"5px\";\n        box.style.paddingRight = \"5px\";\n        return box;\n    };\n\n    var canvasCoords = function(canvas, evt) {\n        // Get canvas position\n        var curr = canvas;\n        var top = 0;\n        var left = 0;\n        while (curr && curr.tagName != 'BODY') {\n            top  += curr.offsetTop;\n            left += curr.offsetLeft;\n            curr = curr.offsetParent;\n        }\n\n        // Return relative mouse position\n        return {\n            x: evt.pageX - left,\n            y: evt.pageY - top\n        };                \n    };\n\n    // Key map\n    mod.KEY_MAP = Sk.builtin.dict([]);\n    var i;\n    var code2key = {};\n\n    // Add letters\n    for (i=65; i<=90; i++) {\n        // Lowercase\n        var ch = String.fromCharCode(i+32);\n        mod.KEY_MAP.mp$ass_subscript(Sk.ffi.basicwrap(ch), \n                                     Sk.builtin.assk$(i, Sk.builtin.nmber.int$));\n        code2key[i] = ch;\n\n        // Uppercase\n        ch = String.fromCharCode(i);        \n        mod.KEY_MAP.mp$ass_subscript(Sk.ffi.basicwrap(ch),\n                                     Sk.builtin.assk$(i, Sk.builtin.nmber.int$));\n    };\n    // Add numbers\n    for (i=48; i<=57; i++) {\n        var ch = String.fromCharCode(i);\n        mod.KEY_MAP.mp$ass_subscript(Sk.ffi.basicwrap(ch),\n                                     Sk.builtin.assk$(i, Sk.builtin.nmber.int$));\n        code2key[i] = ch;\n    };\n    // Add space\n    mod.KEY_MAP.mp$ass_subscript(Sk.ffi.basicwrap(\"space\"), \n                                 Sk.builtin.assk$(32, Sk.builtin.nmber.int$));\n    code2key[32] = \"space\";\n    // Add arrows\n    mod.KEY_MAP.mp$ass_subscript(Sk.ffi.basicwrap(\"left\"),\n                                 Sk.builtin.assk$(37, Sk.builtin.nmber.int$));\n    mod.KEY_MAP.mp$ass_subscript(Sk.ffi.basicwrap(\"up\"),\n                                 Sk.builtin.assk$(38, Sk.builtin.nmber.int$));\n    mod.KEY_MAP.mp$ass_subscript(Sk.ffi.basicwrap(\"right\"), \n                                 Sk.builtin.assk$(39, Sk.builtin.nmber.int$));\n    mod.KEY_MAP.mp$ass_subscript(Sk.ffi.basicwrap(\"down\"), \n                                 Sk.builtin.assk$(40, Sk.builtin.nmber.int$));\n    code2key[37] = String.fromCharCode(0x2190); // \"left\";\n    code2key[38] = String.fromCharCode(0x2191); // \"up\";  \n    code2key[39] = String.fromCharCode(0x2192); // \"right\";\n    code2key[40] = String.fromCharCode(0x2193); // \"down\";\n    \n    // Python frame class\n    var frame = function($gbl, $loc) {\n        $loc.__init__ = new Sk.builtin.func(function(self, title, \n                                                     canvas_width, \n                                                     canvas_height, \n                                                     control_width) {\n            var framediv;\n\n            // Save parameters\n            self.title = title;\n            self.width = Sk.builtin.asnum$(canvas_width);\n            self.height = Sk.builtin.asnum$(canvas_height);\n            if (control_width === undefined) {\n                control_width = 200;\n            } else {\n                control_width = Sk.builtin.asnum$(control_width);\n            }\n            self.ctrlWidth = control_width;\n            self.margin = 23;\n\n            // Initial defaults\n            self.draw_handler = new Sk.builtin.func(function(canvas) {});\n            self.background = \"#000000\";\n\n            // Create frame window\n            var winwidth = self.width + self.ctrlWidth + (self.margin*3) + 4;\n            var winheight = self.height + (self.margin*2) + 4;\n            self.frame_window = window.open('','myframe',\n                                            'width='+winwidth\n                                            +',height='+winheight\n                                            +',location=0'\n                                            +',menubar=0'\n                                            +',toolbar=0'\n                                            +',directories=0'\n                                            +',status=0'\n                                            +',titlebar=0'\n                                            +',scrollbars=0'\n                                            +',resizeable=1');\n\n            // Build empty document\n\n            // Escape title\n            var jstitle = Sk.ffi.unwrapo(title);\n            jstitle = jstitle.replace(/&/g,'&amp;');\n            jstitle = jstitle.replace(/</g,'&lt;');\n            jstitle = jstitle.replace(/>/g,'&gt;');\n\n            var framehtml = '<html>'\n                +             '<head>'\n                +               '<title>'\n                +                 jstitle\n                +               '</title>'\n                +             '</head>'\n                +             '<body>'\n                +               '<div id=\"guiframe\"></div>'\n                +             '</body>'\n                +           '</html>';\n\n            self.frame_window.document.writeln('<!DOCTYPE html>');\n            self.frame_window.document.writeln(framehtml);\n            self.frame_window.document.close();\n\n            // Build GUI areas\n            var framebody = self.frame_window.document.getElementsByTagName(\"body\")[0];\n            framebody.style.margin = \"0px\";\n            \n            // Control Pane\n            self.control = self.frame_window.document.createElement(\"div\");\n            // +4 to match 2px border around canvas\n            self.control.style.height = (self.height+4) + 'px';\n            self.control.style.width = self.ctrlWidth + 'px';\n            self.control.style.position = \"relative\";\n            self.control.style.cssFloat = \"left\";\n\n            // Drawing Canvas\n            self.canvas_border = 2;\n            self.canvas = create_canvas(self.frame_window, self.width, self.height, self.canvas_border);\n\n            self.animationID = null;\n\n            // Key state\n            self.keydown = {};\n            self.keyuphandler = null;\n            self.keydownhandler = null;\n\n            self.canvas.onkeydown = function(evt) {\n                if (!self.keydown[evt.keyCode]) {\n                    self.keydown[evt.keyCode] = true;\n                    if (self.keydownhandler) {\n                        var key = code2key[evt.keyCode];\n                        if (key === undefined) {\n                            key = \"<\" + evt.keyCode + \">\";\n                        }\n                        self.keyevents.textContent = \"Key: Down \" + key;\n                        try {\n                            Sk.setExecStartNow(true);\n                            Sk.currLineNo = self.keydown_lineno;\n                            Sk.misceval.callsim(self.keydownhandler, \n                                                Sk.builtin.assk$(evt.keyCode, Sk.builtin.nmber.int$));\n                        } catch (e) {\n                            Sk.error(e);\n                            Sk.simplegui.cleanup();\n                        };\n                    };\n                };\n            };\n            self.canvas.onkeyup = function(evt) {\n                self.keydown[evt.keyCode] = false;\n                if (self.keyuphandler) {\n                    var key = code2key[evt.keyCode];\n                    if (key === undefined) {\n                        key = \"<\" + evt.keyCode + \">\";\n                    }\n                    self.keyevents.textContent = \"Key: Up \" + key;\n                    try {\n                        Sk.setExecStartNow(true);\n                        Sk.currLineNo = self.keyup_lineno;\n                        Sk.misceval.callsim(self.keyuphandler,\n                                            Sk.builtin.assk$(evt.keyCode, Sk.builtin.nmber.int$));\n                    } catch (e) {\n                        Sk.error(e);\n                        Sk.simplegui.cleanup();\n                    };\n                };\n            };\n\n            // Mouse\n            self.mousedraghandler = null;\n\n            var mousemove = function (evt) {\n                var coords = canvasCoords(self.canvas, evt);\n                // Adjust position to remove border\n                var x = coords.x - self.canvas_border;\n                var y = coords.y - self.canvas_border;\n                if ((x < 0) || (x >= self.width)\n                    || (y < 0) || (y >= self.height)) {                    \n                    // move was in border\n                    return;\n                };\n                var pos = new Sk.builtins['tuple']([Sk.builtin.assk$(x, Sk.builtin.nmber.int$), \n                                                    Sk.builtin.assk$(y, Sk.builtin.nmber.int$)]);\n                self.mouseevents.textContent = \"Mouse: Move - \" + x + \", \" + y;\n                try {\n                    Sk.setExecStartNow(true);\n                    Sk.currLineNo = self.mousedrag_lineno;\n                    Sk.misceval.callsim(self.mousedraghandler, pos);\n                } catch (e) {\n                    Sk.error(e);\n                    Sk.simplegui.cleanup();\n                };\n            };\n\n            var mousedone = function (evt) {\n                self.canvas.removeEventListener(\"mousemove\", mousemove);\n                self.canvas.removeEventListener(\"mouseup\", mousedone);\n                self.canvas.removeEventListener(\"mouseout\", mousedone);\n            };\n\n            self.canvas.onmousedown = function(evt) {\n                if (self.mousedraghandler) {\n                    self.canvas.addEventListener(\"mousemove\", mousemove);\n                    self.canvas.addEventListener(\"mouseup\", mousedone);\n                    self.canvas.addEventListener(\"mouseout\", mousedone);\n                };\n            };\n\n            // Add elements to frame\n            framediv = self.frame_window.document.getElementById(\"guiframe\");\n            framediv.style.width = (self.width + self.ctrlWidth + self.margin + 4) + \"px\";\n            framediv.style.height = (self.height+4) + \"px\";\n            framediv.style.margin = self.margin + \"px\";\n            // framediv.style.overflow = \"auto\";\n            framediv.appendChild(self.control);\n            framediv.appendChild(self.canvas);\n\n            // These need to be added after the control area is on the page\n            // Otherwise, the mouse event box's height cannot be determined\n            self.mouseevents = statusBox(\"Mouse:\", 0, self.ctrlWidth);\n            self.control.appendChild(self.mouseevents);\n            self.keyevents = statusBox(\"Key:\", \n                                       self.mouseevents.offsetHeight + 5, \n                                       self.ctrlWidth);\n            self.control.appendChild(self.keyevents);\n\n            // Store frame\n            frames.push(self);\n\n            // Give the canvas the focus\n            self.canvas.focus();\n        });\n\n        $loc.get_canvas_textwidth = new Sk.builtin.func(function(self, text, size, face) {\n            Sk.builtin.pyCheckArgs(\"draw_text\", arguments, 3, 4);\n            if (!Sk.builtin.checkString(text)) {\n                throw new Sk.builtin.TypeError(\"text must be a string\");\n            };\n            if (!Sk.builtin.checkNumber(size)) {\n                throw new Sk.builtin.TypeError(\"size must be a number\");\n            };\n            size = Sk.builtin.asnum$(size);\n            if (face !== undefined) {\n                if (!Sk.builtin.checkString(face)) {\n                    throw new Sk.builtin.TypeError(\"font face must be a string\");\n                };                \n                face = Sk.ffi.unwrapo(face);\n                // check if face is valid\n                if (fontfaces[face] !== true) {\n                     throw new Sk.builtin.ValueError(\"'\" + face + \"' is not a valid font face\");\n                };\n            } else {\n                // Default value: serif\n                face = \"serif\";\n            };\n                                                 \n            var context = self.canvas.getContext('2d');\n\n            context.font = size + \"px \" + face;\n            text = Sk.ffi.unwrapo(text);\n            var metrics = context.measureText(text);\n            return Sk.builtin.assk$(metrics.width | 0, Sk.builtin.nmber.int$);\n        });\n\n        $loc.set_canvas_background = new Sk.builtin.func(function(self, color) {\n            Sk.builtin.pyCheckArgs(\"set_canvas_background\", arguments, 2, 2);\n            if (!Sk.builtin.checkString(color)) {\n                throw new Sk.builtin.TypeError(\"expected string\");\n            };\n            self.background = Sk.ffi.unwrapo(color);\n\n            return Sk.builtin.none.none$;\n        });\n\n        $loc.get_canvas_image = new Sk.builtin.func(function(self) {\n            Sk.builtin.pyCheckArgs(\"get_canvas_image\", arguments, 1, 1);\n            \n            var imagedata = self.canvas.toDataURL();\n            window.open(imagedata, \"Canvas Image\", \"left=0,top=0,width=\" \n                        + self.canvas.width + \",height=\" + self.canvas.height \n                        + \",toolbar=0,resizeable=0\");\n\n            return Sk.builtin.none.none$;\n        });\n\n        var cancelAnimation = function (frame) {\n            if (frame.animationID) {\n                cancelAnimationFrame(frame.animationID);\n                frame.animationID = null;\n            };            \n        };\n\n        $loc.start = new Sk.builtin.func(function(self) {\n            Sk.builtin.pyCheckArgs(\"start\", arguments, 1, 1);\n\n            // Make the frame visible and start the gui\n            var context = self.canvas.getContext('2d');\n            if (!context || !context.drawImage) {\n                alert(\"Cannot draw on canvas!\");\n                return;\n            };\n            var canvas = Sk.misceval.callsim(mod.Canvas, self.canvas);\n            \n            // Functions for built-in browser animation callback\n            var draw = function () {\n                context.fillStyle = self.background;\n                context.fillRect(0, 0, self.canvas.width, self.canvas.height);\n                try {\n                    Sk.setExecStartNow(true);\n                    Sk.currLineNo = self.draw_lineno;\n                    Sk.misceval.callsim(self.draw_handler, canvas);\n                } catch (e) {\n                    Sk.error(e);\n                    Sk.simplegui.cleanup();\n                }\n            };\n\n            var animate = function animate() {\n                self.animationID = requestAnimationFrame(animate);\n                draw();\n            };\n\n            // Make sure callbacks stop when window is closed\n            self.frame_window.onbeforeunload = function () {\n                // Works for Chrome and FireFox\n                cancelAnimation(self);\n            };\n\n            self.frame_window.onunload = function () {\n                // Needed for Safari\n                cancelAnimation(self);\n            };\n\n            // Request first animation frame\n            self.animationID = requestAnimationFrame(animate);\n\n            return Sk.builtin.none.none$;\n        });\n\n        $loc.stop = new Sk.builtin.func(function(self) {\n            Sk.builtin.pyCheckArgs(\"stop\", arguments, 1, 1);\n\n            self.frame_window.close();\n            cancelAnimation(self);\n\n            return Sk.builtin.none.none$;\n        });\n\n        $loc.add_button = new Sk.builtin.func(function(self, text, handler, width) {\n            Sk.builtin.pyCheckArgs(\"add_button\", arguments, 3, 4);\n            if (!Sk.builtin.checkString(text)) {\n                throw new Sk.builtin.TypeError(\"text must be a string\");\n            };\n            if (!Sk.builtin.checkFunction(handler)) {\n                throw new Sk.builtin.TypeError(\"handler must be a function\");\n            };\n            if (width !== undefined) {\n                if (!Sk.builtin.checkInt(width)) {\n                    throw new Sk.builtin.TypeError(\"width must be an integer\");\n                };                \n                width = Sk.builtin.asnum$(width);\n            };\n\n            var lineno = Sk.currLineNo;\n\n            // Make the actual button\n            var button = document.createElement(\"button\");\n            var br = document.createElement(\"br\");\n            button.type = \"button\";\n            button.textContent = Sk.ffi.unwrapo(text);\n            if (width !== undefined) {\n                button.style.width = width + \"px\";  \n            };\n            button.onclick = function() {\n                try {\n                    Sk.setExecStartNow(true);\n                    Sk.currLineNo = lineno;\n                    Sk.misceval.callsim(handler);  \n                    // Give the canvas back the focus\n                    self.canvas.focus();\n                } catch (e) {\n                    Sk.error(e);\n                    Sk.simplegui.cleanup();\n                }\n            };\n            // Add button to control area\n            self.control.appendChild(button);\n            self.control.appendChild(br);\n            return Sk.misceval.callsim(mod.Control, button);\n        });\n\n        $loc.add_label = new Sk.builtin.func(function(self, text, width) {\n            Sk.builtin.pyCheckArgs(\"add_label\", arguments, 2, 3);\n            if (!Sk.builtin.checkString(text)) {\n                throw new Sk.builtin.TypeError(\"text must be a string\");\n            };\n            if (width !== undefined) {\n                if (!Sk.builtin.checkInt(width)) {\n                    throw new Sk.builtin.TypeError(\"width must be an integer\");\n                };                \n                width = Sk.builtin.asnum$(width);\n            };\n\n            // Make the actual label\n            var label = document.createElement(\"span\");\n            var br = document.createElement(\"br\");\n            label.textContent = Sk.ffi.unwrapo(text);\n            label.style.display = \"inline-block\";\n            if (width !== undefined) {\n                label.style.width = width + \"px\";\n            };\n            // console.log(label.style);\n            // Add label to control area\n            self.control.appendChild(label);\n            self.control.appendChild(br);\n            return Sk.misceval.callsim(mod.Control, label);\n        });\n\n        $loc.add_input = new Sk.builtin.func(function(self, text, handler, width) {\n            Sk.builtin.pyCheckArgs(\"add_input\", arguments, 4, 4);\n            if (!Sk.builtin.checkString(text)) {\n                throw new Sk.builtin.TypeError(\"text must be a string\");\n            };\n            if (!Sk.builtin.checkFunction(handler)) {\n                throw new Sk.builtin.TypeError(\"handler must be a function\");\n            };\n            if (!Sk.builtin.checkInt(width)) {\n                throw new Sk.builtin.TypeError(\"width must be an integer\");\n            };                \n            width = Sk.builtin.asnum$(width);\n\n            var lineno = Sk.currLineNo;\n\n            // Make the actual text field\n            var label = document.createElement(\"span\");\n            var textField = document.createElement(\"textarea\");\n            var br1 = document.createElement(\"br\");\n            var br2 = document.createElement(\"br\");\n            label.textContent = Sk.ffi.unwrapo(text);\n            textField.rows = 1;\n            textField.style.resize = \"none\";\n            textField.style.width = width + \"px\";                \n\n            // Keypress handler to trap \"enter\" key\n            textField.onkeypress = function(evt) {\n                // Call Python handler when \"enter\" is pressed\n                if (evt.keyCode == 13) {\n                    // Don't let the text box contain multiple lines\n                    evt.preventDefault();\n                    try {\n                        var txt = Sk.ffi.basicwrap(textField.value);\n                        Sk.setExecStartNow(true);\n                        Sk.currLineNo = lineno;\n                        Sk.misceval.callsim(handler, txt);\n                        // Give the canvas back the focus\n                        self.canvas.focus();\n                    } catch (e) {\n                        Sk.error(e);\n                        Sk.simplegui.cleanup();\n                    }\n                };\n            };\n\n            // Add text field to control area\n            self.control.appendChild(label);\n            self.control.appendChild(br1);\n            self.control.appendChild(textField);\n            self.control.appendChild(br2);\n            return Sk.misceval.callsim(mod.TextAreaControl, textField);\n        });\n\n        $loc.set_keyup_handler = new Sk.builtin.func(function(self, handler) {\n            Sk.builtin.pyCheckArgs(\"set_keyup_handler\", arguments, 2, 2);\n            if (!Sk.builtin.checkFunction(handler)) {\n                throw new Sk.builtin.TypeError(\"handler must be a function\");\n            };\n\n            self.keyuphandler = handler;\n            self.keyup_lineno = Sk.currLineNo;\n\n            return Sk.builtin.none.none$;\n        });\n\n        $loc.set_keydown_handler = new Sk.builtin.func(function(self, handler) {\n            Sk.builtin.pyCheckArgs(\"set_keydown_handler\", arguments, 2, 2);\n            if (!Sk.builtin.checkFunction(handler)) {\n                throw new Sk.builtin.TypeError(\"handler must be a function\");\n            };\n\n            self.keydownhandler = handler;\n            self.keydown_lineno = Sk.currLineNo;\n\n            return Sk.builtin.none.none$;\n        });\n\n        $loc.set_mouseclick_handler = new Sk.builtin.func(function(self, handler) {\n            Sk.builtin.pyCheckArgs(\"set_mouseclick_handler\", arguments, 2, 2);\n            if (!Sk.builtin.checkFunction(handler)) {\n                throw new Sk.builtin.TypeError(\"handler must be a function\");\n            };\n\n            var lineno = Sk.currLineNo;\n\n            self.canvas.onclick = function(evt) {\n                var coords = canvasCoords(self.canvas, evt);\n                // Adjust position to remove border\n                var x = coords.x - self.canvas_border;\n                var y = coords.y - self.canvas_border;\n                if ((x < 0) || (x >= self.width)\n                    || (y < 0) || (y >= self.height)) {                    \n                    // Click was in border\n                    return;\n                };\n                var pos = new Sk.builtins['tuple']([Sk.builtin.assk$(x, Sk.builtin.nmber.int$), \n                                                    Sk.builtin.assk$(y, Sk.builtin.nmber.int$)]);\n                self.mouseevents.textContent = \"Mouse: Click \" + x + \", \" + y;\n\n                try {\n                    Sk.setExecStartNow(true);\n                    Sk.currLineNo = lineno;\n                    Sk.misceval.callsim(handler, pos);\n                } catch (e) {\n                    Sk.error(e);\n                    Sk.simplegui.cleanup();\n                };\n            };\n\n            return Sk.builtin.none.none$;\n        });\n\n        $loc.set_mousedrag_handler = new Sk.builtin.func(function(self, handler) {\n            Sk.builtin.pyCheckArgs(\"set_mousedrag_handler\", arguments, 2, 2);\n            if (!Sk.builtin.checkFunction(handler)) {\n                throw new Sk.builtin.TypeError(\"handler must be a function\");\n            };\n\n            self.mousedraghandler = handler;\n            self.mousedrag_lineno = Sk.currLineNo;\n\n            return Sk.builtin.none.none$;\n        });\n\n        $loc.set_draw_handler = new Sk.builtin.func(function(self, handler) {\n            Sk.builtin.pyCheckArgs(\"set_draw_handler\", arguments, 2, 2);\n            if (!Sk.builtin.checkFunction(handler)) {\n                throw new Sk.builtin.TypeError(\"handler must be a function\");\n            };\n\n            self.draw_handler = handler;\n            self.draw_lineno = Sk.currLineNo;\n\n            return Sk.builtin.none.none$;\n        });\n    };\n\n\n    mod.Frame = Sk.misceval.buildClass(mod, frame, 'Frame', []);\n\n    mod.create_frame = new Sk.builtin.func(function(title, canvas_width, canvas_height, control_width) {\n        Sk.builtin.pyCheckArgs(\"create_frame\", arguments, 3, 4);\n        if (!Sk.builtin.checkString(title)) {\n            throw new Sk.builtin.TypeError(\"title must be a string\");\n        };\n\n        if (!Sk.builtin.checkNumber(canvas_width)) {\n            throw new Sk.builtin.TypeError(\"canvas width must be a number\");\n        };                \n        if (!Sk.builtin.checkNumber(canvas_height)) {\n            throw new Sk.builtin.TypeError(\"canvas height must be a number\");\n        };                \n\n        if (control_width !== undefined) {\n            if (!Sk.builtin.checkNumber(control_width)) {\n                throw new Sk.builtin.TypeError(\"control width must be a number\");\n            }; \n\n            if (Sk.builtin.asnum$(control_width) < 0) {\n                throw new Sk.builtin.ValueError(\"control width must be >= 0\");\n            };\n        };\n\n\n        if (Sk.builtin.asnum$(canvas_width) < 0) {\n            throw new Sk.builtin.ValueError(\"canvas width must be >= 0\");\n        };\n\n        if (Sk.builtin.asnum$(canvas_height) < 0) {\n            throw new Sk.builtin.ValueError(\"canvas height must be >= 0\");\n        };\n            \n        return Sk.misceval.callsim(mod.Frame, title, canvas_width, canvas_height, control_width);\n    });\n\n    // Python timer class\n    var timer = function($gbl, $loc) {\n        $loc.__init__ = new Sk.builtin.func(function(self, interval, handler) {\n            // Initialize\n            self.interval = interval;\n            self.handler = handler;\n            self._timer = null;\n            self.lineno = Sk.currLineNo;\n\n            // Store timer\n            timers.push(self);\n        });\n\n        $loc.start = new Sk.builtin.func(function(self) {\n            Sk.builtin.pyCheckArgs(\"start\", arguments, 1, 1);\n\n            if (self._timer) {\n                // Already running, ignore\n                return;\n            }\n            // Create new Javascript timer which calls the Python handler\n            self._timer = setInterval(function() {\n                try {\n                    Sk.setExecStartNow(true);\n                    Sk.currLineNo = self.lineno;\n                    Sk.misceval.callsim(self.handler);\n                } catch (e) {\n                    clearInterval(self._timer);\n                    self._timer = null;\n                    Sk.error(e);\n                    Sk.simplegui.cleanup();\n                };                    \n            }, Sk.builtin.asnum$(self.interval));\n\n            return Sk.builtin.none.none$;\n        });\n\n        $loc.stop = new Sk.builtin.func(function(self) {\n            Sk.builtin.pyCheckArgs(\"stop\", arguments, 1, 1);\n\n            // If a Javascript timer exists, stop it and delete it\n            if (self._timer) {\n                clearInterval(self._timer);\n                self._timer = null;\n            }\n\n            return Sk.builtin.none.none$;\n        });\n\n        $loc.get_interval = new Sk.builtin.func(function(self) {\n            Sk.builtin.pyCheckArgs(\"get_interval\", arguments, 1, 1);\n\n            return self.interval;\n        });\n\n        $loc.is_running = new Sk.builtin.func(function(self) {\n            Sk.builtin.pyCheckArgs(\"is_running\", arguments, 1, 1);\n\n            if (self._timer) {\n                return Sk.builtin.bool.true$;\n            } else {\n                return Sk.builtin.bool.false$;\n            }\n        });\n    };\n\n    mod.Timer = Sk.misceval.buildClass(mod, timer, 'Timer', []);\n\n    mod.create_timer = new Sk.builtin.func(function(interval, handler) {\n        Sk.builtin.pyCheckArgs(\"create_timer\", arguments, 2, 2);\n        if (!Sk.builtin.checkNumber(interval)) {\n            throw new Sk.builtin.TypeError(\"interval must be a number\");\n        };                \n        if (!Sk.builtin.checkFunction(handler)) {\n            throw new Sk.builtin.TypeError(\"handler must be a function\");\n        };\n\n        if (Sk.builtin.asnum$(interval) <= 0) {\n            throw new Sk.builtin.ValueError(\"interval must be > 0\");\n        };\n\n        return Sk.misceval.callsim(mod.Timer, interval, handler);        \n    });\n\n    return mod;\n};\n",
  		"src/lib/random/__init__.js": "\n/*\n  I've wrapped Makoto Matsumoto and Takuji Nishimura's code in a namespace\n  so it's better encapsulated. Now you can have multiple random number generators\n  and they won't stomp all over eachother's state.\n  \n  If you want to use this as a substitute for Math.random(), use the random()\n  method like so:\n  \n  var m = new MersenneTwister();\n  var randomNumber = m.random();\n  \n  You can also call the other genrand_{foo}() methods on the instance.\n\n  If you want to use a specific seed in order to get a repeatable random\n  sequence, pass an integer into the constructor:\n\n  var m = new MersenneTwister(123);\n\n  and that will always produce the same random sequence.\n\n  Sean McCullough (banksean@gmail.com)\n*/\n\n/* \n   A C-program for MT19937, with initialization improved 2002/1/26.\n   Coded by Takuji Nishimura and Makoto Matsumoto.\n \n   Before using, initialize the state by using init_genrand(seed)  \n   or init_by_array(init_key, key_length).\n \n   Copyright (C) 1997 - 2002, Makoto Matsumoto and Takuji Nishimura,\n   All rights reserved.                          \n \n   Redistribution and use in source and binary forms, with or without\n   modification, are permitted provided that the following conditions\n   are met:\n \n     1. Redistributions of source code must retain the above copyright\n        notice, this list of conditions and the following disclaimer.\n \n     2. Redistributions in binary form must reproduce the above copyright\n        notice, this list of conditions and the following disclaimer in the\n        documentation and/or other materials provided with the distribution.\n \n     3. The names of its contributors may not be used to endorse or promote \n        products derived from this software without specific prior written \n        permission.\n \n   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n   \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n   A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR\n   CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,\n   EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,\n   PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR\n   PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF\n   LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING\n   NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS\n   SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n \n \n   Any feedback is very welcome.\n   http://www.math.sci.hiroshima-u.ac.jp/~m-mat/MT/emt.html\n   email: m-mat @ math.sci.hiroshima-u.ac.jp (remove space)\n*/\n\nvar MersenneTwister = function(seed) {\n  if (seed == undefined) {\n    seed = new Date().getTime();\n  } \n  /* Period parameters */  \n  this.N = 624;\n  this.M = 397;\n  this.MATRIX_A = 0x9908b0df;   /* constant vector a */\n  this.UPPER_MASK = 0x80000000; /* most significant w-r bits */\n  this.LOWER_MASK = 0x7fffffff; /* least significant r bits */\n \n  this.mt = new Array(this.N); /* the array for the state vector */\n  this.mti=this.N+1; /* mti==N+1 means mt[N] is not initialized */\n\n  this.init_genrand(seed);\n}  \n \n/* initializes mt[N] with a seed */\nMersenneTwister.prototype.init_genrand = function(s) {\n  this.mt[0] = s >>> 0;\n  for (this.mti=1; this.mti<this.N; this.mti++) {\n      var s = this.mt[this.mti-1] ^ (this.mt[this.mti-1] >>> 30);\n   this.mt[this.mti] = (((((s & 0xffff0000) >>> 16) * 1812433253) << 16) + (s & 0x0000ffff) * 1812433253)\n  + this.mti;\n      /* See Knuth TAOCP Vol2. 3rd Ed. P.106 for multiplier. */\n      /* In the previous versions, MSBs of the seed affect   */\n      /* only MSBs of the array mt[].                        */\n      /* 2002/01/09 modified by Makoto Matsumoto             */\n      this.mt[this.mti] >>>= 0;\n      /* for >32 bit machines */\n  }\n}\n \n/* initialize by an array with array-length */\n/* init_key is the array for initializing keys */\n/* key_length is its length */\n/* slight change for C++, 2004/2/26 */\nMersenneTwister.prototype.init_by_array = function(init_key, key_length) {\n  var i, j, k;\n  this.init_genrand(19650218);\n  i=1; j=0;\n  k = (this.N>key_length ? this.N : key_length);\n  for (; k; k--) {\n    var s = this.mt[i-1] ^ (this.mt[i-1] >>> 30)\n    this.mt[i] = (this.mt[i] ^ (((((s & 0xffff0000) >>> 16) * 1664525) << 16) + ((s & 0x0000ffff) * 1664525)))\n      + init_key[j] + j; /* non linear */\n    this.mt[i] >>>= 0; /* for WORDSIZE > 32 machines */\n    i++; j++;\n    if (i>=this.N) { this.mt[0] = this.mt[this.N-1]; i=1; }\n    if (j>=key_length) j=0;\n  }\n  for (k=this.N-1; k; k--) {\n    var s = this.mt[i-1] ^ (this.mt[i-1] >>> 30);\n    this.mt[i] = (this.mt[i] ^ (((((s & 0xffff0000) >>> 16) * 1566083941) << 16) + (s & 0x0000ffff) * 1566083941))\n      - i; /* non linear */\n    this.mt[i] >>>= 0; /* for WORDSIZE > 32 machines */\n    i++;\n    if (i>=this.N) { this.mt[0] = this.mt[this.N-1]; i=1; }\n  }\n\n  this.mt[0] = 0x80000000; /* MSB is 1; assuring non-zero initial array */ \n}\n \n/* generates a random number on [0,0xffffffff]-interval */\nMersenneTwister.prototype.genrand_int32 = function() {\n  var y;\n  var mag01 = new Array(0x0, this.MATRIX_A);\n  /* mag01[x] = x * MATRIX_A  for x=0,1 */\n\n  if (this.mti >= this.N) { /* generate N words at one time */\n    var kk;\n\n    if (this.mti == this.N+1)   /* if init_genrand() has not been called, */\n      this.init_genrand(5489); /* a default initial seed is used */\n\n    for (kk=0;kk<this.N-this.M;kk++) {\n      y = (this.mt[kk]&this.UPPER_MASK)|(this.mt[kk+1]&this.LOWER_MASK);\n      this.mt[kk] = this.mt[kk+this.M] ^ (y >>> 1) ^ mag01[y & 0x1];\n    }\n    for (;kk<this.N-1;kk++) {\n      y = (this.mt[kk]&this.UPPER_MASK)|(this.mt[kk+1]&this.LOWER_MASK);\n      this.mt[kk] = this.mt[kk+(this.M-this.N)] ^ (y >>> 1) ^ mag01[y & 0x1];\n    }\n    y = (this.mt[this.N-1]&this.UPPER_MASK)|(this.mt[0]&this.LOWER_MASK);\n    this.mt[this.N-1] = this.mt[this.M-1] ^ (y >>> 1) ^ mag01[y & 0x1];\n\n    this.mti = 0;\n  }\n\n  y = this.mt[this.mti++];\n\n  /* Tempering */\n  y ^= (y >>> 11);\n  y ^= (y << 7) & 0x9d2c5680;\n  y ^= (y << 15) & 0xefc60000;\n  y ^= (y >>> 18);\n\n  return y >>> 0;\n}\n \n/* generates a random number on [0,0x7fffffff]-interval */\nMersenneTwister.prototype.genrand_int31 = function() {\n  return (this.genrand_int32()>>>1);\n}\n \n/* generates a random number on [0,1]-real-interval */\nMersenneTwister.prototype.genrand_real1 = function() {\n  return this.genrand_int32()*(1.0/4294967295.0); \n  /* divided by 2^32-1 */ \n}\n\n/* generates a random number on [0,1)-real-interval */\nMersenneTwister.prototype.random = function() {\n  return this.genrand_int32()*(1.0/4294967296.0); \n  /* divided by 2^32 */\n}\n \n/* generates a random number on (0,1)-real-interval */\nMersenneTwister.prototype.genrand_real3 = function() {\n  return (this.genrand_int32() + 0.5)*(1.0/4294967296.0); \n  /* divided by 2^32 */\n}\n \n/* generates a random number on [0,1) with 53-bit resolution*/\nMersenneTwister.prototype.genrand_res53 = function() { \n  var a=this.genrand_int32()>>>5, b=this.genrand_int32()>>>6; \n  return(a*67108864.0+b)*(1.0/9007199254740992.0); \n} \n\n/* These real versions are due to Isaku Wada, 2002/01/09 added */\n\n\n\nvar $builtinmodule = function(name)\n{\n\n    var mod = {};\n\n    var myGenerator = new MersenneTwister();\n\n    mod.seed = new Sk.builtin.func(function(x) {\n        Sk.builtin.pyCheckArgs(\"seed\", arguments, 0, 1);\n\tx = Sk.builtin.asnum$(x);\n\n        if (arguments.length > 0)\n            myGenerator = new MersenneTwister(x);\n        else\n            myGenerator = new MersenneTwister();\n\n\treturn Sk.builtin.none.none$;\n    });\n\n    mod.random = new Sk.builtin.func(function() {\n        Sk.builtin.pyCheckArgs(\"random\", arguments, 0, 0);\n\n\treturn new Sk.builtin.nmber(myGenerator.genrand_res53(), Sk.builtin.nmber.float$);\n    });\n\n    var toInt = function(num) {\n        return num | 0;\n    };\n\n    var randrange = function(start, stop, step) {\n        // Ported from CPython 2.7\n        var width, n, ret;\n\n        if (!Sk.builtin.checkInt(start)) {\n            throw new Sk.builtin.ValueError(\"non-integer first argument for randrange()\");\n        };\n\n        if (stop === undefined) {\n            // Random in [0, start)\n            ret = toInt(myGenerator.genrand_res53() * start);\n\t    return new Sk.builtin.nmber(ret, Sk.builtin.nmber.int$);\n        };\n\n        if (!Sk.builtin.checkInt(stop)) {\n            throw new Sk.builtin.ValueError(\"non-integer stop for randrange()\");\n        };\n\n        if (step === undefined) {\n            step = 1;\n        };\n\n        width = stop - start;\n\n        if ((step == 1) && (width > 0)) {\n            // Random in [start, stop), must use toInt on product for correct results with negative ranges\n            ret = start + toInt(myGenerator.genrand_res53() * width);\n\t    return new Sk.builtin.nmber(ret, Sk.builtin.nmber.int$);\n        };\n\n        if (step == 1) {\n            throw new Sk.builtin.ValueError(\"empty range for randrange() (\" + start + \", \" + stop + \", \" + width + \")\");\n        };\n\n        if (!Sk.builtin.checkInt(step)) {\n            throw new Sk.builtin.ValueError(\"non-integer step for randrange()\");\n        };\n\n        if (step > 0) {\n            n = toInt((width + step - 1) / step);\n        } else if (step < 0) {\n            n = toInt((width + step + 1) / step);\n        } else {\n            throw new Sk.builtin.ValueError(\"zero step for randrange()\");\n        };\n\n        if (n <= 0) {\n            throw new Sk.builtin.ValueError(\"empty range for randrange()\");\n        };\n\n        // Random in range(start, stop, step)\n        ret = start + (step * toInt(myGenerator.genrand_res53() * n));\n\treturn new Sk.builtin.nmber(ret, Sk.builtin.nmber.int$);\n    };\n\n    mod.randint = new Sk.builtin.func(function(a, b) {\n        Sk.builtin.pyCheckArgs(\"randint\", arguments, 2, 2);\n\n\ta = Sk.builtin.asnum$(a);\n\tb = Sk.builtin.asnum$(b);\n        return randrange(a, b+1);\n    });\n\n    mod.randrange = new Sk.builtin.func(function(start, stop, step) {\n        Sk.builtin.pyCheckArgs(\"randrange\", arguments, 1, 3);\n\n\tstart = Sk.builtin.asnum$(start);\n\tstop = Sk.builtin.asnum$(stop);\n\tstep = Sk.builtin.asnum$(step);\n        return randrange(start, stop, step);\n    });\n\n    mod.choice = new Sk.builtin.func(function(seq) {\n        Sk.builtin.pyCheckArgs(\"choice\", arguments, 1, 1);\n        Sk.builtin.pyCheckType(\"seq\", \"sequence\", Sk.builtin.checkSequence(seq));\n\n        if (seq.sq$length !== undefined) {\n            var r = toInt(myGenerator.genrand_res53() * seq.sq$length());\n            return seq.mp$subscript(r);\n        } else {\n            throw new Sk.builtin.TypeError(\"object has no length\");\n        }\n    });\n\n    mod.shuffle = new Sk.builtin.func(function(x) {\n        Sk.builtin.pyCheckArgs(\"shuffle\", arguments, 1, 1);\n        Sk.builtin.pyCheckType(\"x\", \"sequence\", Sk.builtin.checkSequence(x));\n\n        if (x.sq$length !== undefined) {\n            if (x.mp$ass_subscript !== undefined) {\n                for (var i = x.sq$length() - 1; i > 0; i -= 1) {\n                    var r = toInt(myGenerator.genrand_res53() * (i + 1));\n                    var tmp = x.mp$subscript(r);\n                    x.mp$ass_subscript(r, x.mp$subscript(i));\n                    x.mp$ass_subscript(i, tmp);\n                };\n            } else {\n                throw new Sk.builtin.TypeError(\"object is immutable\");\n            };\n        } else {\n            throw new Sk.builtin.TypeError(\"object has no length\");\n        };        \n\n\treturn Sk.builtin.none.none$;\n    });\n\n    return mod;\n}\n",
  		"src/lib/urllib2/__init__.js": "var $builtinmodule = function(name)\n{\n    var mod = {};\n\n    // File-like object for network data\n    var netfile = function($gbl, $loc) {\n        $loc.__init__ = new Sk.builtin.func(function(self, data) {\n            Sk.builtin.pyCheckArgs(\"file\", arguments, 2, 2);\n            if (data.__class__ != Sk.builtin.str) {\n                throw new Sk.builtin.TypeError(\"data must be a string\");\n            };\n            self.data = data.v;\n            self.pos = 0;            \n        });\n\n        $loc.read = new Sk.builtin.func(function(self, size) {\n            Sk.builtin.pyCheckArgs(\"read\", arguments, 1, 2);\n            if (size !== undefined) {\n                if (!Sk.builtin.checkInt(size)) {\n                    throw new Sk.builtin.TypeError(\"size must be an int\");\n                }\n                size = Sk.builtin.asnum$(size);\n                if (size < 0) {\n                    size = self.data.length;\n                }\n            }\n            else {\n                size = self.data.length;\n            }\n            if (self.pos + size > self.data.length) {\n                size = self.data.length - self.pos;\n            }\n            var str = new Sk.builtin.str(self.data.substr(self.pos, size));\n            self.pos += size;\n            return str;\n        });\n\n        var readline_ = function(self, size) {\n            if (size !== undefined) {\n                if (!Sk.builtin.checkInt(size)) {\n                    throw new Sk.builtin.TypeError(\"size must be an int\");\n                }\n                size = Sk.builtin.asnum$(size);\n                if (size < 0) {\n                    size = self.data.length;\n                }\n            }\n            else {\n                size = self.data.length;\n            }\n            var nl = self.data.indexOf(\"\\n\", self.pos);\n            if (nl !== -1) {\n                nl -= self.pos;\n                if (size > nl) {\n                    size = nl + 1;\n                }\n            } \n            if (self.pos + size > self.data.length) {\n                size = self.data.length - self.pos;\n            }\n            var str = new Sk.builtin.str(self.data.substr(self.pos, size));\n            self.pos += size;\n            return str;\n        };\n\n        $loc.readline = new Sk.builtin.func(function(self, size) {\n            Sk.builtin.pyCheckArgs(\"readline\", arguments, 1, 2);\n            return readline_(self, size);\n        });\n\n        $loc.readlines = new Sk.builtin.func(function(self, sizehint) {\n            Sk.builtin.pyCheckArgs(\"readlines\", arguments, 1, 2);\n            // ignore sizehint\n            var result = []\n            var line = readline_(self);\n            while (line != Sk.builtin.str.$emptystr) {\n                result.push(line);\n                line = readline_(self);\n            }\n            return new Sk.builtin.list(result);\n        });\n\n        $loc.__iter__ = new Sk.builtin.func(function(self) { \n            var ret =\n                {\n                    tp$iter: function() { return ret; },\n                    $obj: self,\n                    tp$iternext: function()\n                    {\n                        var line = readline_(ret.$obj);\n                        if (line == Sk.builtin.str.$emptystr) {\n                            return undefined;\n                        }\n                        return line;\n                    }\n                };\n            return ret;\n        });\n    };\n\n    mod.NetFile = Sk.misceval.buildClass(mod, netfile, 'NetFile', []);\n\n    // URL open method\n    mod.urlopen = new Sk.builtin.func(function(url, data, timeout) {\n        Sk.builtin.pyCheckArgs(\"urlopen\", arguments, 1, 3);\n        if (!Sk.builtin.checkString(url)) {\n            throw new Sk.builtin.TypeError(\"URL must be a string\");\n        };\n        if (data === undefined) {\n            data = null;\n        };\n        // if ((data != null) && !Sk.builtin.checkString(data)) {\n        //     throw new Sk.builtin.TypeError(\"data must be a string or None\");\n        // };\n        if (data !== null) {\n            throw new Sk.builtin.TypeError(\"currently, data must be None\");\n        };\n        if (timeout === undefined) {\n            // timeout in seconds\n            timeout = 5;\n        };\n        if (!Sk.builtin.checkNumber(timeout)) {\n            throw new Sk.builtin.TypeError(\"timeout must be a number\");\n        };                \n\n        var jsurl = Sk.ffi.unwrapo(url);\n\n        var settings = {\n            async: false,\n            error: function(jqXHR, textStatus, errorThrown) {\n                throw new Sk.builtin.IOError(\"unable to open '\" + jsurl + \"' (\" + errorThrown + \")\");\n            },\n            success: function(data, textStatus, jqXHR) {\n            },\n            timeout: timeout * 1000\n        };\n        \n        if (data !== null) {\n            settings.data = Sk.ffi.unwrapo(data);\n            settings.type = \"POST\";\n        };\n\n        var response = $.ajax('/fetch/?url=' + encodeURIComponent(jsurl), settings).responseText;\n\n        // Reset timeout in case network transfer took a long time\n        Sk.setExecStartNow(true);\n\n        return Sk.misceval.callsim(mod.NetFile, new Sk.builtin.str(response));\n    });\n\n    return mod;\n};",
  		"src/builtin/this.py": "s = \"\"\"Gur Mra bs Clguba, ol Gvz Crgref\n\nOrnhgvshy vf orggre guna htyl.\nRkcyvpvg vf orggre guna vzcyvpvg.\nFvzcyr vf orggre guna pbzcyrk.\nPbzcyrk vf orggre guna pbzcyvpngrq.\nSyng vf orggre guna arfgrq.\nFcnefr vf orggre guna qrafr.\nErnqnovyvgl pbhagf.\nFcrpvny pnfrf nera'g fcrpvny rabhtu gb oernx gur ehyrf.\nNygubhtu cenpgvpnyvgl orngf chevgl.\nReebef fubhyq arire cnff fvyragyl.\nHayrff rkcyvpvgyl fvyraprq.\nVa gur snpr bs nzovthvgl, ershfr gur grzcgngvba gb thrff.\nGurer fubhyq or bar-- naq cersrenoyl bayl bar --boivbhf jnl gb qb vg.\nNygubhtu gung jnl znl abg or boivbhf ng svefg hayrff lbh'er Qhgpu.\nAbj vf orggre guna arire.\nNygubhtu arire vf bsgra orggre guna *evtug* abj.\nVs gur vzcyrzragngvba vf uneq gb rkcynva, vg'f n onq vqrn.\nVs gur vzcyrzragngvba vf rnfl gb rkcynva, vg znl or n tbbq vqrn.\nAnzrfcnprf ner bar ubaxvat terng vqrn -- yrg'f qb zber bs gubfr!\"\"\"\n\nd = {}\nfor c in (65, 97):\n    for i in range(26):\n        d[chr(i+c)] = chr((i+13) % 26 + c)\n\nprint \"\".join([d.get(c, c) for c in s])\n"
  	}
  }