Files
SMANAGE/TempLate/MSOC/Python/Lib/ScriptLib/turtle.js
T
2026-06-16 11:55:14 +08:00

1019 lines
44 KiB
JavaScript

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
};