var $builtinmodule = function() { "use strict"; var e = function getConfiguredTarget() { var e, t; for (e = Sk.TurtleGraphics && Sk.TurtleGraphics.target || "turtle", t = "string" == typeof e ? document.getElementById(e) : e; t.firstChild;) t.removeChild(t.firstChild); return t }(); return e.turtleInstance ? e.turtleInstance.reset() : e.turtleInstance = function generateTurtleModule(e) { var t = Math.round, r = Math.max, n = Math.sqrt, a = Math.min, s = Math.abs, o = Math.PI, d = Math.atan2, _ = Math.sin, c = Math.cos; function getAsset(e) { var t = g.assets, r = "function" == typeof t ? t(e) : t[e]; return "string" == typeof r ? new Promise(function(t, n) { var a = new Image; a.onload = function() { g.assets[e] = this, t(a) }, a.onerror = function() { n(new Error("Missing asset: " + r)) }, a.src = r }) : new InstantPromise(void 0, r) } function InstantPromise(e, t) { this.lastResult = t, this.lastError = e } function FrameManager() { this.reset() } function getFrameManager() { return A || (A = new FrameManager), A } function MouseHandler() { var t = this; for (var r in this._target = getTarget(), this._managers = {}, this._handlers = { mousedown: function(r) { t.onEvent("mousedown", r) }, mouseup: function(r) { t.onEvent("mouseup", r) }, mousemove: function(r) { t.onEvent("mousemove", r) } }, this._handlers) this._target.addEventListener(r, this._handlers[r]) } function EventManager(e, t) { this._type = e, this._target = t, this._handlers = void 0, getMouseHandler() .addManager(e, this) } function Turtle(e) { if (getFrameManager() .addTurtle(this), this._screen = getScreen(), this._managers = {}, this._shape = e.v, !v.hasOwnProperty(this._shape)) throw new Sk.builtin.ValueError("Shape:'" + this._shape + "' not in default shape, please check shape again!"); this.reset() } function Screen() { var e, t; this._frames = 1, this._delay = void 0, this._bgcolor = "none", this._mode = "standard", this._managers = {}, this._keyLogger = {}, e = (g.worldWidth || g.width || getWidth()) / 2, t = (g.worldHeight || g.height || getHeight()) / 2, this.setUpWorld(-e, -t, e, t) } function ensureAnonymous() { return f || (f = Sk.misceval.callsimArray(y.Turtle)), f.instance } function getTarget() { return e } function getScreen() { return p || (p = new Screen), p } function getMouseHandler() { return h || (h = new MouseHandler), h } function getWidth() { return 0 | (p && p._width || g.width || getTarget() .clientWidth || T.width) } function getHeight() { return 0 | (p && p._height || g.height || getTarget() .clientHeight || T.height) } function createLayer(e, t) { var r, n = document.createElement("canvas"), a = getWidth(), s = getHeight(), l = getTarget() .firstChild ? -s + "px" : "0"; return n.width = a, n.height = s, n.style.position = "relative", n.style.display = "block", n.style.setProperty("margin-top", l), n.style.setProperty("z-index", e), t && (n.style.display = "none"), getTarget() .appendChild(n), r = n.getContext("2d"), r.lineCap = "round", r.lineJoin = "round", applyWorld(getScreen(), r), r } function cancelAnimationFrame() { u && ((window.cancelAnimationFrame || window.mozCancelAnimationFrame)(u), u = void 0), m && (window.clearTimeout(m), m = void 0) } function applyWorld(e, t) { var r = e.llx, n = e.lly, a = e.urx, s = e.ury, l = e.xScale, i = e.yScale; t && (clearLayer(t), t.restore(), t.save(), t.scale(1 / l, 1 / i), 0 === n ? t.translate(-r, n - (s - n)) : 0 < n ? t.translate(-r, 2 * -n) : t.translate(-r, -s)) } function pushUndo(e) { var t, r, n; if (g.allowUndo && e._bufferSize) { for (e._undoBuffer || (e._undoBuffer = []); e._undoBuffer.length > e._bufferSize;) e._undoBuffer.shift(); for (r = {}, t = ["x", "y", "angle", "radians", "color", "fill", "down", "filling", "shown", "shape", "size"], n = 0; n < t.length; n++) r[t[n]] = e["_" + t[n]]; return e._undoBuffer.push(r), e.addUpdate(function() { r.fillBuffer = this.fillBuffer ? this.fillBuffer.slice() : void 0, e._paper && e._paper.canvas && (r.image = e._paper.canvas.toDataURL()) }, !1) } } function popUndo(e) { var t; if (e._bufferSize && e._undoBuffer && (t = e._undoBuffer.pop(), !!t)) { for (var r in t) "image" != r && "fillBuffer" !== r && (e["_" + r] = t[r]); return e.addUpdate(function() { var e; t.image && (L.src = t.image, e = L), clearLayer(this.context(), !1, L), delete t.image }, !0, t) } } function removeLayer(e) { e && e.canvas && e.canvas.parentNode && e.canvas.parentNode.removeChild(e.canvas) } function clearLayer(e, t, r) { e && (e.save(), e.setTransform(1, 0, 0, 1, 0, 0), t ? (e.fillStyle = t, e.fillRect(0, 0, e.canvas.width, e.canvas.height)) : e.clearRect(0, 0, e.canvas.width, e.canvas.height), r && e.drawImage(r, 0, 0), e.restore()) } function drawTurtle(e, t) { var r, n, a, s = v[e.shape], l = getScreen(), u = getWidth(), m = getHeight(), p = l.xScale, g = l.yScale; if (t) { if (r = c(e.radians) / p, n = _(e.radians) / g, a = d(n, r) - o / 2, t.save(), t.translate(e.x, e.y), t.scale(p, g), s.nodeName) { var f = s.naturalWidth, h = s.naturalHeight; t.drawImage(s, 0, 0, f, h, -f / 2, -h / 2, f, h) } else { t.rotate(a), t.beginPath(), t.lineWidth = 1, t.strokeStyle = e.color, t.fillStyle = e.fill, t.moveTo(-s[0][0], s[0][1]); for (var $ = 1; $ < s.length; $++) t.lineTo(-s[$][0], s[$][1]); t.closePath(), t.fill(), t.stroke() } t.restore() } } function drawDot(e, t) { var r = this.context(), n = getScreen(), l = n.xScale, i = n.yScale; r && (r.beginPath(), r.moveTo(this.x, this.y), e *= a(s(l), s(i)), r.arc(this.x, this.y, e / 2, 0, Turtle.RADIANS), r.closePath(), r.fillStyle = t || this.color, r.fill()) } function measureText(e, t) { return t && (S.font = t), S.measureText(e) .width } function drawText(e, t, r) { var n = this.context(); n && (n.save(), r && (n.font = r), t && t.match(/^(left|right|center)$/) && (n.textAlign = t), n.scale(1, -1), n.fillStyle = this.fill, n.fillText(e, this.x, -this.y), n.restore()) } function drawLine(e, t) { var r = this.context(); r && (t && (r.beginPath(), r.moveTo(this.x, this.y)), r.lineWidth = this.size * getScreen() .lineScale, r.strokeStyle = this.color, r.lineTo(e.x, e.y), r.stroke()) } function drawFill() { var e, t = this.context(), r = this.fillBuffer; if (t && r && r.length) { for (t.save(), t.beginPath(), t.moveTo(r[0].x, r[0].y), e = 1; e < r.length; e++) t.lineTo(r[e].x, r[e].y); for (t.closePath(), t.fillStyle = this.fill, t.fill(), e = 1; e < r.length; e++) r[e].stroke && (t.beginPath(), t.moveTo(r[e - 1].x, r[e - 1].y), t.lineWidth = r[e].size * getScreen() .lineScale, t.strokeStyle = r[e].color, t.lineTo(r[e].x, r[e].y), t.stroke()); t.restore() } } function partialTranslate(e, t, r, n, a) { return function() { return e.addUpdate(function(e) { this.down && drawLine.call(this, e, n) }, a, { x: t, y: r }, n) } } function translate(e, a, l, o, d, _, c) { var u, m = e._computed_speed, p = getScreen(), g = s(p.xScale), f = s(p.yScale), h = a, $ = l, w = n(o * o * g + d * d * f), b = m ? t(r(1, w / m)) : 1, v = getFrameManager() .willRenderNext() ? Promise.resolve() : new InstantPromise; for (e.addUpdate(function() { this.filling && this.fillBuffer.push({ x: this.x, y: this.y, stroke: this.down, color: this.color, size: this.size }) }, !1), u = 0; u < b; u++) h = a + o / b * (u + 1), $ = l + d / b * (u + 1), v = v.then(partialTranslate(e, h, $, _, m || !c)), _ = !1; return v.then(function() { return [a + o, l + d] }) } function partialRotate(e, t, r, n) { return function() { return e.addUpdate(void 0, n, { angle: t, radians: r }) } } function rotate(e, n, a, l) { var o, d = e._computed_speed, _ = 360 * (a / e._fullCircle), c = d ? t(r(1, s(_) / d)) : 1, u = {}, m = getFrameManager() .willRenderNext() ? Promise.resolve() : new InstantPromise; for (o = 0; o < c; o++) calculateHeading(e, n + a / c * (o + 1), u), m = m.then(partialRotate(e, u.angle, u.radians, d || !l)); return m.then(function() { return calculateHeading(e, n + a) }) } function getCoordinates(e, t) { return void 0 === t && (t = e && (e.y || e._y || e[1]) || 0, e = e && (e.x || e._x || e[0]) || 0), { x: e, y: t } } function hexToRGB(e) { var t, r, n; return (t = /^rgba?\\((\\d+),(\\d+),(\\d+)(?:,([.\\d]+))?\\)$/.exec(e)) ? (n = [parseInt(t[1]), parseInt(t[2]), parseInt(t[3])], t[4] && n.push(parseFloat(t[4]))) : /^#?[a-f\\d]{3}|[a-f\\d]{6}$/i.exec(e) ? (4 === e.length && (e = e.replace(/^#?([a-f\\d])([a-f\\d])([a-f\\d])$/i, function(e, t, r, n) { return t + t + r + r + n + n })), r = /^#?([a-f\\d]{2})([a-f\\d]{2})([a-f\\d]{2})$/i.exec(e), n = [parseInt(r[1], 16), parseInt(r[2], 16), parseInt(r[3], 16)]) : n = e, n } function createColor(e, t, n, s, l) { var o; if (void 0 !== n && (t = [t, n, s, l]), t.constructor === Array && t.length) { if (255 === e) { for (o = 0; 3 > o; o++) if ("number" == typeof t[o]) t[o] = r(0, a(255, parseInt(t[o]))); else throw new Sk.builtin.ValueError("bad color sequence"); } else for (o = 0; 3 > o; o++) if ("number" != typeof t[o]) throw new Sk.builtin.ValueError("bad color sequence"); else if (1 >= t[o]) t[o] = r(0, a(255, parseInt(255 * t[o]))); else throw new Sk.builtin.ValueError("bad color sequence"); "number" == typeof t[o] ? (t[3] = r(0, a(1, t[o])), t = "rgba(" + t.join(",") + ")") : t = "rgb(" + t.slice(0, 3) .join(",") + ")" } else if ("string" == typeof t && !t.match(/\\s*url\\s*\\(/i)) t = t.replace(/\\s+/g, ""); else return "black"; return t } function calculateHeading(e, t, r) { var n = e._angle || 0, a = e._radians || 0; return r || (r = {}), "number" == typeof t && (e._isRadians ? n = a = t % Turtle.RADIANS : e._fullCircle ? (n = t % e._fullCircle, a = n / e._fullCircle * Turtle.RADIANS) : n = a = 0, 0 > n && (n += e._fullCircle, a += Turtle.RADIANS)), r.angle = n, r.radians = a, r } function pythonToJavascriptFunction(e, t) { return function() { var r = Array.prototype.slice.call(arguments), n = r.map(function(e) { return Sk.ffi.remapToPy(e) }); return "undefined" != typeof t && n.unshift(t), Sk.misceval.applyAsync(void 0, e, void 0, void 0, void 0, n) .catch(Sk.uncaughtException) } } function addModuleMethod(e, t, r, n) { var a, s = r.replace(/^\\$/, ""), l = s.replace(/_\\$[a-z]+\\$$/i, ""), o = e.prototype[r].length, d = e.prototype[r].minArgs, _ = e.prototype[r].co_varnames || [], c = e.prototype[r].returnType, u = e.prototype[r].isSk; void 0 === d && (d = o), a = function() { var e, t, a, s, _, m = Array.prototype.slice.call(arguments, 0), p = n ? n() : m.shift() .instance; if (m.length < d || m.length > o) throw _ = d === o ? "exactly " + o : "between " + d + " and " + o, new Sk.builtin.TypeError(l + "() takes " + _ + " positional argument(s) (" + m.length + " given)"); for (e = m.length; 0 <= --e;) void 0 !== m[e] && (m[e] = m[e] instanceof Sk.builtin.func ? pythonToJavascriptFunction(m[e]) : m[e] instanceof Sk.builtin.method ? pythonToJavascriptFunction(m[e].im_func, m[e].im_self) : m[e] && m[e].$d instanceof Sk.builtin.dict && m[e].instance ? m[e].instance : Sk.ffi.remapToJs(m[e])); var g = m.slice(0); for (m = [], e = g.length; 0 <= e; --e) null !== g[e] && (m[e] = g[e]); try { t = p[r].apply(p, m) } catch (t) { throw window && window.console && (window.console.log("wrapped method failed"), window.console.log(t.stack)), t } return t instanceof InstantPromise && (t = t.lastResult), t instanceof Promise ? (t = t.catch(function(t) { throw window && window.console && (window.console.log("promise failed"), window.console.log(t.stack)), t }), a = new Sk.misceval.Suspension, a.resume = function() { return void 0 === s ? Sk.builtin.none.none$ : Sk.ffi.remapToPy(s) }, a.data = { type: "Sk.promise", promise: t.then(function(e) { return s = e, e }) }, a) : void 0 === t ? Sk.builtin.none.none$ : u ? t : "function" == typeof c ? c(t) : Sk.ffi.remapToPy(t) }, a.co_name = new Sk.builtin.str(l), a.co_varnames = _.slice(), a.$defaults = []; for (var m = d; m < _.length; m++) a.$defaults.push(Sk.builtin.none.none$); n || a.co_varnames.unshift("self"), t[s] = new Sk.builtin.func(a) } function initTurtle(e, t) { Sk.builtin.pyCheckArgs("__init__", arguments, 2, 3, !1, !1), e.instance = new Turtle(t), e.instance.skInstance = e } function focusTurtle(e) { return void 0 !== e && (w = !!e, w ? getTarget() .focus() : getTarget() .blur()), w } function resetTurtle() { for (cancelAnimationFrame(), getScreen() .reset(), getFrameManager() .reset(); e.firstChild;) e.removeChild(e.firstChild); h && h.reset(), $ = 0, p = void 0, f = void 0, h = void 0, k = 0 } function stopTurtle() { cancelAnimationFrame(), h && h.reset(), $ = 0, p = void 0, f = void 0, h = void 0, k = 0 } var u, m, p, g, f, h, y = { __name__: new Sk.builtin.str("turtle") }, $ = 0, w = !0, b = 1e3 / 30, v = {}, k = 0, x = {}, T = { target: "turtle", width: 400, height: 400, worldWidth: 0, worldHeight: 0, animate: !0, bufferSize: 0, allowUndo: !0, assets: {} }; e.hasAttribute("tabindex") || e.setAttribute("tabindex", 0), x.FLOAT = function(e) { return new Sk.builtin.float_(e) }, x.COLOR = function(e) { if ("string" == typeof e) return new Sk.builtin.str(e); for (var t = 0; 3 > t; t++) e[t] = Sk.builtin.assk$(e[t]); return 4 === e.length && (e[3] = new Sk.builtin.float_(e[3])), new Sk.builtin.tuple(e) }, x.TURTLE_LIST = function(e) { for (var t = [], r = 0; r < e.length; r++) t.push(e[r].skInstance); return new Sk.builtin.tuple(t) }, v.arrow = [ [-10, 0], [10, 0], [0, 10] ], v.square = [ [10, -10], [10, 10], [-10, 10], [-10, -10] ], v.triangle = [ [10, -5.77], [0, 11.55], [-10, -5.77] ], v.classic = [ [0, 0], [-5, -9], [0, -7], [5, -9] ], v.turtle = [ [0, 16], [-2, 14], [-1, 10], [-4, 7], [-7, 9], [-9, 8], [-6, 5], [-7, 1], [-5, -3], [-8, -6], [-6, -8], [-4, -5], [0, -7], [4, -5], [6, -8], [8, -6], [5, -3], [7, 1], [6, 5], [9, 8], [7, 9], [4, 7], [1, 10], [2, 14] ], v.circle = [ [10, 0], [9.51, 3.09], [8.09, 5.88], [5.88, 8.09], [3.09, 9.51], [0, 10], [-3.09, 9.51], [-5.88, 8.09], [-8.09, 5.88], [-9.51, 3.09], [-10, 0], [-9.51, -3.09], [-8.09, -5.88], [-5.88, -8.09], [-3.09, -9.51], [-0, -10], [3.09, -9.51], [5.88, -8.09], [8.09, -5.88], [9.51, -3.09] ], g = function() { for (var e in Sk.TurtleGraphics || (Sk.TurtleGraphics = {}), T) Sk.TurtleGraphics.hasOwnProperty(e) || (Sk.TurtleGraphics[e] = T[e]); return Sk.TurtleGraphics }(), InstantPromise.prototype.then = function(e) { if (this.lastError) return this; try { this.lastResult = e(this.lastResult) } catch (t) { this.lastResult = void 0, this.lastError = t } return this.lastResult instanceof Promise ? this.lastResult : this }, InstantPromise.prototype.catch = function(e) { if (this.lastError) try { this.lastResult = e(this.lastError), this.lastError = void 0 } catch (t) { this.lastResult = void 0, this.lastError = t } return this.lastResult instanceof Promise ? this.lastResult : this }; var A; (function(e) { function animationFrame(e) { return g.animate ? !e && t ? t : function(t) { return m = window.setTimeout(t, e || b), m } : function(e) { e() } } var t; (function(e) { e && (t = function(t) { return u = e(t) }) })(window.requestAnimationFrame || window.mozRequestAnimationFrame), e.willRenderNext = function() { return !!(this._buffer && this._frameCount + 1 === this.frameBuffer()) }, e.turtles = function() { return this._turtles }, e.addTurtle = function(e) { this._turtles.push(e) }, e.reset = function() { if (this._turtles) for (var e = this._turtles.length; 0 <= --e;) this._turtles[e].reset(); this._turtles = [], this._frames = [], this._frameCount = 0, this._buffer = 1, this._rate = 0, this._animationFrame = animationFrame() }, e.addFrame = function(e, t) { var r = !1; return t && (this._frameCount += 1), this.frames() .push(e), r = !g.animate || this._buffer && this._frameCount === this.frameBuffer(), r ? this.update() : new InstantPromise }, e.frames = function() { return this._frames }, e.frameBuffer = function(e) { return "number" == typeof e && (this._buffer = 0 | e, e && e <= this._frameCount) ? this.update() : this._buffer }, e.refreshInterval = function(e) { return "number" == typeof e && (this._rate = 0 | e, this._animationFrame = animationFrame(e)), this._rate }, e.update = function() { return this._frames && this._frames.length ? this.requestAnimationFrame() : new InstantPromise }, e.requestAnimationFrame = function() { var e, t, r = this._frames, n = this._animationFrame, a = this._turtles, s = getScreen() .spriteLayer(); return this._frames = [], this._frameCount = 0, new Promise(function(l) { n(function paint() { for (t = 0; t < r.length; t++) r[t] && r[t](); for (clearLayer(s), t = 0; t < a.length; t++) e = a[t], e.getState() .shown && drawTurtle(e.getState(), s); l() }) }) } })(FrameManager.prototype), function(e) { e.onEvent = function(t, r) { function computeCoordinates() { if (!_) { var t = getScreen(), l = t.spriteLayer() .canvas.getBoundingClientRect(); e = 0 | r.clientX - l.left, n = 0 | r.clientY - l.top, a = e * t.xScale + t.llx, s = n * t.yScale + t.ury, _ = !0 } } var e, n, a, s, l, o = this._managers[t], d = this._managers.mousemove, _ = !1; if (("mousedown" === t || "mouseup" === t) && d && d.length) for (computeCoordinates(), l = d.length; 0 <= --l;) d[l].test(e, n, a, s) && d[l].canMove("mousedown" === t); if (o && o.length) for (computeCoordinates(), l = o.length; 0 <= --l;) "mousemove" === t && o[l].canMove() && o[l].test(e, n, a, s) ? o[l].trigger([a, s]) : "mousedown" === t && o[l].test(e, n, a, s) && o[l].trigger([a, s]) }, e.reset = function() { this._managers = {} }, e.addManager = function(e, t) { this._managers[e] || (this._managers[e] = []), this._managers[e].push(t) } }(MouseHandler.prototype), function(e) { e.reset = function() { this._handlers = void 0 }, e.canMove = function(e) { return !!(this._target && this._target.hitTest) && (void 0 !== e && (this._target.hitTest.hit = e), this._target.hitTest.hit) }, e.test = function(e, t, r, n) { return this._target && this._target.hitTest ? this._target.hitTest(e, t, r, n) : !!this._target }, e.trigger = function(e) { var t, r = this._handlers; if (r && r.length) for (t = 0; t < r.length; t++) r[t].apply({}, e) }, e.addHandler = function(e, t) { var r = this._handlers; if (!t && r && r.length) for (; r.shift();); return "function" == typeof e ? void(!r && (r = this._handlers = []), r.push(e)) : void(r && !r.length && this.reset()) } }(EventManager.prototype), Turtle.RADIANS = 2 * o, function(e) { function circleRotate(e, t, r) { return function() { return e.addUpdate(void 0, !1, { angle: t, radians: r }) } } function circleSegment(e, t, r, n, a, s) { return function() { return e.translate(t, r, n, a, s, !0) } } e.hitTest = function(e, t) { var r = getScreen() .hitTestLayer(); clearLayer(r), drawTurtle(this.getState(), r); var n = r.getImageData(e, t, 1, 1) .data; return n[3] || n[0] || n[1] || n[2] }, e.addUpdate = function(e, t, r) { var n = this, a = this.getState(), s = Array.prototype.slice.call(arguments, r ? 2 : 3); return getFrameManager() .addFrame(function() { if (e && e.apply(a, s), r) for (var t in r) a[t] = r[t] }, t) }, e.getState = function() { var e = this; return this._state || (this._state = { x: this._x, y: this._y, angle: this._angle, radians: this._radians, shape: this._shape, color: this._color, fill: this._fill, filling: this._filling, size: this._size, speed: this._computed_speed, down: this._down, shown: this._shown, colorMode: this._colorMode, context: function() { return e.getPaper() } }), this._state }, e.translate = function(e, t, r, n, a, s) { var l = this; return translate(this, e, t, r, n, a, s) .then(function(e) { l._x = e[0], l._y = e[1] }) }, e.rotate = function(e, t, r) { var n = this; return rotate(this, e, t, r) .then(function(e) { n._angle = e.angle, n._radians = e.radians }) }, e.queueMoveBy = function(e, t, r, n) { var a = c(r) * n, s = _(r) * n; return this.translate(e, t, a, s, !0) }, e.queueTurnTo = function(e, t) { return t %= this._fullCircle, 0 > t && (t += this._fullCircle), this.rotate(e, t - e) }, e.getManager = function(e) { return this._managers[e] || (this._managers[e] = new EventManager(e, this)), this._managers[e] }, e.getPaper = function() { return this._paper || (this._paper = createLayer(2)) }, e.reset = function() { for (var e in this._x = 0, this._y = 0, this._radians = 0, this._angle = 0, this._shown = !0, this._down = !0, this._color = "black", this._fill = "black", this._size = 1, this._filling = !1, this._undoBuffer = [], this._speed = 3, this._computed_speed = 5, this._colorMode = 1, this._state = void 0, this._managers) this._managers[e].reset(); this._isRadians = !1, this._fullCircle = 360, this._bufferSize = "number" == typeof g.bufferSize ? g.bufferSize : 0, removeLayer(this._paper), this._paper = void 0 }, e.$degrees = function(e) { return e = "number" == typeof e ? s(e) : 360, this._isRadians = !1, this._angle = e && this._fullCircle ? this._angle / this._fullCircle * e : this._radians = 0, this._fullCircle = e, this.addUpdate(void 0, !1, { angle: this._angle, radians: this._radians }) }, e.$degrees.minArgs = 0, e.$degrees.co_varnames = ["fullcircle"], e.$degrees.returnType = x.FLOAT, e.$radians = function() { return this._isRadians || (this._isRadians = !0, this._angle = this._radians, this._fullCircle = Turtle.RADIANS), this._angle }, e.$radians.returnType = x.FLOAT, e.$position = e.$pos = function() { return [this.$xcor(), this.$ycor()] }, e.$position.returnType = function(e) { return new Sk.builtin.tuple([new Sk.builtin.float_(e[0]), new Sk.builtin.float_(e[1])]) }, e.$towards = function(e, t) { var r = getCoordinates(e, t), n = o + d(this._y - r.y, this._x - r.x), a = n * (this._fullCircle / Turtle.RADIANS); return a }, e.$towards.co_varnames = ["x", "y"], e.$towards.minArgs = 1, e.$towards.returnType = x.FLOAT, e.$distance = function(e, t) { var r = getCoordinates(e, t), a = r.x - this._x, s = r.y - this._y; return n(a * a + s * s) }, e.$distance.co_varnames = ["x", "y"], e.$distance.minArgs = 1, e.$distance.returnType = x.FLOAT, e.$heading = function() { return 1e-13 > s(this._angle) ? 0 : this._angle }, e.$heading.returnType = x.FLOAT, e.$xcor = function() { return 1e-13 > s(this._x) ? 0 : this._x }, e.$xcor.returnType = x.FLOAT, e.$ycor = function() { return 1e-13 > s(this._y) ? 0 : this._y }, e.$ycor.returnType = x.FLOAT, e.$forward = e.$fd = function(e) { return pushUndo(this), this.queueMoveBy(this._x, this._y, this._radians, e) }, e.$forward.co_varnames = e.$fd.co_varnames = ["distance"], e.$undo = function() { popUndo(this) }, e.$undobufferentries = function() { return this._undoBuffer.length }, e.$setundobuffer = function(e) { this._bufferSize = "number" == typeof e ? a(s(e), 1e3) : 0 }, e.$setundobuffer.co_varnames = ["size"], e.$backward = e.$back = e.$bk = function(e) { return pushUndo(this), this.queueMoveBy(this._x, this._y, this._radians, -e) }, e.$backward.co_varnames = e.$back.co_varnames = e.$bk.co_varnames = ["distance"], e.$goto_$rw$ = e.$setpos = e.$setposition = function(e, t) { var r = getCoordinates(e, t); return pushUndo(this), this.translate(this._x, this._y, r.x - this._x, r.y - this._y, !0) }, e.$goto_$rw$.co_varnames = e.$setpos.co_varnames = e.$setposition.co_varnames = ["x", "y"], e.$goto_$rw$.minArgs = e.$setpos.minArgs = e.$setposition.minArgs = 1, e.$setx = function(e) { return this.translate(this._x, this._y, e - this._x, 0, !0) }, e.$setx.co_varnames = ["x"], e.$sety = function(e) { return this.translate(this._x, this._y, 0, e - this._y, !0) }, e.$sety.co_varnames = ["y"], e.$home = function() { var e = this, t = this._angle; return pushUndo(this), e.translate(this._x, this._y, -this._x, -this._y, !0) .then(function() { return e.queueTurnTo(t, 0) }) .then(function() {}) }, e.$right = e.$rt = function(e) { return pushUndo(this), this.rotate(this._angle, -e) }, e.$right.co_varnames = e.$rt.co_varnames = ["angle"], e.$left = e.$lt = function(e) { return pushUndo(this), this.rotate(this._angle, e) }, e.$left.co_varnames = e.$lt.co_varnames = ["angle"], e.$setheading = e.$seth = function(e) { return pushUndo(this), this.queueTurnTo(this._angle, e) }, e.$setheading.co_varnames = e.$seth.co_varnames = ["angle"], e.$circle = function(e, t, r) { var n, d, u, m, p, g, f, h, $, b = this, v = this._x, k = this._y, T = this._angle, A = {}, L = 1 / getScreen() .lineScale, S = !0; for (pushUndo(this), void 0 === t && (t = b._fullCircle), void 0 === r && (d = s(t) / b._fullCircle, r = 1 + (0 | a(11 + s(e * L) / 6, 59) * d)), u = t / r, m = .5 * u, p = 2 * e * _(u * o / b._fullCircle), 0 > e ? (p = -p, u = -u, m = -m, n = T - t) : n = T + t, $ = getFrameManager() .willRenderNext() ? Promise.resolve() : new InstantPromise, T += m, g = 0; g < r; g++) calculateHeading(b, T + u * g, A), f = c(A.radians) * p, h = _(A.radians) * p, $ = $.then(circleRotate(b, A.angle, A.radians)) .then(circleSegment(b, v, k, f, h, S)), v += f, k += h, S = !1; return $ = $.then(function() { return calculateHeading(b, n, A), b._angle = A.angle, b._radians = A.radians, b.addUpdate(void 0, !0, A) }), $ }, e.$circle.co_varnames = ["radius", "extent", "steps"], e.$circle.minArgs = 1, e.$penup = e.$up = e.$pu = function() { return this._down = !1, this.addUpdate(void 0, !1, { down: !1 }) }, e.$pendown = e.$down = e.$pd = function() { return this._down = !0, this.addUpdate(void 0, !1, { down: !0 }) }, e.$isdown = function() { return this._down }, e.$speed = function(e) { return void 0 === e ? this._speed : (this._speed = r(0, a(1e3, e)), this._computed_speed = r(0, 2 * e - 1), this.addUpdate(void 0, !1, { speed: this._computed_speed })) }, e.$speed.minArgs = 0, e.$speed.co_varnames = ["speed"], e.$pencolor = function(e, t, r, n) { return void 0 === e ? hexToRGB(this._color) : (this._color = createColor(this._colorMode, e, t, r, n), this.addUpdate(void 0, this._shown, { color: this._color })) }, e.$pencolor.co_varnames = ["r", "g", "b", "a"], e.$pencolor.minArgs = 0, e.$pencolor.returnType = x.COLOR, e.$fillcolor = function(e, t, r, n) { return void 0 === e ? hexToRGB(this._fill) : (this._fill = createColor(this._colorMode, e, t, r, n), this.addUpdate(void 0, this._shown, { fill: this._fill })) }, e.$fillcolor.co_varnames = ["r", "g", "b", "a"], e.$fillcolor.minArgs = 0, e.$fillcolor.returnType = x.COLOR, e.$color = function(e, t, r, n) { return void 0 === e ? [this.$pencolor(), this.$fillcolor()] : (void 0 === t || void 0 !== r ? (this._color = createColor(this._colorMode, e, t, r, n), this._fill = this._color) : (this._color = createColor(this._colorMode, e), this._fill = createColor(this._colorMode, t)), this.addUpdate(void 0, this._shown, { color: this._color, fill: this._fill })) }, e.$color.minArgs = 0, e.$color.co_varnames = ["color", "fill", "b", "a"], e.$color.returnType = function(e) { return new Sk.builtin.tuple([x.COLOR(e[0]), x.COLOR(e[1])]) }, e.$fill = function(e) { this; return void 0 === e ? this._filling : (e = !!e, e === this._filling) ? void 0 : (this._filling = e, e ? (pushUndo(this), this.addUpdate(void 0, !1, { filling: !0, fillBuffer: [{ x: this._x, y: this._y }] })) : (pushUndo(this), this.addUpdate(function() { this.fillBuffer.push(this), drawFill.call(this) }, !0, { filling: !1, fillBuffer: void 0 }))) }, e.$fill.co_varnames = ["flag"], e.$fill.minArgs = 0, e.$begin_fill = function() { return this.$fill(!0) }, e.$end_fill = function() { return this.$fill(!1) }, e.$stamp = function() { return pushUndo(this), this.addUpdate(function() { drawTurtle(this, this.context()) }, !0) }, e.$dot = function(e, t, n, l, i) { return pushUndo(this), e = Sk.builtin.asnum$(e), e = "number" == typeof e ? r(1, 0 | s(e)) : r(this._size + 4, 2 * this._size), t = void 0 === t ? this._color : createColor(this._colorMode, t, n, l, i), this.addUpdate(drawDot, !0, void 0, e, t) }, e.$dot.co_varnames = ["size", "color", "g", "b", "a"], e.$write = function(e, t, r, n) { var a, s, l, i, o, d = this; return pushUndo(this), e += "", n && n.constructor === Array && (s = "string" == typeof n[0] ? n[0] : "Arial", l = (n[1] || "12pt") + "", i = "string" == typeof n[2] ? n[2] : "normal", /^\\d+$/.test(l) && (l += "pt"), n = [i, l, s].join(" ")), r || (r = "left"), a = this.addUpdate(drawText, !0, void 0, e, r, n), t && ("left" === r || "center" === r) && (o = measureText(e, n), "center" === r && (o /= 2), a = a.then(function() { var e = d.getState(); return d.translate(e.x, e.y, o, 0, !0) })), a }, e.$write.co_varnames = ["message", "move", "align", "font"], e.$write.minArgs = 1, e.$pensize = e.$width = function(e) { return void 0 === e ? this._size : (this._size = e, this.addUpdate(void 0, this._shown, { size: e })) }, e.$pensize.minArgs = e.$width.minArgs = 0, e.$pensize.co_varnames = e.$width.co_varnames = ["width"], e.$showturtle = e.$st = function() { return this._shown = !0, this.addUpdate(void 0, !0, { shown: !0 }) }, e.$hideturtle = e.$ht = function() { return this._shown = !1, this.addUpdate(void 0, !0, { shown: !1 }) }, e.$isvisible = function() { return this._shown }, e.$shape = function(e) { return e && v[e] ? (this._shape = e, this.addUpdate(void 0, this._shown, { shape: e })) : this._shape }, e.$shape.minArgs = 0, e.$shape.co_varnames = ["name"], e.$colormode = function(e) { return void 0 === e ? this._colorMode : (this._colorMode = 255 === e ? 255 : 1, this.addUpdate(void 0, this._shown, { colorMode: this._colorMode })) }, e.$colormode.minArgs = 0, e.$colormode.co_varnames = ["cmode"], e.$colormode.returnType = function(e) { return 255 === e ? new Sk.builtin.int_(255) : new Sk.builtin.float_(1) }, e.$window_width = function() { return this._screen.$window_width() }, e.$window_height = function() { return this._screen.$window_height() }, e.$tracer = function(e, t) { return this._screen.$tracer(e, t) }, e.$tracer.minArgs = 0, e.$tracer.co_varnames = ["n", "delay"], e.$update = function() { return this._screen.$update() }, e.$delay = function(e) { return this._screen.$delay(e) }, e.$delay.minArgs = 0, e.$delay.co_varnames = ["delay"], e.$reset = function() { return this.reset(), this.$clear() }, e.$mainloop = e.$done = function() { return this._screen.$mainloop() }, e.$clear = function() { return this.addUpdate(function() { clearLayer(this.context()) }, !0) }, e.$dot.minArgs = 0, e.$onclick = function(e, t, r) { this.getManager("mousedown") .addHandler(e, r) }, e.$onclick.minArgs = 1, e.$onclick.co_varnames = ["method", "btn", "add"], e.$onrelease = function(e, t, r) { this.getManager("mouseup") .addHandler(e, r) }, e.$onrelease.minArgs = 1, e.$onrelease.co_varnames = ["method", "btn", "add"], e.$ondrag = function(e, t, r) { this.getManager("mousemove") .addHandler(e, r) }, e.$ondrag.minArgs = 1, e.$ondrag.co_varnames = ["method", "btn", "add"], e.$getscreen = function() { return Sk.misceval.callsimArray(y.Screen) }, e.$getscreen.isSk = !0, e.$clone = function() { var e = Sk.misceval.callsimOrSuspendArray(y.Turtle); return e.instance._x = this._x, e.instance._y = this._y, e.instance._angle = this._angle, e.instance._radians = this._radians, e.instance._shape = this._shape, e.instance._color = this._color, e.instance._fill = this._fill, e.instance._filling = this._filling, e.instance._size = this._size, e.instance._computed_speed = this._computed_speed, e.instance._down = this._down, e.instance._shown = this._shown, e.instance._colorMode = this._colorMode, e.instance._isRadians = this._isRadians, e.instance._fullCircle = this._fullCircle, e.instance._bufferSize = this._bufferSize, e.instance._undoBuffer = this._undoBuffer, e._clonedFrom = this, e }, e.$clone.returnType = function(e) { return e }, e.$getturtle = e.$getpen = function() { return this.skInstance }, e.$getturtle.isSk = !0 }(Turtle.prototype), function(e) { e.spriteLayer = function() { return this._sprites || (this._sprites = createLayer(3)) }, e.bgLayer = function() { return this._background || (this._background = createLayer(1)) }, e.hitTestLayer = function() { return this._hitTest || (this._hitTest = createLayer(0, !0)) }, e.getManager = function(e) { return this._managers[e] || (this._managers[e] = new EventManager(e, this)), this._managers[e] }, e.reset = function() { for (var e in this._keyListeners = void 0, this._keyLogger) window.clearInterval(this._keyLogger[e]), window.clearTimeout(this._keyLogger[e]), delete this._keyLogger[e]; for (e in this._keyDownListener && (getTarget() .removeEventListener("keydown", this._keyDownListener), this._keyDownListener = void 0), this._keyUpListener && (getTarget() .removeEventListener("keyup", this._keyUpListener), this._keyUpListener = void 0), this._timer && (window.clearTimeout(this._timer), this._timer = void 0), this._managers) this._managers[e].reset(); this._mode = "standard", removeLayer(this._sprites), this._sprites = void 0, removeLayer(this._background), this._background = void 0 }, e.setUpWorld = function(e, t, r, n) { var l = this; l.llx = e, l.lly = t, l.urx = r, l.ury = n, l.xScale = (r - e) / getWidth(), l.yScale = -1 * (n - t) / getHeight(), l.lineScale = a(s(l.xScale), s(l.yScale)) }, e.$setup = function(e, t, r, n) { return isNaN(parseFloat(e)) && (e = getWidth()), isNaN(parseFloat(t)) && (t = getHeight()), 1 >= e && (e = getWidth() * e), 1 >= t && (t = getHeight() * t), this._width = e, this._height = t, this._xOffset = void 0 === r || isNaN(parseInt(r)) ? 0 : parseInt(r), this._yOffset = void 0 === n || isNaN(parseInt(n)) ? 0 : parseInt(n), "world" === this._mode ? this._setworldcoordinates(this.llx, this.lly, this.urx, this.ury) : this._setworldcoordinates(-e / 2, -t / 2, e / 2, t / 2) }, e.$setup.minArgs = 0, e.$setup.co_varnames = ["width", "height", "startx", "starty"], e.$register_shape = e.$addshape = function(e, t) { return t ? void(v[e] = t) : getAsset(e) .then(function(t) { v[e] = t }) }, e.$register_shape.minArgs = 1, e.$getshapes = function() { return Object.keys(v) }, e.$tracer = function(e, t) { return void 0 !== e || void 0 !== t ? ("number" == typeof t && (this._delay = t, getFrameManager() .refreshInterval(t)), "number" == typeof e ? (this._frames = e, getFrameManager() .frameBuffer(e)) : void 0) : this._frames }, e.$tracer.co_varnames = ["frames", "delay"], e.$tracer.minArgs = 0, e.$delay = function(e) { return void 0 === e ? void 0 === this._delay ? b : this._delay : this.$tracer(void 0, e) }, e.$delay.co_varnames = ["delay"], e._setworldcoordinates = function(e, t, r, n) { var a = this, s = getFrameManager() .turtles(); return this.setUpWorld(e, t, r, n), this._sprites && applyWorld(this, this._sprites), this._background && applyWorld(this, this._background), this.$clear() }, e.$setworldcoordinates = function(e, t, r, n) { return this._mode = "world", this._setworldcoordinates(e, t, r, n) }, e.$setworldcoordinates.co_varnames = ["llx", "lly", "urx", "ury"], e.minArgs = 4, e.$clear = e.$clearscreen = function() { return this.reset(), this.$reset() }, e.$update = function() { return getFrameManager() .update() }, e.$reset = e.$resetscreen = function() { var e = this, t = getFrameManager() .turtles(); return getFrameManager() .addFrame(function() { applyWorld(e, e._sprites), applyWorld(e, e._background); for (var r = 0; r < t.length; r++) t[r].reset(), applyWorld(e, t[r]._paper) }, !0) }, e.$window_width = function() { return getWidth() }, e.$window_height = function() { return getHeight() }, e.$delay.minArgs = 0, e.$turtles = function() { return getFrameManager() .turtles() }, e.$turtles.returnType = x.TURTLE_LIST, e.$bgpic = function(e) { var t; return e ? (t = this, getAsset(e) .then(function(e) { clearLayer(t.bgLayer(), void 0, e) })) : this._bgpic }, e.$bgpic.minArgs = 0, e.$bgpic.co_varnames = ["name"], e.$bgcolor = function(e, t, r, n) { return void 0 === e ? hexToRGB(this._bgcolor) : (this._bgcolor = createColor(this._colorMode, e, t, r, n), void clearLayer(this.bgLayer(), this._bgcolor)) }, e.$bgcolor.minArgs = 0, e.$bgcolor.co_varnames = ["color", "g", "b", "a"], e.$bgcolor.returnType = x.COLOR, e.$mainloop = e.$done = function() {}, e.$bye = function() { return Sk.TurtleGraphics.reset() }, e.$exitonclick = function() { return this._exitOnClick = !0, this.getManager("mousedown") .addHandler(function() { resetTurtle() }, !1) }, e.$onclick = function(e, t, r) { this._exitOnClick || this.getManager("mousedown") .addHandler(e, r) }, e.$onclick.minArgs = 1, e.$onclick.co_varnames = ["method", "btn", "add"]; var t = { 8: /^back(space)?$/i, 9: /^tab$/i, 13: /^(enter|return)$/i, 16: /^shift$/i, 17: /^(ctrl|control)$/i, 18: /^alt$/i, 27: /^esc(ape)?$/i, 32: /^space$/i, 33: /^page[\\s\\-]?up$/i, 34: /^page[\\s\\-]?down$/i, 35: /^end$/i, 36: /^home$/i, 37: /^left([\\s\\-]?arrow)?$/i, 38: /^up([\\s\\-]?arrow)?$/i, 39: /^right([\\s\\-]?arrow)?$/i, 40: /^down([\\s\\-]?arrow)?$/i, 45: /^insert$/i, 46: /^del(ete)?$/i }; e._createKeyRepeater = function(e, t) { var r = this; r._keyLogger[t] = window.setTimeout(function() { r._keyListeners[e](), r._keyLogger[t] = window.setInterval(function() { r._keyListeners[e]() }, 50) }, 333) }, e._createKeyDownListener = function() { var r = this; this._keyDownListener || (this._keyDownListener = function(n) { var e = String.fromCharCode; if (focusTurtle()) { var a, s, l = n.charCode || n.keyCode, i = e(l) .toLowerCase(); if (!r._keyLogger[l]) for (a in r._keyListeners) if (s = 1 < a.length && t[l] && t[l].test(a), a === i || s) { r._keyListeners[a](), r._createKeyRepeater(a, l), n.preventDefault(); break } } }, getTarget() .addEventListener("keydown", this._keyDownListener)) }, e._createKeyUpListener = function() { var t = this; this._keyUpListener || (this._keyUpListener = function(r) { var e = t._keyLogger[r.charCode || r.keyCode]; void 0 !== e && (r.preventDefault(), window.clearInterval(e), window.clearTimeout(e), delete t._keyLogger[r.charCode || r.keyCode]) }, getTarget() .addEventListener("keyup", this._keyUpListener)) }, e.$listen = function() { this._createKeyUpListener(), this._createKeyDownListener() }, e.$onkey = function(e, t) { if ("function" == typeof t) { var r = e; e = t, t = r } t = (t + "") .toLowerCase(), e && "function" == typeof e ? (!this._keyListeners && (this._keyListeners = {}), this._keyListeners[t] = e) : delete this._keyListeners[t] }, e.$onkey.minArgs = 2, e.$onkey.co_varnames = ["method", "keyValue"], e.$onscreenclick = function(e, t, r) { this.getManager("mousedown") .addHandler(e, r) }, e.$onscreenclick.minArgs = 1, e.$onscreenclick.co_varnames = ["method", "btn", "add"], e.$ontimer = function(e, t) { this._timer && (window.clearTimeout(this._timer), this._timer = void 0), e && "number" == typeof t && (this._timer = window.setTimeout(e, r(0, 0 | t))) }, e.$ontimer.minArgs = 0, e.$ontimer.co_varnames = ["method", "interval"] }(Screen.prototype); var L = new Image, S = document.createElement("canvas") .getContext("2d"); for (var C in initTurtle.co_varnames = ["self", "shape"], initTurtle.co_name = new Sk.builtin.str("Turtle"), initTurtle.co_argcount = 2, initTurtle.$defaults = [Sk.builtin.none.none$, new Sk.builtin.str("classic")], Turtle.prototype) /^\\$[a-z_]+/.test(C) && addModuleMethod(Turtle, y, C, ensureAnonymous); return addModuleMethod(Screen, y, "$mainloop", getScreen), addModuleMethod(Screen, y, "$done", getScreen), addModuleMethod(Screen, y, "$bye", getScreen), addModuleMethod(Screen, y, "$tracer", getScreen), addModuleMethod(Screen, y, "$update", getScreen), addModuleMethod(Screen, y, "$delay", getScreen), addModuleMethod(Screen, y, "$window_width", getScreen), addModuleMethod(Screen, y, "$window_height", getScreen), y.Turtle = Sk.misceval.buildClass(y, function TurtleWrapper(e, t) { for (var r in t.__init__ = new Sk.builtin.func(initTurtle), Turtle.prototype) /^\\$[a-z_]+/.test(r) && addModuleMethod(Turtle, t, r) }, "Turtle", []), y.Screen = Sk.misceval.buildClass(y, function ScreenWrapper(e, t) { for (var r in t.__init__ = new Sk.builtin.func(function(e) { e.instance = getScreen() }), Screen.prototype) /^\\$[a-z_]+/.test(r) && addModuleMethod(Screen, t, r) }, "Screen", []), { skModule: y, reset: resetTurtle, stop: stopTurtle, focus: focusTurtle, Turtle: Turtle, Screen: Screen } }(e), Sk.TurtleGraphics.module = e.turtleInstance.skModule, Sk.TurtleGraphics.reset = e.turtleInstance.reset, Sk.TurtleGraphics.stop = e.turtleInstance.stop, Sk.TurtleGraphics.focus = e.turtleInstance.focus, Sk.TurtleGraphics.raw = { Turtle: e.turtleInstance.Turtle, Screen: e.turtleInstance.Screen }, e.turtleInstance.skModule };