1603,6,155,70,1253,70,1147,66,1069,64,690,71,968,70,928,66,875,47,925,39,308,39,138,40,198,40,681,45,25115,28,1049,26,939,19,1148,15,221,19,225,19,853,23,684,24,310,19,210,23,146,23,1452,22,687,18,662,22,302,22,5193,22,362,23,6835,25,1027,21,214,25,230,39,2816,25,2603,22,1073,19,1278,15,207,19,138,19,2025,24,793,20,207,24,190,24,703,26,2194,22,353,26,200,26,2882,27,1834,27,815,35,464,25,2135,19,554,15,246,19,196,19,1869,30,602,23,602,32,509,19,154,23,160,20,1362,23,16776,40,1176,37,1150,46,333,34,153,47,1281,59,473,47,1187,59,371,44,911,34,1253,38,923,38,675,53,314,30,3057,26,165,30,859,30,290,36,573,18,207,14,190,18,168,18,505,38,531,25,196,29,203,29,2410,25,1674,26,3921,25,2111,31,1218,32,5845,47,263,22,171,38,718,22,1850,41,1737,31,308,50,4220,48,3137,39,23477,23,992,31,136,34,903,24,486,20,184,24,308,36,1965,33,812,24,517,28,845,26,1323,30,975,32,797,28,4428,28,1420,22,514,43,450,52,750,54,748,38,670,45,246,20,1567,36,301,23,485,27,238,27,1014,29,790,24,3735,20,510,24,189,27,8232,24,8350,33,409,29,219,33,199,33,1834,28,442,25,1021,22,1096,18,204,22,249,22,717,27,839,29,1151,49,896,33,509,33,2459,24,329,26,1404,29,2097,32,5210,28,1234,30,918,24,1661,31,282,22,194,22,472,22,2341,22,333,24,487,42,750,29,194,33,203,33,804,36,714,23,359,27,195,27,840,32,259,19,821,23,202,23,2096,23,1516,34,785,35,972,25,205,34,388,32,1020,41,182,19,2074,17,1040,19,904,34,493,19,2032,25,750,33,1574,21,274,25,181,25,6279,33,3437,27,120,45,1265,33,3201,40,663,32,2506,31,205,31,285,35,2403,22,658,22,2269,34,616,25,3254,21,208,25,202,25,3263,31,310,27,266,31,165,31,1700,22,309,18,857,22,261,22,3046 _info {"project":"c-renderer","branch":"master","version":205,"versionDate":"2024-06-04T13:22:54.000Z","fromVersion":0,"reset":true,"checksumDocs":"216-312903"} _experimental/div-renderer/canvasCubes/canvasBigCube/canvasBigCube.ls (function(){ return function(color){ var lightColor, canvas, c, i$, y, j$, z, k$, x, xOffset, yOffset, zOffset; color = color || Color.teal[700]; lightColor = inc("/../app01/lib/util/changeLightness/change")(color, 0.25); canvas = document.createElement("canvas").attr({ width: 601, height: 601 }); c = canvas.getContext("2d"); c.lineWidth = 1; c.strokeStyle = "black"; for (i$ = 9; i$ >= 0; --i$) { y = i$; for (j$ = 0; j$ <= 9; ++j$) { z = j$; for (k$ = 9; k$ >= 0; --k$) { x = k$; xOffset = x * 50 + z * 10; yOffset = y * 50; zOffset = z * 10; c.fillStyle = lightColor; c.strokeRect(10.5 + xOffset, 10.5 + zOffset + yOffset, 50, 50); c.fillRect(10.5 + xOffset, 10.5 + zOffset + yOffset, 49.3, 49.3); c.beginPath(); c.moveTo(60.5 + xOffset, 10.5 + zOffset + yOffset); c.lineTo(50.5 + xOffset, 0.5 + zOffset + yOffset); c.lineTo(0.5 + xOffset, 0.5 + zOffset + yOffset); c.lineTo(0.5 + xOffset, 50.5 + zOffset + yOffset); c.lineTo(10.5 + xOffset, 60.5 + zOffset + yOffset); c.lineTo(10.5 + xOffset, 10.5 + zOffset + yOffset); c.lineTo(60.5 + xOffset, 10.5 + zOffset + yOffset); c.moveTo(0.5 + xOffset, 0.5 + zOffset + yOffset); c.lineTo(10.5 + xOffset, 10.5 + zOffset + yOffset); c.fillStyle = color; c.fill(); c.stroke(); } } } return canvas; }; })(); _experimental/div-renderer/canvasCubes/canvasBoard-old/canvasBoard.ls (function(){ return function(){ var canvas, c, i$, i, xOffset, yOffset; canvas = document.createElement("canvas").attr({ width: 611, height: 151 }); c = canvas.getContext("2d"); c.lineWidth = 1; for (i$ = 9; i$ >= 0; --i$) { i = i$; c.strokeStyle = "blue"; c.fillStyle = "red"; xOffset = i * 50; c.strokeRect(10.5 + xOffset, 10.5, 50, 50); c.fillRect(10.5 + xOffset, 10.5, 49.4, 49.4); } for (i$ = 9; i$ >= 0; --i$) { i = i$; xOffset = i * 50; yOffset = 0; c.beginPath(); if (i === 0) { c.moveTo(60.5 + xOffset, 10.5 + yOffset); c.lineTo(50.5 + xOffset, 0.5 + yOffset); c.lineTo(0.5 + xOffset, 0.5 + yOffset); c.lineTo(0.5 + xOffset, 50.5 + yOffset); c.lineTo(10.5 + xOffset, 60.5 + yOffset); c.lineTo(10.5 + xOffset, 10.5 + yOffset); c.lineTo(60.5 + xOffset, 10.5 + yOffset); c.moveTo(0.5 + xOffset, 0.5 + yOffset); c.lineTo(10.5 + xOffset, 10.5 + yOffset); } else { c.moveTo(0.5 + xOffset, 0.5 + yOffset); c.lineTo(10.5 + xOffset, 10.5 + yOffset); c.lineTo(60.5 + xOffset, 10.5 + yOffset); c.lineTo(50.5 + xOffset, 0.5 + yOffset); c.lineTo(0.5 + xOffset, 0.5 + yOffset); } c.fillStyle = "orange"; c.fill(); c.stroke(); } return canvas; }; })(); _experimental/div-renderer/canvasCubes/canvasBoard/canvasBoard.ls (function(){ return function(color){ var lightColor, canvas, c, i$, z, j$, x, xOffset, zOffset; color = color || Color.teal[700]; lightColor = inc("/../app01/lib/util/changeLightness/change")(color, 0.25); canvas = document.createElement("canvas").attr({ width: 601, height: 151 }); c = canvas.getContext("2d"); c.lineWidth = 1; c.strokeStyle = "black"; for (i$ = 0; i$ <= 9; ++i$) { z = i$; for (j$ = 9; j$ >= 0; --j$) { x = j$; xOffset = x * 50 + z * 10; zOffset = z * 10; c.fillStyle = lightColor; c.strokeRect(10.5 + xOffset, 10.5 + zOffset, 50, 50); c.fillRect(10.5 + xOffset, 10.5 + zOffset, 49.4, 49.4); c.beginPath(); c.moveTo(60.5 + xOffset, 10.5 + zOffset); c.lineTo(50.5 + xOffset, 0.5 + zOffset); c.lineTo(0.5 + xOffset, 0.5 + zOffset); c.lineTo(0.5 + xOffset, 50.5 + zOffset); c.lineTo(10.5 + xOffset, 60.5 + zOffset); c.lineTo(10.5 + xOffset, 10.5 + zOffset); c.lineTo(60.5 + xOffset, 10.5 + zOffset); c.moveTo(0.5 + xOffset, 0.5 + zOffset); c.lineTo(10.5 + xOffset, 10.5 + zOffset); c.fillStyle = color; c.fill(); c.stroke(); } } return canvas; }; })(); _experimental/div-renderer/canvasCubes/canvasCube/canvasCube.ls (function(){ return function(color){ var lightColor, canvas, c; color = color || Color.teal[700]; lightColor = inc("/../app01/lib/util/changeLightness/change")(color, 0.25); canvas = document.createElement("canvas").attr({ width: 61, height: 61 }); c = canvas.getContext("2d"); c.strokeStyle = "black"; c.fillStyle = lightColor; c.lineWidth = 1; c.strokeRect(10.5, 10.5, 50, 50); c.fillRect(10.5, 10.5, 49.4, 49.4); c.beginPath(); c.moveTo(60.5, 10.5); c.lineTo(50.5, 0.5); c.lineTo(0.5, 0.5); c.lineTo(0.5, 50.5); c.lineTo(10.5, 60.5); c.lineTo(10.5, 10.5); c.lineTo(60.5, 10.5); c.moveTo(0.5, 0.5); c.lineTo(10.5, 10.5); c.fillStyle = color; c.fill(); c.stroke(); return canvas; }; })(); _experimental/div-renderer/canvasCubes/canvasTower-copy/canvasTower.ls (function(){ return function(){ var canvas, c, i$, z, zOffset, j$, i, yOffset; canvas = document.createElement("canvas").attr({ width: 300, height: 601 }).css({ border: "1px solid red" }); c = canvas.getContext("2d"); c.lineWidth = 1; for (i$ = 0; i$ <= 9; ++i$) { z = i$; zOffset = z * 10; for (j$ = 9; j$ >= 0; --j$) { i = j$; c.strokeStyle = "blue"; c.fillStyle = "red"; yOffset = i * 50 + z * 10; c.fillRect(zOffset + 10.5, yOffset + 10.5, 50, 50); c.strokeRect(zOffset + 10.5, yOffset + 10.5, 50, 50); c.beginPath(); c.moveTo(zOffset + 60.5, yOffset + 10.5); c.lineTo(zOffset + 50.5, yOffset + 0.5); c.lineTo(zOffset + 0.5, yOffset + 0.5); c.lineTo(zOffset + 0.5, yOffset + 50.5); c.lineTo(zOffset + 10.5, yOffset + 60.5); c.lineTo(zOffset + 10.5, yOffset + 10.5); c.lineTo(zOffset + 60.5, yOffset + 10.5); c.moveTo(zOffset + 0.5, yOffset + 0.5); c.lineTo(zOffset + 10.5, yOffset + 10.5); c.fillStyle = "orange"; c.fill(); c.stroke(); } } return canvas; }; })(); _experimental/div-renderer/canvasCubes/canvasTower-old/canvasTower.ls (function(){ return function(){ var canvas, c, i$, i, yOffset; canvas = document.createElement("canvas").attr({ width: 61, height: 511 }); c = canvas.getContext("2d"); c.lineWidth = 1; for (i$ = 9; i$ >= 0; --i$) { i = i$; c.strokeStyle = "blue"; c.fillStyle = "red"; yOffset = i * 50; c.strokeRect(10.5, yOffset + 10.5, 50, 50); c.fillRect(10.5, yOffset + 10.5, 49.4, 49.4); c.beginPath(); if (i === 0) { c.moveTo(60.5, yOffset + 10.5); c.lineTo(50.5, yOffset + 0.5); c.lineTo(0.5, yOffset + 0.5); c.lineTo(0.5, yOffset + 50.5); c.lineTo(10.5, yOffset + 60.5); c.lineTo(10.5, yOffset + 10.5); c.lineTo(60.5, yOffset + 10.5); c.moveTo(0.5, yOffset + 0.5); c.lineTo(10.5, yOffset + 10.5); } else { c.moveTo(0.5, yOffset + 0.5); c.lineTo(0.5, yOffset + 50.5); c.lineTo(10.5, yOffset + 60.5); c.lineTo(10.5, yOffset + 10.5); c.lineTo(60.5, yOffset + 10.5); } c.fillStyle = "orange"; c.fill(); c.stroke(); } return canvas; }; })(); _experimental/div-renderer/canvasCubes/canvasTower/canvasTower.ls (function(){ return function(color){ var lightColor, canvas, c, i$, i, yOffset; color = color || Color.teal[700]; lightColor = inc("/../app01/lib/util/changeLightness/change")(color, 0.25); canvas = document.createElement("canvas").attr({ width: 61, height: 511 }); c = canvas.getContext("2d"); c.lineWidth = 1; for (i$ = 9; i$ >= 0; --i$) { i = i$; c.strokeStyle = "black"; c.fillStyle = lightColor; yOffset = i * 50; c.strokeRect(10.5, yOffset + 10.5, 50, 50); c.fillRect(10.5, yOffset + 10.5, 49.4, 49.4); c.beginPath(); c.moveTo(60.5, yOffset + 10.5); c.lineTo(50.5, yOffset + 0.5); c.lineTo(0.5, yOffset + 0.5); c.lineTo(0.5, yOffset + 50.5); c.lineTo(10.5, yOffset + 60.5); c.lineTo(10.5, yOffset + 10.5); c.lineTo(60.5, yOffset + 10.5); c.moveTo(0.5, yOffset + 0.5); c.lineTo(10.5, yOffset + 10.5); c.fillStyle = color; c.fill(); c.stroke(); } return canvas; }; })(); _experimental/div-renderer/canvasCubes/page.ls (function(){ return function(){ return { addons: inc("/../app01/addons/topbar2/topbar")({ back: true, title: "Lsg speed" }), start: function(page){ var cube, tower, towerCopy, board, bigCube; cube = inc("canvasCube/canvasCube")(); tower = inc("canvasTower/canvasTower")(); towerCopy = inc("canvasTower-copy/canvasTower")(); board = inc("canvasBoard/canvasBoard")(); bigCube = inc("canvasBigCube/canvasBigCube")(); page.append(Div().html("create Cube").tap(function(){ return page.append(cube); }), Div().html("create Tower").tap(function(){ return page.append(tower); }), Div().html("create Tower copy").tap(function(){ return page.append(towerCopy); }), Div().html("create Board").tap(function(){ return page.append(board); }), Div().html("create big Cube").tap(function(){ return page.append(bigCube); }), Div().html("clear").tap(function(){ return page.find("canvas").remove(); })); return app.centerPage(); } }; }; })(); _experimental/div-renderer/level-01.ls (function(){ return { uid: 'j703fq', title: "Test", voiceLang: "de", voice: "m1", keyboardLayout: "numbers", lsg: { lsg: path("renderer.ls"), width: 300, flags: 10 }, gapLength: 2, trainers: { trainer: "buttons", instruction: { text: "Zähle in 5er-Schritten!" }, atoms: { a: 100, b: "++100 200" } } }; })(); _experimental/div-renderer/renderer.ls (function(){ return function(o){ return inc("canvasCubes/canvasBigCube/canvasBigCube")().css({ width: "25em", height: "25em" }); }; })(); _experimental/laser-tablet/examples.lsg (function(){ return { version: 2, width: "1000mm", height: "300mm", background: Color.grey[100], objects: { type: 'lsg', lsg: path('renderer.lsr'), numberPrefix: "181106", numberStart: 1 } }; })(); _experimental/laser-tablet/renderer.lsr (function(){ return function(o){ var numberPrefix, lineColor, ref$, lineSize, ref1$, ref2$, textSize, ref3$, textColor, textFont, ref4$, lsg; numberPrefix = o.numberStart; numberPrefix = o.numberStart; lineColor = ((ref$ = o.lines) != null ? ref$.color : void 8) || Color.grey[800]; lineSize = (ref1$ = (ref2$ = o.lines) != null ? ref2$.size : void 8) != null ? ref1$ : 1; textSize = (ref1$ = (ref3$ = o.text) != null ? ref3$.size : void 8) != null ? ref1$ : 10; textColor = ((ref1$ = o.text) != null ? ref1$.color : void 8) || Color.grey[800]; textFont = (ref4$ = o.text) != null ? ref4$.font : void 8; lsg = { width: "300mm", height: "300mm", objects: [] }; return lsg; }; })(); _experimental/laser-tablet/three-tablets.svg ANTON - Tablet - Engraving Livescript angle/calcPieBorder/calc.ls (function(){ return function(o){ var startAngle, endAngle, angle, radius, centerX, centerY, direction, x1, y1, x2, y2, svg; startAngle = o.from; endAngle = o.to; angle = endAngle - startAngle; radius = o.radius - o.borderSize / 2; centerX = o.radius; centerY = o.radius; direction = angle > 180 ? 1 : 0; x1 = centerX + Math.sin(startAngle * Math.PI / 180) * radius; y1 = centerY - Math.cos(startAngle * Math.PI / 180) * radius; x2 = centerX + Math.sin(endAngle * Math.PI / 180) * radius; y2 = centerY - Math.cos(endAngle * Math.PI / 180) * radius; return svg = "\n \n"; }; })(); angle/calcPieFill/calc.ls (function(){ return function(o){ var startAngle, endAngle, angle, radius, centerX, centerY, direction, x1, y1, x2, y2, svg; startAngle = o.from; endAngle = o.to; angle = endAngle - startAngle; radius = o.radius; centerX = o.radius; centerY = o.radius; direction = angle > 180 ? 1 : 0; x1 = centerX + Math.sin(startAngle * Math.PI / 180) * radius; y1 = centerY - Math.cos(startAngle * Math.PI / 180) * radius; x2 = centerX + Math.sin(endAngle * Math.PI / 180) * radius; y2 = centerY - Math.cos(endAngle * Math.PI / 180) * radius; return svg = "\n \n"; }; })(); angle/examples.lsg (function(){ return { version: 2, width: 300, height: 1000, background: Color.grey[100], objects: [ { type: 'text', text: 'angles examples', x: 20, y: 10, size: 15, align: 'left' }, { type: 'text', text: 'only "to" value', x: 20, y: 35, size: 10, align: 'left' }, { type: 'lsg', lsg: path('renderer.lsr'), x: 20, y: 50, w: 100, to: 90 }, { type: 'text', text: '"to" and "from values', x: 20, y: 164, size: 10, align: 'left' }, { type: 'lsg', lsg: path('renderer.lsr'), x: 20, y: 179, w: 100, from: 15, to: 90 }, { type: 'text', text: 'custom colors and line size', x: 20, y: 290, size: 10, align: 'left' }, { type: 'lsg', lsg: path('renderer.lsr'), x: 20, y: 305, w: 100, fill: Color.red[500], border: Color.green[500], borderSize: 1, from: 15, to: 180 }, { type: 'text', text: 'line only', x: 22, y: 420, size: 10, align: 'left' }, { type: 'lsg', lsg: path('renderer.lsr'), x: 22, y: 435, w: 100, border: Color.pink[500], fillOpacity: 0, from: 0, to: 270 }, { type: 'text', text: 'fill only', x: 20, y: 553, size: 10, align: 'left' }, { type: 'lsg', lsg: path('renderer.lsr'), x: 28, y: 575, w: 100, borderSize: 0, from: -20, to: 180 } ] }; })(); angle/level.ls (function(){ return { uid: '3eyro5', trainers: { trainer: "buttons", instruction: { text: "instruction" }, lsg: { lsg: path("renderer.lsr"), width: 300, pieces: 10, to: 10, from: 5 }, atoms: { a: "a", b: "a" } } }; })(); angle/lsgEditor.ls (function(){ return { name: "Angles", 'default': { type: 'lsg', lsg: path('renderer.lsr'), x: 20, y: 150, w: 100, fill: Color.red[500], fillOpacity: 0.5, border: Color.green[500], borderSize: 10, from: 15, to: 180 } }; })(); angle/renderer.lsr (function(){ return function(o){ var lsg, pieSvgFill, pieSvgBorder; o.from = o.from || 0; o.radius = o.radius || 100; o.fill = o.fill || Color.blue[600]; o.fillOpacity = o.fillOpacity === 0 ? 0 : o.fillOpacity ? o.fillOpacity : 0.5; o.border = o.border || Color.blue[600]; o.borderSize = o.borderSize === 0 ? 0 : o.borderSize ? o.borderSize : 10; lsg = { width: o.radius * 2, height: o.radius * 2, objects: [], background: o.background, requiredArguments: "to" }; if (o.to == null) { return lsg; } pieSvgFill = inc("calcPieFill/calc")(o); lsg.objects.push({ type: 'svg', svg: pieSvgFill, x: 0, y: 0, w: o.radius * 2, color: o.fill, opacity: o.fillOpacity }); pieSvgBorder = inc("calcPieBorder/calc")(o); lsg.objects.push({ type: 'svg', svg: pieSvgBorder, x: 0, y: 0, w: o.radius * 2, lineColor: o.border, lineSize: o.borderSize }); return lsg; }; })(); calc-eggs/examples.lsg (function(){ return { version: 2, width: 300, height: 1000, background: Color.grey[100], objects: [ { type: 'text', text: 'Examples', x: 20, y: 10, color: 'black', size: 12, align: 'left' }, { type: 'lsg', lsg: path('renderer.lsr'), x: 38.4, y: 44.3, w: 206, color: 'white', tens: 3 }, { type: 'lsg', lsg: path('renderer.lsr'), x: 20, y: 120, w: 250, color: 'white', tens: 5 }, { type: 'lsg', lsg: path('renderer.lsr'), x: 20, y: 240, w: 250, color: 'white', ones: 2 }, { type: 'lsg', lsg: path('renderer.lsr'), x: 20, y: 310, w: 250, color: 'white', tens: 12, ones: 2 }, { type: 'lsg', lsg: path('renderer.lsr'), x: 20, y: 560, w: 250, color: 'white', tens: 5, ones: 12 } ] }; })(); calc-eggs/examples2.lsg (function(){ return { version: 2, width: 300, height: 1000, background: 'white', objects: [ { type: 'lsg', lsg: path('renderer.lsr'), x: 20, y: 50, w: 250, color: 'white', tens: 3, ones: 6 }, { type: 'line', 'class': 'line1', x1: 56, y1: 268, x2: 184, y2: 268, lineColor: Color.black, lineSize: 5 } ] }; })(); calc-eggs/level.ls (function(){ return { uid: '3eyro5', trainers: { trainer: "buttons", instruction: { text: "instruction" }, lsg: { lsg: path("renderer.lsr"), width: 300, tens: 3, ones: 3 }, atoms: { a: "a", b: "a" } } }; })(); calc-eggs/lsgEditor.ls (function(){ return { name: "Calc Eggs", 'default': { type: 'lsg', lsg: path('renderer.lsr'), w: 250, color: 'white', tens: 3, ones: 6 } }; })(); calc-eggs/renderer.lsr (function(){ return function(o){ var rows, rowHeight, colWidth1, colWidth10, padding, tensExtraPadding, lsg, i$, to$, i; o.ones == null && (o.ones = 0); o.tens == null && (o.tens = 0); if (o.ones === 0 && o.tens === 0) { debug("bitte entweder ones oder tens definieren"); } rows = Math.max(Math.ceil(o.tens / 2), Math.ceil(o.ones / 3)); rowHeight = 33; colWidth1 = 20; colWidth10 = 90; padding = (240 - 2 * colWidth10 - 3 * colWidth1) / 2; padding += 3; tensExtraPadding = Math.max(0, 2 - o.tens) * colWidth10 / 2; if (o.ones === 0) { tensExtraPadding += 33; } if (o.tens === 0 && o.ones === 1) { padding += 16; } if (o.tens === 0 && o.ones === 2) { padding += 6; } if (o.tens === 0 && o.ones >= 3) { padding -= 4; } lsg = { version: 2, 'class': 'color1', width: 246, height: rowHeight * rows, requiredArguments: ["tens", "ones"], objects: [] }; if (o.tens > 0) { for (i$ = 0, to$ = o.tens - 1; i$ <= to$; ++i$) { i = i$; lsg.objects.push({ type: 'svg', svg: path("/../c-svg/2020/08/05-renderer-calc-eggs-10-eggs.svg"), x: padding + tensExtraPadding + colWidth10 * (i % 2), y: Math.floor(i / 2) * rowHeight + 3, h: 25 }); } } if (o.ones > 0) { for (i$ = 0, to$ = o.ones - 1; i$ <= to$; ++i$) { i = i$; lsg.objects.push({ type: 'svg', svg: path("/../c-svg/2020/08/05-renderer-calc-eggs-one-egg.svg"), x: 10 + padding + 2 * colWidth10 + (i % 3) * colWidth1 - tensExtraPadding, y: 6 + Math.floor(i / 3) * rowHeight + 3, h: 13 }); } } return lsg; }; })(); calcline/examples.lsg (function(){ return { version: 2, width: 300, height: 2000, background: Color.grey[100], objects: [ { type: 'text', text: 'calcline examples one split:', x: 20, y: 10, color: 'black', size: 12, align: 'left' }, { type: 'lsg', lsg: path('renderer.lsr'), x: 20, y: 40, w: 250, h: 100, background: 'white', splits: 1, direction: 'right' }, { type: 'lsg', lsg: path('renderer.lsr'), x: 20, y: 170, w: 250, h: 100, background: 'white', splits: 0.1, direction: 'right', isDebug: true }, { type: 'lsg', lsg: path('renderer.lsr'), x: 20, y: 300, w: 250, h: 100, background: 'white', splits: [0.2, 0.6], direction: 'right', arrowDirections: ['right', 'left', 'right'], isDebug: true } ] }; })(); calcline/level.ls (function(){ return { uid: '3eyro5', keyboardLayout: "numbers", instruction: "Rechne zuerst die Einer dazu und dann die Zehner.", lsg: { lsg: path("/../c-renderer/calcline/renderer.lsr"), version: 2, width: 400, colorArrowLeft: Color.amber[600], colorArrowRight: Color.blue[600], direction: "right" }, gapLength: 2, gapAlign: "center", trainers: { trainer: "lsg", gapMode: 'write', lsg: { splits: [0.5] }, atoms: [ { id: "labelArrowBig", b: "+ 32" }, { id: "labelArrowLeft", b: "+((2))" }, { id: "labelFooterMiddle", b: "((55))" }, { id: "labelArrowRight", b: "+((30))" }, { id: "labelFooterLeft", b: "53" }, { id: "labelFooterRight", b: "((85))" } ] } }; })(); calcline/lsgEditor.ls (function(){ return { name: "Calc Line", 'default': { type: 'lsg', lsg: path('renderer.lsr'), x: 20, y: 690, w: 250, h: 100, background: 'white', splits: 0.5, direction: 'left', labelText: { footerLeft: 10, footerMiddle: 20, footerRight: 30, arrowBig: 'X', arrowLeft: 'Y', arrowRight: 'Z' } } }; })(); calcline/oneSplit.lsr (function(){ return function(o){ var width, height, paddingTop, paddingBottom, paddingH, isDebug, direction, arrowDirections, colorArrowBig, colorArrowLeft, colorArrowRight, split, heightLeftArrow, heightRightArrow, lsg, y, bigArrow, leftArrow, rightArrow, labelColor, x2, y2, ref$, ref1$, ref2$, ref3$, ref4$, ref5$; o = o || {}; width = 300; height = 100; if ((o != null && o.w) && (o != null && o.h)) { width = o.w; height = o.h; } paddingTop = 10; paddingBottom = 30; paddingH = 10; isDebug = (o != null ? o.isDebug : void 8) || false; direction = (o != null ? o.direction : void 8) || "right"; arrowDirections = _.ensureArray(o.arrowDirections); colorArrowBig = (o != null ? o.colorArrowBig : void 8) || Color.deepPurple[500]; colorArrowLeft = (o != null ? o.colorArrowLeft : void 8) || Color.blue[600]; colorArrowRight = (o != null ? o.colorArrowRight : void 8) || Color.amber[600]; split = (o != null ? o.split : void 8) || 0.3; split = Math.min(0.88, split); split = Math.max(0.12, split); heightLeftArrow = split <= 0.1 ? height * 0.25 : split <= 0.2 ? height * 0.3 : split <= 0.3 ? height * 0.35 : height * 0.4; heightRightArrow = split >= 0.9 ? height * 0.25 : split >= 0.8 ? height * 0.3 : split >= 0.7 ? height * 0.35 : height * 0.4; lsg = { width: width, height: height + paddingBottom - 10, background: "white", objects: [] }; lsg.objects.push({ type: 'line', 'class': 'mainLine', lineColor: Color.grey[400], lineSize: 1, x1: paddingH, x2: width - paddingH, y1: y = height - paddingTop + 10, y2: y }); lsg.objects.push(bigArrow = { type: 'lsg', 'class': "bigArrow", lsg: path("../ellipse-arrow/renderer.lsr"), x: 0, y: 0 + 10, w: width, h: height, color: colorArrowBig, lineColor: colorArrowBig, direction: direction, yEnd: 8 }); leftArrow = { type: 'lsg', 'class': "leftArrow", lsg: path("../ellipse-arrow/renderer.lsr"), x: 0, y: height - heightLeftArrow + 10, w: (width + 2 * paddingH) * split, h: heightLeftArrow, color: colorArrowLeft, lineColor: colorArrowLeft, direction: (arrowDirections != null ? arrowDirections[0] : void 8) || direction, shape: 0.3 }; rightArrow = { type: 'lsg', 'class': "rightArrow", lsg: path("../ellipse-arrow/renderer.lsr"), x: (width + 2 * paddingH) * split - paddingH * 2, y: height - heightRightArrow + 10, w: (width + 2 * paddingH) * (1 - split), h: heightRightArrow, color: colorArrowRight, lineColor: colorArrowRight, direction: (arrowDirections != null ? arrowDirections[1] : void 8) || direction, shape: 0.3 }; if (direction === "left") { lsg.objects.push(leftArrow); lsg.objects.push(rightArrow); } else { lsg.objects.push(rightArrow); lsg.objects.push(leftArrow); } labelColor = isDebug ? Color.grey[500] : "transparent"; lsg.objects.push({ type: "rect", 'class': "labelFooterLeft", x: x2 = 5, y: y2 = y + 13, w: 10, h: 10, color: labelColor }); if ((o != null ? (ref$ = o.labelText) != null ? ref$.footerLeft : void 8 : void 8) != null) { lsg.objects.push({ type: "text", 'class': "textFooterLeft", x: x2 + 8, y: y2 - 5, color: "black", text: o.labelText.footerLeft, align: "center", size: 12 }); } lsg.objects.push({ type: "rect", 'class': "labelFooterMiddle", x: x2 = (width + 2 * paddingH) * split - paddingH * 2 + 5, y: y2 = y + 13, w: 10, h: 10, color: labelColor }); if ((o != null ? (ref1$ = o.labelText) != null ? ref1$.footerMiddle : void 8 : void 8) != null) { lsg.objects.push({ type: "text", 'class': "textFooterMiddle", x: x2 + 5, y: y2 - 5, color: "black", text: o.labelText.footerMiddle, align: "center", size: 12 }); } lsg.objects.push({ type: "rect", 'class': "labelFooterRight", x: x2 = width - paddingH - 5, y: y2 = y + 13, w: 10, h: 10, color: labelColor }); if ((o != null ? (ref2$ = o.labelText) != null ? ref2$.footerRight : void 8 : void 8) != null) { lsg.objects.push({ type: "text", 'class': "textFooterRight", x: x2 + 2, y: y2 - 5, color: "black", text: o.labelText.footerRight, align: "center", size: 12 }); } lsg.objects.push({ type: "rect", 'class': "labelArrowBig", x: x2 = bigArrow.x + bigArrow.w / 2 - 5, y: y2 = 0, w: 10, h: 10, color: labelColor }); if ((o != null ? (ref3$ = o.labelText) != null ? ref3$.arrowBig : void 8 : void 8) != null) { lsg.objects.push({ type: "text", 'class': "textArrowBig", x: x2 + 5, y: y2, color: "black", text: o.labelText.arrowBig, align: "center", size: 12 }); } lsg.objects.push({ type: "rect", 'class': "labelArrowLeft", x: x2 = Math.max(leftArrow.x + leftArrow.w / 2, width * 0.1), y: y2 = leftArrow.y - 13, w: 10, h: 10, color: labelColor }); if ((o != null ? (ref4$ = o.labelText) != null ? ref4$.arrowLeft : void 8 : void 8) != null) { lsg.objects.push({ type: "text", 'class': "textArrowLeft", x: x2 + 5, y: y2 - 2, color: "black", text: o.labelText.arrowLeft, align: "center", size: 12 }); } lsg.objects.push({ type: "rect", 'class': "labelArrowRight", x: x2 = Math.min(rightArrow.x + rightArrow.w / 2, width * 0.86), y: y2 = rightArrow.y - 13, w: 10, h: 10, color: labelColor }); if ((o != null ? (ref5$ = o.labelText) != null ? ref5$.arrowRight : void 8 : void 8) != null) { lsg.objects.push({ type: "text", 'class': "textArrowRight", x: x2 + 5, y: y2 - 2, color: "black", text: o.labelText.arrowRight, align: "center", size: 12 }); } return lsg; }; })(); calcline/renderer.lsr (function(){ return function(o){ var splits, i$, to$, i; splits = _.ensureArray(o.splits); for (i$ = 0, to$ = splits.length; i$ < to$; ++i$) { i = i$; splits[i] = Math.min(0.88, splits[i]); splits[i] = Math.max(0.12, splits[i]); } if (splits.length === 1) { o.split = splits[0]; return inc("oneSplit.lsr")(o); } else { return inc("twoSplits.lsr")(o); } }; })(); calcline/twoSplits.lsr (function(){ return function(o){ var width, height, paddingTop, paddingBottom, paddingH, isDebug, direction, arrowDirections, colorArrowBig, colorArrowLeft, colorArrowMiddle, colorArrowRight, splits, i$, to$, i, arrowHeight, heightLeftArrow, heightMiddleArrow, heightRightArrow, lsg, y, bigArrow, leftArrow, middleArrow, rightArrow, labelColor, x2, y2, ref$, ref1$, ref2$, ref3$, ref4$, ref5$, ref6$, ref7$; width = 300; height = 100; if ((o != null && o.w) && (o != null && o.h)) { width = o.w; height = o.h; } paddingTop = 10; paddingBottom = 30; paddingH = 10; isDebug = (o != null ? o.isDebug : void 8) || false; direction = (o != null ? o.direction : void 8) || "right"; arrowDirections = _.ensureArray(o.arrowDirections); colorArrowBig = (o != null ? o.colorArrowBig : void 8) || Color.deepPurple[500]; colorArrowLeft = (o != null ? o.colorArrowLeft : void 8) || Color.blue[600]; colorArrowMiddle = (o != null ? o.colorArrowMiddle : void 8) || Color.red[500]; colorArrowRight = (o != null ? o.colorArrowRight : void 8) || Color.amber[600]; splits = (o != null ? o.splits : void 8) || [0.12, 0.88]; for (i$ = 0, to$ = splits.length; i$ < to$; ++i$) { i = i$; splits[i] = Math.min(0.88, splits[i]); splits[i] = Math.max(0.12, splits[i]); } arrowHeight = function(length){ if (length <= 0.1) { height * 0.25; } if (length <= 0.2) { height * 0.3; } if (length <= 0.3) { return height * 0.35; } else { return height * 0.4; } }; heightLeftArrow = arrowHeight(splits[0]); heightMiddleArrow = arrowHeight(splits[1] - splits[0]); heightRightArrow = arrowHeight(1 - splits[1]); lsg = { width: width, height: height + paddingBottom - 10, background: "white", requiredArguments: "splits", objects: [] }; lsg.objects.push({ type: 'line', 'class': 'mainLine', lineColor: Color.grey[400], lineSize: 1, x1: paddingH, x2: width - paddingH, y1: y = height - paddingTop + 10, y2: y }); lsg.objects.push(bigArrow = { type: 'lsg', 'class': "bigArrow", lsg: path("../ellipse-arrow/renderer.lsr"), x: 0, y: 0 + 10, w: width, h: height, color: colorArrowBig, lineColor: colorArrowBig, direction: direction, yEnd: 8 }); leftArrow = { type: 'lsg', 'class': "leftArrow", lsg: path("../ellipse-arrow/renderer.lsr"), x: 0, y: height - heightLeftArrow + 10, w: (width + 4 * paddingH) * splits[0], h: heightLeftArrow, color: colorArrowLeft, lineColor: colorArrowLeft, direction: (arrowDirections != null ? arrowDirections[0] : void 8) || direction, shape: 0.3 }; middleArrow = { type: 'lsg', 'class': "rightArrow", lsg: path("../ellipse-arrow/renderer.lsr"), x: (width + 4 * paddingH) * splits[0] - paddingH * 2, y: height - heightMiddleArrow + 10, w: (width + 4 * paddingH) * (splits[1] - splits[0]), h: heightMiddleArrow, color: colorArrowMiddle, lineColor: colorArrowMiddle, direction: (arrowDirections != null ? arrowDirections[1] : void 8) || direction, shape: 0.3 }; rightArrow = { type: 'lsg', 'class': "rightArrow", lsg: path("../ellipse-arrow/renderer.lsr"), x: (width + 4 * paddingH) * splits[1] - paddingH * 4, y: height - heightRightArrow + 10, w: (width + 4 * paddingH) * (1 - splits[1]), h: heightRightArrow, color: colorArrowRight, lineColor: colorArrowRight, direction: (arrowDirections != null ? arrowDirections[2] : void 8) || direction, shape: 0.3 }; lsg.objects.push(leftArrow); lsg.objects.push(middleArrow); lsg.objects.push(rightArrow); labelColor = isDebug ? Color.grey[500] : "transparent"; lsg.objects.push({ type: "rect", 'class': "labelFooterLeft", x: x2 = 5, y: y2 = y + 13, w: 10, h: 10, color: labelColor }); if ((o != null ? (ref$ = o.labelText) != null ? ref$.footerLeft : void 8 : void 8) != null) { lsg.objects.push({ type: "text", 'class': "textFooterLeft", x: x2 + 8, y: y2 - 5, color: "black", text: o.labelText.footerLeft, align: "center", size: 12 }); } lsg.objects.push({ type: "rect", 'class': "labelFooterMiddleLeft", x: x2 = (width + 4 * paddingH) * splits[0] - paddingH * 2 + 5, y: y2 = y + 13, w: 10, h: 10, color: labelColor }); if ((o != null ? (ref1$ = o.labelText) != null ? ref1$.footerMiddleLeft : void 8 : void 8) != null) { lsg.objects.push({ type: "text", 'class': "textFooterMiddleLeft", x: x2 + 5, y: y2 - 5, color: "black", text: o.labelText.footerMiddleLeft, align: "center", size: 12 }); } lsg.objects.push({ type: "rect", 'class': "labelFooterMiddleRight", x: x2 = (width + 4 * paddingH) * splits[1] - paddingH * 4 + 5, y: y2 = y + 13, w: 10, h: 10, color: labelColor }); if ((o != null ? (ref2$ = o.labelText) != null ? ref2$.footerMiddleRight : void 8 : void 8) != null) { lsg.objects.push({ type: "text", 'class': "textFooterMiddleRight", x: x2 + 5, y: y2 - 5, color: "black", text: o.labelText.footerMiddleRight, align: "center", size: 12 }); } lsg.objects.push({ type: "rect", 'class': "labelFooterRight", x: x2 = width - paddingH - 5, y: y2 = y + 13, w: 10, h: 10, color: labelColor }); if ((o != null ? (ref3$ = o.labelText) != null ? ref3$.footerRight : void 8 : void 8) != null) { lsg.objects.push({ type: "text", 'class': "textFooterRight", x: x2 + 2, y: y2 - 5, color: "black", text: o.labelText.footerRight, align: "center", size: 12 }); } lsg.objects.push({ type: "rect", 'class': "labelArrowBig", x: x2 = bigArrow.x + bigArrow.w / 2 - 5, y: y2 = 0, w: 10, h: 10, color: labelColor }); if ((o != null ? (ref4$ = o.labelText) != null ? ref4$.arrowBig : void 8 : void 8) != null) { lsg.objects.push({ type: "text", 'class': "textArrowBig", x: x2 + 5, y: y2, color: "black", text: o.labelText.arrowBig, align: "center", size: 12 }); } lsg.objects.push({ type: "rect", 'class': "labelArrowLeft", x: x2 = Math.max(leftArrow.x + leftArrow.w / 2, width * 0.1), y: y2 = leftArrow.y - 13, w: 10, h: 10, color: labelColor }); if ((o != null ? (ref5$ = o.labelText) != null ? ref5$.arrowLeft : void 8 : void 8) != null) { lsg.objects.push({ type: "text", 'class': "textArrowLeft", x: x2 + 5, y: y2 - 2, color: "black", text: o.labelText.arrowLeft, align: "center", size: 12 }); } lsg.objects.push({ type: "rect", 'class': "labelArrowMiddle", x: x2 = Math.max(middleArrow.x + middleArrow.w / 2, width * 0.1), y: y2 = middleArrow.y - 13, w: 10, h: 10, color: labelColor }); if ((o != null ? (ref6$ = o.labelText) != null ? ref6$.arrowMiddle : void 8 : void 8) != null) { lsg.objects.push({ type: "text", 'class': "textArrowMiddle", x: x2 + 5, y: y2 - 2, color: "black", text: o.labelText.arrowMiddle, align: "center", size: 12 }); } lsg.objects.push({ type: "rect", 'class': "labelArrowRight", x: x2 = Math.min(rightArrow.x + rightArrow.w / 2, width * 0.86), y: y2 = rightArrow.y - 13, w: 10, h: 10, color: labelColor }); if ((o != null ? (ref7$ = o.labelText) != null ? ref7$.arrowRight : void 8 : void 8) != null) { lsg.objects.push({ type: "text", 'class': "textArrowRight", x: x2 + 5, y: y2 - 2, color: "black", text: o.labelText.arrowRight, align: "center", size: 12 }); } return lsg; }; })(); calcstripes/examples.lsg (function(){ return { version: 2, width: 300, height: 1000, background: Color.grey[100], objects: [ { type: 'lsg', lsg: path('renderer.lsr'), x: 50, y: 20, w: 200, background: 'white', dots: 7, circleBorder: true }, { type: 'lsg', lsg: path('renderer.lsr'), x: 50, y: 70, w: 200, background: 'white', dots: 6, plusDots: 2 }, { type: 'lsg', lsg: path('renderer.lsr'), x: 50, y: 120, w: 200, background: 'white', dots: 6, minusDots: 2 }, { type: 'lsg', lsg: path('renderer.lsr'), x: 50, y: 170, w: 200, background: 'white', dots: 10, plusDots: 5, circleBorder: true }, { type: 'lsg', lsg: path('renderer.lsr'), x: 50, y: 250, w: 200, background: 'white', dots: 10, plusDots: 5, circleBorder: true, rows: 10 }, { type: 'lsg', lsg: path('renderer.lsr'), x: 50, y: 500, w: 200, color: 'white', background: 'white', dots: 10, plusDots: 5, circleBorder: true, columns: 5, rows: 5 }, { type: 'lsg', lsg: path('renderer.lsr'), x: 50, y: 250, w: 200, background: 'white', dots: 10, plusDots: 5, circleBorder: true, rows: 10 } ] }; })(); calcstripes/level.ls (function(){ return { uid: '3eyro5', trainers: { trainer: "buttons", instruction: { text: "instruction" }, lsg: { lsg: path("renderer.lsr"), width: 300, columns: 8, dots: 88 }, atoms: { a: "a", b: "a" } } }; })(); calcstripes/lsgEditor.ls (function(){ return { name: "Calc Stripes", 'default': { type: 'lsg', x: 50, y: 50, w: 200, color: "white", lsg: path("renderer.lsr"), background: "white", dots: 10, plusDots: 5, circleBorder: true, columns: 5, rows: 5 } }; })(); calcstripes/renderer-wip-until-900.lsr (function(){ return function(o){ var totalDots, cols, rows, rowHeight, colWidth, offset, emptyDots, circleBorderColor, lsg, i$, to$, i, x, y, j; if (o.columns > 30 || o.rows > 30) { debug("columns or rows must be <= 30 (maximum 900 dots are allowed currently)"); } o.plusDots = o.plusDots || 0; o.minusDots = o.minusDots || 0; totalDots = o.dots + o.plusDots + o.minusDots; cols = o.columns || 10; rows = o.rows || Math.floor(totalDots / cols) + (totalDots % cols === 0 ? 0 : 1); rowHeight = 301 / 10; colWidth = 300 / 10; offset = 2; emptyDots = rows * cols; emptyDots -= o.dots || 0; emptyDots -= o.plusDots || 0; emptyDots -= o.minusDots || 0; circleBorderColor = o.circleBorder ? Color.grey[500] : "transparent"; lsg = { width: 5 + colWidth * cols + (cols < 6 ? 2 : 0 + (cols % 5 === 0 ? Math.floor(cols / 5 - 1) * 10 : Math.floor(cols / 5) * 10)), height: 5 + rowHeight * rows + (rows < 6 ? 2 : 0 + (rows % 5 === 0 ? Math.floor(rows / 5 - 1) * 10 : Math.floor(rows / 5) * 10)), requiredArguments: "dots", objects: [] }; if (o.dots) { for (i$ = 0, to$ = o.dots - 1; i$ <= to$; ++i$) { i = i$; x = offset + i % cols * 30 + Math.floor((i % cols) / 5) * 10; y = offset + Math.floor(i / cols) * 30 + Math.floor((i / cols) / 5) * 10; lsg.objects.push({ type: 'oval', 'class': "dot", color: Color.blue[500], lineColor: circleBorderColor, lineSize: 1, x: x + 3, y: y + 3, w: 25, h: 25 }); } } if (o.plusDots) { for (i$ = 0, to$ = o.plusDots - 1; i$ <= to$; ++i$) { i = i$; j = o.dots + i; x = offset + j % cols * 30 + Math.floor((j % cols) / 5) * 10; y = offset + Math.floor(j / cols) * 30 + Math.floor((j / cols) / 5) * 10; lsg.objects.push({ type: 'oval', 'class': "plusDot", color: Color.red[500], lineColor: circleBorderColor, lineSize: 1, x: x + 3, y: y + 3, w: 25, h: 25 }); } } if (o.minusDots) { for (i$ = 0, to$ = o.minusDots - 1; i$ <= to$; ++i$) { i = i$; j = o.dots + _.defaultTo(o.plusDots, 0) + i; x = offset + j % cols * 30 + Math.floor((j % cols) / 5) * 10; y = offset + Math.floor(j / cols) * 30 + Math.floor((j / cols) / 5) * 10; lsg.objects.push({ type: 'oval', 'class': "dot", color: Color.blue[500], lineColor: circleBorderColor, lineSize: 1, x: x + 3, y: y + 3, w: 25, h: 25 }); lsg.objects.push({ type: 'line', 'class': "minusLine", lineColor: Color.red[600], lineSize: 5, x1: 4.2 + x + 22, y1: 4.2 + y, x2: 4.2 + x, y2: 4.2 + y + 22 }); } } if (o.circleBorder) { for (i$ = 0, to$ = emptyDots - 1; i$ <= to$; ++i$) { i = i$; j = o.dots + _.defaultTo(o.plusDots, 0) + _.defaultTo(o.minusDots, 0) + i; x = offset + j % cols * 30 + Math.floor((j % cols) / 5) * 10; y = offset + Math.floor(j / cols) * 30 + Math.floor((j / cols) / 5) * 10; lsg.objects.push({ type: 'oval', color: "transparent", lineColor: circleBorderColor, lineSize: 1, x: x + 3, y: y + 3, w: 25, h: 25 }); } } return lsg; }; })(); calcstripes/renderer.lsr (function(){ return function(o){ var totalDots, cols, rows, rowHeight, colWidth, offset, emptyDots, circleBorderColor, lsg, i$, to$, i, x, y, j; if (o.columns > 10 || o.rows > 10) { debug("columns or rows must be <= 10"); } o.plusDots = o.plusDots || 0; o.minusDots = o.minusDots || 0; totalDots = o.dots + o.plusDots + o.minusDots; cols = o.columns || 10; rows = o.rows || Math.floor(totalDots / cols) + (totalDots % cols === 0 ? 0 : 1); rowHeight = 301 / 10; colWidth = 300 / 10; offset = 2; emptyDots = rows * cols; emptyDots -= o.dots || 0; emptyDots -= o.plusDots || 0; emptyDots -= o.minusDots || 0; circleBorderColor = o.circleBorder ? Color.grey[500] : "transparent"; lsg = { width: 5 + colWidth * cols + (cols > 5 ? 10 : 2), height: 5 + rowHeight * rows + (rows > 5 ? 10 : 2), requiredArguments: "dots", objects: [] }; if (o.dots) { for (i$ = 0, to$ = o.dots - 1; i$ <= to$; ++i$) { i = i$; x = offset + i % cols * 30 + (i % cols > 4 ? 10 : 0); y = offset + Math.floor(i / cols) * 30 + (Math.floor(i / cols) > 4 ? 10 : 0); lsg.objects.push({ type: 'oval', 'class': "dot", color: Color.blue[500], lineColor: circleBorderColor, lineSize: 1, x: x + 3, y: y + 3, w: 25, h: 25 }); } } if (o.plusDots) { for (i$ = 0, to$ = o.plusDots - 1; i$ <= to$; ++i$) { i = i$; j = o.dots + i; x = offset + j % cols * 30 + (j % cols > 4 ? 10 : 0); y = offset + Math.floor(j / cols) * 30 + (Math.floor(j / cols) > 4 ? 10 : 0); lsg.objects.push({ type: 'oval', 'class': "plusDot", color: Color.red[500], lineColor: circleBorderColor, lineSize: 1, x: x + 3, y: y + 3, w: 25, h: 25 }); } } if (o.minusDots) { for (i$ = 0, to$ = o.minusDots - 1; i$ <= to$; ++i$) { i = i$; j = o.dots + _.defaultTo(o.plusDots, 0) + i; x = offset + j % cols * 30 + (j % cols > 4 ? 10 : 0); y = offset + Math.floor(j / cols) * 30 + (Math.floor(j / cols) > 4 ? 10 : 0); lsg.objects.push({ type: 'oval', 'class': "dot", color: Color.blue[500], lineColor: circleBorderColor, lineSize: 1, x: x + 3, y: y + 3, w: 25, h: 25 }); lsg.objects.push({ type: 'line', 'class': "minusLine", lineColor: Color.red[600], lineSize: 5, x1: 4.2 + x + 22, y1: 4.2 + y, x2: 4.2 + x, y2: 4.2 + y + 22 }); } } if (o.circleBorder) { for (i$ = 0, to$ = emptyDots - 1; i$ <= to$; ++i$) { i = i$; j = o.dots + _.defaultTo(o.plusDots, 0) + _.defaultTo(o.minusDots, 0) + i; x = offset + j % cols * 30 + (j % cols > 4 ? 10 : 0); y = offset + Math.floor(j / cols) * 30 + (Math.floor(j / cols) > 4 ? 10 : 0); lsg.objects.push({ type: 'oval', color: "transparent", lineColor: circleBorderColor, lineSize: 1, x: x + 3, y: y + 3, w: 25, h: 25 }); } } return lsg; }; })(); clock/calcPie/calc.ls (function(){ return function(startHour, duration){ var startAngle, endAngle, radius, centerX, centerY, direction, x1, y1, x2, y2, svg; if (startHour == null) { startHour = 0; } startHour = startHour % 12; if (startHour < 0 || startHour > 12 || duration < 0 || duration > 12) { return; } startAngle = 360 * (startHour / 12); endAngle = 360 * (duration / 12) + startAngle; radius = 130; centerX = 150; centerY = 150; direction = duration > 6 ? 1 : 0; x1 = centerX + Math.sin(startAngle * Math.PI / 180) * radius; y1 = centerY - Math.cos(startAngle * Math.PI / 180) * radius; x2 = centerX + Math.sin(endAngle * Math.PI / 180) * radius; y2 = centerY - Math.cos(endAngle * Math.PI / 180) * radius; return svg = "\n \n"; }; })(); clock/examples.lsg (function(){ return { version: 2, width: 300, height: 1150, background: Color.grey[100], objects: [ { type: 'text', text: 'clock examples', x: 20, y: 10, color: 'black', size: 12, align: 'left' }, { type: 'lsg', lsg: path('renderer.lsr'), x: 20, y: 30, w: 100, time: '20:20' }, { type: 'lsg', lsg: path('renderer.lsr'), x: 20, y: 150, w: 100, color: { pie: Color.yellow[400] }, time: '20:20', pieStartHour: 6, pieDuration: 4 }, { type: 'lsg', lsg: path('renderer.lsr'), x: 20, y: 270, w: 100, color: { pie: Color.blue[400] }, time: '20:20', pieStartHour: 15, pieDuration: 0.5 }, { type: 'lsg', lsg: path('renderer.lsr'), x: 20, y: 390, w: 100, color: { background: Color.purple[100], border: Color.red[700], numbers: Color.pink[500], pointerMinutes: Color.green[500], pointerHours: Color.orange[600] }, time: '20:20' }, { type: 'lsg', lsg: path('renderer.lsr'), x: 20, y: 510, w: 150, time: '5:00' }, { type: 'lsg', lsg: path('renderer.lsr'), x: 20, y: 670, w: 150, time: '20:10' }, { type: 'lsg', lsg: path('renderer.lsr'), x: 20, y: 850, w: 150, time: '20:10:57' }, { type: 'lsg', lsg: path('renderer.lsr'), x: 20, y: 1020, w: 100, numerals: "roman", color: { pie: Color.yellow[400], numbers: Color.blue[700] }, time: '22:22:13', pieStartHour: 12, pieDuration: 4 } ] }; })(); clock/level.ls (function(){ return { uid: '3eyro5', trainers: { trainer: "buttons", instruction: { text: "instruction" }, lsg: { lsg: path("renderer.lsr"), width: 300, time: "13:37" }, atoms: { a: "a", b: "a" } } }; })(); clock/lsgEditor.ls (function(){ return { name: "Clock", 'default': { type: 'lsg', lsg: path('renderer.lsr'), x: 20, y: 150, w: 100, time: "12:30" } }; })(); clock/renderer.lsr (function(){ return function(o){ var time, numerals, lsg, hours, minutes, seconds, hourRotation, minuteRotation, secondRotation, pieSvg; time = o.time; numerals = o.numerals || "arabic"; lsg = { width: 300, height: 300, objects: [], requiredArguments: "time", color: { background: "white", border: Color.blue[700], numbers: "black", pointerSeconds: Color.grey[500], pointerMinutes: Color.deepOrange[700], pointerHours: "black", pie: Color.green[100] } }; if (!time) { return lsg; } hours = time.split(":")[0]; if (hours > 12) { hours -= 12; } minutes = time.split(":")[1]; seconds = time.split(":")[2]; hourRotation = 360 * (hours / 12) + (360 / 12) * (minutes / 60); minuteRotation = 360 * (minutes / 60); if (seconds) { secondRotation = 360 * (seconds / 60); } lsg.objects.push({ type: 'oval', 'class': "background", w: 296, h: 296, x: 2, y: 2 }); if (o.pieStartHour != null && o.pieDuration != null) { pieSvg = inc("calcPie/calc")(o.pieStartHour, o.pieDuration); lsg.objects.push({ type: 'svg', 'class': "pie", svg: pieSvg, x: 0, y: 0, w: 300 }); } lsg.objects.push({ type: 'svg', svg: path("/../c-svg/2021/04/01-renderer-clock.svg"), 'class': "border", x: 0, y: 0, w: 300 }); lsg.objects.push({ type: 'svg', svg: (function(){ switch (numerals) { case "arabic": return path("/../c-svg/2020/08/05-renderer-clock-numbers.svg"); case "roman": return path("/../c-svg/2022/06/23-renderer-clock-roman-numerals.svg"); } }()), 'class': "numbers", x: 0, y: 0, w: 300 }); if (seconds) { lsg.objects.push({ type: 'svg', svg: path("/../c-svg/2021/02/22-renderer-clock-pointer-seconds.svg"), 'class': "pointerSeconds", rotate: secondRotation, x: 0, y: 0, w: 300 }); } lsg.objects.push({ type: 'svg', svg: path("/../c-svg/2020/08/05-renderer-clock-pointer-minutes.svg"), 'class': "pointerMinutes", rotate: minuteRotation, x: 0, y: 0, w: 300 }); lsg.objects.push({ type: 'svg', svg: path("/../c-svg/2020/08/05-renderer-clock-pointer-hours.svg"), 'class': "pointerHours", rotate: hourRotation, x: 0, y: 0, w: 300 }); return lsg; }; })(); color-text/examples.lsg (function(){ return { version: 2, width: 150, height: 1000, background: Color.grey[100], objects: [ { type: 'text', text: 'Color set examples:', x: 20, y: 10, color: 'black', size: 12, align: 'left' }, { type: 'lsg', lsg: path('renderer.lsr'), x: 20, y: 40, w: 100, background: 'white', text: 'Hallo', textColor: Color.red[600] }, { type: 'lsg', lsg: path('renderer.lsr'), x: 20, y: 160, w: 100, textSize: 30, background: 'white', text: 'Hallo gut', textColor: 'blue' }, { type: 'text', text: 'Color random examples:', x: 20, y: 268, color: 'black', size: 12, align: 'left' }, { type: 'lsg', lsg: path('renderer.lsr'), x: 20, y: 290, w: 100, background: 'white', text: 'Hallo' }, { type: 'lsg', lsg: path('renderer.lsr'), x: 20, y: 400, w: 100, background: 'white', text: 'Hallo' } ] }; })(); color-text/level.ls (function(){ return { uid: '3eyro5', trainers: { trainer: "buttons", instruction: { text: "instruction" }, lsg: { lsg: path("renderer.lsr"), width: 300, text: "Hallo" }, atoms: { a: "a", b: "a" } } }; })(); color-text/lsgEditor.ls (function(){ return { name: "Color Text", 'default': { type: 'lsg', lsg: path('renderer.lsr'), x: 20, y: 40, w: 100, background: 'white', text: 'Hallo', textColor: Color.red[600] } }; })(); color-text/renderer.lsr (function(){ return function(o){ var textSize, textColor, availableColors, lsg; textSize = o.textSize || 40; if (o.textColor != null) { textColor = o.textColor; } else { availableColors = _.filter(_.keys(Color), function(c){ return c !== "black" && c !== "white" && c !== "grey"; }); textColor = availableColors[_.random(0, availableColors.length - 1)]; textColor = Color[textColor][700]; } lsg = { width: 150, height: 40 * textSize / 34, objects: [], requiredArguments: "text" }; if (!o.text) { return lsg; } lsg.objects.push({ type: "text", text: o.text, x: 75, y: -6 * textSize / 40, size: textSize, lineHeight: 22, color: textColor, align: "center", font: "Solocode School" }); return lsg; }; })(); division-box/examples.lsg (function(){ return { version: 2, width: 300, height: 1000, background: Color.white, objects: [ { type: 'lsg', lsg: path('renderer.lsr'), x: 0, y: 0, w: 300, divisor: '20', dividend: '100', quotient: '5' }, { type: 'lsg', lsg: path('renderer.lsr'), x: 0, y: 225, w: 300, color: Color.teal[500], divisor: '20', dividend: '100', quotient: '5', quotientGap: true }, { type: 'lsg', lsg: path('renderer.lsr'), x: 0, y: 450, w: 300, color: Color.purple[700], background: Color.yellow[300], divisor: '20', dividend: '100', quotient: '5', dividendGap: true }, { type: 'lsg', lsg: path('renderer.lsr'), x: 0, y: 675, w: 300, color: Color.pink[700], background: Color.green[100], divisor: '20', dividend: '100', quotient: '5', divisorGap: true }, { type: 'lsg', lsg: path('renderer.lsr'), x: 100.8, y: 931.7, color: Color.pink[700], background: Color.blue[100], textSize: 20, divisor: '20', dividend: '100', quotient: '5', divisorGap: true, dividendGap: true, quotientGap: true }, { type: 'lsg', lsg: path('renderer.lsr'), x: 0, y: 930, color: Color.pink[700], background: Color.blue[100], textSize: 20, divisor: '20', dividend: '100', quotient: '5', divisorGap: true, dividendGap: true }, { type: 'lsg', lsg: path('renderer.lsr'), x: 208.3, y: 929.2, color: Color.pink[700], background: Color.blue[100], textSize: 20, divisor: '20', dividend: '100', quotient: '5', divisorGap: true, quotientGap: true }, { type: 'text', text: 'Dividend, Divisor and Quotient shown:', x: 20, y: 10, color: 'black', size: 12, align: 'left' }, { type: 'text', text: 'Gap for the quotient:', x: 20, y: 250, color: 'black', size: 12, align: 'left' }, { type: 'text', text: 'Gap for the dividend:', x: 20, y: 460, color: 'black', size: 12, align: 'left' }, { type: 'text', text: 'Gap for the divisor:', x: 20, y: 690, color: 'black', size: 12, align: 'left' }, { type: 'text', text: 'Gap for divisor \nand dividend:', x: 0, y: 900, color: 'black', size: 12, align: 'left' }, { type: 'text', text: 'Gap for divisor, \ndividend and quotient:', x: 90, y: 900, color: 'black', size: 12, align: 'left' }, { type: 'text', text: 'Gap for divisor \nand dividend:', x: 220, y: 900, color: 'black', size: 12, align: 'left' } ] }; })(); division-box/level.ls (function(){ return { uid: '8gga9k', trainers: { trainer: "lsg", gapMode: "write", instruction: { text: "", speaker: true }, shuffleButtons: false, lsg: { width: 100, lsg: path('renderer.lsr'), divisor: "20", dividend: "100", quotient: "5", dividendGap: true, textSize: 50, color: Color.purple[700] }, atoms: { id: "dividend", b: "((++5))" } } }; })(); division-box/lsgEditor.ls (function(){ return { name: "Division Box", 'default': { type: 'lsg', lsg: path('renderer.lsr'), x: 92.9, y: 173.4, w: 139, divisor: '20', dividend: '100', quotient: '5', quotientGap: true } }; })(); division-box/renderer.lsr (function(){ return function(o){ var textSize, color, dividendGap, ref$, divisorGap, quotientGap, padding, digitsDividend, digitsDivisor, digitsQuotient, lsgHeight, lsgWidth, lsg; o.renderLanguage == null && (o.renderLanguage = "de"); textSize = o.textSize || 40; color = o.color || Color.black; dividendGap = (ref$ = o.dividendGap) != null ? ref$ : false; divisorGap = (ref$ = o.divisorGap) != null ? ref$ : false; quotientGap = (ref$ = o.quotientGap) != null ? ref$ : false; padding = 5; digitsDividend = (o.dividend + "").length; digitsDivisor = (o.divisor + "").length; digitsQuotient = (o.quotient + "").length; lsgHeight = textSize * 5 / 2 + padding * 2; lsgWidth = padding * 2 + digitsDividend * textSize / 2 + digitsDividend * textSize / 2 + textSize; lsg = { width: lsgWidth, height: lsgHeight, objects: [], requiredArguments: ["dividend", "divisor", "quotient"] }; lsg.objects.push({ 'class': "line", type: "line", lineColor: color, x1: padding + digitsDividend * textSize / 2 + textSize / 6, y1: padding + textSize * 4 / 3, x2: lsgWidth - padding, y2: padding + textSize * 4 / 3, lineSize: textSize / 10 }); lsg.objects.push({ 'class': "line", type: "text", text: o.renderLanguage === "es" ? "|" : ")", color: color, x: padding + digitsDividend * textSize / 2 + textSize / 3 - (o.renderLanguage === "es" ? 5 : 0), y: padding + textSize, size: textSize * 4 / 3, align: "center", font: "Source Sans Pro" }); if (divisorGap) { lsg.objects.push({ 'class': "divisor", type: "rect", x: padding, y: padding + textSize * 3 / 2, w: digitsDividend * textSize / 2, h: textSize, color: "transparent" }); } else { lsg.objects.push({ 'class': "divisor", type: "text", color: color, text: o.divisor, x: padding + digitsDividend * textSize / 4, y: padding + textSize * 4 / 3, size: textSize, align: "center", font: "Source Sans Pro" }); } if (dividendGap) { lsg.objects.push({ 'class': "dividend", type: "rect", x: padding + digitsDividend * textSize / 2 + 3 * textSize / 4, y: padding + textSize * 3 / 2, w: digitsDividend * textSize / 2, h: textSize, color: "transparent" }); } else { lsg.objects.push({ 'class': "dividend", type: "text", color: color, text: o.dividend, x: padding + digitsDividend * textSize / 2 + 3 * textSize / 4 + digitsDividend * textSize / 4, y: padding + textSize * 4 / 3, size: textSize, align: "center", font: "Source Sans Pro" }); } if (quotientGap) { lsg.objects.push({ 'class': "quotient", type: "rect", x: padding + digitsDividend * textSize / 2 + 3 * textSize / 4, y: padding + textSize * 1 / 6, w: digitsDividend * textSize / 2, h: textSize, color: "transparent" }); } else { lsg.objects.push({ 'class': "quotient", type: "text", color: color, text: o.quotient, x: padding + digitsDividend * textSize / 2 + 3 * textSize / 4 + digitsDividend * textSize / 4, y: padding, size: textSize, align: "center", font: "Source Sans Pro" }); } return lsg; }; })(); ellipse-arrow/examples.lsg (function(){ return { version: 2, width: 300, height: 1300, background: Color.grey[100], objects: [ { type: 'text', text: 'ellipseArrow examples:', x: 20, y: 10, color: 'black', size: 12, align: 'left' }, { type: 'lsg', lsg: path('renderer.lsr'), x: 19.3, y: 40, w: 200, h: 100, background: 'white' }, { type: 'lsg', lsg: path('renderer.lsr'), x: 20, y: 160, w: 200, h: 70, color: 'orange', background: 'white', direction: 'right' }, { type: 'lsg', lsg: path('renderer.lsr'), x: 20, y: 240, w: 200, h: 70, lineColor: 'blue', background: 'white', direction: 'right', shape: 0.3 }, { type: 'lsg', lsg: path('renderer.lsr'), x: 20, y: 320, w: 200, h: 70, color: 'orange', lineColor: 'pink', background: 'white', direction: 'right', shape: 0.3, yEnd: 10 }, { type: 'lsg', lsg: path('renderer.lsr'), x: 20, y: 400, w: 200, h: 40, color: 'orange', lineColor: 'orange', background: 'white', direction: 'right', shape: 0.3 }, { type: 'lsg', lsg: path('renderer.lsr'), x: 20, y: 480, w: 200, h: 100, background: 'white', direction: 'left' }, { type: 'lsg', lsg: path('renderer.lsr'), x: 20, y: 600, w: 60, h: 60, background: 'white', direction: 'right' }, { type: 'text', text: 'big arrow:', x: 20, y: 680, color: 'black', size: 12, align: 'left' }, { type: 'lsg', lsg: path('renderer.lsr'), x: 20, y: 710, w: 200, h: 100, background: 'white' }, { type: 'lsg', lsg: path('renderer.lsr'), x: 20, y: 840, w: 200, h: 100, background: 'white', direction: 'left', shape: 0.3 }, { type: 'text', text: 'down arrows:', x: 20, y: 970, color: 'black', size: 12, align: 'left' }, { type: 'lsg', lsg: path('renderer.lsr'), x: 20, y: 1000, w: 70, h: 200, background: 'white', direction: 'downRight', shape: 0.2 }, { type: 'lsg', lsg: path('renderer.lsr'), x: 127, y: 1000, w: 70, h: 200, background: 'white', direction: 'downLeft', shape: 0.2 } ] }; })(); ellipse-arrow/renderer.lsr (function(){ return function(o){ var direction, width, height, padding, shape, xEnd, yEnd, lineColor, lsg; direction = (o != null ? o.direction : void 8) || "right"; if (direction === "left" || direction === "right") { width = 300; height = 100; } else { width = 100; height = 300; } if ((o != null && o.w) && (o != null && o.h)) { width = o.w; height = o.h; } padding = 10; shape = (o != null ? o.shape : void 8) || 0; xEnd = (o != null ? o.xEnd : void 8) || 0; yEnd = (o != null ? o.yEnd : void 8) || 0; lineColor = (o != null ? o.lineColor : void 8) || "black"; lsg = { width: width, height: height, objects: [inc("svg/svg")({ width: width - padding * 2, height: height - padding * 2, padding: padding, direction: direction, shape: shape, xEnd: xEnd, yEnd: yEnd, lineColor: lineColor })] }; return lsg; }; })(); ellipse-arrow/svg/marker/marker.ls (function(){ return function(color, markerEndId){ return "\n \n \n \n"; }; })(); ellipse-arrow/svg/svg.ls (function(){ return function(o){ var w, h, padding, direction, outerW, outerH, d, x1, x2, xStretch, ref$, y1, y2, ySkew, markerEndId, marker, svg, object; w = o.width; h = o.height; padding = o.padding; direction = o.direction; outerW = w + padding * 2; outerH = h + padding * 2; d = ""; if (direction === "right") { x1 = padding; x2 = w + padding; xStretch = w * ((ref$ = o.shape) != null ? ref$ : 0); y1 = h + padding; y2 = -(1 / 3 * h) + padding; d += "M" + x1 + "," + y1 + " "; d += "C" + (x1 + xStretch) + "," + y2 + " "; d += (x2 - xStretch) + "," + y2 + " "; d += x2 + "," + (y1 - o.yEnd) + " "; } else if (direction === "left") { x1 = padding; x2 = w + padding; xStretch = w * ((ref$ = o.shape) != null ? ref$ : 0); y1 = h + padding; y2 = -(1 / 3 * h) + padding; d += "M" + x2 + "," + y1 + " "; d += "C" + (x2 - xStretch) + "," + y2 + " "; d += (x1 + xStretch) + "," + y2 + " "; d += x1 + "," + (y1 - o.yEnd) + " "; } else if (direction === "downLeft") { x1 = w + padding; xStretch = h * ((ref$ = o.shape) != null ? ref$ : 0); y1 = padding; y2 = h + padding; ySkew = 1 / 3 * h; d += "M" + x1 + "," + y1 + " "; d += "C" + (x1 - xStretch) + "," + (y1 + ySkew) + " "; d += (x1 - xStretch) + "," + (y2 - ySkew) + " "; d += (x1 - o.xEnd) + "," + y2 + " "; } else if (direction === "downRight") { x1 = padding; xStretch = h * ((ref$ = o.shape) != null ? ref$ : 0); y1 = padding; y2 = h + padding; ySkew = 1 / 3 * h; d += "M" + x1 + "," + y1 + " "; d += "C" + (x1 + xStretch) + "," + (y1 + ySkew) + " "; d += (x1 + xStretch) + "," + (y2 - ySkew) + " "; d += (x1 - o.xEnd) + "," + y2 + " "; } markerEndId = "smallCaret" + _.random(10000000000); marker = inc("marker/marker")(o.lineColor, markerEndId); svg = "\n " + marker + "\n \n"; return object = { type: "svg", svg: svg, x: 0, y: 0, w: outerW, h: outerH }; }; })(); flags/examples.lsg (function(){ return { width: 300, height: 1000, background: Color.grey[100], objects: [ { type: 'lsg', lsg: path('renderer.lsr'), x: 20, y: 30, w: 250, color: { flag1: 'pink', flag2: 'orange' }, background: 'white', flags: 5 }, { type: 'lsg', lsg: path('renderer.lsr'), x: 20, y: 140, w: 250, color: { flag1: Color.blue[100], flag2: Color.blue[700] }, background: 'white', flags: 10 }, { type: 'lsg', lsg: path('renderer.lsr'), x: 20, y: 210, w: 250, color: { flag1: Color.blue[100], flag2: Color.blue[700] }, background: 'white', flags: 15 } ] }; })(); flags/level.ls (function(){ return { uid: '3eyro5', trainers: { trainer: "buttons", instruction: { text: "instruction" }, lsg: { lsg: path("renderer.lsr"), width: 300, flags: 10, color: { flag1: 'pink', flag2: 'orange' } }, atoms: { a: "a", b: "a" } } }; })(); flags/lsgEditor.ls (function(){ return { name: "Flags", 'default': { type: 'lsg', lsg: path('renderer.lsr'), x: 20, y: 30, w: 250, color: { flag1: 'pink', flag2: 'orange' }, background: 'white', flags: 5 } }; })(); flags/renderer.lsr (function(){ return function(o){ var flagWidth, flagHeight, flagPadding, lineHeight, paddingTop, paddingBottom, lsgWidth, lsgHeight, flagColors, leafColors, leafRotations, lsg, i$, to$, i; o.flag1Color = Color.purple[500]; o.flag2Color = Color.red[500]; flagWidth = 40; flagHeight = 60; flagPadding = 2; lineHeight = 5; paddingTop = 20; paddingBottom = 10; lsgWidth = flagWidth * o.flags + flagPadding * 2 * o.flags; lsgHeight = paddingTop + paddingBottom + flagHeight; flagColors = [Color.blue[300], Color.red[600]]; leafColors = [Color.green[300], Color.green[600]]; leafRotations = [20, 70]; lsg = { width: lsgWidth, height: lsgHeight, objects: [], requiredArguments: "flags", color: { flag1: "green", flag2: "red" } }; for (i$ = 0, to$ = o.flags - 1; i$ <= to$; ++i$) { i = i$; lsg.objects.push({ type: 'svg', svg: path("/../c-svg/2020/08/05-renderer-flags.svg"), 'class': i % 2 === 0 ? "flag1" : "flag2", x: flagPadding + flagWidth * i + flagPadding * 2 * i, y: flagPadding + lineHeight + paddingTop - 1, w: 40, h: 65 }); } for (i$ = 0, to$ = o.flags - 1; i$ <= to$; ++i$) { i = i$; lsg.objects.push({ type: 'rect', color: Color.grey[200], 'class': "label id" + (i + 1), x: flagPadding + flagWidth * i + flagPadding * 2 * i + 5, y: flagPadding + lineHeight + paddingTop - 1 + 5, w: flagWidth - 10, h: flagHeight - 20 }); } lsg.objects.push({ type: 'rect', 'class': 'color3', color: Color.brown[300], x: flagPadding, y: flagPadding + paddingTop, w: lsgWidth - flagPadding * 2, h: lineHeight }); for (i$ = 0, to$ = Math.max(4, o.flags); i$ <= to$; ++i$) { i = i$; lsg.objects.push({ type: 'svg', color: leafColors[_.random(0, leafColors.length - 1)], svg: path("/../c-svg/2020/08/05-renderer-flags-leaf.svg"), x: _.random(flagWidth / 2, lsgWidth - flagWidth / 2), y: 10, w: 30, rotate: leafRotations[_.random(0, leafRotations.length - 1)] }); } return lsg; }; })(); graphPlot/example-matteam.lsg (function(){ return { version: 2, 'class': 'rect', width: 300, height: 300, objects: { type: 'lsg', lsg: path('renderer.lsr'), x: 0, y: 0, background: 'transparent', width: 300, height: 300, grid: { color: Color.grey[400], steps: { x: 0.5, y: 0.5 } }, xAxis: { label: 'x', min: -1.5, max: 4, stepDistance: 1 }, yAxis: { label: 'y', min: -1.5, max: 5, stepDistance: 1 }, functions: [ { f: function(x){ return -1.5 * (x + 0.5) + 4; }, color: Color.purple[600] }, { f: function(x){ return Math.pow(x, 2); }, color: Color.green[500] }, { f: function(x){ return 1.5; }, color: Color.red[500] } ] } }; })(); graphPlot/example2.lsg (function(){ return { version: 2, 'class': 'rect', width: 300, height: 300, objects: { type: 'lsg', lsg: path('renderer.lsr'), x: 0, y: 0, background: 'transparent', width: 300, height: 300, grid: { color: Color.grey[400], steps: { x: 0.5, y: 0.5 } }, xAxis: { label: 'x', min: -1.5, max: 4, stepDistance: 1 }, yAxis: { label: 'y', min: -1.5, max: 5, stepDistance: 1 }, functions: [ { f: function(x){ return -1.5 * (x + 0.5) + 4; }, color: Color.purple[600] }, { f: function(x){ return Math.pow(x, 2); }, color: Color.green[500] }, { f: function(x){ return 1.5; }, color: Color.red[500] } ] } }; })(); graphPlot/examples-renderer.lsg (function(){ return { version: 2, 'class': 'rect', width: 1000, height: 5300, objects: { type: 'lsg', lsg: path('renderer.lsr'), x: 0, y: 0, background: 'transparent', width: 1000, height: 1000, fontSize: 80, grid: { color: Color.grey[400], steps: { x: 0.5, y: 0.5 } }, xAxis: { label: 'x', min: -1.5, max: 4, stepDistance: 1 }, yAxis: { label: 'y', min: -1.5, max: 5, stepDistance: 1 }, functions: { f: function(x){ return 2 * x; }, color: Color.purple[600], functionLineSize: 9, lineDash: true } } }; })(); graphPlot/level.ls (function(){ return { uid: '4ifp8l', trainers: { trainer: "buttons", lsg: { lsg: path("example2.lsg"), width: 500 }, atoms: { a: "1", b: "1" } } }; })(); graphPlot/lsgEditor.ls (function(){ return { name: "Graph Plot", 'default': { type: 'lsg', lsg: path('renderer.lsr'), w: 300, h: 300, x: 0, y: 0, background: 'transparent' } }; })(); graphPlot/n_neg.lsg (function(){ return { version: 2, width: 300, height: 300, background: 'transparent', objects: [ { type: 'lsg', lsg: path('/../c-renderer/graphPlot/renderer.lsr'), x: -0.5, y: -0.5, w: 301, h: 301, background: 'transparent', grid: { color: Color.grey[400], steps: { x: 1, y: 1 } }, xAxis: { label: 'x', min: -4, max: 4, stepDistance: 1 }, yAxis: { label: 'y', min: -4, max: 4, stepDistance: 1 }, functions: [ { f: function(x){ if (x > 0) { return Math.pow(x, -3); } }, functionLineSize: 6, color: Color.purple[500] }, { f: function(x){ if (x < 0) { return Math.pow(x, -3); } }, functionLineSize: 6, color: Color.purple[500] }, { f: function(x){ if (x < 0) { return Math.pow(x, -2); } }, functionLineSize: 6, color: Color.lime[500] }, { f: function(x){ if (x > 0) { return Math.pow(x, -2); } }, functionLineSize: 6, color: Color.lime[500] } ] }, { type: 'text', text: 'x', x: 64.83, y: 58.78, color: Color.lime[500], size: 26, align: 'center', font: 'Source Sans Pro' }, { type: 'text', text: '-2', x: 77.66, y: 56.09, color: Color.lime[500], size: 17, align: 'center', font: 'Source Sans Pro' }, { type: 'text', text: 'x', x: 64.77, y: 213.97, color: Color.purple[500], size: 26, align: 'center', font: 'Source Sans Pro' }, { type: 'text', text: '-3', x: 77.6, y: 211.28, color: Color.purple[500], size: 17, align: 'center', font: 'Source Sans Pro' } ] }; })(); graphPlot/renderer.lsr (function(){ return function(o){ var lsgWidth, lsgHeight, drawGrid, gridColor, ref$, gridSteps, ref1$, ref2$, ref3$, ref4$, ref5$, ref6$, ref7$, minX, ref8$, maxX, ref9$, minY, ref10$, maxY, ref11$, minZ, ref12$, maxZ, ref13$, lineWidth, gridWidth, stepWidth, textSize, ref14$, pointSize, functionWidth, helpLineWidth, xAxisColor, yAxisColor, ref15$, zAxisColor, ref16$, pointDefaultColor, functionDefaultColor, helpLineDefaultColor, decimalPoint, padding, ref17$, paddingLeft, textLength, toLsgXY, lsg, gridPoints, step, stepPrecision, i$, to$, x, from, y, ref18$, len$, to, drawXAxis, drawYAxis, drawZAxis, drawPoints, drawFunctions, drawHelpLines, constructInvisibleGridPoints; lsgWidth = o.width || o.height || 1000; lsgHeight = o.height || o.width || 1000; drawGrid = o.grid; gridColor = ((ref$ = o.grid) != null ? ref$.color : void 8) || Color.grey[400]; gridSteps = _.isFinite((ref1$ = o.grid) != null ? ref1$.steps : void 8) ? { x: o.grid.steps, y: o.grid.steps } : { x: ((ref2$ = o.grid) != null ? (ref3$ = ref2$.steps) != null ? ref3$.x : void 8 : void 8) || ((ref4$ = o.xAxis) != null ? ref4$.stepDistance : void 8) || 1, y: ((ref5$ = o.grid) != null ? (ref6$ = ref5$.steps) != null ? ref6$.y : void 8 : void 8) || ((ref7$ = o.yAxis) != null ? ref7$.stepDistance : void 8) || 1 }; minX = ((ref8$ = o.xAxis) != null ? ref8$.min : void 8) || 0; maxX = ((ref9$ = o.xAxis) != null ? ref9$.max : void 8) || 10; minY = ((ref10$ = o.yAxis) != null ? ref10$.min : void 8) || 0; maxY = ((ref11$ = o.yAxis) != null ? ref11$.max : void 8) || 10; minZ = ((ref12$ = o.zAxis) != null ? ref12$.min : void 8) || 0; maxZ = ((ref13$ = o.zAxis) != null ? ref13$.max : void 8) || 10; if (!o.zAxis) { maxZ = 0; } lineWidth = lsgWidth / 150; gridWidth = lsgWidth / 400; stepWidth = (lsgWidth / 400) * 5; textSize = (ref14$ = o.fontSize) != null ? ref14$ : (lsgWidth / 400) * 20; pointSize = (ref14$ = o.pointSize) != null ? ref14$ : (lsgWidth / 400) * 15; functionWidth = (ref14$ = o.functionLineSize) != null ? ref14$ : lineWidth * 2; helpLineWidth = (ref14$ = o.helpLineSize) != null ? ref14$ : lineWidth * 2; xAxisColor = ((ref14$ = o.xAxis) != null ? ref14$.color : void 8) || Color.grey[800]; yAxisColor = ((ref15$ = o.yAxis) != null ? ref15$.color : void 8) || Color.grey[800]; zAxisColor = ((ref16$ = o.zAxis) != null ? ref16$.color : void 8) || Color.grey[800]; pointDefaultColor = Color.blue[500]; functionDefaultColor = Color.blue[500]; helpLineDefaultColor = Color.blue[500]; o.renderLanguage == null && (o.renderLanguage = "de"); decimalPoint = (function(){ switch (o.renderLanguage) { case "de": case "fr": case "pt": return ","; case "en_gb": case "en_us": case "es": return "."; } }()); padding = (ref17$ = o.padding) != null ? ref17$ : textSize * 1.75; paddingLeft = padding; if (minX === 0 && ((ref17$ = o.yAxis) != null && ref17$.stepDistance)) { paddingLeft *= 2; textLength = Math.max((minY + "").length, (maxY + "").length); paddingLeft = Math.max(padding, textLength * textSize * 0.75); } toLsgXY = function(x, y, z){ var availableWidth, availableHeight, coordinateWidth, coordinateHeight, coordinateOffsetX, coordinateOffsetY; z == null && (z = 0); availableWidth = lsgWidth - padding - paddingLeft; availableHeight = lsgHeight - 2 * padding; coordinateWidth = Math.max(maxX, -minZ / 2) - Math.min(minX, -maxZ / 2); coordinateHeight = Math.max(maxY, -minZ / 2) - Math.min(minY, -maxZ / 2); coordinateOffsetX = Math.min(minX, -maxZ / 2); coordinateOffsetY = Math.min(minY, -maxZ / 2); return { x: _.clamp(paddingLeft + (x - coordinateOffsetX - 0.5 * z) * availableWidth / coordinateWidth, -lsgWidth, 2 * lsgWidth), y: _.clamp(lsgHeight - padding - (y - coordinateOffsetY - 0.5 * z) * availableHeight / coordinateHeight, -lsgHeight, 2 * lsgHeight) }; }; lsg = { width: lsgWidth, height: lsgHeight, objects: [] }; if (drawGrid) { gridPoints = { x: [], y: [] }; step = gridSteps.x; stepPrecision = (step + "").indexOf(".") >= 0 ? (step + "").split(".")[1].length : 0; for (i$ = 0, to$ = maxX + step * 20; step < 0 ? i$ > to$ : i$ < to$; i$ += step) { x = i$; from = toLsgXY(x, minY); if (from.x < 0 || from.x > lsgWidth) { break; } gridPoints.x.push(_.round(x, stepPrecision)); } x = -step; while (x > minX - step * 20) { from = toLsgXY(x, minY); if (from.x < 0 || from.x > lsgWidth) { break; } gridPoints.x.unshift(_.round(x, stepPrecision)); x -= step; } step = gridSteps.y; stepPrecision = (step + "").indexOf(".") >= 0 ? (step + "").split(".")[1].length : 0; for (i$ = 0, to$ = maxY + step * 20; step < 0 ? i$ > to$ : i$ < to$; i$ += step) { y = i$; from = toLsgXY(minX, y); if (from.y < 0 || from.y > lsgHeight) { break; } gridPoints.y.push(_.round(y, stepPrecision)); } y = -step; while (y > minY - step * 20) { from = toLsgXY(minX, y); if (from.y < 0 || from.y > lsgHeight) { break; } gridPoints.y.unshift(_.round(y, stepPrecision)); y -= step; } for (i$ = 0, len$ = (ref18$ = gridPoints.x).length; i$ < len$; ++i$) { x = ref18$[i$]; from = toLsgXY(x, minY); to = toLsgXY(x, maxY); from.y = 0; to.y = lsgHeight; lsg.objects.push({ type: 'line', lineColor: gridColor, lineSize: gridWidth, x1: from.x, y1: from.y, x2: to.x, y2: to.y }); } for (i$ = 0, len$ = (ref18$ = gridPoints.y).length; i$ < len$; ++i$) { y = ref18$[i$]; from = toLsgXY(minX, y); to = toLsgXY(maxX, y); from.x = 0; to.x = lsgWidth; lsg.objects.push({ type: 'line', lineColor: gridColor, lineSize: gridWidth, x1: from.x, y1: from.y, x2: to.x, y2: to.y }); } } drawXAxis = function(){ var from, to, shiftX, arrowPath, ref$, ref1$, step, ref2$, stepPrecision, labelPrecision, ref3$, ref4$, hideStepLabels, ref5$, i$, to$, x, textX, results$ = []; from = toLsgXY(minX, 0); to = toLsgXY(maxX, 0); lsg.objects.push({ type: 'line', lineColor: xAxisColor, lineSize: lineWidth, x1: from.x, y1: from.y, x2: to.x, y2: to.y }); shiftX = 2; arrowPath = "M" + (to.x - stepWidth * 2 + shiftX) + "," + (to.y - stepWidth - shiftX) + " L" + (to.x + shiftX) + "," + to.y + " L" + (to.x - stepWidth * 2 + shiftX) + "," + (to.y + stepWidth + shiftX); lsg.objects.push({ type: "path", color: "transparent", lineColor: xAxisColor, lineSize: lineWidth, path: arrowPath }); if (((ref$ = o.xAxis) != null ? ref$.label : void 8) != null) { lsg.objects.push({ type: 'text', text: (ref1$ = o.xAxis) != null ? ref1$.label : void 8, x: lsgWidth - textSize, y: to.y - textSize * 1.5, color: xAxisColor, size: textSize, align: 'right' }); } if (step = (ref2$ = o.xAxis) != null ? ref2$.stepDistance : void 8) { stepPrecision = (step + "").indexOf(".") >= 0 ? (step + "").split(".")[1].length : 0; labelPrecision = (ref3$ = (ref4$ = o.xAxis) != null ? ref4$.precision : void 8) != null ? ref3$ : stepPrecision; hideStepLabels = (ref3$ = (ref5$ = o.xAxis) != null ? ref5$.hideStepLabels : void 8) != null ? ref3$ : false; for (i$ = step, to$ = maxX; step < 0 ? i$ > to$ : i$ < to$; i$ += step) { x = i$; if (stepPrecision > 0) { x = _.round(x, stepPrecision); } from = toLsgXY(x, 0); to = toLsgXY(x, 0); lsg.objects.push({ type: 'line', lineColor: xAxisColor, lineSize: lineWidth, x1: from.x, y1: from.y - stepWidth, x2: to.x, y2: to.y + stepWidth }); if (!hideStepLabels) { lsg.objects.push({ type: 'text', text: x.toFixed(labelPrecision).replace(".", decimalPoint), x: from.x, y: to.y + textSize / 4, color: xAxisColor, size: textSize, align: 'center' }); } } x = -step; while (x > minX) { if (stepPrecision > 0) { x = _.round(x, stepPrecision); } from = toLsgXY(x, 0); to = toLsgXY(x - step / 4, 0); textX = Math.abs(from.x - to.x) > textSize / 2 ? from.x : to.x; lsg.objects.push({ type: 'line', lineColor: xAxisColor, lineSize: lineWidth, x1: from.x, y1: from.y - stepWidth, x2: from.x, y2: to.y + stepWidth }); if (!hideStepLabels) { lsg.objects.push({ type: 'text', text: x.toFixed(labelPrecision).replace(".", decimalPoint), x: textX, y: to.y + textSize / 4, color: xAxisColor, size: textSize, align: 'center' }); } results$.push(x -= step); } return results$; } }; drawYAxis = function(){ var from, to, shiftY, arrowPath, ref$, step, ref1$, stepPrecision, labelPrecision, ref2$, ref3$, hideStepLabels, ref4$, i$, to$, y, textY, results$ = []; from = toLsgXY(0, minY); to = toLsgXY(0, maxY); lsg.objects.push({ type: 'line', lineColor: yAxisColor, lineSize: lineWidth, x1: from.x, y1: from.y, x2: to.x, y2: to.y }); shiftY = 2; arrowPath = "M" + (to.x - stepWidth - shiftY) + "," + (to.y + stepWidth * 2 - shiftY) + " L" + to.x + "," + (to.y - shiftY) + " L" + (to.x + stepWidth + shiftY) + "," + (to.y + stepWidth * 2 - shiftY); lsg.objects.push({ type: "path", color: "transparent", lineColor: yAxisColor, lineSize: lineWidth, path: arrowPath }); if (((ref$ = o.yAxis) != null ? ref$.label : void 8) != null) { lsg.objects.push({ type: 'text', text: o.yAxis.label, x: to.x - textSize, y: to.y - textSize * 1.5, color: yAxisColor, size: textSize, align: 'left' }); } if (step = (ref1$ = o.yAxis) != null ? ref1$.stepDistance : void 8) { stepPrecision = (step + "").indexOf(".") >= 0 ? (step + "").split(".")[1].length : 0; labelPrecision = (ref2$ = (ref3$ = o.yAxis) != null ? ref3$.precision : void 8) != null ? ref2$ : stepPrecision; hideStepLabels = (ref2$ = (ref4$ = o.yAxis) != null ? ref4$.hideStepLabels : void 8) != null ? ref2$ : false; for (i$ = step, to$ = maxY; step < 0 ? i$ > to$ : i$ < to$; i$ += step) { y = i$; if (stepPrecision > 0) { y = _.round(y, stepPrecision); } from = toLsgXY(0, y); to = toLsgXY(0, y); lsg.objects.push({ type: 'line', lineColor: yAxisColor, lineSize: lineWidth, x1: from.x - stepWidth, y1: from.y, x2: to.x + stepWidth, y2: to.y }); if (!hideStepLabels) { lsg.objects.push({ type: 'text', text: y.toFixed(labelPrecision).replace(".", decimalPoint), x: from.x - textSize / 2, y: to.y - textSize * 0.6, color: yAxisColor, size: textSize, align: 'right' }); } } y = -step; while (y > minY) { if (stepPrecision > 0) { y = _.round(y, stepPrecision); } from = toLsgXY(0, y); to = toLsgXY(0, y - step / 4); textY = Math.abs(from.y - to.y) > textSize / 2 ? from.y : to.y; lsg.objects.push({ type: 'line', lineColor: yAxisColor, lineSize: lineWidth, x1: from.x - stepWidth, y1: from.y, x2: to.x + stepWidth, y2: from.y }); if (!hideStepLabels) { lsg.objects.push({ type: 'text', text: y.toFixed(labelPrecision).replace(".", decimalPoint), x: from.x - textSize / 2, y: textY - textSize * 0.6, color: yAxisColor, size: textSize, align: 'right' }); } results$.push(y -= step); } return results$; } }; drawZAxis = function(){ var from, to, shiftZ, arrowPath, ref$, step, ref1$, stepPrecision, labelPrecision, ref2$, ref3$, hideStepLabels, ref4$, i$, to$, z, pos, results$ = []; if (!o.zAxis) { return; } from = toLsgXY(0, 0, minZ); to = toLsgXY(0, 0, maxZ); lsg.objects.push({ type: 'line', lineColor: zAxisColor, lineSize: lineWidth, x1: from.x, y1: from.y, x2: to.x, y2: to.y }); shiftZ = 0.5; arrowPath = "M" + to.x + "," + (to.y - stepWidth * 2) + " L" + (to.x - shiftZ) + "," + (to.y + shiftZ) + " L" + (to.x + stepWidth * 2) + "," + to.y; lsg.objects.push({ type: "path", color: "transparent", lineColor: zAxisColor, lineSize: lineWidth, path: arrowPath }); if (((ref$ = o.zAxis) != null ? ref$.label : void 8) != null) { lsg.objects.push({ type: 'text', text: o.zAxis.label, x: to.x - textSize * 0.5, y: to.y - textSize * 0.25, color: zAxisColor, size: textSize, align: 'left' }); } if (step = (ref1$ = o.zAxis) != null ? ref1$.stepDistance : void 8) { stepPrecision = (step + "").indexOf(".") >= 0 ? (step + "").split(".")[1].length : 0; labelPrecision = (ref2$ = (ref3$ = o.zAxis) != null ? ref3$.precision : void 8) != null ? ref2$ : stepPrecision; hideStepLabels = (ref2$ = (ref4$ = o.zAxis) != null ? ref4$.hideStepLabels : void 8) != null ? ref2$ : false; for (i$ = step, to$ = maxZ; step < 0 ? i$ > to$ : i$ < to$; i$ += step) { z = i$; if (stepPrecision > 0) { z = _.round(z, stepPrecision); } pos = toLsgXY(0, 0, z); lsg.objects.push({ type: 'line', lineColor: zAxisColor, lineSize: lineWidth, x1: pos.x - stepWidth * 0.75, y1: pos.y - stepWidth * 0.75, x2: pos.x + stepWidth * 0.75, y2: pos.y + stepWidth * 0.75 }); if (!hideStepLabels) { lsg.objects.push({ type: 'text', text: z.toFixed(labelPrecision).replace(".", decimalPoint), x: pos.x + textSize * 0.8, y: pos.y - textSize * 0.2, color: zAxisColor, size: textSize, align: 'right' }); } } z = -step; while (z > minZ) { if (stepPrecision > 0) { z = _.round(z, stepPrecision); } pos = toLsgXY(0, 0, z); lsg.objects.push({ type: 'line', lineColor: zAxisColor, lineSize: lineWidth, x1: pos.x - stepWidth * 0.75, y1: pos.y - stepWidth * 0.75, x2: pos.x + stepWidth * 0.75, y2: pos.y + stepWidth * 0.75 }); if (!hideStepLabels) { lsg.objects.push({ type: 'text', text: z.toFixed(labelPrecision).replace(".", decimalPoint), x: pos.x + textSize * 0.8, y: pos.y - textSize * 0.2, color: zAxisColor, size: textSize, align: 'right' }); } results$.push(z -= step); } return results$; } }; drawPoints = function(points){ var i$, ref$, len$, i, p, pos, ref1$, results$ = []; if (points == null) { return; } for (i$ = 0, len$ = (ref$ = _.ensureArray(points)).length; i$ < len$; ++i$) { i = i$; p = ref$[i$]; pos = toLsgXY(p.x, p.y, p.z); results$.push(lsg.objects.push({ type: 'oval', 'class': (ref1$ = p['class']) != null ? ref1$ : "point" + i, color: p.color || pointDefaultColor, x: pos.x - pointSize / 2, y: pos.y - pointSize / 2, w: pointSize, h: pointSize })); } return results$; }; drawFunctions = function(){ var minPerc, numFnPts, calcPath, i$, ref$, len$, i, f, ref1$, results$ = []; minPerc = (maxX - minX) / lsgWidth; if (o.functions != null) { numFnPts = Math.ceil(lsgWidth / 5); calcPath = function(f){ var xDelta, pts, xPrev, prevCanvasY, i$, to$, i, x, xTarget, ref$, y, canvasPt, perc, result, needsM, len$, p; if (_.isString(f)) { eval("f = " + f); } xDelta = (maxX - minX) / (numFnPts - 1); pts = []; xPrev = minX; for (i$ = 0, to$ = numFnPts; i$ < to$; ++i$) { i = i$; xTarget = minX + i * xDelta; do { x = xTarget; if (xPrev < (ref$ = Math.floor(x)) && ref$ < x) { x = Math.floor(x); xTarget = x; } y = f(x); canvasPt = toLsgXY(x, y); perc = 0.5; while (prevCanvasY != null && Math.abs(prevCanvasY - canvasPt.y) > 30 && y > minY && y < maxY && perc > minPerc) { x = (1 - perc) * xPrev + perc * xTarget; y = f(x); canvasPt = toLsgXY(x, y); perc /= 2; } pts.push(canvasPt); xPrev = x; prevCanvasY = canvasPt.y; } while (x < xTarget); } result = ""; needsM = true; for (i$ = 0, len$ = pts.length; i$ < len$; ++i$) { i = i$; p = pts[i$]; if (!_.isFinite(p.y)) { needsM = true; continue; } if (needsM) { result += "M" + p.x + "," + p.y; needsM = false; } else { result += " L" + p.x + "," + p.y; } } return result; }; for (i$ = 0, len$ = (ref$ = _.ensureArray(o.functions)).length; i$ < len$; ++i$) { i = i$; f = ref$[i$]; results$.push(lsg.objects.push({ 'class': (ref1$ = f['class']) != null ? ref1$ : "function" + i, type: 'path', color: 'transparent', lineColor: f.color || functionDefaultColor, lineSize: (ref1$ = f.functionLineSize) != null ? ref1$ : functionWidth, lineDash: f.lineDash, path: calcPath(f.f) })); } return results$; } }; drawHelpLines = function(){ var i$, ref$, len$, i, line, from, to, ref1$, results$ = []; if (o.helpLines != null) { for (i$ = 0, len$ = (ref$ = _.ensureArray(o.helpLines)).length; i$ < len$; ++i$) { i = i$; line = ref$[i$]; from = toLsgXY(line.from.x, line.from.y, line.from.z); to = toLsgXY(line.to.x, line.to.y, line.to.z); results$.push(lsg.objects.push({ 'class': (ref1$ = line['class']) != null ? ref1$ : "helpLine" + i, type: 'line', lineColor: line.color || helpLineDefaultColor, lineSize: line.helpLineSize || helpLineWidth, x1: from.x, y1: from.y, x2: to.x, y2: to.y, lineDash: line.lineDash, arrowStart: line.arrowStart, arrowEnd: line.arrowEnd })); } return results$; } }; constructInvisibleGridPoints = function(){ var ref$, customPoints, points, i$, ref1$, len$, x, j$, ref2$, len1$, y, customPoint, ref3$, classes, ref4$, ref5$; if (!((ref$ = o.grid) != null && ref$.invisibleGridPoints)) { return; } customPoints = _.isArray(o.grid.invisibleGridPoints) ? _.groupBy(o.grid.invisibleGridPoints, function(p){ return p.x + "_" + p.y; }) : {}; points = []; for (i$ = 0, len$ = (ref1$ = gridPoints.x).length; i$ < len$; ++i$) { x = ref1$[i$]; for (j$ = 0, len1$ = (ref2$ = gridPoints.y).length; j$ < len1$; ++j$) { y = ref2$[j$]; customPoint = (ref3$ = customPoints[x + "_" + y]) != null ? ref3$[0] : void 8; classes = (ref4$ = customPoint != null ? (ref5$ = customPoint['class']) != null ? ref5$.split(" ") : void 8 : void 8) != null ? ref4$ : []; classes.unshift("point"); classes = _.uniq(classes).join(" "); points.push({ x: x, y: y, 'class': classes, color: "transparent" }); } } return points; }; drawXAxis(); drawYAxis(); drawZAxis(); drawHelpLines(); drawFunctions(); drawPoints(o.points); drawPoints(constructInvisibleGridPoints()); return lsg; }; })(); graphPlotClimate/00high_prec_mumbai.lsg (function(){ return { version: 2, width: 300, height: 300, background: 'transparent', objects: [ { type: 'lsg', lsg: path('renderer.lsr'), x: 0.34, y: -0.42, w: 301, h: 301, background: 'transparent', grid: { color: Color.grey[400], steps: { x: 1, y: 9 } }, yAxis: { minTemp: 0, maxTemp: 40, minPrec: 0, maxPrec: 700, stepDistance: 10 }, avgTemp: true, sumPrec: true, hidePoints: true, isSouth: false, values: [ { month: "jan", temp: 23.9, prec: 0 }, { month: "feb", temp: 24.7, prec: 1 }, { month: "mar", temp: 26.7, prec: 0 }, { month: "apr", temp: 28.2, prec: 0 }, { month: "may", temp: 29, prec: 27 }, { month: "jun", temp: 27.4, prec: 487 }, { month: "jul", temp: 25.9, prec: 661 }, { month: "aug", temp: 25.6, prec: 459 }, { month: "sep", temp: 26.1, prec: 300 }, { month: "oct", temp: 27.3, prec: 66 }, { month: "nov", temp: 27, prec: 6 }, { month: "dec", temp: 25.1, prec: 5 } ] }, { type: 'text', text: 'Mumbai, 11m', x: 48.2, y: -2.27, color: Color.blue[800], size: 16, align: 'center', font: 'Source Sans Pro' }, { type: 'text', text: '18°54\'N/72°49\'O', x: 240.81, y: -0.62, color: Color.blue[800], size: 16, align: 'center', font: 'Source Sans Pro' } ] }; })(); graphPlotClimate/01-isSouth-true.lsg (function(){ return { version: 2, width: 300, height: 300, background: 'transparent', objects: [ { type: 'lsg', lsg: path('renderer.lsr'), x: 0, y: 0, w: 301, h: 301, background: 'transparent', grid: { color: Color.grey[400], steps: { x: 1, y: 10 } }, yAxis: { minTemp: -10, maxTemp: 40, minPrec: 0, maxPrec: 130, stepDistance: 10 }, hidePoints: false, avgTemp: true, sumPrec: true, isSouth: true, values: [ { month: "jan", temp: 1, prec: 10 }, { month: "feb", temp: 3, prec: 40 }, { month: "mar", temp: 6, prec: 52 }, { month: "apr", temp: 10, prec: 60 }, { month: "may", temp: 14, prec: 63.4 }, { month: "jun", temp: 18, prec: 90 }, { month: "jul", temp: 21, prec: 101 }, { month: "aug", temp: 23, prec: 132 }, { month: "sep", temp: 19, prec: 72 }, { month: "oct", temp: 13, prec: 54 }, { month: "nov", temp: 7, prec: 32 }, { month: "dec", temp: 3, prec: 12 } ] }, { type: 'text', text: 'ORT, HÜMS', x: 47.36, y: 2.73, color: Color.blue[800], size: 16, align: 'center', font: 'Source Sans Pro' }, { type: 'text', text: 'XX°YY\'N/XX°YY\'O', x: 240.39, y: 3.12, color: Color.blue[800], size: 16, align: 'center', font: 'Source Sans Pro' } ] }; })(); graphPlotClimate/addThousandsSeperator/add.ls (function(){ var addThousandsSeparator; return addThousandsSeparator = function(t, o){ var pattern, parts, t1, t2; pattern = /(-?\d+)(\d{3})/; parts = t.split(o.decimalPoint); t1 = parts[0]; t2 = parts[1]; while (pattern.test(t1)) { t1 = t1.replace(pattern, "$1 $2"); } t = t1; if (t2) { t += decimalPoint + t2; } return t; }; })(); graphPlotClimate/drawAxis/draw.ls (function(){ return function(o, lsg){ inc("drawXAxis/draw")(o, lsg); inc("drawPrecAxis/draw")(o, lsg); return inc("drawTempAxis/draw")(o, lsg); }; })(); graphPlotClimate/drawAxis/drawPrecAxis/draw.ls (function(){ return function(o, lsg){ var toLsgXY, coordsStart, coordsEnd, drawSumPrec, i$, step$, to$, y, results$ = []; toLsgXY = inc("../../toLsgXY/toLsgXY"); coordsStart = toLsgXY(o, o.maxX, o.minY); coordsEnd = toLsgXY(o, o.maxX, o.maxY); lsg.objects.push({ type: "line", lineColor: o.yAxisColor, lineSize: o.lineWidth, x1: coordsStart.x, y1: coordsStart.y, x2: coordsEnd.x, y2: coordsEnd.y }); lsg.objects.push({ type: "text", text: "mm", x: coordsStart.x + o.textSize / 4, y: coordsEnd.y - o.textSize * 1.1, color: o.precDefaultColor, size: o.textSize, align: "left" }); if (o.sumPrec) { drawSumPrec = inc("drawSumPrec/draw")(o, lsg, coordsStart); } for (i$ = o.stepDistance, to$ = o.maxY, step$ = o.stepDistance; step$ < 0 ? i$ > to$ : i$ < to$; i$ += step$) { y = i$; coordsStart = toLsgXY(o, o.maxX, y); coordsEnd = toLsgXY(o, o.maxX, y); lsg.objects.push({ type: "line", lineColor: o.yAxisColor, lineSize: o.lineWidth, x1: coordsStart.x - o.stepWidth, y1: coordsStart.y, x2: coordsEnd.x + o.stepWidth, y2: coordsEnd.y }); results$.push(lsg.objects.push({ type: "text", text: y <= 50 ? y * 2 : (y - 40) * 10, x: coordsStart.x + o.textSize / 2, y: coordsEnd.y - o.textSize * 0.6, color: o.precDefaultColor, size: o.textSize, align: "left" })); } return results$; }; })(); graphPlotClimate/drawAxis/drawPrecAxis/drawSumPrec/draw.ls (function(){ return function(o, lsg, coords){ var addThousandsSeperator, sumPrec; addThousandsSeperator = inc("../../../addThousandsSeperator/add"); sumPrec = addThousandsSeperator(_.sum(o.precPoints) + "", o).replace(".", o.decimalPoint); return lsg.objects.push({ type: "text", text: sumPrec + " mm", x: coords.x + 2 * o.textSize, y: o.minY < 0 ? coords.y + o.textSize / 2 : coords.y + o.textSize, color: o.precDefaultColor, size: o.textSize, align: "right" }); }; })(); graphPlotClimate/drawAxis/drawTempAxis/draw.ls (function(){ return function(o, lsg){ var toLsgXY, coordsStart, coordsEnd, drawAvgTemp, i$, step$, to$, y, coord, results$ = []; toLsgXY = inc("../../toLsgXY/toLsgXY"); coordsStart = toLsgXY(o, 0, o.minY); coordsEnd = toLsgXY(o, 0, o.maxY); lsg.objects.push({ type: "line", lineColor: o.yAxisColor, lineSize: o.lineWidth, x1: coordsStart.x, y1: coordsStart.y, x2: coordsEnd.x, y2: coordsEnd.y }); lsg.objects.push({ type: "text", text: "°C", x: coordsEnd.x - o.textSize / 2, y: coordsEnd.y - o.textSize * 1.1, color: o.tempDefaultColor, size: o.textSize, align: "right" }); if (o.avgTemp) { drawAvgTemp = inc("drawAvgTemp/draw")(o, lsg, coordsStart); } for (i$ = o.minTemp + o.stepDistance, to$ = o.maxTemp, step$ = o.stepDistance; step$ < 0 ? i$ > to$ : i$ < to$; i$ += step$) { y = i$; coord = toLsgXY(o, 0, y); lsg.objects.push({ type: "line", lineColor: o.yAxisColor, lineSize: o.lineWidth, x1: coord.x - o.stepWidth, y1: coord.y, x2: coord.x + o.stepWidth, y2: coord.y }); results$.push(lsg.objects.push({ type: "text", text: y, x: coord.x - o.textSize / 2, y: coord.y - o.textSize * 0.6, color: o.tempDefaultColor, size: o.textSize, align: "right" })); } return results$; }; })(); graphPlotClimate/drawAxis/drawTempAxis/drawAvgTemp/draw.ls (function(){ return function(o, lsg, coords){ var avgTemp; avgTemp = (_.round(_.mean(o.tempPoints), 1) + "").replace(".", o.decimalPoint); return lsg.objects.push({ type: "text", text: avgTemp + " °C", x: coords.x - 2 * o.textSize, y: o.minY < 0 ? coords.y + o.textSize / 2 : coords.y + o.textSize, color: o.tempDefaultColor, size: o.textSize, align: "left" }); }; })(); graphPlotClimate/drawAxis/drawXAxis/draw.ls (function(){ return function(o, lsg){ var toLsgXY, coordsStart, i$, ref$, len$, i, month, coordsEnd, results$ = []; toLsgXY = inc("../../toLsgXY/toLsgXY"); coordsStart = toLsgXY(o, 0, 0); for (i$ = 0, len$ = (ref$ = o.months).length; i$ < len$; ++i$) { i = i$; month = ref$[i$]; coordsEnd = toLsgXY(o, i + 1, 0); lsg.objects.push({ type: "line", lineColor: o.xAxisColor, lineSize: o.lineWidth, x1: coordsStart.x, y1: coordsStart.y, x2: coordsEnd.x, y2: coordsEnd.y }); if (i !== o.months.length - 1) { lsg.objects.push({ type: "line", lineColor: o.xAxisColor, lineSize: o.lineWidth, x1: coordsEnd.x, y1: coordsEnd.y - o.stepWidth, x2: coordsEnd.x, y2: coordsEnd.y + o.stepWidth }); } lsg.objects.push({ type: "text", text: month, x: (coordsStart.x + coordsEnd.x) / 2, y: coordsEnd.y, color: o.xAxisColor, size: o.textSize, align: "center" }); results$.push(coordsStart = coordsEnd); } return results$; }; })(); graphPlotClimate/drawGrid/draw.ls (function(){ return function(o, lsg){ var toLsgXY, gridPoints, stepX, i$, to$, x, stepY, y, ref$, len$, coordsStart, coordsEnd, results$ = []; toLsgXY = inc("../toLsgXY/toLsgXY"); if (!o.grid) { return; } gridPoints = { x: [], y: [] }; stepX = o.gridSteps.x; for (i$ = o.minX, to$ = o.maxX; stepX < 0 ? i$ >= to$ : i$ <= to$; i$ += stepX) { x = i$; gridPoints.x.push(x); } stepY = o.gridSteps.y; for (i$ = o.minY, to$ = o.maxY; stepY < 0 ? i$ >= to$ : i$ <= to$; i$ += stepY) { y = i$; gridPoints.y.push(y); } if ((Math.abs(o.minY) + o.maxY) % stepY !== 0) { gridPoints.y.push(o.maxY); } for (i$ = 0, len$ = (ref$ = gridPoints.x).length; i$ < len$; ++i$) { x = ref$[i$]; coordsStart = toLsgXY(o, x, o.minY); coordsEnd = toLsgXY(o, x, o.maxY); lsg.objects.push({ type: "line", lineColor: o.gridColor, lineSize: o.gridWidth, x1: coordsStart.x, y1: coordsStart.y, x2: coordsEnd.x, y2: coordsEnd.y }); } for (i$ = 0, len$ = (ref$ = gridPoints.y).length; i$ < len$; ++i$) { y = ref$[i$]; coordsStart = toLsgXY(o, o.minX, y); coordsEnd = toLsgXY(o, o.maxX, y); results$.push(lsg.objects.push({ type: "line", lineColor: o.gridColor, lineSize: o.gridWidth, x1: coordsStart.x, y1: coordsStart.y, x2: coordsEnd.x, y2: coordsEnd.y })); } return results$; }; })(); graphPlotClimate/drawPrecBars/draw.ls (function(){ return function(o, lsg){ var toLsgXY, barX1, barX2, barWidth, coordZero, i$, len$, i, point, coord, barHeight, results$ = []; toLsgXY = inc("../toLsgXY/toLsgXY"); barX1 = 0.25; barX2 = 0.75; barWidth = toLsgXY(o, barX2, 0).x - toLsgXY(o, barX1, 0).x; coordZero = toLsgXY(o, 0, 0).y; for (i$ = 0, len$ = o.precPoints.length; i$ < len$; ++i$) { i = i$; point = o.precPoints[i]; coord = toLsgXY(o, i + barX1, point, true); if (point === 0) { continue; } barHeight = Math.abs(coord.y - coordZero); lsg.objects.push({ type: "rect", color: point.color || o.precDefaultColor, x: coord.x, y: coord.y, w: barWidth, h: barHeight, lineSize: 0.75, lineColor: Color.grey[800] }); if (point > 100) { results$.push(lsg.objects.push({ type: "rect", color: o.precDefaultColor2, x: coord.x, y: coord.y, w: barWidth, h: toLsgXY(o, 0, 50).y - coord.y, lineSize: 0.75, lineColor: Color.grey[800] })); } } return results$; }; })(); graphPlotClimate/drawTempLine/draw.ls (function(){ return function(o, lsg){ var toLsgXY, tempPath, i$, len$, i, point, coord, drawTempPoints; toLsgXY = inc("../toLsgXY/toLsgXY"); tempPath = ""; for (i$ = 0, len$ = o.tempPoints.length; i$ < len$; ++i$) { i = i$; point = o.tempPoints[i]; coord = toLsgXY(o, i + 1 / 2, point); if (!o.hidePoints) { drawTempPoints = inc("drawTempPoints/draw")(o, lsg, point, coord, i); } if (i === 0) { tempPath += "M" + coord.x + "," + coord.y; continue; } tempPath += " L" + (coord.x + "," + coord.y); } return lsg.objects.push({ type: "path", color: "transparent", lineColor: point.color || o.tempDefaultColor, lineSize: point.lineSize || o.tempWidth, path: tempPath }); }; })(); graphPlotClimate/drawTempLine/drawTempPoints/draw.ls (function(){ return function(o, lsg, point, coord, i){ var ref$; return lsg.objects.push({ type: "oval", 'class': (ref$ = point['class']) != null ? ref$ : "point" + i, color: point.color || o.tempDefaultColor, x: coord.x - o.pointSize / 2, y: coord.y - o.pointSize / 2, w: o.pointSize, h: o.pointSize }); }; })(); graphPlotClimate/init/init.ls (function(){ return function(param){ var o, ref$, ref1$, ref2$, nextEvenNumber, ref3$, ref4$; o = {}; o.lsgWidth = param.w || param.h || 300; o.lsgHeight = param.h || param.w || 300; o.gridColor = ((ref$ = param.grid) != null ? ref$.color : void 8) || Color.grey[400]; o.grid = param.grid; o.gridSteps = { x: ((ref1$ = param.grid) != null ? ref1$.steps.x : void 8) || 1, y: ((ref2$ = param.grid) != null ? ref2$.steps.y : void 8) || 10 }; o.stepDistance = param.yAxis.stepDistance || 10; o.minTemp = Math.floor(param.yAxis.minTemp / o.stepDistance) * o.stepDistance || 0; o.maxTemp = param.yAxis.maxTemp + o.stepDistance || 30; o.minPrec = param.yAxis.minPrec || 0; o.maxPrec = param.yAxis.maxPrec || 60; o.minY = Math.min(o.minTemp, o.minPrec); o.maxY = o.maxPrec > 100 ? (nextEvenNumber = Math.ceil(o.maxPrec / (o.stepDistance * 10)) * o.stepDistance * 10, Math.max(o.maxTemp, 50 + (nextEvenNumber - 100) / 10 + o.stepDistance)) : Math.max(o.maxTemp, o.maxPrec / 2); o.minX = 0; o.maxX = 12; o.sumPrec = param.sumPrec; o.avgTemp = param.avgTemp; o.hidePoints = param.hidePoints; o.isSouth = param.isSouth; o.lineWidth = o.lsgWidth / 150; o.gridWidth = o.lsgWidth / 400; o.stepWidth = (o.lsgWidth / 400) * 5; o.tempWidth = o.lineWidth; o.textSize = (ref3$ = param.fontSize) != null ? ref3$ : (o.lsgWidth / 400) * 20; o.pointSize = (ref3$ = param.pointSize) != null ? ref3$ : (o.lsgWidth / 400) * 15; o.values = param.values; o.monthOrder = o.isSouth ? ["jul", "aug", "sep", "oct", "nov", "dec", "jan", "feb", "mar", "apr", "may", "jun"] : ["jan", "feb", "mar", "apr", "may", "jun", "jul", "aug", "sep", "oct", "nov", "dec"]; o.sortedMonths = _.orderBy(o.values, function(value){ return o.monthOrder.indexOf(value.month); }); o.tempPoints = _.map(o.sortedMonths, "temp"); o.precPoints = _.map(o.sortedMonths, "prec"); o.xAxisColor = ((ref3$ = param.xAxis) != null ? ref3$.color : void 8) || Color.grey[800]; o.yAxisColor = ((ref4$ = param.yAxis) != null ? ref4$.color : void 8) || Color.grey[800]; o.tempDefaultColor = Color.pink[400]; o.precDefaultColor = Color.blue[400]; o.precDefaultColor2 = Color.blue[800]; param.renderLanguage == null && (param.renderLanguage = "de"); o.decimalPoint = (function(){ switch (param.renderLanguage) { case "de": case "fr": case "pt": return ","; case "en_gb": case "en_us": case "es": return "."; } }()); o.months = (function(){ switch (param.renderLanguage) { case "de": case "en_gb": case "en_us": case "fr": case "pt": if (!param.isSouth) { return ["J", "F", "M", "A", "M", "J", "J", "A", "S", "O", "N", "D"]; } else { return ["J", "A", "S", "O", "N", "D", "J", "F", "M", "A", "M", "J"]; } case "es": if (!param.isSouth) { return ["E", "F", "M", "A", "M", "J", "J", "A", "S", "O", "N", "D"]; } else { return ["J", "A", "S", "O", "N", "D", "E", "F", "M", "A", "M", "J"]; } } }()); o.padding = o.textSize * 2; o.textLength = Math.max((o.minY + "").length, (o.maxY + "").length, (o.minPrec + "").length, (o.maxPrec + "").length); o.paddingSide = Math.max(o.padding, o.textLength * o.textSize * 0.75); return o; }; })(); graphPlotClimate/level.ls (function(){ return { trainers: { trainer: "buttons", instruction: { text: "instruction" }, lsg: { lsg: path("renderer.lsr") }, atoms: { a: "a", b: "a" } } }; })(); graphPlotClimate/lsgEditor.ls (function(){ return { name: "graphPlotClimate", 'default': { type: 'lsg', lsg: path('renderer.lsr'), x: 0, y: 0, w: 300, h: 300, background: 'transparent', grid: { color: Color.grey[400], steps: { x: 1, y: 5 } }, yAxis: { minTemp: -10, maxTemp: 30, minPrec: 10, maxPrec: 100, stepDistance: 5 }, avgTemp: true, sumPrec: true, hideTempPoints: false, isSouth: false, values: [ { month: "jan", temp: 0.5, prec: 43 }, { month: "feb", temp: 1.2, prec: 36 }, { month: "mar", temp: 4.6, prec: 41 }, { month: "apr", temp: 8.7, prec: 38 }, { month: "may", temp: 13.9, prec: 53 }, { month: "jun", temp: 16.6, prec: 67 }, { month: "jul", temp: 18.4, prec: 55 }, { month: "aug", temp: 17.8, prec: 62 }, { month: "sep", temp: 13.6, prec: 45 }, { month: "oct", temp: 9.1, prec: 37 }, { month: "nov", temp: 4.4, prec: 45 }, { month: "dec", temp: 1.8, prec: 57 } ] } }; })(); graphPlotClimate/renderer.lsr (function(){ return function(param){ var o, lsg; o = inc("init/init")(param); lsg = { width: o.lsgWidth, height: o.lsgHeight, objects: [] }; inc("drawGrid/draw")(o, lsg); inc("drawPrecBars/draw")(o, lsg); inc("drawAxis/draw")(o, lsg); inc("drawTempLine/draw")(o, lsg); return lsg; }; })(); graphPlotClimate/toLsgXY/toLsgXY.ls (function(){ return function(o, x, y, isPrec){ var availableWidth, availableHeight, coordinateWidth, coordinateHeight, coordinateOffsetY; if (isPrec) { y = y <= 100 ? y / 2 : (y - 100) / 10 + 50; } availableWidth = o.lsgWidth - 2 * o.paddingSide; availableHeight = o.lsgHeight - 2 * o.paddingSide; coordinateWidth = o.maxX - o.minX; coordinateHeight = o.maxY - o.minY; coordinateOffsetY = o.minY; return { x: o.paddingSide + (x * availableWidth) / coordinateWidth, y: o.lsgHeight - o.paddingSide - ((y - coordinateOffsetY) * availableHeight) / coordinateHeight }; }; })(); math/examples.lsg (function(){ return { version: 2, width: 150, height: 1000, background: Color.grey[100], objects: { type: 'lsg', lsg: path('renderer.lsr'), x: 20, y: 40, w: 100, background: 'white', text: '2x+1' } }; })(); math/level.ls (function(){ return { uid: '3eyro5', trainers: { trainer: "gap", gapMode: "buttons", lsg: { lsg: path("renderer.lsr"), text: "(2x+1)/sqrt(x^2-4)" }, atoms: { a: "a", b: "((a))" } } }; })(); math/lsgEditor.ls (function(){ return { name: "MathDiv", 'default': { type: "lsg", lsg: path("renderer.lsr"), x: 20, y: 40, text: "2x+1", fontSize: 30, textColor: Color.black } }; })(); math/renderer.lsr (function(){ return function(o){ var text, fontSize, textColor, m, svg, width, height; text = o.text || ""; fontSize = o.fontSize || 22; textColor = o.textColor || Color.black; m = MathDiv2({ mode: "display", value: text, color: textColor, fontSize: fontSize + "px", addSvgExportClasses: true }); svg = m.getSvgElement(); width = parseInt(svg.attr("width")); height = parseInt(svg.attr("height")); return { width: width, height: height, objects: { type: "svg", svg: svg.outerHTML, h: height } }; }; })(); measuring-glass/examples-renderer.lsg (function(){ return { version: 2, 'class': 'rect', width: 300, height: 1000, background: Color.grey[100], objects: [ { type: 'lsg', lsg: path('renderer.lsr'), x: 52, y: 41, background: 'transparent', fillLevel: 300 }, { type: 'lsg', lsg: path('renderer.lsr'), x: 50, y: 197, background: 'transparent', fillLevel: 500, fillColor: Color.pink[600] }, { type: 'lsg', lsg: path('renderer.lsr'), x: 50, y: 357, background: 'transparent', fillLevel: 20, maxFillLevel: 30, step: 5, fillColor: Color.orange[600], unit: "fl oz" } ] }; })(); measuring-glass/level.ls (function(){ return { uid: '4ifp8l', lsg: { lsg: path("renderer.lsr"), width: 300, fillColor: Color.cyan[300], fillLevel: 2 }, trainers: { trainer: "buttons", atoms: { a: "1", b: "1" } } }; })(); measuring-glass/lsgEditor.ls (function(){ return { name: "Measuring Glass", 'default': { type: 'lsg', lsg: path('renderer.lsr'), w: 100, x: 51, y: 34, background: 'transparent', fillLevel: 250, fillColor: Color.blue[200] } }; })(); measuring-glass/renderer.lsr (function(){ return function(o){ var fillLevel, fillColor, unit, maxFillLevel, ref$, step, fontSize, stepPrecision, lsgWidth, lsgHeight, pot, yForFillLevel, fillY, lsg, addMark, lastMark, i$, mark; fillLevel = o.fillLevel; fillColor = o.fillColor || Color.blue[200]; unit = o.unit || "ml"; maxFillLevel = (ref$ = o.maxFillLevel) != null ? ref$ : 1000; step = (ref$ = o.step) != null ? ref$ : 100; fontSize = (ref$ = o.fontSize) != null ? ref$ : 5; stepPrecision = (step + "").indexOf(".") >= 0 ? (step + "").split(".")[1].length : 0; lsgWidth = 100; lsgHeight = 130; pot = { x: 0, y: 10, width: lsgWidth, height: lsgHeight - 11 }; yForFillLevel = function(level){ return pot.y + pot.height * (1 - level / maxFillLevel); }; fillY = yForFillLevel(fillLevel); lsg = { width: lsgWidth, height: lsgHeight, requiredArguments: "fillLevel", objects: [] }; lsg.objects.push({ type: 'rect', color: Color.grey[100], x: pot.x, y: pot.y - 10, w: pot.width, h: pot.height + 10 }); lsg.objects.push({ type: 'rect', color: fillColor, x: pot.x, y: fillY, w: pot.width, h: pot.y + pot.height - fillY }); lsg.objects.push({ type: 'line', lineColor: Color.grey[700], lineSize: 2, x1: pot.x, y1: pot.y + pot.height, x2: pot.x + pot.width, y2: pot.y + pot.height }); lsg.objects.push({ type: 'line', lineColor: Color.grey[700], lineSize: 2, x1: pot.x + 1, y1: pot.y - 10, x2: pot.x + 1, y2: pot.y + pot.height }); lsg.objects.push({ type: 'line', lineColor: Color.grey[700], lineSize: 2, x1: pot.x + pot.width - 1, y1: pot.y - 10, x2: pot.x + pot.width - 1, y2: pot.y + pot.height }); addMark = function(mark){ var y; y = yForFillLevel(mark); lsg.objects.push({ type: 'line', lineColor: Color.grey[700], lineSize: 0.5, x1: pot.x + 20 - (fontSize - 5), y1: y, x2: pot.x + 35 - (fontSize - 5), y2: y }); lsg.objects.push({ type: 'line', lineColor: Color.grey[700], lineSize: 0.5, x1: pot.x + pot.width - 20 + (fontSize - 5), y1: y, x2: pot.x + pot.width - 35 + (fontSize - 5), y2: y }); return lsg.objects.push({ type: 'text', text: mark.toFixed(stepPrecision) + " " + unit, x: pot.x + pot.width / 2, y: y - (2 * fontSize) / 3, color: Color.grey[700], size: fontSize, align: 'center' }); }; for (i$ = step; step < 0 ? i$ >= maxFillLevel : i$ <= maxFillLevel; i$ += step) { mark = i$; mark = _.round(mark, stepPrecision); lastMark = mark; addMark(mark); } if (lastMark !== maxFillLevel) { addMark(maxFillLevel); } return lsg; }; })(); molecule/classes/Edge.ls (function(){ var norm, getParralelLines, Edge; norm = function(vec){ var l; l = Math.sqrt(vec.x * vec.x + vec.y * vec.y); vec.x /= l; vec.y /= l; return vec; }; getParralelLines = function(p1, p2, amount, offset){ var vec, orth, i$, i, o, results$ = []; if (amount === 1) { return [{ p1: p1, p2: p2 }]; } vec = { x: p2.x - p1.x, y: p2.y - p1.y }; orth = norm({ x: -vec.y, y: vec.x }); for (i$ = 0; i$ < amount; ++i$) { i = i$; o = (-(amount - 1) / 2 + i) * offset; results$.push({ p1: { x: p1.x + o * orth.x, y: p1.y + o * orth.y }, p2: { x: p2.x + o * orth.x, y: p2.y + o * orth.y } }); } return results$; }; return Edge = (function(){ Edge.displayName = 'Edge'; var prototype = Edge.prototype, constructor = Edge; function Edge(node1, node2, data){ this.source = node1; this.target = node2; this.data = data; } Edge.prototype.toLsgObjects = function(colorTheme, scale, renderImplicitH){ var numBonds, lineSize, multiLineOffset, lines, objects, i, l; renderImplicitH == null && (renderImplicitH = true); if (this.data.name === "H" && !renderImplicitH && _.includes(this.data.id, "C")) { return []; } numBonds = Math.floor(this.data.order); lineSize = 0.075 * scale; multiLineOffset = 2 * lineSize; lines = getParralelLines(this.source.position, this.target.position, numBonds, multiLineOffset); return objects = (function(){ var i$, ref$, len$, results$ = []; for (i$ = 0, len$ = (ref$ = lines).length; i$ < len$; ++i$) { i = i$; l = ref$[i$]; results$.push({ type: 'line', 'class': this.data.id + "b" + i, lineColor: colorTheme.bond, lineSize: 0.075 * scale, x1: l.p1.x, y1: l.p1.y, x2: l.p2.x, y2: l.p2.y }); } return results$; }.call(this)); }; return Edge; }()); })(); molecule/classes/Graph.ls (function(){ var Edge, Node, Graph; Edge = include("Edge"); Node = include("Node"); return Graph = (function(){ Graph.displayName = 'Graph'; var prototype = Graph.prototype, constructor = Graph; function Graph(molecule){ var res$, i$, ref$, len$, atom, nodesById, bond, edge; this.scaleTo = bind$(this, 'scaleTo', prototype); this.layout = bind$(this, 'layout', prototype); res$ = []; for (i$ = 0, len$ = (ref$ = _.values(molecule.atoms)).length; i$ < len$; ++i$) { atom = ref$[i$]; res$.push(new Node(atom)); } this.nodes = res$; nodesById = _.groupBy(this.nodes, "id"); res$ = []; for (i$ = 0, len$ = (ref$ = _.values(molecule.bonds)).length; i$ < len$; ++i$) { bond = ref$[i$]; res$.push(edge = new Edge(nodesById[bond.atoms[0]][0], nodesById[bond.atoms[1]][0], bond)); } this.edges = res$; this.data = molecule; for (i$ = 0, len$ = (ref$ = this.edges).length; i$ < len$; ++i$) { edge = ref$[i$]; edge.source.edges.push(edge); edge.target.edges.push(edge); edge.source.neighbors.push(edge.target); edge.target.neighbors.push(edge.source); } this.scale = 1; } Graph.prototype.traverse = function(cb){ var visited, queue, node, i$, ref$, len$, next; visited = {}; queue = [this.nodes[0]]; while (queue.length > 0) { node = queue.shift(); cb(node); for (i$ = 0, len$ = (ref$ = node.neighbors).length; i$ < len$; ++i$) { next = ref$[i$]; if (!visited[next.id]) { visited[next.id] = true; queue.push(next); } } } }; Graph.prototype.layout = function(layout){ layout(this); return this; }; Graph.prototype.scaleTo = function(width, height, padding){ var minX, maxX, minY, maxY, i$, ref$, len$, v, scaleX, scaleY, center; minX = 9999999999; maxX = -9999999999; minY = 9999999999; maxY = -9999999999; for (i$ = 0, len$ = (ref$ = this.nodes).length; i$ < len$; ++i$) { v = ref$[i$]; if (v.position.x - v.radius < minX) { minX = v.position.x - v.radius; } if (v.position.x + v.radius > maxX) { maxX = v.position.x + v.radius; } if (v.position.y - v.radius < minY) { minY = v.position.y - v.radius; } if (v.position.y + v.radius > maxY) { maxY = v.position.y + v.radius; } } scaleX = (width - 2 * padding) / (maxX - minX); scaleY = (height - 2 * padding) / (maxY - minY); this.scale = Math.min(scaleX, scaleY); center = { x: width / 2 - (maxX + minX) * 0.5 * this.scale, y: height / 2 + (maxY + minY) * 0.5 * this.scale }; for (i$ = 0, len$ = (ref$ = this.nodes).length; i$ < len$; ++i$) { v = ref$[i$]; v.position.x *= this.scale; v.position.y *= -this.scale; v.position.x += center.x; v.position.y += center.y; v.radius *= this.scale; } return this; }; Graph.prototype.getSubgraphAdjacencyMatrix = function(vertexIds){ var length, adjacencyMatrix, i$, i, j$, j; length = vertexIds.length; adjacencyMatrix = Array(length); for (i$ = 0; i$ < length; ++i$) { i = i$; adjacencyMatrix[i] = new Array(length); adjacencyMatrix[i].fill(0); for (j$ = 0; j$ < length; ++j$) { j = j$; if (i === j) { continue; } if (in$(this.nodes[i], this.nodes[j].neighbors)) { adjacencyMatrix[i][j] = 1; } } } return adjacencyMatrix; }; Graph.prototype.getSubgraphDistanceMatrix = function(vertexIds){ var length, adja, dist, i$, i, j$, j, k, k$; length = vertexIds.length; adja = this.getSubgraphAdjacencyMatrix(vertexIds); dist = Array(length); for (i$ = 0; i$ < length; ++i$) { i = i$; dist[i] = Array(length); dist[i].fill(Infinity); } for (i$ = 0; i$ < length; ++i$) { i = i$; for (j$ = 0; j$ < length; ++j$) { j = j$; if (adja[i][j] === 1) { dist[i][j] = 1; } } } for (i$ = 0; i$ < length; ++i$) { k = i$; for (j$ = 0; j$ < length; ++j$) { i = j$; for (k$ = 0; k$ < length; ++k$) { j = k$; if (dist[i][j] > dist[i][k] + dist[k][j]) { dist[i][j] = dist[i][k] + dist[k][j]; } } } } return dist; }; return Graph; }()); })(); function bind$(obj, key, target){ return function(){ return (target || obj)[key].apply(obj, arguments) }; } function in$(x, xs){ var i = -1, l = xs.length >>> 0; while (++i < l) if (x === xs[i]) return true; return false; } molecule/classes/Node.ls (function(){ var Node; return Node = (function(){ Node.displayName = 'Node'; var prototype = Node.prototype, constructor = Node; function Node(data){ this.edges = []; this.data = data; this.id = data.id; this.neighbors = []; this.position = { x: 0, y: 0 }; this.radius = data.name === "H" ? 0.666 : 1; } Node.prototype.toLsgObjects = function(colorTheme, scale, renderImplicitH){ var isImplicitH, objects, ref$, ref1$, ref2$, ref3$, amount, text, ref4$; renderImplicitH == null && (renderImplicitH = true); isImplicitH = this.data.name === "H" && _.includes(this.data.bonds.id[0], "C"); if (isImplicitH && !renderImplicitH) { return []; } objects = [ { type: 'oval', 'class': this.id, color: (ref$ = (ref1$ = colorTheme.atomBackground) != null ? ref1$[this.data.name] : void 8) != null ? ref$ : colorTheme.defaultAtomBackground, x: this.position.x - this.radius, y: this.position.y - this.radius, w: 2 * this.radius, h: 2 * this.radius, lineSize: 0.05 * scale, lineColor: (ref$ = (ref2$ = colorTheme.atomBorder) != null ? ref2$[this.data.name] : void 8) != null ? ref$ : colorTheme.defaultAtomBorder }, { type: "text", color: (ref$ = (ref3$ = colorTheme.atomForeground) != null ? ref3$[this.data.name] : void 8) != null ? ref$ : colorTheme.defaultAtomForeground, text: this.data.name, x: this.position.x, y: this.position.y - this.radius * 0.65, size: this.radius, align: "center" } ]; if (this.data.properties.charge) { amount = Math.abs(this.data.properties.charge); text = this.data.properties.charge > 0 ? repeatString$("+", amount) : repeatString$("-", amount); objects.push({ type: "text", color: (ref$ = (ref4$ = colorTheme.atomForeground) != null ? ref4$[this.data.name] : void 8) != null ? ref$ : colorTheme.defaultAtomForeground, text: text, x: this.position.x + Math.sin(Math.PI / 8) * this.radius + this.radius * 0.15, y: this.position.y - Math.cos(Math.PI / 8) * this.radius - this.radius * 0.15, size: this.radius, align: "center" }); } return objects; }; return Node; }()); })(); function repeatString$(str, n){ for (var r = ''; n > 0; (n >>= 1) && (str += str)) if (n & 1) r += str; return r; } molecule/examples-renderer.lsg (function(){ return { version: 2, 'class': 'rect', width: 1000, height: 5300, objects: [ { type: 'lsg', lsg: path('renderer.lsr'), x: 0, y: 0, background: Color.white, width: 1000, height: 1000, smiles: "Clc(c(Cl)c(Cl)c1C(=O)O)c(Cl)c1Cl", forceLayoutStartIndex: 1, namePosition: "bottomleft" }, { type: 'lsg', lsg: path('renderer.lsr'), x: 0, y: 1000, background: Color.white, width: 1000, height: 1000, smiles: "C(C(CO[N+](=O)[O-])O[N+](=O)[O-])O[N+](=O)[O-]", forceLayoutStartIndex: 14, padding: 50, namePosition: "topright" }, { type: 'lsg', lsg: path('renderer.lsr'), x: 0, y: 2000, background: Color.white, width: 1000, height: 1000, smiles: "CCO", namePosition: "top", name: "C2H5OH" }, { type: 'lsg', lsg: path('renderer.lsr'), x: 0, y: 3000, background: Color.white, width: 1000, height: 1000, smiles: "CC(C)(C)O", name: "C4H9OH", namePosition: "bottomright", colorTheme: Color.black }, { type: 'lsg', lsg: path('renderer.lsr'), x: 0, y: 4000, background: Color.white, width: 1000, height: 1000, colorTheme: { bond: Color.grey[300], defaultAtomBackground: Color.grey[200], atomBackground: { C: Color.grey[500] }, atomForeground: { H: Color.grey[500] } }, smiles: "C1CCCC1", namePosition: "center" } ] }; })(); molecule/layout/force/layout.ls (function(){ return function(startVertexId){ startVertexId == null && (startVertexId = 0); return function(graph){ var mathHelper, kkLayout, vertexIds, res$, i$, to$, ridx$, center, bondLength; mathHelper = include("mathHelper/mathHelper")(); kkLayout = function(vertexIds, center, startVertexId, bondLength, threshold, innerThreshold, maxIteration, maxInnerIteration, maxEnergy){ var edgeStrength, i, vertex, j, matDist, length, radius, angle, a, arrPositionX, arrPositionY, arrPositioned, index, matLength, matStrength, matEnergy, arrEnergySumX, arrEnergySumY, ux, uy, dEx, dEy, vx, vy, denom, energy, highestEnergy, update, maxEnergyId, dEX, dEY, delta, iteration, innerIteration, ref$, results$ = []; threshold == null && (threshold = 0.1); innerThreshold == null && (innerThreshold = 0.1); maxIteration == null && (maxIteration = 500); maxInnerIteration == null && (maxInnerIteration = 50); maxEnergy == null && (maxEnergy = 1e9); edgeStrength = bondLength; i = vertexIds.length; while (i--) { vertex = graph.nodes[vertexIds[i]]; j = vertex.neighbors.length; } matDist = graph.getSubgraphDistanceMatrix(vertexIds); length = vertexIds.length; radius = mathHelper.polyCircumradius(500, length); angle = mathHelper.centralAngle(length); a = 0.0; arrPositionX = new Float32Array(length); arrPositionY = new Float32Array(length); arrPositioned = Array(length); i = length; while (i--) { index = (i + startVertexId) % length; vertex = graph.nodes[vertexIds[index]]; if (!vertex.positioned) { arrPositionX[index] = center.x + Math.cos(a) * radius; arrPositionY[index] = center.y + Math.sin(a) * radius; } else { arrPositionX[index] = vertex.position.x; arrPositionY[index] = vertex.position.y; } arrPositioned[index] = vertex.positioned; a += angle; } matLength = Array(length); i = length; while (i--) { matLength[i] = new Array(length); j = length; while (j--) { matLength[i][j] = bondLength * matDist[i][j]; } } matStrength = Array(length); i = length; while (i--) { matStrength[i] = Array(length); j = length; while (j--) { matStrength[i][j] = edgeStrength * Math.pow(matDist[i][j], -2.0); } } matEnergy = Array(length); arrEnergySumX = new Float32Array(length); arrEnergySumY = new Float32Array(length); i = length; while (i--) { matEnergy[i] = Array(length); } i = length; while (i--) { ux = arrPositionX[i]; uy = arrPositionY[i]; dEx = 0.0; dEy = 0.0; j = length; while (j--) { if (i === j) { continue; } vx = arrPositionX[j]; vy = arrPositionY[j]; denom = 1.0 / Math.sqrt((ux - vx) * (ux - vx) + (uy - vy) * (uy - vy)); matEnergy[i][j] = [matStrength[i][j] * ((ux - vx) - matLength[i][j] * (ux - vx) * denom), matStrength[i][j] * ((uy - vy) - matLength[i][j] * (uy - vy) * denom)]; matEnergy[j][i] = matEnergy[i][j]; dEx += matEnergy[i][j][0]; dEy += matEnergy[i][j][1]; } arrEnergySumX[i] = dEx; arrEnergySumY[i] = dEy; } energy = function(index){ return [arrEnergySumX[index] * arrEnergySumX[index] + arrEnergySumY[index] * arrEnergySumY[index], arrEnergySumX[index], arrEnergySumY[index]]; }; highestEnergy = function(){ var maxEnergy, maxEnergyId, maxDEX, maxDEY, i, ref$, delta, dEX, dEY; maxEnergy = 0.0; maxEnergyId = 0; maxDEX = 0.0; maxDEY = 0.0; i = length; while (i--) { ref$ = energy(i), delta = ref$[0], dEX = ref$[1], dEY = ref$[2]; if (delta > maxEnergy && !arrPositioned[i]) { maxEnergy = delta; maxEnergyId = i; maxDEX = dEX; maxDEY = dEY; } } return [maxEnergyId, maxEnergy, maxDEX, maxDEY]; }; update = function(index, dEX, dEY){ var dxx, dyy, dxy, ux, uy, arrL, arrK, i, vx, vy, l, k, m, denom, dy, dx, arrE, prevEx, prevEy; dxx = 0.0; dyy = 0.0; dxy = 0.0; ux = arrPositionX[index]; uy = arrPositionY[index]; arrL = matLength[index]; arrK = matStrength[index]; i = length; while (i--) { if (i === index) { continue; } vx = arrPositionX[i]; vy = arrPositionY[i]; l = arrL[i]; k = arrK[i]; m = (ux - vx) * (ux - vx); denom = 1.0 / Math.pow(m + (uy - vy) * (uy - vy), 1.5); dxx += k * (1 - l * (uy - vy) * (uy - vy) * denom); dyy += k * (1 - l * m * denom); dxy += k * (l * (ux - vx) * (uy - vy) * denom); } if (dxx === 0) { dxx = 0.1; } if (dyy === 0) { dyy = 0.1; } if (dxy === 0) { dxy = 0.1; } dy = (dEX / dxx + dEY / dxy) / (dxy / dxx - dyy / dxy); dx = -(dxy * dy + dEX) / dxx; arrPositionX[index] += dx; arrPositionY[index] += dy; arrE = matEnergy[index]; dEX = 0.0; dEY = 0.0; ux = arrPositionX[index]; uy = arrPositionY[index]; i = length; while (i--) { if (index === i) { continue; } vx = arrPositionX[i]; vy = arrPositionY[i]; prevEx = arrE[i][0]; prevEy = arrE[i][1]; denom = 1.0 / Math.sqrt((ux - vx) * (ux - vx) + (uy - vy) * (uy - vy)); dx = arrK[i] * ((ux - vx) - arrL[i] * (ux - vx) * denom); dy = arrK[i] * ((uy - vy) - arrL[i] * (uy - vy) * denom); arrE[i] = [dx, dy]; dEX += dx; dEY += dy; arrEnergySumX[i] += dx - prevEx; arrEnergySumY[i] += dy - prevEy; } arrEnergySumX[index] = dEX; return arrEnergySumY[index] = dEY; }; maxEnergyId = 0; dEX = 0.0; dEY = 0.0; delta = 0.0; iteration = 0; innerIteration = 0; while (maxEnergy > threshold && maxIteration > iteration) { iteration++; ref$ = highestEnergy(), maxEnergyId = ref$[0], maxEnergy = ref$[1], dEX = ref$[2], dEY = ref$[3]; delta = maxEnergy; innerIteration = 0; while (delta > innerThreshold && maxInnerIteration > innerIteration) { innerIteration++; update(maxEnergyId, dEX, dEY); ref$ = energy(maxEnergyId), delta = ref$[0], dEX = ref$[1], dEY = ref$[2]; } } i = length; while (i--) { index = vertexIds[i]; vertex = graph.nodes[index]; vertex.position.x = arrPositionX[i]; vertex.position.y = arrPositionY[i]; vertex.positioned = true; results$.push(vertex.forcePositioned = true); } return results$; }; res$ = []; for (i$ = 0, to$ = graph.nodes.length; i$ < to$; ++i$) { ridx$ = i$; res$.push(ridx$); } vertexIds = res$; center = { x: 0, y: 0 }; bondLength = 2.5; return kkLayout(vertexIds, center, startVertexId, bondLength); }; }; })(); molecule/layout/force/mathHelper/mathHelper.ls (function(){ return function(){ var toRad; toRad = function(deg){ return deg * Math.PI / 180.0; }; return { polyCircumradius: function(s, n){ return s / (2 * Math.sin(Math.PI / n)); }, centralAngle: function(n){ return toRad(360 / n); }, roRad: toRad }; }; })(); molecule/lsgEditor.ls (function(){ return { name: "Molecule", 'default': { type: 'lsg', lsg: path('renderer.lsr'), w: 300, h: 300, x: 0, y: 0, background: 'transparent', smiles: "O" } }; })(); molecule/moleculeNameObject/object.ls (function(){ return function(name, namePosition, lsgWidth, lsgHeight, padding){ var fontSize; fontSize = 50 * Math.min(lsgWidth, lsgHeight) / 1000; return { type: "text", color: Color.black, text: (name != null ? name : graph.data.name).replace(/\d/g, function(t){ return String.fromCharCode(+t + 8320); }), x: _.includes(namePosition, "left") ? padding : _.includes(namePosition, "right") ? lsgWidth - padding : lsgWidth / 2, y: _.includes(namePosition, "top") ? padding : _.includes(namePosition, "bottom") ? lsgHeight - fontSize * (6 / 5) - padding : lsgHeight / 2 - fontSize / 2, size: fontSize, align: _.includes(namePosition, "left") ? "left" : _.includes(namePosition, "right") ? "right" : "center" }; }; })(); molecule/renderer.lsr (function(){ var Graph; Graph = include("classes/Graph"); return function(o){ var lsgWidth, lsgHeight, padding, smiles, name, namePosition, ref$, colorTheme, forceLayoutStartIndex, lsg, molecule, graph, layout, atomLsgs, bondLsgs, i$, len$, obj; lsgWidth = o.width || o.height || 1000; lsgHeight = o.height || o.width || 1000; padding = o.padding || 10 * Math.min(lsgWidth, lsgHeight) / 1000; smiles = o.smiles; name = o.name; namePosition = ((ref$ = o.namePosition) != null ? ref$ : "bottomRight").toLowerCase(); colorTheme = o.colorTheme || "cpk"; forceLayoutStartIndex = (ref$ = o.forceLayoutStartIndex) != null ? ref$ : 0; lsg = { width: lsgWidth, height: lsgHeight, objects: [] }; if (!smiles) { return lsg; } if (colorTheme === "cpk") { colorTheme = include("themes/cpk")(); } else if (_.isString(colorTheme)) { colorTheme = include("themes/singleColor")(colorTheme); } molecule = include("smilesParser/parse")(smiles); graph = new Graph(molecule); if (!graph.nodes.length) { return lsg; } layout = include("layout/force/layout")(forceLayoutStartIndex); atomLsgs = []; bondLsgs = []; graph.layout(layout).scaleTo(lsgWidth, lsgHeight, padding).traverse(function(node){ var i$, ref$, len$, edge, results$ = []; atomLsgs.push.apply(atomLsgs, node.toLsgObjects(colorTheme, graph.scale)); for (i$ = 0, len$ = (ref$ = node.edges).length; i$ < len$; ++i$) { edge = ref$[i$]; if (!edge.isDrawn) { edge.isDrawn = true; results$.push(bondLsgs.push.apply(bondLsgs, edge.toLsgObjects(colorTheme, graph.scale))); } } return results$; }); for (i$ = 0, len$ = (ref$ = _.concat(bondLsgs, atomLsgs)).length; i$ < len$; ++i$) { obj = ref$[i$]; lsg.objects.push(obj); } if (namePosition !== "none") { lsg.objects.push(include("moleculeNameObject/object")(name != null ? name : graph.data.name, namePosition, lsgWidth, lsgHeight, padding)); } return lsg; }; })(); molecule/smilesParser/getMolecule/get.ls (function(){ return function(atoms, bonds, id){ var getFormula, getName, getMass, mass, formula, name; atoms == null && (atoms = {}); bonds == null && (bonds = {}); id == null && (id = 0); getFormula = function(atoms, formula){ var keys, i$, to$, i; formula == null && (formula = {}); if (typeof atoms !== 'object') { return null; } keys = Object.keys(atoms); for (i$ = 0, to$ = keys.length; i$ < to$; ++i$) { i = i$; if (formula[atoms[keys[i]].name] === undefined) { formula[atoms[keys[i]].name] = 1; } else { formula[atoms[keys[i]].name] += 1; } } return formula; }; getName = function(formula, name){ var keys, remove, update, i$, to$, i; name == null && (name = []); if (typeof formula !== 'object') { return null; } keys = Object.keys(formula).sort(); remove = function(element){ return keys.splice(keys.indexOf(element), 1); }; update = function(element){ if (formula[element] === 1) { return name.push(element); } else { return name.push(element + formula[element]); } }; if (keys.indexOf('C') !== -1) { update('C'); remove('C'); } if (keys.indexOf('H') !== -1) { update('H'); remove('H'); } if (keys.length > 0) { for (i$ = 0, to$ = keys.length; i$ < to$; ++i$) { i = i$; update(keys[i]); } } return name.join(''); }; getMass = function(atoms, mass){ var keys, i$, to$, i; mass == null && (mass = 0); if (typeof atoms !== 'object') { return null; } keys = Object.keys(atoms); for (i$ = 0, to$ = keys.length; i$ < to$; ++i$) { i = i$; mass += atoms[keys[i]].protons + atoms[keys[i]].neutrons; } return Math.round(mass * 10000) / 10000; }; mass = getMass(atoms); formula = getFormula(atoms); name = getName(formula); return { id: id, name: name, atoms: atoms, bonds: bonds, properties: { mass: mass, formula: formula } }; }; })(); molecule/smilesParser/parse.ls (function(){ return function(smiles){ var smilesParser, tokens, ref$, atoms, bonds; smilesParser = include("parser/parser")(); tokens = smilesParser.tokenize(smiles).tokens; ref$ = smilesParser.decode(tokens), atoms = ref$.atoms, bonds = ref$.bonds; return include("getMolecule/get")(atoms, bonds); }; })(); molecule/smilesParser/parser/elements/elements.ls (function(){ return function(){ return { H: { protons: 1, neutrons: 0.0079, electrons: 1, group: 1, period: 1 }, D: { protons: 1, neutrons: 1.0000, electrons: 1, group: 1, period: 1 }, He: { protons: 2, neutrons: 2.0026, electrons: 2, group: 18, period: 1 }, Li: { protons: 3, neutrons: 3.9410, electrons: 3, group: 1, period: 2 }, Be: { protons: 4, neutrons: 5.0122, electrons: 4, group: 2, period: 2 }, B: { protons: 5, neutrons: 5.8110, electrons: 5, group: 13, period: 2 }, C: { protons: 6, neutrons: 6.0107, electrons: 6, group: 14, period: 2 }, N: { protons: 7, neutrons: 7.0067, electrons: 7, group: 15, period: 2 }, O: { protons: 8, neutrons: 7.9994, electrons: 8, group: 16, period: 2 }, F: { protons: 9, neutrons: 9.9984, electrons: 9, group: 17, period: 2 }, Ne: { protons: 10, neutrons: 10.1797, electrons: 10, group: 18, period: 2 }, Na: { protons: 11, neutrons: 11.9897, electrons: 11, group: 1, period: 3 }, Mg: { protons: 12, neutrons: 12.3050, electrons: 12, group: 2, period: 3 }, Al: { protons: 13, neutrons: 13.9815, electrons: 13, group: 13, period: 3 }, Si: { protons: 14, neutrons: 14.0855, electrons: 14, group: 14, period: 3 }, P: { protons: 15, neutrons: 15.9738, electrons: 15, group: 15, period: 3 }, S: { protons: 16, neutrons: 16.0650, electrons: 16, group: 16, period: 3 }, Cl: { protons: 17, neutrons: 18.4500, electrons: 17, group: 17, period: 3 }, Ar: { protons: 18, neutrons: 21.9480, electrons: 18, group: 18, period: 3 }, K: { protons: 19, neutrons: 20.0983, electrons: 19, group: 1, period: 4 }, Ca: { protons: 20, neutrons: 20.0780, electrons: 20, group: 2, period: 4 }, Sc: { protons: 21, neutrons: 23.9559, electrons: 21, group: 3, period: 4 }, Ti: { protons: 22, neutrons: 25.8670, electrons: 22, group: 4, period: 4 }, V: { protons: 23, neutrons: 27.9415, electrons: 23, group: 5, period: 4 }, Cr: { protons: 24, neutrons: 27.9961, electrons: 24, group: 6, period: 4 }, Mn: { protons: 25, neutrons: 29.9380, electrons: 25, group: 7, period: 4 }, Fe: { protons: 26, neutrons: 29.8450, electrons: 26, group: 8, period: 4 }, Co: { protons: 27, neutrons: 31.9332, electrons: 27, group: 9, period: 4 }, Ni: { protons: 28, neutrons: 30.6934, electrons: 28, group: 10, period: 4 }, Cu: { protons: 29, neutrons: 34.5460, electrons: 29, group: 11, period: 4 }, Zn: { protons: 30, neutrons: 35.3900, electrons: 30, group: 12, period: 4 }, Ga: { protons: 31, neutrons: 38.7230, electrons: 31, group: 13, period: 4 }, Ge: { protons: 32, neutrons: 40.6100, electrons: 32, group: 14, period: 4 }, As: { protons: 33, neutrons: 41.9216, electrons: 33, group: 15, period: 4 }, Se: { protons: 34, neutrons: 44.9600, electrons: 34, group: 16, period: 4 }, Br: { protons: 35, neutrons: 44.9040, electrons: 35, group: 17, period: 4 }, Kr: { protons: 36, neutrons: 47.8000, electrons: 36, group: 18, period: 4 }, Rb: { protons: 37, neutrons: 48.4678, electrons: 37, group: 1, period: 5 }, Sr: { protons: 38, neutrons: 49.6210, electrons: 38, group: 2, period: 5 }, Y: { protons: 39, neutrons: 49.9058, electrons: 39, group: 3, period: 5 }, Zr: { protons: 40, neutrons: 52.2242, electrons: 40, group: 4, period: 5 }, Nb: { protons: 41, neutrons: 51.9064, electrons: 41, group: 5, period: 5 }, Mo: { protons: 42, neutrons: 53.9510, electrons: 42, group: 6, period: 5 }, Tc: { protons: 43, neutrons: 55.0000, electrons: 43, group: 7, period: 5 }, Ru: { protons: 44, neutrons: 57.0720, electrons: 44, group: 8, period: 5 }, Rh: { protons: 45, neutrons: 57.9055, electrons: 45, group: 9, period: 5 }, Pd: { protons: 46, neutrons: 60.4210, electrons: 46, group: 10, period: 5 }, Ag: { protons: 47, neutrons: 60.8682, electrons: 47, group: 11, period: 5 }, Cd: { protons: 48, neutrons: 64.4144, electrons: 48, group: 12, period: 5 }, In: { protons: 49, neutrons: 65.8181, electrons: 49, group: 13, period: 5 }, Sn: { protons: 50, neutrons: 68.7107, electrons: 50, group: 14, period: 5 }, Sb: { protons: 51, neutrons: 70.7601, electrons: 51, group: 15, period: 5 }, Te: { protons: 52, neutrons: 75.6030, electrons: 52, group: 16, period: 5 }, I: { protons: 53, neutrons: 73.9045, electrons: 53, group: 17, period: 5 }, Xe: { protons: 54, neutrons: 77.2936, electrons: 54, group: 18, period: 5 } }; }; })(); molecule/smilesParser/parser/grammar/grammar.ls (function(){ return function(){ var grammar; return grammar = [ { type: 'atom', term: 'H', tag: 'H', expression: /(?=[A-Z])H(?=[^efgos]|$)([0-9]?)+/g }, { type: 'atom', term: 'D', tag: 'H', expression: /(?=[A-Z])D(?=[^bsy]|$)([0-9]?)+/g }, { type: 'atom', term: 'He', tag: 'He', expression: /He/g }, { type: 'atom', term: 'Li', tag: 'Li', expression: /Li/g }, { type: 'atom', term: 'Be', tag: 'Be', expression: /Be/g }, { type: 'atom', term: 'B', tag: 'B', expression: /B(?=[^aehikr]|$)/g }, { type: 'atom', term: 'C', tag: 'C', expression: /C(?=[^adeflmnorsu]|$)/g }, { type: 'atom', term: 'N', tag: 'N', expression: /N(?=[^abdeiop]|$)/g }, { type: 'atom', term: 'O', tag: 'O', expression: /O(?=[^s]|$)/g }, { type: 'atom', term: 'F', tag: 'F', expression: /F(?=[^elmr]|$)/g }, { type: 'atom', term: 'Ne', tag: 'Ne', expression: /Ne/g }, { type: 'atom', term: 'Na', tag: 'Na', expression: /Na/g }, { type: 'atom', term: 'Mg', tag: 'Mg', expression: /Mg/g }, { type: 'atom', term: 'Al', tag: 'Al', expression: /Al/g }, { type: 'atom', term: 'Si', tag: 'Si', expression: /Si/g }, { type: 'atom', term: 'P', tag: 'P', expression: /P(?=[^abdmortu]|$)/g }, { type: 'atom', term: 'S', tag: 'S', expression: /S(?=[^bcegimnr]|$)/g }, { type: 'atom', term: 'Cl', tag: 'Cl', expression: /Cl/g }, { type: 'atom', term: 'Ar', tag: 'Ar', expression: /Ar/g }, { type: 'atom', term: 'As', tag: 'As', expression: /As/g }, { type: 'atom', term: 'Se', tag: 'Se', expression: /Se/g }, { type: 'atom', term: 'Br', tag: 'Br', expression: /Br/g }, { type: 'atom', term: 'I', tag: 'I', expression: /I(?=[^nr]|$)/g }, { type: 'atom', term: 'b', tag: 'B', expression: /b(?=[^e]|$)/g }, { type: 'atom', term: 'c', tag: 'C', expression: /c(?=[^l]|$)/g }, { type: 'atom', term: 'n', tag: 'N', expression: /n(?=[^ae]|$)/g }, { type: 'atom', term: 'o', tag: 'O', expression: /o(?=[^s]|$)/g }, { type: 'atom', term: 'p', tag: 'P', expression: /p/g }, { type: 'atom', term: 's', tag: 'S', expression: /s(?=[^ei]|$)/g }, { type: 'atom', term: 'se', tag: 'Se', expression: /se/g }, { type: 'bond', term: '-', tag: 'single', expression: /(?=([^0-9]))[-](?=[^0-9-\]])/g }, { type: 'bond', term: '=', tag: 'double', expression: /[=]/g }, { type: 'bond', term: '#', tag: 'triple', expression: /[#]/g }, { type: 'bond', term: '(', tag: 'branch', expression: /[(]/g }, { type: 'bond', term: ')', tag: 'branch', expression: /[)]/g }, { type: 'bond', term: '%', tag: 'ring', expression: /(?=[^+-])(?:[a-zA-Z]{1,2}[@]{1,2})?(?:[a-zA-Z]|[a-zA-Z]*.?[\]])[%]?\d+(?=([^+]|$))/g }, { type: 'bond', term: '.', tag: 'dot', expression: /(?:[A-Z][+-]?[\[])?[.]/g }, { type: 'property', term: '+', tag: 'charge', expression: /[a-zA-Z]{1,2}[0-9]*[+]+[0-9]*(?=[\]])/g }, { type: 'property', term: '-', tag: 'charge', expression: /[a-zA-Z]{1,2}[0-9]*[-]+[0-9]*(?=[\]])/g }, { type: 'property', term: 'n', tag: 'isotope', expression: /(?:[\[])[0-9]+[A-Z]{1,2}(?=.?[^\[]*[\]])/g }, { type: 'property', term: 'S', tag: 'chiral', expression: /[A-Z][a-z]?[@](?![A-Z]{2}[0-9]+|[@])/g }, { type: 'property', term: 'R', tag: 'chiral', expression: /[A-Z][a-z]?[@]{2}(?![A-Z]{2}[0-9]+)/g } ]; }; })(); molecule/smilesParser/parser/parser.ls (function(){ return function(){ var elements, grammar, tokenize, decode, compareArrays, addAtom, addBond, nextAtom, previousAtom; elements = include("elements/elements")(); grammar = include("grammar/grammar")(); tokenize = function(input, tokens){ var i$, ref$, len$, i, token, text, to$, ringID, exception, j$, to1$, j, checkID, prefix; tokens == null && (tokens = []); for (i$ = 0, len$ = (ref$ = grammar).length; i$ < len$; ++i$) { i = i$; token = ref$[i$]; text = []; while (text = token.expression.exec(input)) { tokens.push({ index: text.index, type: token.type, term: text[0], tag: token.tag }); } } tokens.sort(function(a, b){ if (a.index < b.index) { return -1; } if (a.index > b.index) { return +1; } return 0; }); for (i$ = 0, to$ = tokens.length; i$ < to$; ++i$) { i = i$; if (tokens[i].tag === 'ring') { ringID = tokens[i].term.match(/[0-9]+/g); if (ringID !== null) { ringID = ringID[0]; } else { continue; } if (ringID.length > 1) { exception = 0; for (j$ = 0, to1$ = tokens.length; j$ < to1$; ++j$) { j = j$; if (i === j || tokens[j].tag !== 'ring') { continue; } checkID = tokens[j].term.match(/[0-9]+/g); if (checkID !== null) { checkID = checkID[0]; } else { continue; } if (ringID === checkID) { exception = 1; break; } } if (exception === 1) { continue; } prefix = tokens[i].term.match(/[a-zA-Z]/g)[0]; for (j$ = 0, to1$ = ringID.length; j$ < to1$; ++j$) { j = j$; tokens.splice(i + 1, 0, { index: tokens[i].index + j, type: tokens[i].type, term: prefix + ringID.substr(j, j + 1), tag: tokens[i].tag }); } tokens.splice(i, 1); } } } return { tokens: tokens }; }; decode = function(tokens){ var validateTokens, readTokens, defaultAtoms, updateAtoms, explicitBonds, implicitBonds, clean, atoms, bonds, properties, keys, ref$; validateTokens = function(tokens){ var fields, i$, to$, i, mmatch; if (typeof tokens !== 'object') { console.log('Error: Tokens must be of type "object"'); return false; } else if (tokens.tokens != null) { tokens = tokens.tokens; } fields = ['index', 'type', 'term', 'tag']; for (i$ = 0, to$ = tokens.length; i$ < to$; ++i$) { i = i$; mmatch = compareArrays(fields, Object.keys(tokens[i])); if (mmatch.reduce(fn$) < 4) { console.log('Error: Invalid token at index "' + i + '"'); return false; } } return tokens; function fn$(a, b){ return a + b; } }; readTokens = function(tokens, atoms, bonds, properties, keys){ var i$, to$, i, ref$, type, term, tag, index, key; atoms == null && (atoms = {}); bonds == null && (bonds = {}); properties == null && (properties = {}); keys == null && (keys = {}); for (i$ = 0, to$ = tokens.length; i$ < to$; ++i$) { i = i$; ref$ = tokens[i], type = ref$.type, term = ref$.term, tag = ref$.tag, index = ref$.index; key = index.toString(); switch (type) { case 'atom': atoms[key] = addAtom(key, tag, term); break; case 'bond': bonds[key] = addBond(key, tag, term); break; case 'property': properties[key] = { id: key, name: tag, value: term }; } } keys.all = []; for (i$ = 0, to$ = tokens.length; i$ < to$; ++i$) { i = i$; keys.all[i] = tokens[i].index.toString(); } if (atoms.length < 1) { console.log('Error: Could not find atoms'); return false; } keys.atoms = Object.keys(atoms); keys.bonds = Object.keys(bonds); keys.properties = Object.keys(properties); return [atoms, bonds, properties, keys]; }; defaultAtoms = function(atoms, keys){ var i$, ref$, len$, i, atomID, element; for (i$ = 0, len$ = (ref$ = keys.atoms).length; i$ < len$; ++i$) { i = i$; atomID = ref$[i$]; if (!(element = elements[atoms[atomID].name])) { continue; } if (atoms[atomID].value === 'D') { element = elements[atoms[atomID].value]; } atoms[atomID].group = element.group; atoms[atomID].protons = element.protons; atoms[atomID].neutrons = element.neutrons; atoms[atomID].electrons = element.electrons; atoms[atomID].bonds = { id: [], atoms: [], electrons: 0 }; atoms[atomID].properties = { chiral: 0, charge: 0, aromatic: 0 }; if (atoms[atomID].value === atoms[atomID].value.toLowerCase()) { atoms[atomID].properties.aromatic = 1; } } return atoms; }; updateAtoms = function(atoms, properties, keys){ var i$, ref$, len$, i, propertyID, ref1$, name, value, isotope, atomID, neutrons, sign, charge; for (i$ = 0, len$ = (ref$ = keys.properties).length; i$ < len$; ++i$) { i = i$; propertyID = ref$[i$]; ref1$ = properties[propertyID], name = ref1$.name, value = ref1$.value; switch (name) { case 'chiral': if ((ref1$ = atoms[propertyID]) != null) { ref1$.properties.chiral = value.slice(value.indexOf('@')); } break; case 'isotope': isotope = value.match(/[0-9]+/g); atomID = 1 + isotope.toString().length + parseInt(propertyID); if (isotope >= 0 && isotope < 250 && atoms[atomID] != null) { neutrons = isotope - atoms[atomID].protons; if (neutrons >= 0) { atoms[atomID].neutrons = neutrons; } } break; case 'charge': sign = value.indexOf('+') !== -1 ? 1 : -1; charge = value.match(/(?:[^H])[0-9]+/g); if (charge != null && atoms[propertyID] != null) { charge = charge[0].substr(1); atoms[propertyID].properties.charge = charge * sign; } else { charge = value.match(/([+]+|[-]+)/g); if (charge != null && atoms[propertyID] != null) { atoms[propertyID].properties.charge = charge[0].length * sign; } } } } return atoms; }; explicitBonds = function(atoms, bonds, keys){ var i$, ref$, len$, i, bondID, sourceAtom, targetAtom, bondIndex, sourceIndex, targetIndex, exceptions, bond1, bond2, keysBefore, keysAfter, skip, j$, to$, j, bondOrder, sourceID, bondsBefore, bondsAfter, targetID, k$, to1$, k, a, b; if (keys.bonds == null || keys.bonds.length === 0) { return [atoms, bonds, keys]; } for (i$ = 0, len$ = (ref$ = keys.bonds).length; i$ < len$; ++i$) { i = i$; bondID = ref$[i$]; sourceAtom = atoms[previousAtom(bondID, keys.all, atoms)]; targetAtom = atoms[nextAtom(bondID, keys.all, atoms)]; bondIndex = keys.all.indexOf(bondID); sourceIndex = 0; targetIndex = 0; if (sourceAtom != null) { sourceIndex = keys.atoms.indexOf(sourceAtom.id); if ((bonds[bondID].name === 'double' || bonds[bondID].name === 'triple') && deepEq$(sourceAtom.name, 'H', '===')) { while ((sourceAtom.name === 'H' || atoms[keys.atoms[sourceIndex]] === undefined) && sourceIndex > -1) { sourceAtom = atoms[keys.atoms[sourceIndex]]; sourceIndex -= 1; } } sourceIndex = keys.all.indexOf(sourceAtom.id); } if (sourceIndex < 0) { continue; } if (targetAtom != null) { targetIndex = keys.all.indexOf(targetAtom.id); } exceptions = 0; if (targetIndex > bondIndex && bondIndex > sourceIndex) { if (bonds[keys.all[bondIndex - 1]] !== undefined) { bond1 = bonds[keys.all[bondIndex - 1]].value; bond2 = bonds[bondID].value; switch (bond1) { case ')': // fallthrough case '(': switch (bond2) { case '-': // fallthrough case '=': // fallthrough case '#': // fallthrough case '.': exceptions = 1; } } } } switch (bonds[bondID].name) { case 'single': if (exceptions === 1 || sourceAtom === undefined || targetAtom === undefined) { continue; } bonds[bondID].order = 1; bonds[bondID].atoms = [sourceAtom.id, targetAtom.id]; break; case 'double': if (exceptions === 1 || sourceAtom === undefined || targetAtom === undefined) { continue; } if (targetAtom.name === 'H') { continue; } bonds[bondID].order = 2; bonds[bondID].atoms = [sourceAtom.id, targetAtom.id]; break; case 'triple': if (exceptions === 1 || sourceAtom === undefined || targetAtom === undefined) { continue; } if (targetAtom.name === 'H') { continue; } bonds[bondID].order = 3; bonds[bondID].atoms = [sourceAtom.id, targetAtom.id]; break; case 'dot': if (exceptions === 1 || sourceAtom === undefined || targetAtom === undefined) { continue; } bonds[bondID].order = 0; break; case 'branch': keysBefore = keys.all.slice(0, bondIndex).reverse(); keysAfter = keys.all.slice(bondIndex + 1, keys.all.length); switch (bonds[bondID].value) { case '(': skip = 0; for (j$ = 0, to$ = keysBefore.length; j$ < to$; ++j$) { j = j$; sourceAtom = atoms[keysBefore[j]]; if (sourceAtom !== undefined && sourceAtom.name !== 'H' && skip === 0) { bondOrder = 1; if (sourceAtom.properties.aromatic === 1 && targetAtom.properties.aromatic === 1) { bondOrder = 1.5; } bonds[bondID].order = bondOrder; bonds[bondID].atoms = [sourceAtom.id, targetAtom.id]; break; } else if (bonds[keysBefore[j]] !== undefined) { switch (bonds[keysBefore[j]].value) { case ')': skip++; break; case '(': skip--; } } } bondOrder = bonds[bondID].order; skip = 0; for (j$ = 0, to$ = keysAfter.length; j$ < to$; ++j$) { j = j$; if (bonds[keysAfter[j]] !== undefined && skip === 0) { switch (bonds[keysAfter[j]].value) { case '-': bondOrder = 1; break; case '=': bondOrder = 2; break; case '#': bondOrder = 3; break; case '.': bondOrder = 0; } } if (skip === 0) { bonds[bondID].order = bondOrder; break; } else if (bonds[keysAfter[j]] !== undefined) { switch (bonds[keysAfter[j]].value) { case ')': skip--; break; case '(': skip++; } } } break; case ')': skip = 1; for (j$ = 0, to$ = keysBefore.length; j$ < to$; ++j$) { j = j$; sourceAtom = atoms[keysBefore[j]]; if (sourceAtom !== undefined && sourceAtom.name !== 'H' && skip === 0) { bondOrder = 1; if (sourceAtom.properties.aromatic === 1) { bondOrder = 1.5; } bonds[bondID].order = bondOrder; bonds[bondID].atoms[0] = sourceAtom.id; break; } else if (bonds[keysBefore[j]] !== undefined) { switch (bonds[keysBefore[j]].value) { case ')': skip++; break; case '(': skip--; } } } bondOrder = bonds[bondID].order; skip = 0; for (j$ = 0, to$ = keysAfter.length; j$ < to$; ++j$) { j = j$; targetAtom = atoms[keysAfter[j]]; if (bonds[keysAfter[j]] !== undefined && skip === 0) { switch (bonds[keysAfter[j]].value) { case '-': bondOrder = 1; break; case '=': bondOrder = 2; break; case '#': bondOrder = 3; break; case '.': bondOrder = 0; } } if (targetAtom !== undefined && skip === 0) { if (targetAtom.properties.aromatic === 1) { bondOrder = 1.5; } bonds[bondID].order = bondOrder; bonds[bondID].atoms[1] = targetAtom.id; break; } else if (bonds[keysAfter[j]] !== undefined) { switch (bonds[keysAfter[j]].value) { case ')': skip--; break; case '(': skip++; } } } } break; case 'ring': sourceID = bonds[bondID].value.match(/[0-9]+/g); bondsBefore = keys.bonds.slice(0, keys.bonds.indexOf(bondID)); bondsAfter = keys.bonds.slice(keys.bonds.indexOf(bondID), keys.bonds.length); for (j$ = 1, to$ = bondsAfter.length; j$ < to$; ++j$) { j = j$; if (bonds[bondsAfter[j]].name !== 'ring') { continue; } targetID = bonds[bondsAfter[j]].value.match(/[0-9]+/g); targetIndex = bondsAfter[j]; sourceIndex = bondID; if (sourceID !== null && targetID !== null && sourceID[0] === targetID[0]) { while (atoms[sourceIndex] === undefined && sourceIndex >= -1) { sourceIndex -= 1; } while (atoms[targetIndex] === undefined && targetIndex >= -1) { targetIndex -= 1; } if (sourceIndex === -1 || targetIndex === -1) { break; } bondOrder = 1; if (atoms[sourceIndex].properties.aromatic === 1 && atoms[targetIndex].properties.aromatic === 1) { bondOrder = 1.5; } bonds[bondID].order = bondOrder; bonds[bondID].atoms = [sourceIndex.toString(), targetIndex.toString()]; break; } if (j === bondsAfter.length - 1) { for (k$ = 0, to1$ = bondsBefore.length; k$ < to1$; ++k$) { k = k$; if (bonds[bondsAfter[j]].name !== 'ring') { continue; } targetID = bonds[bondsBefore[k]].value.match(/[0-9]+/g); targetIndex = bondID; sourceIndex = bondsBefore[k]; if (sourceID !== null && targetID !== null && sourceID[0] === targetID[0]) { while (atoms[sourceIndex] === undefined && sourceIndex >= -1) { sourceIndex -= 1; } while (atoms[targetIndex] === undefined && targetIndex >= -1) { targetIndex -= 1; } if (sourceIndex === -1 || targetIndex === -1) { break; } bondOrder = 1; if (atoms[sourceIndex].properties.aromatic === 1 && atoms[targetIndex].properties.aromatic === 1) { bondOrder = 1.5; } bonds[bondID].order = bondOrder; bonds[bondID].atoms = [sourceIndex.toString(), targetIndex.toString()]; break; } } } } } } for (i$ = 0, to$ = keys.bonds.length; i$ < to$; ++i$) { i = i$; if (keys.bonds[i] === undefined) { keys.bonds.splice(i, 1); i--; continue; } if (bonds[keys.bonds[i]].atoms.length !== 2) { delete bonds[keys.bonds[i]]; keys.bonds.splice(i, 1); i--; continue; } if (i === keys.bonds.length - 1) { continue; } bondsAfter = keys.bonds.slice(i, keys.bonds.length); for (j$ = 1, to1$ = bondsAfter.length; j$ < to1$; ++j$) { j = j$; bondID = bondsAfter[j]; a = bonds[keys.bonds[i]]; b = bonds[bondID]; if (a === undefined || b === undefined) { continue; } if ((a.atoms[0] === b.atoms[0] && a.atoms[1] === b.atoms[1]) || (a.atoms[0] === b.atoms[1] && a.atoms[1] === b.atoms[0])) { if (a.name === 'ring' && b.name === 'ring') { delete bonds[bondID]; keys.bonds.splice(keys.bonds.indexOf(bondID), 1); } else if (a.name === 'branch' && (b.name === 'single' || b.name === 'double' || b.name === 'triple')) { delete bonds[keys.bonds[i]]; keys.bonds.splice(i, 1); } else if ((a.name === 'single' || a.name === 'double' || a.name === 'triple') && b.name === 'branch') { delete bonds[bondID]; keys.bonds.splice(keys.bonds.indexOf(bondID), 1); } else { delete bonds[keys.bonds[i]]; keys.bonds.splice(i, 1); } i--; break; } } } for (i$ = 0, len$ = (ref$ = keys.bonds).length; i$ < len$; ++i$) { i = i$; bondID = ref$[i$]; sourceID = bonds[bondID].atoms[0]; targetID = bonds[bondID].atoms[1]; if (sourceID === undefined || targetID === undefined) { continue; } atoms[sourceID].bonds.id.push(bondID); atoms[targetID].bonds.id.push(bondID); atoms[sourceID].bonds.atoms.push(targetID); atoms[targetID].bonds.atoms.push(sourceID); atoms[sourceID].bonds.electrons += bonds[bondID].order; atoms[targetID].bonds.electrons += bonds[bondID].order; } return [atoms, bonds, keys]; }; implicitBonds = function(atoms, bonds, keys){ var valence, charge, checkRow, updateAtoms, i$, to$, i, sourceAtom, targetAtom, sourceIndex, sourceTotal, targetTotal, n, exceptions, keysBetween, j$, to1$, j, bondID, bondValue, bondName, bondOrder, H, update, bondCount, targetID, count, k$, k, total; valence = function(group, electrons){ electrons == null && (electrons = 18); if (group <= 2) { return 2; } if (group > 2 && group <= 12) { return 12; } if (group > 12 && group <= 18) { return 18; } }; charge = function(electrons, charge){ if (charge > 0) { return electrons -= charge; } }; checkRow = function(group, protons, electrons){ if (group > 12 && protons > 10 && electrons <= 0) { return electrons += 4; } else { return electrons; } }; updateAtoms = function(sourceID, targetID, bondID, bondOrder){ atoms[sourceID].bonds.id.push(bondID); atoms[targetID].bonds.id.push(bondID); atoms[sourceID].bonds.atoms.push(targetID); atoms[targetID].bonds.atoms.push(sourceID); atoms[sourceID].bonds.electrons += bondOrder; return atoms[targetID].bonds.electrons += bondOrder; }; for (i$ = 0, to$ = keys.atoms.length - 1; i$ < to$; ++i$) { i = i$; sourceAtom = atoms[keys.atoms[i]]; targetAtom = atoms[keys.atoms[i + 1]]; sourceIndex = i; while ((sourceAtom.name === 'H' || atoms[keys.atoms[sourceIndex]] === undefined) && sourceIndex > -1) { sourceAtom = atoms[keys.atoms[sourceIndex]]; sourceIndex -= 1; } if (sourceIndex === -1) { continue; } sourceTotal = charge(valence(sourceAtom.group) - sourceAtom.bonds.electrons, sourceAtom.properties.charge); targetTotal = charge(valence(targetAtom.group) - targetAtom.bonds.electrons, targetAtom.properties.charge); sourceTotal = checkRow(sourceTotal); targetTotal = checkRow(targetTotal); if (sourceTotal <= 0 || targetTotal <= 0) { continue; } if (sourceAtom.bonds.atoms.indexOf(targetAtom.id) !== -1) { continue; } n = keys.all.indexOf(targetAtom.id) - keys.all.indexOf(sourceAtom.id); exceptions = 0; if (n > 1) { keysBetween = keys.all.slice(keys.all.indexOf(sourceAtom.id) + 1, keys.all.indexOf(targetAtom.id)); for (j$ = 0, to1$ = keysBetween.length; j$ < to1$; ++j$) { j = j$; if (bonds[keysBetween[j]] === undefined) { exceptions += 0; } else if (bonds[keysBetween[j]].name !== 'ring') { exceptions += 1; } } } if (exceptions === 0) { bondID = (sourceAtom.name + sourceAtom.id) + (targetAtom.name + targetAtom.id); bondValue = sourceAtom.name + targetAtom.name; bondName = 'single'; bondOrder = 1; if (sourceAtom.name === 'H' || targetAtom.name === 'H') { bondName = 'H'; } if (sourceAtom.properties.aromatic === 1 && targetAtom.properties.aromatic === 1) { bondName = 'aromatic'; bondOrder = 1.5; } keys.bonds.push(bondID); bonds[bondID] = addBond(bondID, bondName, bondValue, bondOrder, [sourceAtom.id, targetAtom.id]); updateAtoms(sourceAtom.id, targetAtom.id, bondID, bondOrder); } } H = elements.H; update = function(x, sourceID, sourceName){ var bondID, targetID; bondID = 'H' + (x + 1) + sourceName + sourceID; targetID = bondID; atoms[targetID] = addAtom(targetID, 'H', 'H', H.group, H.protons, H.neutrons, H.electrons); bonds[bondID] = addBond(bondID, 'H', 'H', 1, [sourceID, targetID]); atoms[sourceID].bonds.id.push(bondID); atoms[sourceID].bonds.atoms.push(targetID); atoms[sourceID].bonds.electrons += 1; atoms[targetID].bonds.id.push(bondID); atoms[targetID].bonds.atoms.push(sourceID); return atoms[targetID].bonds.electrons += 1; }; for (i$ = 0, to$ = keys.atoms.length; i$ < to$; ++i$) { i = i$; sourceAtom = atoms[keys.atoms[i]]; if (sourceAtom.group < 13 && sourceAtom.group > 1) { continue; } bondCount = sourceAtom.bonds.atoms.length; if (sourceAtom.name !== 'H' && bondCount > 0) { for (j$ = 0; j$ < bondCount; ++j$) { j = j$; targetID = sourceAtom.bonds.atoms[j]; targetAtom = atoms[targetID]; if (targetAtom.name === 'H') { count = parseInt(targetAtom.value.match(/[0-9]+/g)); if (count > 1 && count < sourceAtom.electrons) { for (k$ = 0, to1$ = count - 1; k$ < to1$; ++k$) { k = k$; update(k, sourceAtom.id, sourceAtom.name); } } } } } else if (sourceAtom.name === 'H' && sourceAtom.properties.charge === 0 && bondCount === 0) { update(i, sourceAtom.id, sourceAtom.name); } total = 18 - sourceAtom.group - sourceAtom.bonds.electrons; charge = sourceAtom.properties.charge; if (total <= 0 || sourceAtom.group === 1) { continue; } if (charge > 0) { total -= charge; } else if (charge < 0) { total += charge; if (total === 1) { total -= 1; atoms[sourceAtom.id].bonds.electrons += 1; } } if (total <= 0) { continue; } for (j$ = 0; j$ < total; ++j$) { j = j$; if (sourceAtom.properties.aromatic === 1 && j > 1) { continue; } update(j, sourceAtom.id, sourceAtom.name); } } return [atoms, bonds, keys]; }; clean = function(atoms, bonds){ var atomID, bondID, i$, to$, i, source, target, order, getID, setID, oldID, newID, j$, to1$, j, key, index; atomID = Object.keys(atoms); bondID = Object.keys(bonds); for (i$ = 0, to$ = bondID.length; i$ < to$; ++i$) { i = i$; source = atoms[bonds[bondID[i]].atoms[0]]; target = atoms[bonds[bondID[i]].atoms[1]]; order = bonds[bondID[i]].order; bonds[bondID[i]].value = source.name + order + target.name; } getID = function(name, i){ return name + (i + 1); }; setID = function(obj, a, b){ var ref$; if (obj.hasOwnProperty(a)) { obj[b] = obj[a]; return ref$ = obj[a], delete obj[a], ref$; } }; for (i$ = 0, to$ = atomID.length; i$ < to$; ++i$) { i = i$; oldID = atomID[i]; newID = getID(atoms[oldID].name, i); atoms[oldID].id = newID; for (j$ = 0, to1$ = atoms[oldID].bonds.id.length; j$ < to1$; ++j$) { j = j$; key = atoms[oldID].bonds.id[j]; index = bonds[key].atoms.indexOf(oldID); if (index !== -1) { bonds[key].atoms[index] = newID; } key = atoms[oldID].bonds.atoms[j]; index = atoms[key].bonds.atoms.indexOf(oldID); if (index !== -1) { atoms[key].bonds.atoms[index] = newID; } } setID(atoms, oldID, newID); } return [atoms, bonds]; }; tokens = validateTokens(tokens); if (!tokens) { return false; } ref$ = readTokens(tokens), atoms = ref$[0], bonds = ref$[1], properties = ref$[2], keys = ref$[3]; atoms = defaultAtoms(atoms, keys); atoms = updateAtoms(atoms, properties, keys); ref$ = explicitBonds(atoms, bonds, keys), atoms = ref$[0], bonds = ref$[1], keys = ref$[2]; ref$ = implicitBonds(atoms, bonds, keys), atoms = ref$[0], bonds = ref$[1], keys = ref$[2]; ref$ = clean(atoms, bonds), atoms = ref$[0], bonds = ref$[1]; return { atoms: atoms, bonds: bonds }; }; compareArrays = function(a, b, ab){ var i$, to$, i; ab == null && (ab = []); for (i$ = 0, to$ = a.length; i$ < to$; ++i$) { i = i$; ab[i] = b.indexOf(a[i]) > -1 ? 1 : 0; } return ab; }; addAtom = function(id, name, value, group, protons, neutrons, electrons){ group == null && (group = 0); protons == null && (protons = 0); neutrons == null && (neutrons = 0); electrons == null && (electrons = 0); return { id: id, name: name, value: value, group: group, protons: protons, neutrons: neutrons, electrons: electrons, bonds: { id: [], atoms: [], electrons: 0 }, properties: { chiral: 0, charge: 0, aromatic: 0 } }; }; addBond = function(id, name, value, order, atoms){ order == null && (order = 0); atoms == null && (atoms = []); return { id: id, name: name, value: value, order: order, atoms: atoms }; }; nextAtom = function(start, keys, atoms){ var index, ii, i$, i; index = keys.indexOf(start); if (index !== -1) { keys = keys.slice(index, keys.length); ii = keys.length; for (i$ = 1; i$ < ii; ++i$) { i = i$; if (atoms[keys[i]] !== undefined) { return keys[i]; } } } return null; }; previousAtom = function(start, keys, atoms){ var index, ii, i$, i; if (start === '0' && atoms['0'] !== undefined) { return '0'; } index = keys.indexOf(start); if (index !== -1) { keys = keys.slice(0, index).reverse(); ii = keys.length; for (i$ = 0; i$ < ii; ++i$) { i = i$; if (atoms[keys[i]] !== undefined) { return keys[i]; } } } return null; }; return { grammar: grammar, tokenize: tokenize, decode: decode }; }; })(); function deepEq$(x, y, type){ var toString = {}.toString, hasOwnProperty = {}.hasOwnProperty, has = function (obj, key) { return hasOwnProperty.call(obj, key); }; var first = true; return eq(x, y, []); function eq(a, b, stack) { var className, length, size, result, alength, blength, r, key, ref, sizeB; if (a == null || b == null) { return a === b; } if (a.__placeholder__ || b.__placeholder__) { return true; } if (a === b) { return a !== 0 || 1 / a == 1 / b; } className = toString.call(a); if (toString.call(b) != className) { return false; } switch (className) { case '[object String]': return a == String(b); case '[object Number]': return a != +a ? b != +b : (a == 0 ? 1 / a == 1 / b : a == +b); case '[object Date]': case '[object Boolean]': return +a == +b; case '[object RegExp]': return a.source == b.source && a.global == b.global && a.multiline == b.multiline && a.ignoreCase == b.ignoreCase; } if (typeof a != 'object' || typeof b != 'object') { return false; } length = stack.length; while (length--) { if (stack[length] == a) { return true; } } stack.push(a); size = 0; result = true; if (className == '[object Array]') { alength = a.length; blength = b.length; if (first) { switch (type) { case '===': result = alength === blength; break; case '<==': result = alength <= blength; break; case '<<=': result = alength < blength; break; } size = alength; first = false; } else { result = alength === blength; size = alength; } if (result) { while (size--) { if (!(result = size in a == size in b && eq(a[size], b[size], stack))){ break; } } } } else { if ('constructor' in a != 'constructor' in b || a.constructor != b.constructor) { return false; } for (key in a) { if (has(a, key)) { size++; if (!(result = has(b, key) && eq(a[key], b[key], stack))) { break; } } } if (result) { sizeB = 0; for (key in b) { if (has(b, key)) { ++sizeB; } } if (first) { if (type === '<<=') { result = size < sizeB; } else if (type === '<==') { result = size <= sizeB } else { result = size === sizeB; } } else { first = false; result = size === sizeB; } } } stack.pop(); return result; } } molecule/themes/cpk.ls (function(){ return function(){ return { bond: Color.black, defaultAtomBackground: Color.pink[200], defaultAtomForeground: Color.black, defaultAtomBorder: Color.black, atomBackground: { H: Color.white, C: Color.black, N: Color.blue[500], O: Color.red[500], F: Color.green[500], Cl: Color.green[500], Br: Color.red[900], I: Color.purple[900], He: Color.cyan[500], Ne: Color.cyan[500], Ar: Color.cyan[500], Kr: Color.cyan[500], Xe: Color.cyan[500], P: Color.orange[500], S: Color.yellow[500], B: Color.brown[200], Li: Color.purple[300], Na: Color.purple[300], K: Color.purple[300], Rb: Color.purple[300], Cs: Color.purple[300], Fr: Color.purple[300], Be: Color.green[900], Mg: Color.green[900], Ca: Color.green[900], Sr: Color.green[900], Ba: Color.green[900], Ra: Color.green[900], Ti: Color.grey[500], Fe: Color.orange[900] }, atomForeground: { C: Color.white, I: Color.white, Be: Color.white, Mg: Color.white, Ca: Color.white, Sr: Color.white, Ba: Color.white, Ra: Color.white } }; }; })(); molecule/themes/singleColor.ls (function(){ return function(color){ return { bond: color, defaultAtomBackground: Color.white, defaultAtomForeground: color }; }; })(); musicStaff/calcDimensions/calc.ls (function(){ return function(o){ var last, dw, keys, key; o.gridWidth = o.gridWidth || o.defaults.gridWidth; last = _.last(o.notesParsed); dw = (last != null ? last.type : void 8) === 'separator' && !(last != null && last.bold) ? -1 * o.gridWidth / 2 + 1 : (last != null && last.bold) && !(last != null && last.repeat) ? -1 * o.gridWidth / 2 + 5 : (last != null && last.bold) && (last != null ? last.repeat : void 8) === "end" ? -1 * o.gridWidth / 2 + 7 : 0; o.lsgHeight = 113; o.offsetY = 43; o.clefWidth = o.noClef ? 0 : o.notes.clef === "bass" ? 47 : o.notes.clef === "alto" ? 41 : 41; keys = inc("/../music-components/lib/keys/keys"); key = o.notes.key || o.defaults.key; o.keyWidth = o.noKey ? 0 : !keys[key] ? 0 : keys[key].notes.length * 9 + 10; o.metricWidth = o.noMetric ? 0 : 19; return o.lsgWidth = o.clefWidth + o.keyWidth + o.metricWidth + o.notesParsed.length * o.gridWidth + dw; }; })(); musicStaff/examples.lsg (function(){ return { version: 2, width: 300, height: 1000, background: Color.grey[100], objects: [ { type: 'lsg', lsg: path('renderer.lsr'), x: 20, y: -40, w: 260, notes: { musicAscii: 'B2 D3-1/2', clef: 'alto' } }, { type: 'lsg', lsg: path('renderer.lsr'), x: 35.1, y: 202.1, h: 77, notes: { musicAscii: 'D4-1/8 ||: Ds5 :|| Cf4 E-1', key: 'Cmin', clef: 'violin', octave: 4, noteValue: '1/4', metric: '4/4' }, noClef: false, noLines: false, noMetric: true, noPitch: false } ] }; })(); musicStaff/level.ls (function(){ return { uid: '3eyro5', trainers: { trainer: "buttons", instruction: { text: "instruction" }, lsg: { lsg: path("examples.lsg") }, atoms: { a: "1", b: "++1 2" } } }; })(); musicStaff/lsgEditor.ls (function(){ return { name: "Music Staff", 'default': { type: 'lsg', lsg: path('renderer.lsr'), h: 100, x: 50, y: 50, notes: { musicAscii: 'C', key: 'Cmaj', clef: 'violin', octave: 4, noteValue: "1/4", metric: "4/4", gridWidth: 30 }, noClef: false, noLines: false, noMetric: false, noPitch: false } }; })(); musicStaff/notesParser/note/note.ls (function(){ return function(o, part){ var note, ref$, dots, ref1$, value, ref2$, ref3$, ref4$, dottedValue, noteParsed, octave, noteSignShort, noteSign, keys, key, keySign, ref5$, sign, parsedNote; note = part.split("-")[0]; if ((ref$ = note.match(/\./g)) != null && ref$.length) { dots = (ref1$ = note.match(/\./g)) != null ? ref1$.length : void 8; note = note.replace(/\./g, ''); } value = ((ref2$ = part.split("-")) != null ? ref2$[1] : void 8) || o.currentNoteValue || o.defaultNoteValue; if (typeof value.match == 'function' && ((ref3$ = value.match(/\./g)) != null && ref3$.length)) { dots = (ref4$ = value.match(/\./g)) != null ? ref4$.length : void 8; value = value.replace(/\./g, ''); } value = eval(value); o.currentNoteValue = value; dottedValue = dots ? value * (2 - 1 / Math.pow(2, dots)) : value; if (note === "P") { noteParsed = { type: "rest", value: eval(value) }; return noteParsed; } octave = note.length === 1 || _.includes(["s", "f"], _.last(note)) ? o.currentOctave || o.defaultOctave : _.last(note); o.currentOctave = octave; noteSignShort = _.includes(["s", "f"], _.last(note)) ? _.last(note) : _.includes(["s", "f"], note[1]) ? note[1] : void 8; noteSign = noteSignShort === "s" ? "sharp" : noteSignShort === "f" ? "flat" : void 8; keys = inc("/../music-components/lib/keys/keys"); key = o.key; keySign = _.includes((ref5$ = keys[key]) != null ? ref5$.notes : void 8, note[0]) ? keys[key].sign : void 8; sign = o.currentSign != null && o.currentSign !== noteSign && noteSign !== keySign ? noteSign || "natural" : !o.currentSign && noteSign !== keySign ? noteSign || "natural" : void 8; o.currentSign = sign !== "natural" ? sign : void 8; parsedNote = { type: "note", note: _.first(note), sign: sign != null ? sign : null, dots: dots, octave: octave * 1, value: value, dottedValue: dottedValue, start: o.currentTime, end: o.currentTime + dottedValue, originalSign: noteSignShort }; o.currentTime += dottedValue; return parsedNote; }; })(); musicStaff/notesParser/parser.ls (function(){ return function(o){ var parsedNotes, i$, ref$, len$, i, part, partTrimmed, parsedNote; parsedNotes = []; o.currentValue = null; o.currentSign = null; o.currentOctave = null; o.currentTime = 0; for (i$ = 0, len$ = (ref$ = o.musicAscii.split(/\s/g)).length; i$ < len$; ++i$) { i = i$; part = ref$[i$]; partTrimmed = part.trim(); if (partTrimmed) { parsedNote = (fn$()); } if (parsedNote) { parsedNotes.push(parsedNote); } } return parsedNotes; function fn$(){ switch (partTrimmed) { case "||": return { type: "separator", bold: true }; case "||:": return { type: "separator", bold: true, repeat: "start" }; case ":||": return { type: "separator", bold: true, repeat: "end" }; case "|": o.currentSign = null; return { type: "separator" }; default: return inc("note/note")(o, partTrimmed); } } }; })(); musicStaff/renderer.lsr (function(){ return function(o){ o = o || {}; o.defaults = { key: "Cmaj", clef: "violin", octave: 4, noteValue: "1/4", metric: "4/4", gridWidth: 40 }; o.notesParsed = inc("notesParser/parser")({ musicAscii: o.notes.musicAscii, defaultNoteValue: o.notes.noteValue || o.defaults.noteValue, defaultOctave: o.notes.octave || o.defaults.octave, key: o.notes.key || o.defaults.key }); inc("calcDimensions/calc")(o); o.lsg = { width: o.lsgWidth, height: o.lsgHeight, objects: [] }; inc("row/row")(o); return o.lsg; }; })(); musicStaff/row/clef/clef.ls (function(){ return function(o){ var clef; if (o.noClef) { return; } clef = o.notes.clef || o.defaults.clef; o.lsg.objects.push({ type: 'rect', 'class': 'note key-c', x: 0, y: 0, w: o.clefWidth, h: o.lsgHeight, color: Color.cyan[200], lineSize: 1, lineColor: Color.cyan[600], opacity: 0 }); if (clef === "bass") { return o.lsg.objects.push({ type: 'svg', 'class': 'clef', svg: path('/../c-svg/2020/08/05-renderer-music-staff-clef-bass.svg'), x: 5, y: o.offsetY, h: 36 }); } else if (clef === "alto") { return o.lsg.objects.push({ type: 'svg', 'class': 'alto', svg: path('/../c-svg/2020/08/05-renderer-music-staff-clef-alto.svg'), x: 5, y: o.offsetY, h: 40 }); } else { return o.lsg.objects.push({ type: 'svg', 'class': 'clef', svg: path('/../c-svg/2020/08/05-renderer-music-staff-clef-violin.svg'), x: 5, y: o.offsetY - 13, h: 70 }); } }; })(); musicStaff/row/key/key.ls (function(){ return function(o){ var dx, key, clef, keys, sign, notes, octaveShifts, dysign, dyclef, i$, len$, i, note, octaveShift, dyoct, noteNumber, x, y, results$ = []; if (o.noKey) { return; } dx = o.clefWidth; key = o.notes.key || o.defaults.key; clef = o.notes.clef || o.defaults.clef; keys = inc("/../music-components/lib/keys/keys"); if (!keys[key]) { return; } sign = keys[key].sign; notes = keys[key].notes; octaveShifts = clef === "bass" ? keys[key].octaveShifts.bass : clef === "alto" ? keys[key].octaveShifts.alto : keys[key].octaveShifts.violin; dysign = sign === "sharp" ? 13 : 19; dyclef = clef === "bass" ? 25 : clef === "alto" ? 30 : 0; o.lsg.objects.push({ type: 'rect', 'class': 'note key-c', x: dx, y: 0, w: o.keyWidth, h: o.lsgHeight, color: Color.cyan[200], lineSize: 1, lineColor: Color.cyan[600], opacity: 0 }); for (i$ = 0, len$ = notes.length; i$ < len$; ++i$) { i = i$; note = notes[i$]; octaveShift = octaveShifts[i]; dyoct = octaveShift * 35; noteNumber = _.indexOf(["C", "D", "E", "F", "G", "A", "B"], note); x = i * 9 + o.clefWidth; y = o.offsetY + 50 - dysign - dyclef - dyoct - noteNumber * 5; results$.push(o.lsg.objects.push({ type: 'svg', 'class': 'clef', svg: path("/../c-svg/2020/08/05-renderer-music-staff-sign-" + sign + ".svg"), x: x, y: y, h: 25 })); } return results$; }; })(); musicStaff/row/lines/lines.ls (function(){ return function(o){ var dx, ref$; if (o.noLines) { return; } dx = ((ref$ = _.last(o.notesParsed)) != null ? ref$.type : void 8) === 'separator' ? -1 * o.gridWidth / 2 + 5 : 0; o.lsg.objects.push({ type: 'line', 'class': 'line1', x1: 0, y1: o.offsetY, x2: o.lsgWidth, y2: o.offsetY, lineColor: Color.black, lineSize: 1 }); o.lsg.objects.push({ type: 'line', 'class': 'line2', x1: 0, y1: o.offsetY + 10, x2: o.lsgWidth, y2: o.offsetY + 10, lineColor: Color.black, lineSize: 1 }); o.lsg.objects.push({ type: 'line', 'class': 'line3', x1: 0, y1: o.offsetY + 20, x2: o.lsgWidth, y2: o.offsetY + 20, lineColor: Color.black, lineSize: 1 }); o.lsg.objects.push({ type: 'line', 'class': 'line4', x1: 0, y1: o.offsetY + 30, x2: o.lsgWidth, y2: o.offsetY + 30, lineColor: Color.black, lineSize: 1 }); return o.lsg.objects.push({ type: 'line', 'class': 'line5', x1: 0, y1: o.offsetY + 40, x2: o.lsgWidth, y2: o.offsetY + 40, lineColor: Color.black, lineSize: 1 }); }; })(); musicStaff/row/metric/metric.ls (function(){ return function(o){ var metric, numerator, denominator, dx; if (o.noMetric) { return; } metric = o.notes.metric || o.defaults.metric; numerator = metric.split("/")[0]; denominator = metric.split("/")[1]; dx = o.clefWidth + o.keyWidth; o.lsg.objects.push({ type: 'rect', 'class': 'note key-c', x: dx, y: 0, w: 19, h: o.lsgHeight, color: Color.cyan[200], lineSize: 1, lineColor: Color.cyan[600], opacity: 0 }); o.lsg.objects.push({ type: 'svg', 'class': 'clef', svg: path("/../c-svg/2020/08/05-renderer-music-staff-metric-number-" + numerator + ".svg"), x: dx, y: o.offsetY - 1, h: 22 }); return o.lsg.objects.push({ type: 'svg', 'class': 'clef', svg: path("/../c-svg/2020/08/05-renderer-music-staff-metric-number-" + denominator + ".svg"), x: dx, y: o.offsetY + 19, h: 22 }); }; })(); musicStaff/row/note/note.ls (function(){ return function(o, note, i){ var dx, notes, noteNumberAbs, clef, clefOffset, noteNumber, onLine, noteClass, dox, dlox, dloy, sox, dy, i$, to$; dx = o.clefWidth + o.keyWidth + o.metricWidth + i * o.gridWidth; notes = ["C", "D", "E", "F", "G", "A", "B"]; noteNumberAbs = _.indexOf(notes, note.note) + note.octave * notes.length; clef = o.notes.clef || o.defaults.clef; clefOffset = clef === "violin" ? 4 * notes.length : clef === "alto" ? 3 * notes.length + 1 : clef === "bass" ? 2 * notes.length + 2 : void 8; noteNumber = o.noPitch ? 2 : noteNumberAbs - clefOffset; onLine = noteNumber % 2 === 0; noteClass = "note-" + note.note; if (note.originalSign) { noteClass += note.originalSign[0]; } noteClass += note.octave; noteClass += " value-" + note.value + " start-" + note.start + " end-" + note.end; dox = note.dots && onLine ? -1 * note.dots * 2 : note.dots ? -1 * note.dots * 2 : 0; dlox = onLine ? 0 : 3; dloy = onLine ? 5 : 0; sox = note.sign === "natural" ? 10 : note.sign === "sharp" ? 12 : note.sign === "flat" ? 12 : 8; dy = o.offsetY + 10 - noteNumber * 5; if (note.value < 0.25) { if (noteNumber < 6) { o.lsg.objects.push({ type: "svg", 'class': "flag " + noteClass, svg: path("/../c-svg/2020/08/05-renderer-music-staff-note-flag.svg"), x: dx + 19 + dox + sox, y: dy + 5, h: 24 }); } else { o.lsg.objects.push({ type: "svg", 'class': "flag " + noteClass, svg: path("/../c-svg/2020/08/05-renderer-music-staff-note-flag.svg"), x: dx + 8 + dox + sox, y: dy + 49, h: 24, flipY: true }); } } if (note.value < 0.125) { if (noteNumber < 6) { o.lsg.objects.push({ type: "svg", 'class': "flag " + noteClass, svg: path("/../c-svg/2020/08/05-renderer-music-staff-note-flag.svg"), x: dx + 19 + dox + sox, y: dy + 13, h: 24 }); } else { o.lsg.objects.push({ type: "svg", 'class': "flag " + noteClass, svg: path("/../c-svg/2020/08/05-renderer-music-staff-note-flag.svg"), x: dx + 8 + dox + sox, y: dy + 41, h: 24, flipY: true }); } } if (note.value < 1) { if (noteNumber < 6) { o.lsg.objects.push({ type: "rect", 'class': "stem " + noteClass, x: dx + 18.4 + dox + sox, y: dy + 5, w: 1.6, h: 33.7, color: Color.black }); } else { o.lsg.objects.push({ type: "rect", 'class': "stem " + noteClass, x: dx + 6.4 + dox + sox, y: dy + 42, w: 1.6, h: 33.7, color: Color.black }); } } if (note.value === 1 || note.value === 0.5) { o.lsg.objects.push({ type: "svg", 'class': "head " + noteClass, svg: path("/../c-svg/2020/08/05-renderer-music-staff-note-head-full.svg"), x: dx + 6 + dox + sox, y: dy + 35.2, w: 14.3, h: 10 }); } else { o.lsg.objects.push({ type: "svg", 'class': "head " + noteClass, svg: path("/../c-svg/2020/08/05-renderer-music-staff-note-head.svg"), x: dx + 6 + dox + sox, y: dy + 35.2, w: 14.3, h: 10 }); } if (noteNumber < 1) { o.lsg.objects.push({ type: "line", 'class': "line " + i, x1: dx + 3 + dox + sox, y1: o.offsetY + 50, x2: dx + 23 + dox + sox, y2: o.offsetY + 50, lineColor: Color.black, lineSize: 1 }); } if (noteNumber < -1) { o.lsg.objects.push({ type: "line", 'class': "line " + i, x1: dx + 3 + dox + sox, y1: o.offsetY + 60, x2: dx + 23 + dox + sox, y2: o.offsetY + 60, lineColor: Color.black, lineSize: 1 }); } if (noteNumber > 11) { o.lsg.objects.push({ type: "line", 'class': "line " + i, x1: dx + 3 + dox + sox, y1: o.offsetY - 10, x2: dx + 23 + dox + sox, y2: o.offsetY - 10, lineColor: Color.black, lineSize: 1 }); } if (noteNumber > 13) { o.lsg.objects.push({ type: "line", 'class': "line " + i, x1: dx + 3 + dox + sox, y1: o.offsetY - 20, x2: dx + 23 + dox + sox, y2: o.offsetY - 20, lineColor: Color.black, lineSize: 1 }); } if (note.sign) { o.lsg.objects.push({ type: "svg", 'class': "sign " + noteClass, svg: path("/../c-svg/2020/08/05-renderer-music-staff-sign-" + note.sign + ".svg"), x: note.sign === "natural" ? dx - 2 + dox + sox : note.sign === "sharp" ? dx - 4 + dox + sox : note.sign === "flat" ? dx - 4 + dox + sox : void 8, y: note.sign === "natural" ? dy + 28 : note.sign === "sharp" ? dy + 28 : note.sign === "flat" ? dy + 22 : void 8, h: 24 }); } for (i$ = 0, to$ = note.dots; i$ < to$; ++i$) { i = i$; o.lsg.objects.push({ type: "oval", 'class': "dot " + noteClass, x: dx + 19 + dox + sox + i * 4 + dlox, y: dy + 38 + dloy, w: 3, h: 3, color: Color.black }); } return o.lsg.objects.push({ type: "rect", 'class': "zone " + noteClass, x: dx, y: 0, w: o.gridWidth, h: o.lsgHeight, color: Color.cyan[200], lineSize: 1, lineColor: Color.cyan[600], opacity: 0 }); }; })(); musicStaff/row/rest/rest.ls (function(){ return function(o, part, i){ var value, dx; value = part.value; dx = o.clefWidth + o.keyWidth + o.metricWidth + i * o.gridWidth; o.lsg.objects.push({ type: 'rect', 'class': 'note key-c', x: dx, y: 0, w: o.gridWidth, h: o.lsgHeight, color: Color.cyan[200], lineSize: 1, lineColor: Color.cyan[600], opacity: 0 }); if (value === 1) { return o.lsg.objects.push({ type: 'rect', 'class': 'rest', color: Color.black, x: dx + 14, y: o.offsetY + 10, w: 12, h: 6 }); } else if (value === 0.5) { return o.lsg.objects.push({ type: 'rect', 'class': 'rest', color: Color.black, x: dx + 14, y: o.offsetY + 14, w: 12, h: 6 }); } else if (value === 0.25) { return o.lsg.objects.push({ type: 'svg', 'class': 'rest', svg: path('/../c-svg/2020/08/05-renderer-music-staff-rest-4.svg'), x: dx + 14, y: o.offsetY + 7, h: 27 }); } else if (value === 0.125) { return o.lsg.objects.push({ type: 'svg', 'class': 'rest', svg: path('/../c-svg/2020/08/05-renderer-music-staff-rest-8.svg'), x: dx + 14, y: o.offsetY + 13, h: 17 }); } else if (value === 0.0625) { return o.lsg.objects.push({ type: 'svg', 'class': 'rest', svg: path('/../c-svg/2020/08/05-renderer-music-staff-rest-16.svg'), x: dx + 13, y: o.offsetY + 13, h: 27 }); } else if (value === 0.03125) { return o.lsg.objects.push({ type: 'svg', 'class': 'rest', svg: path('/../c-svg/2020/08/05-renderer-music-staff-rest32.svg'), x: dx + 12, y: o.offsetY + 3, h: 37 }); } }; })(); musicStaff/row/row.ls (function(){ return function(o){ var i$, ref$, len$, i, part, results$ = []; inc("lines/lines")(o); inc("clef/clef")(o); inc("key/key")(o); inc("metric/metric")(o); for (i$ = 0, len$ = (ref$ = o.notesParsed).length; i$ < len$; ++i$) { i = i$; part = ref$[i$]; switch (part.type) { case "separator": results$.push(inc("separator/separator")(o, part, i)); break; case "rest": results$.push(inc("rest/rest")(o, part, i)); break; case "note": results$.push(inc("note/note")(o, part, i)); } } return results$; }; })(); musicStaff/row/separator/bold/separator.ls (function(){ return function(o, part, i, dx){ o.lsg.objects.push({ type: 'line', 'class': 'separator', x1: dx + o.gridWidth / 2 - 5, y1: o.offsetY, x2: dx + o.gridWidth / 2 - 5, y2: o.offsetY + 40, lineColor: Color.black, lineSize: 2 }); return o.lsg.objects.push({ type: 'line', 'class': 'separatorBold', x1: dx + o.gridWidth / 2 + 2, y1: o.offsetY, x2: dx + o.gridWidth / 2 + 2, y2: o.offsetY + 40, lineColor: Color.black, lineSize: 6 }); }; })(); musicStaff/row/separator/boldRepeatEnd/separator.ls (function(){ return function(o, part, i, dx){ o.lsg.objects.push({ type: 'line', 'class': 'separator', x1: dx + o.gridWidth / 2 - 3, y1: o.offsetY, x2: dx + o.gridWidth / 2 - 3, y2: o.offsetY + 40, lineColor: Color.black, lineSize: 2 }); o.lsg.objects.push({ type: 'line', 'class': 'separatorBold', x1: dx + o.gridWidth / 2 + 4, y1: o.offsetY, x2: dx + o.gridWidth / 2 + 4, y2: o.offsetY + 40, lineColor: Color.black, lineSize: 6 }); o.lsg.objects.push({ type: 'oval', 'class': 'separatorRepeatDot', x: dx + o.gridWidth / 2 - 10, y: o.offsetY + 13, w: 5, h: 5, color: Color.black }); return o.lsg.objects.push({ type: 'oval', 'class': 'separatorRepeatDot', x: dx + o.gridWidth / 2 - 10, y: o.offsetY + 23, w: 5, h: 5, color: Color.black }); }; })(); musicStaff/row/separator/boldRepeatStart/separator.ls (function(){ return function(o, part, i, dx){ o.lsg.objects.push({ type: 'line', 'class': 'separator', x1: dx + o.gridWidth / 2 + 2, y1: o.offsetY, x2: dx + o.gridWidth / 2 + 2, y2: o.offsetY + 40, lineColor: Color.black, lineSize: 2 }); o.lsg.objects.push({ type: 'line', 'class': 'separatorBold', x1: dx + o.gridWidth / 2 - 5, y1: o.offsetY, x2: dx + o.gridWidth / 2 - 5, y2: o.offsetY + 40, lineColor: Color.black, lineSize: 6 }); o.lsg.objects.push({ type: 'oval', 'class': 'separatorRepeatDot', x: dx + o.gridWidth / 2 + 4, y: o.offsetY + 13, w: 5, h: 5, color: Color.black }); return o.lsg.objects.push({ type: 'oval', 'class': 'separatorRepeatDot', x: dx + o.gridWidth / 2 + 4, y: o.offsetY + 23, w: 5, h: 5, color: Color.black }); }; })(); musicStaff/row/separator/separator.ls (function(){ return function(o, part, i){ var dx; dx = o.clefWidth + o.keyWidth + o.metricWidth + i * o.gridWidth; o.lsg.objects.push({ type: 'rect', x: dx, y: 0, w: o.gridWidth, h: o.lsgHeight, color: Color.cyan[200], lineSize: 1, lineColor: Color.cyan[600], opacity: 0 }); switch (false) { case !(!part.bold && !part.repeat): return inc("simple/separator")(o, part, i, dx); case !(part.bold && !part.repeat): return inc("bold/separator")(o, part, i, dx); case !(part.bold && part.repeat === "start"): return inc("boldRepeatStart/separator")(o, part, i, dx); case !(part.bold && part.repeat === "end"): return inc("boldRepeatEnd/separator")(o, part, i, dx); } }; })(); musicStaff/row/separator/simple/separator.ls (function(){ return function(o, part, i, dx){ return o.lsg.objects.push({ type: 'line', 'class': 'separator', x1: dx + o.gridWidth / 2, y1: o.offsetY, x2: dx + o.gridWidth / 2, y2: o.offsetY + 40, lineColor: Color.black, lineSize: 2 }); }; })(); musicStaff/test.lsg (function(){ return { version: 2, width: 300, height: 75, objects: [ { type: 'line', 'class': 'line1', x1: 0, y1: 10, x2: 300, y2: 10, lineColor: Color.black, lineSize: 1 }, { type: 'line', 'class': 'line1', x1: 0, y1: 20, x2: 300, y2: 20, lineColor: Color.black, lineSize: 1 }, { type: 'line', 'class': 'line1', x1: 0, y1: 30, x2: 300, y2: 30, lineColor: Color.black, lineSize: 1 }, { type: 'line', 'class': 'line1', x1: 0, y1: 40, x2: 300, y2: 40, lineColor: Color.black, lineSize: 1 }, { type: 'line', 'class': 'line1', x1: 0, y1: 50, x2: 300, y2: 50, lineColor: Color.black, lineSize: 1 }, { type: 'line', 'class': 'line1', x1: 19, y1: 25, x2: 19, y2: 60, lineColor: Color.black, lineSize: 2 }, { type: 'svg', svg: path('/../c-svg/2020/08/05-renderer-music-staff-note-flag.svg'), x: 19, y: 25, h: 24 }, { type: 'oval', x: 6, y: 55, w: 14, h: 10, color: Color.black, rotate: 345 }, { type: 'oval', x: 7, y: 57, w: 12, h: 6, color: Color.white, rotate: 345 }, { type: 'oval', x: 21, y: 62, w: 4, h: 4, color: Color.black, lineSize: 0, lineColor: Color.black }, { type: 'line', 'class': 'line1', x1: 3, y1: 60, x2: 23, y2: 60, lineColor: Color.black, lineSize: 1 }, { type: 'svg', 'class': 'clef', svg: path('/../c-svg/2020/08/05-renderer-music-staff-clef-violin.svg'), x: 37, y: -3, h: 70 }, { type: 'svg', 'class': 'clef', svg: path('/../c-svg/2020/08/05-renderer-music-staff-metric-number-4.svg'), x: 112, y: 9, h: 22 }, { type: 'svg', 'class': 'clef', svg: path('/../c-svg/2020/08/05-renderer-music-staff-metric-number-4.svg'), x: 112, y: 29, h: 22 } ] }; })(); number-puzzle/examples-renderer.lsg (function(){ return { version: 2, width: 300, height: 1000, background: Color.grey[100], objects: { type: 'lsg', lsg: path('/../c-renderer/number-puzzle/renderer.lsr'), x: 52, y: 41, background: 'transparent', fieldWidth: 4, numbers: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, -1] } }; })(); number-puzzle/level.ls (function(){ return { uid: '710fcg', lsg: { lsg: path("renderer.lsr"), width: 150 }, trainers: { trainer: "imageButtons", atoms: { a: "1", b: [ { text: "a", correct: true, lsg: { fieldWidth: 4, numbers: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 0] } }, { text: "b", lsg: { fieldWidth: 4, numbers: [1, 2, 3, 4, 5, 6, 7, 8, 9, 13, 14, 15, 10, 11, 12, 0] } }, { text: "c", lsg: { fieldWidth: 4, numbers: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 0] } } ] } } }; })(); number-puzzle/lsgEditor.ls (function(){ return { name: "Number Puzzle", 'default': { type: 'lsg', lsg: path('renderer.lsr'), w: 100, x: 51, y: 34, background: 'transparent', fieldWidth: 4, numbers: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, -1] } }; })(); number-puzzle/renderer.lsr (function(){ return function(o){ var lsgWidth, lsgHeight, textSize, lsg, i$, to$, i, x, y; o.lineColor = o.lineColor || Color.grey[500]; o.textColor = o.textColor || Color.black; o.fillColor = o.fillColor || Color.white; lsgWidth = o.fieldWidth * 50; lsgHeight = o.fieldWidth * 50; textSize = 20; lsg = { width: lsgWidth, height: lsgHeight, requiredArguments: ["fieldWidth", "numbers"], objects: [] }; for (i$ = 0, to$ = Math.pow(o.fieldWidth, 2); i$ < to$; ++i$) { i = i$; x = i % o.fieldWidth; y = Math.floor(i / o.fieldWidth); if (o.numbers[i] !== 0) { lsg.objects.push({ type: 'rect', x: x * 50, y: y * 50, w: 50, h: 50, color: o.fillColor, lineSize: 2, lineColor: o.lineColor, 'class': "puzzle-field field-" + o.numbers[i] }); } if (o.numbers[i] > 0) { lsg.objects.push({ type: 'text', text: o.numbers[i], x: x * 50 + 25, y: y * 50 + 25 - textSize / 1.5, size: textSize, lineHeight: 22, color: o.textColor, align: 'center', 'class': "puzzle-field field-" + o.numbers[i] + "-text" }); } } return lsg; }; })(); numberline/examples-copy.lsg (function(){ return { version: 2, width: 300, height: 1000, background: Color.grey[100], objects: [ { type: 'lsg', lsg: path('/../c-renderer/numberline/renderer.lsr'), x: 20, y: 0, w: 250, background: 'white', from: 0, to: 0.01, step: 0.001, rangePadding: 15 }, { type: 'lsg', lsg: path('/../c-renderer/numberline/renderer.lsr'), x: 20, y: 53, w: 250, background: 'white', from: 10, to: 10.01, step: 0.001, stepLabel: 0.002 }, { type: 'lsg', lsg: path('/../c-renderer/numberline/renderer.lsr'), x: 20, y: 100, w: 250, background: 'white', from: 10, to: 20, step: 1, stepLabel: 5, numberFlags: [11, 12, 18] }, { type: 'lsg', lsg: path('/../c-renderer/numberline/renderer.lsr'), x: 20, y: 170, w: 250, background: 'white', from: 0, to: 20, step: 1, stepLabel: 2, flags: [14, 18] } ] }; })(); numberline/examples.lsg (function(){ return { version: 2, width: 300, height: 1200, background: Color.grey[100], objects: [ { type: 'lsg', lsg: path('renderer.lsr'), x: 19.5, y: 12, w: 250, background: 'white', from: 10000, to: 100000, step: 10000, rangePadding: 15 }, { type: 'lsg', lsg: path('renderer.lsr'), x: 20, y: 53, w: 250, background: 'white', decimalPoint: '.', from: 10, to: 10.01, step: 0.001, stepLabel: 0.002 }, { type: 'lsg', lsg: path('renderer.lsr'), x: 20, y: 100, w: 250, background: 'white', from: 10, to: 20, step: 1, stepLabel: 5, numberFlags: [11, 12, 18] }, { type: 'lsg', lsg: path('renderer.lsr'), x: 20, y: 160, w: 250, background: 'white', from: 0, to: 20, step: 1, stepLabel: 2, flags: [14, 18] }, { type: 'lsg', lsg: path('renderer.lsr'), x: 20, y: 220, w: 250, background: 'white', from: 0, to: 50, step: 1, stepLabel: 5, flags: [11, 42] }, { type: 'text', text: 'Correct click correctRanges examples:', x: 20, y: 300, color: 'black', size: 12, align: 'left' }, { type: 'lsg', lsg: path('renderer.lsr'), x: 20, y: 330, w: 250, background: 'white', from: 0, to: 50, step: 10, stepLabel: 10, isDebug: true, correctRanges: ['10-20', '40-45'] }, { type: 'lsg', lsg: path('renderer.lsr'), x: 20, y: 390, w: 250, background: 'white', from: 0, to: 50, step: 10, stepLabel: 10, isDebug: true, correctRanges: ['10-20'], wrongRanges: ['0-10', '10-20', '20-30', '30-40', '40-50'] }, { type: 'lsg', lsg: path('renderer.lsr'), x: 20, y: 450, w: 250, background: 'white', from: -50, to: 50, step: 10, stepLabel: 10, isDebug: true, correctRanges: ['-10-10', '-50--40'], wrongRanges: ['20-30', '30-40', '40-50'] }, { type: 'lsg', lsg: path('renderer.lsr'), x: 20, y: 510, w: 250, background: 'white', from: 0, to: 50, step: 10, stepLabel: 10, correctRanges: ['10-20'], wrongRanges: ['0-10', '20-30', '30-40', '40-50'] }, { type: 'text', text: 'Long label examples:', x: 20, y: 580, color: 'black', size: 12, align: 'left' }, { type: 'lsg', lsg: path('renderer.lsr'), x: 20, y: 610, w: 250, background: 'white', from: 0, to: 5000, step: 500, stepLabel: 10 }, { type: 'text', text: 'Long label examples (with rangePadding):', x: 20, y: 660, color: 'black', size: 12, align: 'left' }, { type: 'lsg', lsg: path('renderer.lsr'), x: 20, y: 690, w: 250, background: 'white', from: 0, to: 5000, step: 500, stepLabel: 10, rangePadding: 10 }, { type: 'lsg', lsg: path('renderer.lsr'), x: 20, y: 740, w: 250, background: 'white', from: 0, to: 5000000, step: 500000, stepLabel: 10, rangePadding: 43 }, { type: 'text', text: 'examples with arrowHeads:', x: 20, y: 770, color: 'black', size: 12, align: 'left' }, { type: 'lsg', lsg: path('renderer.lsr'), x: 20, y: 790, w: 250, background: 'white', from: 0, to: 100, step: 10, stepLabel: 10, arrowHeadLeft: true }, { type: 'lsg', lsg: path('renderer.lsr'), x: 20.1, y: 838.6, w: 250, background: 'white', from: 0, to: 100, step: 10, stepLabel: 10, arrowHeadRight: true }, { type: 'lsg', lsg: path('renderer.lsr'), x: 20, y: 890, w: 250, background: 'white', from: 0, to: 100, step: 10, stepLabel: 10, arrowHeadRight: true, arrowHeadLeft: true }, { type: 'lsg', lsg: path('renderer.lsr'), x: 20, y: 940, w: 250, background: 'white', from: 0, to: 1, step: 0.1, stepLabel: 0.1, fractionLabels: true }, { type: 'lsg', lsg: path('renderer.lsr'), x: 20, y: 1010, w: 250, background: 'white', from: 0, to: 3, step: 0.3333333333333333, fractionLabels: 3 }, { type: 'lsg', lsg: path('renderer.lsr'), x: 20, y: 1080, w: 250, background: 'white', from: 0, to: 1, step: 0.1, rangePadding: 15, fractionLabels: 1000 }, { type: 'lsg', lsg: path('renderer.lsr'), x: 20, y: 1150, w: 250, background: 'white', from: 1000000, to: 1000000.2, step: 0.1, rangePadding: 15, decimalPoint: '.', thousandsSeparator: ',' } ] }; })(); numberline/level.ls (function(){ return { uid: '3eyro5', trainers: [ { trainer: "buttons", instruction: { text: "instruction" }, lsg: { lsg: path("renderer.lsr"), width: 300, from: 0.1, to: 1, flags: [0.4, 0.7], step: 0.1 }, atoms: { a: "flag04", b: "++20000" } }, { trainer: "buttons", instruction: { text: "instruction (mit . als trennung, zB für us version)" }, lsg: { lsg: path("renderer.lsr"), width: 300, from: 0.1, to: 1, flags: [0.4, 0.7], step: 0.1, decimalPoint: "." }, atoms: { a: "flag04", b: "++20000" } } ] }; })(); numberline/lsgEditor.ls (function(){ return { name: "Number Line", 'default': { type: 'lsg', lsg: path('renderer.lsr'), x: 0, y: 0, w: 100, background: 'white', from: 1, to: 3, step: 1, rangePadding: 2 } }; })(); numberline/renderer-JP.lsr (function(){ return function(o){ var step, stepLabel, rangePadding, arrowHeadLeft, ref$, arrowHeadRight, fractionLabels, fractionLabelDenumerator, decimalPoint, thousandsSeparator, grid, fromDigits, toDigits, arrowHeadLeftPadding, arrowHeadRightPadding, paddingLeft, paddingRight, paddingTop, ref1$, total, gridX, calcGGT, addThousandsSeparator, numberToString, lsg, i$, i, x, prec, x2, s2, drawLabel, digits, ref2$, ref3$, denumerator, numerator, ggt, lineLength, len$, flag, flagClassClean, r, rFrom, rTo; o.renderLanguage == null && (o.renderLanguage = "de"); step = o.step || 1; if (o.stepLabel !== false) { stepLabel = o.stepLabel || step; } rangePadding = o.rangePadding || 0; arrowHeadLeft = (ref$ = o.arrowHeadLeft) != null ? ref$ : false; arrowHeadRight = (ref$ = o.arrowHeadRight) != null ? ref$ : false; fractionLabels = (ref$ = o.fractionLabels) != null ? ref$ : false; fractionLabelDenumerator = fractionLabels && _.isFinite(fractionLabels) ? fractionLabels : void 8; decimalPoint = (function(){ switch (o.renderLanguage) { case "de": case "fr": return ","; case "en_gb": case "en_us": case "es": return "."; } }()); thousandsSeparator = (function(){ switch (o.renderLanguage) { case "de": case "fr": case "es": return " "; case "en_gb": case "en_us": return ","; } }()); grid = 40; fromDigits = (o.from + "").length; toDigits = (o.to + "").length; arrowHeadLeftPadding = arrowHeadLeft ? 25 : 0; arrowHeadRightPadding = arrowHeadRight ? 25 : 0; paddingLeft = 5 + fromDigits * 5 + arrowHeadLeftPadding; paddingRight = 5 + toDigits * 5 + arrowHeadRightPadding; paddingTop = ((ref$ = o.flags) != null ? ref$.length : void 8) > 0 || ((ref1$ = o.numberFlags) != null ? ref1$.length : void 8) > 0 ? 35 : 3; total = _.round((o.to - o.from) / step); gridX = 400 / total + rangePadding; if (fractionLabels) { calcGGT = function(m, n){ if (n === 0) { return m; } return calcGGT(n, m % n); }; } addThousandsSeparator = function(t){ var parts, r, i$, i; parts = t.split(decimalPoint); if (parts[0].length > 3) { r = ""; for (i$ = parts[0].length - 1; i$ >= 0; --i$) { i = i$; r = parts[0][i] + r; if ((parts[0].length - i) % 3 === 0) { r = thousandsSeparator + r; } } parts[0] = r; } return parts.join(decimalPoint); }; numberToString = function(n){ var t; t = _.replaceAll(n + "", ".", decimalPoint); if (thousandsSeparator) { t = addThousandsSeparator(t); } return t; }; lsg = { width: total * gridX + paddingLeft + paddingRight, requiredArguments: ["from", "to"], height: grid + 30 + paddingTop + (fractionLabels ? 22 : 0), objects: [] }; for (i$ = 0; i$ <= total; ++i$) { i = i$; x = i * step + o.from; if (step < 1) { prec = (step + "").split(".")[1].length; x = _.round(x, prec); x2 = _.round(x * Math.pow(10, prec)); s2 = _.round(stepLabel * Math.pow(10, prec)); drawLabel = x2 % s2 === 0; if (fractionLabels && !o.stepLabel) { drawLabel = true; } } else { drawLabel = x % stepLabel === 0; } if (drawLabel) { lsg.objects.push({ 'class': "labelLine", type: 'rect', color: "black", x: paddingLeft + i * gridX, y: grid / 4 + grid / 8 + paddingTop - 3, w: 2, h: grid / 2 }); if (fractionLabels && step < 1) { digits = (x + "").split("."); prec = (ref2$ = (ref3$ = digits[1]) != null ? ref3$.length : void 8) != null ? ref2$ : 0; denumerator = Math.pow(10, prec); numerator = +digits[0] * denumerator + +((ref2$ = digits[1]) != null ? ref2$ : "0"); ggt = calcGGT(numerator, denumerator); numerator /= ggt; denumerator /= ggt; if (fractionLabelDenumerator != null) { if (denumerator !== fractionLabelDenumerator) { numerator *= fractionLabelDenumerator / denumerator; denumerator = fractionLabelDenumerator; numerator = _.round(numerator); } } if (numerator === 0 && fractionLabelDenumerator == null) { lsg.objects.push({ 'class': "label", type: "text", text: "0", x: paddingLeft + i * gridX, y: grid * 0.8 + paddingTop, size: 22, color: 'black', align: 'center' }); } else if (denumerator === 1) { lsg.objects.push({ 'class': "label", type: "text", text: numerator + "", x: paddingLeft + i * gridX, y: grid * 0.8 + paddingTop, size: 22, color: 'black', align: 'center' }); } else { lsg.objects.push({ 'class': "label", type: "text", text: numerator + "", x: paddingLeft + i * gridX, y: grid * 0.8 + paddingTop, size: 22, color: 'black', align: 'center' }); lineLength = 10 + 9 * Math.max((numerator + "").length, (denumerator + "").length); lsg.objects.push({ type: 'line', lineColor: "black", x1: paddingLeft + i * gridX - lineLength / 2, x2: paddingLeft + i * gridX + lineLength / 2, y1: grid * 0.8 + paddingTop + 26, y2: grid * 0.8 + paddingTop + 26, lineSize: 2 }); lsg.objects.push({ 'class': "label", type: "text", text: denumerator + "", x: paddingLeft + i * gridX, y: grid * 0.8 + paddingTop + 26, size: 22, color: 'black', align: 'center' }); } } else { lsg.objects.push({ 'class': "label", type: "text", text: numberToString(x), x: paddingLeft + i * gridX, y: grid * 0.8 + paddingTop, size: 22, color: 'black', align: 'center' }); } } } if (o.flags) { for (i$ = 0, len$ = (ref2$ = o.flags).length; i$ < len$; ++i$) { flag = ref2$[i$]; flagClassClean = _.replaceAll(flag + "", ".", ""); lsg.objects.push({ type: 'rect', 'class': "flagLine" + flagClassClean, color: Color.black, x: paddingLeft + gridX * (flag - o.from) / step, y: 25, w: 2, h: grid * 0.8 }); lsg.objects.push({ type: 'rect', 'class': "flag" + flagClassClean, color: Color.grey[100], x: paddingLeft + gridX * (flag - o.from) / step - grid * 0.4, y: -3, w: grid * 0.8, h: grid * 0.8 }); } } if (o.numberFlags) { for (i$ = 0, len$ = (ref2$ = o.numberFlags).length; i$ < len$; ++i$) { flag = ref2$[i$]; flagClassClean = _.replaceAll(flag + "", ".", ""); lsg.objects.push({ type: 'rect', 'class': "flagLine" + flagClassClean, color: Color.black, x: paddingLeft + gridX * (flag - o.from) / step, y: 25, w: 2, h: grid * 0.8 }); lsg.objects.push({ type: 'rect', 'class': "flag" + flagClassClean, color: Color.grey[100], x: paddingLeft + gridX * (flag - o.from) / step - grid * 0.4, y: 3, w: grid * 0.8, h: grid * 0.8 }); lsg.objects.push({ type: 'text', text: numberToString(flag), size: 19, lineHeight: 22, color: 'black', align: 'center', x: paddingLeft + gridX * (flag - o.from) / step, y: 6 }); } } for (i$ = 0; i$ <= total; ++i$) { i = i$; lsg.objects.push({ 'class': "stepLine", type: 'rect', color: "black", x: paddingLeft + i * gridX, y: grid / 4 + grid / 8 + 1 + paddingTop, w: 2, h: grid / 4 }); } if (o.wrongRanges != null) { for (i$ = 0, len$ = (ref2$ = _.ensureArray(o.wrongRanges)).length; i$ < len$; ++i$) { r = ref2$[i$]; r = r.split("-"); rFrom = (r[0] - o.from) / step; rTo = (r[1] - o.from) / step; lsg.objects.push({ 'class': "wrong", type: 'rect', color: "transparent", lineSize: o.isDebug ? 1 : void 8, lineColor: o.isDebug ? "red" : void 8, x: paddingLeft + rFrom * gridX, y: paddingTop, w: (rTo - rFrom) * gridX, h: grid }); } } if (o.correctRanges != null) { for (i$ = 0, len$ = (ref2$ = _.ensureArray(o.correctRanges)).length; i$ < len$; ++i$) { r = ref2$[i$]; r = r.split("-"); rFrom = (r[0] - o.from) / step; rTo = (r[1] - o.from) / step; lsg.objects.push({ 'class': "correct", type: 'rect', color: "transparent", lineSize: o.isDebug ? 1 : void 8, lineColor: o.isDebug ? "green" : void 8, x: paddingLeft + rFrom * gridX, y: paddingTop, w: (rTo - rFrom) * gridX, h: grid }); } } if (arrowHeadLeft) { lsg.objects.push({ type: 'rect', color: "black", x: 5, y: grid / 2 + paddingTop, w: paddingLeft, h: 2 }); lsg.objects.push({ 'class': "arrowHeadLeft", type: 'path', color: 'transparent', lineColor: Color.black, lineSize: 3, path: 'M50.666,0.5 L0.5,50.666 L50.666,100.833', x: 5, y: grid / 2 + paddingTop - 7, w: 12, h: 16 }); } if (arrowHeadRight) { lsg.objects.push({ type: 'rect', color: "black", x: paddingLeft - 5 + total * gridX, y: grid / 2 + paddingTop, w: paddingRight, h: 2 }); lsg.objects.push({ 'class': "arrowHeadRight", type: 'path', color: 'transparent', lineColor: Color.black, lineSize: 3, path: 'M50.666,0.5 L0.5,50.666 L50.666,100.833', rotate: 180, x: paddingLeft + paddingRight - 15 + total * gridX, y: grid / 2 + paddingTop - 7, w: 12, h: 16 }); } lsg.objects.push({ 'class': "horizontalLine", type: 'rect', color: "black", x: paddingLeft, y: grid / 2 + paddingTop, w: total * gridX, h: 2 }); return lsg; }; })(); numberline/renderer.lsr (function(){ return function(o){ var step, stepLabel, rangePadding, arrowHeadLeft, ref$, arrowHeadRight, fractionLabels, fractionLabelDenumerator, decimalPoint, thousandsSeparator, calcGGT, addThousandsSeparator, numberToString, grid, fromDigits, that, toDigits, arrowHeadLeftPadding, arrowHeadRightPadding, paddingLeft, paddingRight, paddingTop, ref1$, total, gridX, lsg, i$, i, x, prec, x2, s2, drawLabel, digits, ref2$, ref3$, denumerator, numerator, ggt, lineLength, len$, flag, flagClassClean, r, splitIndex, rFrom, rTo; step = o.step || 1; if (o.stepLabel !== false) { stepLabel = o.stepLabel || step; } rangePadding = o.rangePadding || 0; arrowHeadLeft = (ref$ = o.arrowHeadLeft) != null ? ref$ : false; arrowHeadRight = (ref$ = o.arrowHeadRight) != null ? ref$ : false; fractionLabels = (ref$ = o.fractionLabels) != null ? ref$ : false; fractionLabelDenumerator = fractionLabels && _.isFinite(fractionLabels) ? fractionLabels : void 8; decimalPoint = o.decimalPoint || ","; thousandsSeparator = o.thousandsSeparator; if (fractionLabels) { calcGGT = function(m, n){ if (n === 0) { return m; } return calcGGT(n, m % n); }; } addThousandsSeparator = function(t){ var pattern, parts, t1, t2; pattern = /(-?\d+)(\d{3})/; parts = t.split(decimalPoint); t1 = parts[0]; t2 = parts[1]; while (pattern.test(t1)) { t1 = t1.replace(pattern, "$1" + thousandsSeparator + "$2"); } t = t1; if (t2) { t += decimalPoint + t2; } return t; }; numberToString = function(n){ var t; t = _.replaceAll(n + "", ".", decimalPoint); if (thousandsSeparator) { t = addThousandsSeparator(t); } return t; }; grid = 40; fromDigits = (that = fractionLabelDenumerator) ? numberToString(that).length : fractionLabels ? 2 : numberToString(o.from).length; toDigits = (that = fractionLabelDenumerator) ? numberToString(that).length : fractionLabels ? 2 : numberToString(o.to).length; arrowHeadLeftPadding = arrowHeadLeft ? 25 : 0; arrowHeadRightPadding = arrowHeadRight ? 25 : 0; paddingLeft = 5 + fromDigits * 5 + arrowHeadLeftPadding; paddingRight = 5 + toDigits * 5 + arrowHeadRightPadding; paddingTop = ((ref$ = o.flags) != null ? ref$.length : void 8) > 0 || ((ref1$ = o.numberFlags) != null ? ref1$.length : void 8) > 0 ? 35 : 3; total = _.round((o.to - o.from) / step); gridX = 400 / total + rangePadding; lsg = { width: total * gridX + paddingLeft + paddingRight, requiredArguments: ["from", "to"], height: grid + 30 + paddingTop + (fractionLabels ? 22 : 0), objects: [] }; for (i$ = 0; i$ <= total; ++i$) { i = i$; x = i * step + o.from; if (step < 1) { prec = (step + "").split(".")[1].length; x = _.round(x, prec); x2 = _.round(x * Math.pow(10, prec)); s2 = _.round(stepLabel * Math.pow(10, prec)); drawLabel = x2 % s2 === 0; if (fractionLabels && !o.stepLabel) { drawLabel = true; } } else { drawLabel = x % stepLabel === 0; } if (drawLabel) { lsg.objects.push({ 'class': "labelLine", type: 'rect', color: "black", x: paddingLeft + i * gridX, y: grid / 4 + grid / 8 + paddingTop - 3, w: 2, h: grid / 2 }); if (fractionLabels && step < 1) { digits = (x + "").split("."); prec = (ref2$ = (ref3$ = digits[1]) != null ? ref3$.length : void 8) != null ? ref2$ : 0; denumerator = Math.pow(10, prec); numerator = +digits[0] * denumerator + +((ref2$ = digits[1]) != null ? ref2$ : "0"); ggt = calcGGT(numerator, denumerator); numerator /= ggt; denumerator /= ggt; if (fractionLabelDenumerator != null) { if (denumerator !== fractionLabelDenumerator) { numerator *= fractionLabelDenumerator / denumerator; denumerator = fractionLabelDenumerator; numerator = _.round(numerator); } } if (numerator === 0 && fractionLabelDenumerator == null) { lsg.objects.push({ 'class': "label", type: "text", text: "0", x: paddingLeft + i * gridX, y: grid * 0.8 + paddingTop, size: 22, color: 'black', align: 'center' }); } else if (denumerator === 1) { lsg.objects.push({ 'class': "label", type: "text", text: numerator + "", x: paddingLeft + i * gridX, y: grid * 0.8 + paddingTop, size: 22, color: 'black', align: 'center' }); } else { lsg.objects.push({ 'class': "label", type: "text", text: numerator + "", x: paddingLeft + i * gridX, y: grid * 0.8 + paddingTop, size: 22, color: 'black', align: 'center' }); lineLength = 10 + 9 * Math.max((numerator + "").length, (denumerator + "").length); lsg.objects.push({ type: 'line', lineColor: "black", x1: paddingLeft + i * gridX - lineLength / 2, x2: paddingLeft + i * gridX + lineLength / 2, y1: grid * 0.8 + paddingTop + 26, y2: grid * 0.8 + paddingTop + 26, lineSize: 2 }); lsg.objects.push({ 'class': "label", type: "text", text: denumerator + "", x: paddingLeft + i * gridX, y: grid * 0.8 + paddingTop + 26, size: 22, color: 'black', align: 'center' }); } } else { lsg.objects.push({ 'class': "label", type: "text", text: numberToString(x), x: paddingLeft + i * gridX, y: grid * 0.8 + paddingTop, size: 22, color: 'black', align: 'center' }); } } } if (o.flags) { for (i$ = 0, len$ = (ref2$ = o.flags).length; i$ < len$; ++i$) { flag = ref2$[i$]; flagClassClean = _.replaceAll(flag + "", ".", ""); lsg.objects.push({ type: 'rect', 'class': "flagLine" + flagClassClean, color: Color.black, x: paddingLeft + gridX * (flag - o.from) / step, y: 25, w: 2, h: grid * 0.8 }); lsg.objects.push({ type: 'rect', 'class': "flag" + flagClassClean, color: Color.grey[100], x: paddingLeft + gridX * (flag - o.from) / step - grid * 0.4, y: -3, w: grid * 0.8, h: grid * 0.8 }); } } if (o.numberFlags) { for (i$ = 0, len$ = (ref2$ = o.numberFlags).length; i$ < len$; ++i$) { flag = ref2$[i$]; flagClassClean = _.replaceAll(flag + "", ".", ""); lsg.objects.push({ type: 'rect', 'class': "flagLine" + flagClassClean, color: Color.black, x: paddingLeft + gridX * (flag - o.from) / step, y: 25, w: 2, h: grid * 0.8 }); lsg.objects.push({ type: 'rect', 'class': "flag" + flagClassClean, color: Color.grey[100], x: paddingLeft + gridX * (flag - o.from) / step - grid * 0.4, y: 3, w: grid * 0.8, h: grid * 0.8 }); lsg.objects.push({ type: 'text', text: numberToString(flag), size: 19, lineHeight: 22, color: 'black', align: 'center', x: paddingLeft + gridX * (flag - o.from) / step, y: 6 }); } } for (i$ = 0; i$ <= total; ++i$) { i = i$; lsg.objects.push({ 'class': "stepLine", type: 'rect', color: "black", x: paddingLeft + i * gridX, y: grid / 4 + grid / 8 + 1 + paddingTop, w: 2, h: grid / 4 }); } if (o.wrongRanges != null) { for (i$ = 0, len$ = (ref2$ = _.ensureArray(o.wrongRanges)).length; i$ < len$; ++i$) { r = ref2$[i$]; splitIndex = _.startsWith(r, "-") ? _.indexOf(r, "-", 1) : _.indexOf(r, "-"); rFrom = (r.substring(0, splitIndex) - o.from) / step; rTo = (r.substring(splitIndex + 1) - o.from) / step; lsg.objects.push({ 'class': "wrong", type: 'rect', color: "transparent", lineSize: o.isDebug ? 1 : void 8, lineColor: o.isDebug ? "red" : void 8, x: paddingLeft + rFrom * gridX, y: paddingTop, w: (rTo - rFrom) * gridX, h: grid }); } } if (o.correctRanges != null) { for (i$ = 0, len$ = (ref2$ = _.ensureArray(o.correctRanges)).length; i$ < len$; ++i$) { r = ref2$[i$]; splitIndex = _.startsWith(r, "-") ? _.indexOf(r, "-", 1) : _.indexOf(r, "-"); rFrom = (r.substring(0, splitIndex) - o.from) / step; rTo = (r.substring(splitIndex + 1) - o.from) / step; lsg.objects.push({ 'class': "correct", type: 'rect', color: "transparent", lineSize: o.isDebug ? 1 : void 8, lineColor: o.isDebug ? "green" : void 8, x: paddingLeft + rFrom * gridX, y: paddingTop, w: (rTo - rFrom) * gridX, h: grid }); } } if (arrowHeadLeft) { lsg.objects.push({ type: 'rect', color: "black", x: 5, y: grid / 2 + paddingTop, w: paddingLeft, h: 2 }); lsg.objects.push({ 'class': "arrowHeadLeft", type: 'path', color: 'transparent', lineColor: Color.black, lineSize: 3, path: 'M50.666,0.5 L0.5,50.666 L50.666,100.833', x: 5, y: grid / 2 + paddingTop - 7, w: 12, h: 16 }); } if (arrowHeadRight) { lsg.objects.push({ type: 'rect', color: "black", x: paddingLeft - 5 + total * gridX, y: grid / 2 + paddingTop, w: paddingRight, h: 2 }); lsg.objects.push({ 'class': "arrowHeadRight", type: 'path', color: 'transparent', lineColor: Color.black, lineSize: 3, path: 'M50.666,0.5 L0.5,50.666 L50.666,100.833', rotate: 180, x: paddingLeft + paddingRight - 15 + total * gridX, y: grid / 2 + paddingTop - 7, w: 12, h: 16 }); } lsg.objects.push({ 'class': "horizontalLine", type: 'rect', color: "black", x: paddingLeft, y: grid / 2 + paddingTop, w: total * gridX, h: 2 }); return lsg; }; })(); person-with-callout/examples.lsg (function(){ return { version: 2, width: 300, height: 2600, background: Color.grey[100], objects: [ { type: 'lsg', lsg: path('/../c-renderer/person-with-callout/renderer.lsr'), x: 100, y: 42, w: 100, color: { callOut: 'yellow' }, background: 'white', person: 1 }, { type: 'lsg', lsg: path('/../c-renderer/person-with-callout/renderer.lsr'), x: 100, y: 180, w: 100, background: 'white', person: 5 } ] }; })(); person-with-callout/level.ls (function(){ return { uid: '3eyro5', title: "hallo", trainers: { trainer: "buttons", instruction: { text: "instruction" }, lsg: { lsg: path("renderer.lsr"), width: 300, person: 2 }, atoms: { a: "a", b: "a" } } }; })(); person-with-callout/lsgEditor.ls (function(){ return { name: "Person with Callout", 'default': { type: 'lsg', lsg: path('renderer.lsr'), x: 100, y: 42, w: 100, color: { callOut: 'yellow' }, background: 'white', person: 1 } }; })(); person-with-callout/renderer.lsr (function(){ return function(o){ var svg, svgs, person, lsg; svg = function(i){ var id; id = ("0" + i).slice(-2); return path("/../c-svg/2022/07/26-person" + id + ".svg"); }; svgs = { p1: { x: 15, y: 60, svg: svg(1) }, p2: { x: 15, y: 60, svg: svg(2) }, p3: { x: 15, y: 60, svg: svg(3) }, p4: { x: 15, y: 60, svg: svg(4) }, p5: { x: 15, y: 60, svg: svg(5) }, p6: { x: 15, y: 60, svg: svg(6) }, p7: { x: 15, y: 60, svg: svg(7) }, p8: { x: 15, y: 60, svg: svg(8) }, p9: { x: 15, y: 60, svg: svg(9) }, p10: { x: 15, y: 60, svg: svg(10) }, p11: { x: 15, y: 60, svg: svg(11) }, p12: { x: 15, y: 60, svg: svg(12) }, p13: { x: 15, y: 60, svg: svg(13) }, p14: { x: 15, y: 60, svg: svg(14) }, p15: { x: 15, y: 60, svg: svg(15) }, p16: { x: 15, y: 60, svg: svg(16) }, p17: { x: 15, y: 60, svg: svg(17) }, p18: { x: 15, y: 60, svg: svg(18) }, p19: { x: 15, y: 60, svg: svg(19) }, p20: { x: 15, y: 60, svg: svg(20) }, p21: { x: 15, y: 60, svg: svg(21) }, p22: { x: 15, y: 60, svg: svg(22) }, p23: { x: 15, y: 60, svg: svg(23) }, p24: { x: 15, y: 60, svg: svg(24) }, p25: { x: 15, y: 60, svg: svg(25) }, p26: { x: 15, y: 60, svg: svg(26) }, p27: { x: 15, y: 60, svg: svg(27) }, p28: { x: 15, y: 60, svg: svg(28) }, p29: { x: 15, y: 60, svg: svg(29) }, p30: { x: 15, y: 60, svg: svg(30) }, callOut: { svg: path("remote-svg/callout.svg") } }; person = svgs["p" + (o.person || 0)]; lsg = { width: 300, height: 300, requiredArguments: "person", color: { callOut: Color.grey[200] }, objects: [] }; if (!person) { debug("invalid person = " + o.person); return lsg; } lsg.objects.push({ type: 'svg', 'class': "person", svg: person.svg, x: person.x, y: person.y, w: 70 }, { type: 'svg', 'class': "callOut", svg: svgs.callOut.svg, x: 80, y: 10, w: 205, h: 90 }, { type: 'rect', 'class': "callOut id1", x: 115, y: 35, w: 160, h: 30 }); return lsg; }; })(); pieChart/calcColors/calc.ls (function(){ return function(o){ var colors, i$, ref$, len$, c, k, v; colors = []; if (_.isString(o.color)) { colors = _.times(o.pieces.length, o.color); } else if (_.isArray(o.color)) { for (i$ = 0, len$ = (ref$ = o.color).length; i$ < len$; ++i$) { c = ref$[i$]; if (_.isObject(c)) { k = _.keys(c)[0]; v = _.values(c)[0]; colors = colors.concat(_.times(_.toNumber(k), _.constant(v))); } else { colors.push(c); } } } return colors; }; })(); pieChart/calcPie/calc.ls (function(){ return function(o, start, n){ var startAngle, angle, endAngle, radius, centerX, centerY, direction, x1, y1, x2, y2, svg, ref$; startAngle = start * 360; angle = n * 360; endAngle = startAngle + angle; radius = 130; centerX = 150; centerY = 150; direction = angle > 180 ? 1 : 0; x1 = centerX + Math.sin(startAngle * Math.PI / 180) * radius; y1 = centerY - Math.cos(startAngle * Math.PI / 180) * radius; x2 = centerX + Math.sin(endAngle * Math.PI / 180) * radius; y2 = centerY - Math.cos(endAngle * Math.PI / 180) * radius; return svg = "\n \n"; }; })(); pieChart/examples.lsg (function(){ return { version: 2, width: 300, height: 1000, background: Color.grey[100], objects: [ { type: 'text', text: 'pieces examples', x: 20, y: 10, size: 15, align: 'left' }, { type: 'text', text: 'set the number of pieces', x: 20, y: 25, size: 12, align: 'left' }, { type: 'lsg', lsg: path('/../c-renderer/pieChart/renderer.lsr'), x: 20, y: 40, w: 100, color: Color.deepPurple[300], pieces: 8, border: 'black' }, { type: 'lsg', lsg: path('/../c-renderer/pieChart/renderer.lsr'), x: 20, y: 150, w: 100, color: [ Color.blue[500], Color.blue[500], Color.blue[500], { 5: Color.red[500] }, { 16: Color.blue[500] } ], pieces: 24 }, { type: 'lsg', lsg: path('/../c-renderer/pieChart/renderer.lsr'), x: 20, y: 260, w: 100, color: [Color.red[500], Color.purple[500], Color.green[500]], pieces: 9 }, { type: 'lsg', lsg: path('/../c-renderer/pieChart/renderer.lsr'), x: 20, y: 400, w: 300, color: [ Color.blueGrey[500], Color.purple[500], Color.green[500], { 5: Color.red[500] }, { 5: Color.blue[500] } ], pieces: [0.1, 0.05, 0.1, 0.05, 0.1, 0.05, 0.1, 0.05, 0.1, 0.05, 0.1, 0.05, 0.1] } ] }; })(); pieChart/level.ls (function(){ return { uid: '3eyro5', trainers: { trainer: "buttons", instruction: { text: "instruction" }, lsg: { lsg: path("renderer.lsr"), width: 300, pieces: 10 }, atoms: { a: "a", b: "a" } } }; })(); pieChart/lsgEditor.ls (function(){ return { name: "Pie Chart", 'default': { type: 'lsg', lsg: path('renderer.lsr'), x: 20, y: 150, w: 100, color: [ Color.blue[500], Color.blue[500], Color.blue[500], { 5: Color.red[500] }, { 16: Color.blue[500] } ], pieces: 24 } }; })(); pieChart/renderer.lsr (function(){ return function(o){ var lsg, last, i$, ref$, len$, i, p, pieSvg; lsg = { width: 300, height: 300, objects: [], background: o.background || "white", requiredArguments: "pieces" }; if (o.pieces == null) { return lsg; } if (_.isInteger(o.pieces) && o.pieces > 0) { o.pieces = _.times(o.pieces, _.constant(1 / o.pieces)); } else { o.pieces = _.ensureArray(o.pieces); } last = 0; o.colors = inc("calcColors/calc")(o); for (i$ = 0, len$ = (ref$ = o.pieces).length; i$ < len$; ++i$) { i = i$; p = ref$[i$]; pieSvg = inc("calcPie/calc")(o, last, p); lsg.objects.push({ type: 'svg', 'class': 'clickable', color: o.colors[i % o.colors.length], svg: pieSvg, x: 0, y: 0, w: 300 }); last += p; } return lsg; }; })(); polyhedron/classes/Face.ls (function(){ var Face; return Face = (function(){ Face.displayName = 'Face'; var prototype = Face.prototype, constructor = Face; function Face(f){ this.id = f.id; this.vertices = f.vertices; this.lineColor = f.lineColor; this.lineSize = f.lineSize; this.fillColor = f.fillColor; this.lineDash = f.lineDash; this.midX = null; this.midY = null; this.midZ = null; } Face.prototype.updateSortValues = function(){ this.midX = _.meanBy(this.vertices, "x"); this.midY = _.meanBy(this.vertices, "y"); this.midZ = _.meanBy(this.vertices, "z"); }; Face.prototype.toPath = function(){ var p, i$, ref$, len$, v; p = "M" + _.last(this.vertices).x2d + "," + _.last(this.vertices).y2d; for (i$ = 0, len$ = (ref$ = this.vertices).length; i$ < len$; ++i$) { v = ref$[i$]; p += " L" + v.x2d + "," + v.y2d; } p += " Z"; return p; }; return Face; }()); })(); polyhedron/classes/Vertex.ls (function(){ var Vertex; return Vertex = (function(){ Vertex.displayName = 'Vertex'; var prototype = Vertex.prototype, constructor = Vertex; function Vertex(v){ this.translate = bind$(this, 'translate', prototype); this.rotate = bind$(this, 'rotate', prototype); this.id = v.id; this.x = v.x; this.y = v.y; this.z = v.z; this.x2d = null; this.y2d = null; } Vertex.prototype.rotate = function(rotation){ var cosZ, sinZ, x, y, z, cosY, sinY, zz, xx, yy, cosX, sinX; cosZ = Math.cos(rotation.z); sinZ = Math.sin(rotation.z); x = this.x * cosZ - this.y * sinZ; y = this.x * sinZ + this.y * cosZ; z = this.z; cosY = Math.cos(rotation.y); sinY = Math.sin(rotation.y); zz = z * cosY - x * sinY; xx = z * sinY + x * cosY; yy = y; cosX = Math.cos(rotation.x); sinX = Math.sin(rotation.x); this.y = yy * cosX - zz * sinX; this.z = yy * sinX + zz * cosX; this.x = xx; return this; }; Vertex.prototype.translate = function(translation){ this.x += translation.x; this.y += translation.y; this.z += translation.z; return this; }; return Vertex; }()); })(); function bind$(obj, key, target){ return function(){ return (target || obj)[key].apply(obj, arguments) }; } polyhedron/convertToScreenCoordinates/convert.ls (function(){ return function(vertices, width, height, padding){ var minX, maxX, minY, maxY, i$, len$, v, scaleX, scaleY, scale, center, results$ = []; minX = 9999999999; maxX = -9999999999; minY = 9999999999; maxY = -9999999999; for (i$ = 0, len$ = vertices.length; i$ < len$; ++i$) { v = vertices[i$]; v.x2d = v.x; v.y2d = v.y; if (v.x2d < minX) { minX = v.x2d; } if (v.x2d > maxX) { maxX = v.x2d; } if (v.y2d < minY) { minY = v.y2d; } if (v.y2d > maxY) { maxY = v.y2d; } } scaleX = (width - 2 * padding) / (maxX - minX); scaleY = (height - 2 * padding) / (maxY - minY); scale = Math.min(scaleX, scaleY); center = { x: width / 2 - (maxX + minX) * 0.5 * scale, y: height / 2 + (maxY + minY) * 0.5 * scale }; for (i$ = 0, len$ = vertices.length; i$ < len$; ++i$) { v = vertices[i$]; v.x2d *= scale; v.y2d *= -scale; v.x2d += center.x; results$.push(v.y2d += center.y); } return results$; }; })(); polyhedron/drawOrderProblems.lsg (function(){ var a; return { version: 2, 'class': 'rect', width: 1000, height: 5300, objects: { type: 'lsg', lsg: path('renderer.lsr'), x: 0, y: 0, background: Color.white, width: 800, height: 2000, padding: 50, debugDrawOrder: true, objects: (function(){ var i$, results$ = []; for (i$ = 0; i$ <= 0; i$ += 45) { a = i$; results$.push({ type: "pyramid", translation: { x: 0, y: a / 13, z: 0 }, rotation: { x: 0, y: 0, z: a }, sides: 3, radius: 2, height: 2, lineSize: 5 }); } return results$; }()) } }; })(); polyhedron/examples-renderer.lsg (function(){ var i; return { version: 2, 'class': 'rect', width: 1000, height: 5300, objects: [ { type: 'lsg', lsg: path('renderer.lsr'), x: 0, y: 0, background: Color.white, width: 1000, height: 500, padding: 50, cameraAngle: { x: 0, y: 0, z: 0 }, objects: [{ type: "custom", translation: { x: 0, y: 0, z: 0 }, rotation: { x: 0, y: 0, z: 0 }, vertices: [ { id: 0, x: -1, y: 0, z: 0 }, { id: 1, x: 0, y: 1, z: 0 }, { id: 2, x: 1, y: 0, z: 0 } ], faces: [{ id: 0, vertices: [0, 1, 2], lineColor: Color.red[500], lineSize: 20, lineDash: true, fillColor: Color.orange[300] }] }] }, { type: 'lsg', lsg: path('renderer.lsr'), x: 0, y: 500, background: Color.white, width: 1000, height: 1000, padding: 50, objects: [{ type: "pyramid", translation: { x: 0, y: 0, z: 0 }, rotation: { x: 0, y: 0, z: 0 }, sides: 4, radius: 2, height: 2, lineSize: 5, fillColor: Color.pink[500], fillOpacity: 1 }] }, { type: 'lsg', lsg: path('renderer.lsr'), x: 0, y: 1500, background: Color.white, width: 1000, height: 1000, padding: 50, objects: [{ type: "prism", translation: { x: 0, y: 0, z: 0 }, rotation: { x: 0, y: 30, z: 0 }, sides: 6, radius: 2, height: 2, lineSize: 2 }] }, { type: 'lsg', lsg: path('renderer.lsr'), x: 0, y: 2500, background: Color.white, width: 1000, height: 1000, padding: 50, objects: [{ type: "platonian", translation: { x: 0, y: 0, z: 0 }, rotation: { x: 0, y: 0, z: 0 }, sides: 12, radius: 10, lineSize: 4 }] }, { type: 'lsg', lsg: path('renderer.lsr'), x: 0, y: 3500, background: Color.white, width: 1000, height: 1000, padding: 50, cameraAngle: { y: -160 }, objects: _.concat((function(){ var i$, results$ = []; for (i$ = 0; i$ < 12; ++i$) { i = i$; results$.push({ type: "custom", translation: { x: 0, y: 0, z: 10 }, rotation: { x: 10, y: 0, z: i * 360 / 12 }, vertices: [ { id: 0, x: 0, y: 0, z: 0 }, { id: 1, x: -5, y: 1, z: 0 }, { id: 2, x: -10, y: 0, z: 0 }, { id: 3, x: -5, y: -1, z: 0 } ], faces: [{ vertices: [0, 1, 2, 3] }], lineSize: 2, fillColor: Color.yellow[700] }); } return results$; }()), [{ type: "prism", translation: { x: 0, y: -10, z: 0 }, rotation: { x: 0, y: 0, z: 0 }, sides: 32, radius: 0.3, height: 20, lineSize: 0, fillColor: Color.green[500] }]) }, { type: 'lsg', lsg: path('renderer.lsr'), x: 0, y: 4500, background: Color.white, width: 1000, height: 700, padding: 50, objects: [{ type: "box", translation: { x: 0, y: 0, z: 0 }, rotation: { x: 0, y: 0, z: 0 }, dimensions: { x: 5, y: 3, z: 1 }, lineSize: 2 }] } ] }; })(); polyhedron/lsgEditor.ls (function(){ return { name: "Polyhedron", 'default': { type: 'lsg', lsg: path('renderer.lsr'), w: 300, h: 300, x: 0, y: 0, background: 'transparent', objects: [ { type: 'pyramid', sides: 5, radius: 2, height: 2, lineSize: 4 }, { type: 'prism', sides: 5, radius: 2, height: 2, lineSize: 4, translation: { y: -1.9 } } ] } }; })(); polyhedron/objects/box.ls (function(){ return function(o, cameraAngle){ var dimensions, ref$, ref1$, ref2$, ref3$, vertices, i$, len$, i, v, faces, f; dimensions = { x: (ref$ = (ref1$ = o.dimensions) != null ? ref1$.x : void 8) != null ? ref$ : 1, y: (ref$ = (ref2$ = o.dimensions) != null ? ref2$.y : void 8) != null ? ref$ : 1, z: (ref$ = (ref3$ = o.dimensions) != null ? ref3$.z : void 8) != null ? ref$ : 1 }; vertices = [ { x: -dimensions.x / 2, y: -dimensions.y / 2, z: -dimensions.z / 2 }, { x: -dimensions.x / 2, y: -dimensions.y / 2, z: dimensions.z / 2 }, { x: dimensions.x / 2, y: -dimensions.y / 2, z: dimensions.z / 2 }, { x: dimensions.x / 2, y: -dimensions.y / 2, z: -dimensions.z / 2 }, { x: -dimensions.x / 2, y: dimensions.y / 2, z: -dimensions.z / 2 }, { x: -dimensions.x / 2, y: dimensions.y / 2, z: dimensions.z / 2 }, { x: dimensions.x / 2, y: dimensions.y / 2, z: dimensions.z / 2 }, { x: dimensions.x / 2, y: dimensions.y / 2, z: -dimensions.z / 2 } ]; for (i$ = 0, len$ = vertices.length; i$ < len$; ++i$) { i = i$; v = vertices[i$]; v.id = i; } faces = [ { vertices: [0, 1, 2, 3] }, { vertices: [4, 5, 6, 7] }, { vertices: [0, 1, 5, 4] }, { vertices: [2, 3, 7, 6] }, { vertices: [0, 3, 7, 4] }, { vertices: [1, 2, 6, 5] } ]; for (i$ = 0, len$ = faces.length; i$ < len$; ++i$) { i = i$; f = faces[i$]; f.id = i; } o.faces = faces; o.vertices = vertices; return include("custom")(o, cameraAngle); }; })(); polyhedron/objects/custom.ls (function(){ var Vertex, Face; Vertex = include("../classes/Vertex"); Face = include("../classes/Face"); return function(o, cameraAngle){ var lineColor, ref$, lineSize, lineDash, fillColor, fillOpacity, translation, ref1$, ref2$, ref3$, rotation, ref4$, ref5$, ref6$, vertices, res$, i$, len$, v, verticesById, faces, f, ref7$; lineColor = (ref$ = o.lineColor) != null ? ref$ : Color.black; lineSize = (ref$ = o.lineSize) != null ? ref$ : 1; lineDash = (ref$ = o.lineDash) != null ? ref$ : false; fillColor = (ref$ = o.fillColor) != null ? ref$ : Color.blue[300]; fillOpacity = (ref$ = o.fillOpacity) != null ? ref$ : 0.75; if (_.startsWith(fillColor, "rgba(")) { fillColor = fillColor.replace(",1)", "," + fillOpacity + ")"); } translation = { x: (ref$ = (ref1$ = o.translation) != null ? ref1$.x : void 8) != null ? ref$ : 0, y: (ref$ = (ref2$ = o.translation) != null ? ref2$.y : void 8) != null ? ref$ : 0, z: (ref$ = (ref3$ = o.translation) != null ? ref3$.z : void 8) != null ? ref$ : 0 }; rotation = { x: (((ref$ = (ref4$ = o.rotation) != null ? ref4$.x : void 8) != null ? ref$ : 0) - cameraAngle.x) * Math.PI / 180, y: (((ref$ = (ref5$ = o.rotation) != null ? ref5$.y : void 8) != null ? ref$ : 0) - cameraAngle.y) * Math.PI / 180, z: -(((ref$ = (ref6$ = o.rotation) != null ? ref6$.z : void 8) != null ? ref$ : 0) - cameraAngle.z) * Math.PI / 180 }; res$ = []; for (i$ = 0, len$ = (ref$ = o.vertices).length; i$ < len$; ++i$) { v = ref$[i$]; res$.push(new Vertex(v).rotate(rotation).translate(translation)); } vertices = res$; verticesById = _.groupBy(vertices, "id"); res$ = []; for (i$ = 0, len$ = (ref$ = o.faces).length; i$ < len$; ++i$) { f = ref$[i$]; res$.push(new Face({ id: f.id, vertices: _.map(f.vertices, fn$), lineColor: (ref7$ = f.lineColor) != null ? ref7$ : lineColor, lineSize: (ref7$ = f.lineSize) != null ? ref7$ : lineSize, lineDash: (ref7$ = f.lineDash) != null ? ref7$ : lineDash, fillColor: (ref7$ = f.fillColor) != null ? ref7$ : fillColor })); } faces = res$; return { faces: faces, vertices: vertices }; function fn$(id){ return verticesById[id][0]; } }; })(); polyhedron/objects/platonian.ls (function(){ return function(o, cameraAngle){ var sides, ref$, radius, enrichProperties, tetrahedron, hexahedron, centroid, cross, dot, minus, sortClockwise, dual, projectToSphere, octahedron, icosahedron, dodecahedron, mesh, i$, len$, f, v; sides = (ref$ = o.sides) != null ? ref$ : 3; radius = (ref$ = o.radius) != null ? ref$ : 1; enrichProperties = function(mesh){ var i$, ref$, len$, i, v, f; for (i$ = 0, len$ = (ref$ = mesh.vertices).length; i$ < len$; ++i$) { i = i$; v = ref$[i$]; v.id = i; v.faces = []; } for (i$ = 0, len$ = (ref$ = mesh.faces).length; i$ < len$; ++i$) { i = i$; f = ref$[i$]; f.id = i; f.vertices = _.map(f.vertices, fn$); } return mesh; function fn$(v){ mesh.vertices[v].faces.push(f); return mesh.vertices[v]; } }; tetrahedron = function(){ var a, b, c, d, vertices, faces; a = (1.0 / 3.0) * radius; b = Math.sqrt(8.0 / 9.0) * radius; c = Math.sqrt(2.0 / 9.0) * radius; d = Math.sqrt(2.0 / 3.0) * radius; vertices = [ { x: 0, y: 0, z: radius }, { x: -c, y: d, z: -a }, { x: -c, y: -d, z: -a }, { x: b, y: 0, z: -a } ]; faces = [ { vertices: [0, 1, 2] }, { vertices: [0, 2, 3] }, { vertices: [0, 3, 1] }, { vertices: [3, 2, 1] } ]; return enrichProperties({ faces: faces, vertices: vertices }); }; hexahedron = function(){ var a, vertices, faces; a = (1.0 / Math.sqrt(3.0)) * radius; vertices = [ { x: -a, y: -a, z: -a }, { x: a, y: -a, z: -a }, { x: a, y: a, z: -a }, { x: -a, y: a, z: -a }, { x: -a, y: -a, z: a }, { x: a, y: -a, z: a }, { x: a, y: a, z: a }, { x: -a, y: a, z: a } ]; faces = [ { vertices: [3, 2, 1, 0] }, { vertices: [2, 6, 5, 1] }, { vertices: [5, 6, 7, 4] }, { vertices: [0, 4, 7, 3] }, { vertices: [3, 7, 6, 2] }, { vertices: [1, 5, 4, 0] } ]; return enrichProperties({ faces: faces, vertices: vertices }); }; centroid = function(vertices){ var c, n, i$, len$, v; c = { x: 0, y: 0, z: 0 }; n = 0; for (i$ = 0, len$ = vertices.length; i$ < len$; ++i$) { v = vertices[i$]; c.x += v.x; c.y += v.y; c.z += v.z; n++; } c.x /= n; c.y /= n; c.z /= n; return c; }; cross = function(a, b){ return { x: a.y * b.z - a.z * b.y, y: a.z * b.x - a.x * b.z, z: a.x * b.y - a.y * b.x }; }; dot = function(a, b){ return a.x * b.x + a.y * b.y + a.z * b.z; }; minus = function(a, b){ return { x: a.x - b.x, y: a.y - b.y, z: a.z - b.z }; }; sortClockwise = function(vertices){ var centerPoint, normal, testOrder; centerPoint = centroid(vertices); normal = cross(vertices[0], vertices[1]); testOrder = function(a, b){ return dot(normal, cross(minus(a, centerPoint), minus(b, centerPoint))); }; vertices.sort(testOrder); if (_.map(vertices, "id").join(",") === "15,14,5,4,0") { vertices = _.orderBy(vertices, function(v){ return [14, 0, 15, 4, 5].indexOf(v.id); }); } return vertices; }; dual = function(mesh){ var vertices, i$, ref$, len$, f, faces; vertices = []; for (i$ = 0, len$ = (ref$ = mesh.faces).length; i$ < len$; ++i$) { f = ref$[i$]; f.fvertex = centroid(f.vertices); f.fvertex.id = vertices.length; vertices.push(f.fvertex); } faces = _.map(mesh.vertices, function(v){ var vertices; vertices = sortClockwise(_.map(v.faces, "fvertex")); return { vertices: _.map(vertices, "id") }; }); return enrichProperties({ faces: faces, vertices: vertices }); }; projectToSphere = function(mesh){ var i$, ref$, len$, v, l; for (i$ = 0, len$ = (ref$ = mesh.vertices).length; i$ < len$; ++i$) { v = ref$[i$]; l = Math.sqrt(v.x * v.x + v.y * v.y + v.z * v.z); v.x *= radius / l; v.y *= radius / l; v.z *= radius / l; } return mesh; }; octahedron = function(){ return projectToSphere(dual(hexahedron())); }; icosahedron = function(){ var phi, a, b, vertices, faces; phi = (1.0 + Math.sqrt(5.0)) * 0.5; a = 1.0; b = 1.0 / phi; vertices = [ { x: 0, y: b, z: -a }, { x: b, y: a, z: 0 }, { x: -b, y: a, z: 0 }, { x: 0, y: b, z: a }, { x: 0, y: -b, z: a }, { x: -a, y: 0, z: b }, { x: 0, y: -b, z: -a }, { x: a, y: 0, z: -b }, { x: a, y: 0, z: b }, { x: -a, y: 0, z: -b }, { x: b, y: -a, z: 0 }, { x: -b, y: -a, z: 0 } ]; faces = [ { vertices: [2, 1, 0] }, { vertices: [1, 2, 3] }, { vertices: [5, 4, 3] }, { vertices: [4, 8, 3] }, { vertices: [7, 6, 0] }, { vertices: [6, 9, 0] }, { vertices: [11, 10, 4] }, { vertices: [10, 11, 6] }, { vertices: [9, 5, 2] }, { vertices: [5, 9, 11] }, { vertices: [8, 7, 1] }, { vertices: [7, 8, 10] }, { vertices: [2, 5, 3] }, { vertices: [8, 1, 3] }, { vertices: [9, 2, 0] }, { vertices: [1, 7, 0] }, { vertices: [11, 9, 6] }, { vertices: [7, 10, 6] }, { vertices: [5, 11, 4] }, { vertices: [10, 8, 4] } ]; return projectToSphere(enrichProperties({ faces: faces, vertices: vertices })); }; dodecahedron = function(){ return projectToSphere(dual(icosahedron())); }; mesh = (function(){ switch (sides) { case 3: return tetrahedron(); case 6: return hexahedron(); case 8: return octahedron(); case 12: return dodecahedron(); case 20: return icosahedron(); default: throw Error("invalid sides, must be 3, 6, 8, 12 or 20"); } }()); for (i$ = 0, len$ = (ref$ = mesh.faces).length; i$ < len$; ++i$) { f = ref$[i$]; f.vertices = _.map(f.vertices, "id"); } for (i$ = 0, len$ = (ref$ = mesh.vertices).length; i$ < len$; ++i$) { v = ref$[i$]; delete v.faces; } o.faces = mesh.faces; o.vertices = mesh.vertices; return include("custom")(o, cameraAngle); }; })(); polyhedron/objects/prism.ls (function(){ return function(o, cameraAngle){ var sides, ref$, height, radius, angleStep, vertices, res$, i$, i, faces; sides = (ref$ = o.sides) != null ? ref$ : 3; height = (ref$ = o.height) != null ? ref$ : 1; radius = (ref$ = o.radius) != null ? ref$ : 2; angleStep = 2 * Math.PI / sides; res$ = []; for (i$ = 0; i$ < sides; ++i$) { i = i$; res$.push({ id: i, x: Math.sin(angleStep * i) * radius, y: -height / 2, z: Math.cos(angleStep * i) * radius }); } vertices = res$; for (i$ = 0; i$ < sides; ++i$) { i = i$; vertices.push({ id: sides + i, x: Math.sin(angleStep * i) * radius, y: height / 2, z: Math.cos(angleStep * i) * radius }); } res$ = []; for (i$ = 0; i$ < sides; ++i$) { i = i$; res$.push({ id: i, vertices: [i, (i + 1) % sides, sides + (i + 1) % sides, sides + i] }); } faces = res$; faces.push({ id: sides, vertices: (function(){ var i$, to$, results$ = []; for (i$ = 0, to$ = sides; i$ < to$; ++i$) { results$.push(i$); } return results$; }()) }); faces.push({ id: sides + 1, vertices: (function(){ var i$, to$, results$ = []; for (i$ = sides, to$ = 2 * sides; i$ < to$; ++i$) { results$.push(i$); } return results$; }()) }); o.faces = faces; o.vertices = vertices; return include("custom")(o, cameraAngle); }; })(); polyhedron/objects/pyramid.ls (function(){ return function(o, cameraAngle){ var sides, ref$, height, radius, angleStep, vertices, res$, i$, i, faces; sides = (ref$ = o.sides) != null ? ref$ : 3; height = (ref$ = o.height) != null ? ref$ : 1; radius = (ref$ = o.radius) != null ? ref$ : 2; angleStep = 2 * Math.PI / sides; res$ = []; for (i$ = 0; i$ < sides; ++i$) { i = i$; res$.push({ id: i, x: Math.sin(angleStep * i) * radius, y: -height / 2, z: Math.cos(angleStep * i) * radius }); } vertices = res$; vertices.push({ id: sides, x: 0, y: height / 2, z: 0 }); res$ = []; for (i$ = 0; i$ < sides; ++i$) { i = i$; res$.push({ id: i, vertices: [i, (i + 1) % sides, sides] }); } faces = res$; faces.push({ id: sides, vertices: (function(){ var i$, to$, results$ = []; for (i$ = 0, to$ = sides; i$ < to$; ++i$) { results$.push(i$); } return results$; }()) }); o.faces = faces; o.vertices = vertices; return include("custom")(o, cameraAngle); }; })(); polyhedron/renderer.lsr (function(){ return function(o){ var lsgWidth, lsgHeight, padding, cameraAngle, ref$, ref1$, ref2$, ref3$, lsg, objects, res$, i$, ref4$, len$, object, vertices, faces, f, i; lsgWidth = o.width || o.height || 1000; lsgHeight = o.height || o.width || 1000; padding = o.padding || 10; cameraAngle = { x: (ref$ = (ref1$ = o.cameraAngle) != null ? ref1$.x : void 8) != null ? ref$ : -15, y: (ref$ = (ref2$ = o.cameraAngle) != null ? ref2$.y : void 8) != null ? ref$ : -15, z: (ref$ = (ref3$ = o.cameraAngle) != null ? ref3$.z : void 8) != null ? ref$ : 0 }; lsg = { width: lsgWidth, height: lsgHeight, objects: [] }; res$ = []; for (i$ = 0, len$ = (ref$ = _.ensureArray((ref4$ = o.objects) != null ? ref4$ : [])).length; i$ < len$; ++i$) { object = ref$[i$]; if (object.type) { res$.push(include("objects/" + object.type)(object, cameraAngle)); } } objects = res$; vertices = _.flatMap(objects, "vertices"); include("convertToScreenCoordinates/convert")(vertices, lsgWidth, lsgHeight, padding); faces = _.flatMap(objects, "faces"); for (i$ = 0, len$ = faces.length; i$ < len$; ++i$) { f = faces[i$]; f.updateSortValues(); } faces = _.orderBy(faces, ["midZ", "midY", "midX"], ["asc", "asc", "asc"]); if (o.debugDrawOrder) { debug(faces); } for (i$ = 0, len$ = faces.length; i$ < len$; ++i$) { i = i$; f = faces[i$]; lsg.objects.push({ type: 'path', x: 0, y: 0, color: f.fillColor, lineColor: f.lineColor, lineSize: f.lineSize, path: f.toPath(), lineDash: f.lineDash }); if (o.debugDrawOrder) { lsg.objects.push({ type: "text", x: _.meanBy(f.vertices, "x2d"), y: _.meanBy(f.vertices, "y2d"), text: i + "", color: Color.red[500], size: 40 }); } } return lsg; }; })(); row-calc/examples-renderer.lsg (function(){ return { version: 2, 'class': 'rect', width: 300, height: 1000, background: Color.grey[100], objects: { type: 'lsg', lsg: path('/../c-renderer/row-calc/renderer.lsr'), x: 20, y: 30, w: 250, rows: [ { number: '652', mode: '' }, { number: '_12', mode: '+' } ] } }; })(); row-calc/lsgEditor.ls (function(){ return { name: "Row Calc", 'default': { type: 'lsg', lsg: path('renderer.lsr'), x: 20, y: 30, w: 250, rows: [ { number: '652', mode: '' }, { number: '_12', mode: '+' } ] } }; })(); row-calc/rect/rect.ls (function(){ return function(row, col, o, lsg){ var r, rect, value; r = o.rows[row]; rect = { type: 'rect', x: o.headerWidth * col + o.signPadding - col, y: o.headerHeight + _.sum(o.rowHeights.slice(0, row)) - (row + 1), w: o.rectWidth, h: o.rowHeights[row], color: o.rectColor, lineSize: 1, lineColor: Color.deepOrange[200] }; value = r.number[col]; if (value === "x") { o.id++; rect['class'] = "x" + o.id; rect.color = "white"; } return lsg.objects.push(rect); }; })(); row-calc/renderer.lsr (function(){ return function(o){ var rectHeight, carryoverRectHeight, res$, i$, ref$, len$, r, lsg, to$, i, j$, to1$, j, y; o = _.clone(o); o.digits = o.rows[0].number.length; if (!o.rows.every(function(r){ return r.number.length === o.digits; })) { debug("row-calc renderer: all numbers must be the same length!"); } o.headerLabels = ["M", "HT", "ZT", "T", "H", "Z", "E"]; o.signs = ["+", "-"]; o.headerColors = [Color.green[500], Color.blue[500], Color.red[500], Color.green[500], Color.blue[500], Color.red[500], Color.green[500]]; o.valueColor = o.valueColor || Color.black; o.rectColor = o.rectColor || "transparent"; o.headerColor = o.headerColor || "transparent"; o.headerWidth = 35; o.headerHeight = o.header === true ? 35 : 1; o.rectWidth = 35; rectHeight = 35; carryoverRectHeight = 20; res$ = []; for (i$ = 0, len$ = (ref$ = o.rows).length; i$ < len$; ++i$) { r = ref$[i$]; if (r.mode === "carryover") { res$.push(carryoverRectHeight); } else { res$.push(rectHeight); } } o.rowHeights = res$; o.signPadding = o.rows.some(function(r){ return o.signs.includes(r.mode); }) ? 15 : 0; o.lsgWidth = o.headerWidth * o.digits + o.signPadding - (o.digits - 1); o.lsgHeight = o.headerHeight + _.sum(o.rowHeights) - (o.rows.length - 1); lsg = { width: o.lsgWidth, height: o.lsgHeight, requiredArguments: "rows", objects: [] }; if (o.header) { for (i$ = 0, to$ = o.digits; i$ < to$; ++i$) { i = i$; lsg.objects.push({ type: 'rect', x: o.headerWidth * i + o.signPadding - i, y: 0, w: o.headerWidth, h: o.headerHeight, color: o.headerColor, lineSize: 1, lineColor: Color.deepOrange[200] }); lsg.objects.push({ type: 'text', text: o.headerLabels.slice(-o.digits)[i], x: 18 + o.headerWidth * i + o.signPadding - i, y: 7 - 1, color: o.headerColors.slice(-o.digits)[i], size: 20, align: 'center', font: 'Solocode School' }); } } o.id = 0; for (i$ = 0, to$ = o.rows.length; i$ < to$; ++i$) { i = i$; for (j$ = 0, to1$ = o.digits; j$ < to1$; ++j$) { j = j$; inc("sign/sign")(i, o, lsg); inc("rect/rect")(i, j, o, lsg); inc("value/value")(i, j, o, lsg); } if (o.rows[i].mode === "solution") { y = o.headerHeight + _.sum(o.rowHeights.slice(0, i)) - i; lsg.objects.push({ type: 'line', x1: o.signPadding + 1, y1: y, x2: o.rectWidth * o.digits + o.signPadding - o.digits, y2: y, lineColor: Color.deepOrange[300], lineSize: 2 }); } } return lsg; }; })(); row-calc/sign/sign.ls (function(){ return function(row, o, lsg){ var sign; sign = o.rows[row].mode; if (!o.signs.includes(sign)) { return; } return lsg.objects.push({ type: 'text', text: sign, x: 6, y: 4 + o.headerHeight + _.sum(o.rowHeights.slice(0, row)) - (row + 1), color: o.valueColor, size: 20, align: 'center', font: 'Solocode School' }); }; })(); row-calc/value/value.ls (function(){ return function(row, col, o, lsg){ var text, mode; text = o.rows[row].number[col]; if (text === "_" || text === "x") { return; } mode = o.rows[row].mode; return lsg.objects.push({ type: 'text', text: text, x: 18 + o.rectWidth * col + o.signPadding - col, y: o.headerHeight + _.sum(o.rowHeights.slice(0, row)) + 3 - (row + 1) - (mode === "carryover" ? 0.5 : 0), color: o.valueColor, size: mode === "carryover" ? 13 : 24, align: 'center', font: 'Solocode School' }); }; })(); squared-paper-milli/examples-renderer.lsg (function(){ return { version: 2, 'class': 'rect', width: 300, height: 1000, background: Color.grey[100], objects: [ { type: 'lsg', lsg: path('/../c-renderer/squared-paper-milli/renderer.lsr'), x: 52, y: 41, w: 200, background: 'transparent', horizontalBoxes: 100, verticalBoxes: 100 }, { type: 'lsg', lsg: path('/../c-renderer/squared-paper-milli/renderer.lsr'), x: 50, y: 300, w: 200, background: 'transparent', horizontalBoxes: 100, verticalBoxes: 100, overlap: false }, { type: 'text', text: 'overlap: true (default)', x: 72, y: 10, color: Color.black, size: 13, align: 'center', font: 'Source Sans Pro' }, { type: 'text', text: 'overlap: false', x: 53, y: 270, color: Color.black, size: 13, align: 'center', font: 'Source Sans Pro' } ] }; })(); squared-paper-milli/level.ls (function(){ return { uid: '710fcg', trainers: { trainer: "buttons", atoms: { a: '1', b: '1', lsg: { lsg: path("renderer.lsr"), verticalBoxes: 70, horizontalBoxes: 70, width: 300 } } } }; })(); squared-paper-milli/lsgEditor.ls (function(){ return { name: "Squared Paper Milli", 'default': { type: 'lsg', lsg: path('renderer.lsr'), w: 100, x: 51, y: 34, background: 'transparent', horizontalBoxes: 70, verticalBoxes: 70 } }; })(); squared-paper-milli/renderer.lsr (function(){ return function(o){ var lsgWidth, lsgHeight, lsg, offset, i$, to$, i; lsgWidth = o.horizontalBoxes * 19 + 1 + 4; lsgHeight = o.verticalBoxes * 19 + 1 + 4; lsg = { width: lsgWidth, height: lsgHeight, requiredArguments: ["horizontalBoxes", "verticalBoxes"], objects: [] }; offset = 2.5; for (i$ = 0, to$ = o.horizontalBoxes; i$ <= to$; ++i$) { i = i$; lsg.objects.push({ type: 'line', x1: 19 * i + offset, y1: 0, x2: 19 * i + offset, y2: lsgHeight, lineColor: Color.red[500], lineSize: i % 10 === 0 ? 5 : i % 5 === 0 ? 3 : 1 }); } for (i$ = 0, to$ = o.verticalBoxes; i$ <= to$; ++i$) { i = i$; lsg.objects.push({ type: 'line', x1: 0, y1: 19 * i + offset, x2: lsgWidth, y2: 19 * i + offset, lineColor: Color.red[500], lineSize: i % 10 === 0 ? 5 : i % 5 === 0 ? 3 : 1 }); } return lsg; }; })(); squared-paper/examples-renderer.lsg (function(){ return { version: 2, 'class': 'rect', width: 300, height: 1000, background: Color.grey[100], objects: [ { type: 'lsg', lsg: path('/../c-renderer/squared-paper/renderer.lsr'), x: 52, y: 41, background: 'transparent', horizontalBoxes: 8, verticalBoxes: 5 }, { type: 'lsg', lsg: path('/../c-renderer/squared-paper/renderer.lsr'), x: 50, y: 197, background: 'transparent', horizontalBoxes: 8, verticalBoxes: 5, overlap: false }, { type: 'text', text: 'overlap: true (default)', x: 72, y: 10, color: Color.black, size: 13, align: 'center', font: 'Source Sans Pro' }, { type: 'text', text: 'overlap: false', x: 53, y: 167, color: Color.black, size: 13, align: 'center', font: 'Source Sans Pro' } ] }; })(); squared-paper/level.ls (function(){ return { uid: '710fcg', lsg: { lsg: path("renderer.lsr"), width: 150 }, trainers: { trainer: "imageButtons", atoms: { a: "1", b: [ { text: "a", correct: true, lsg: { verticalBoxes: 6, horizontalBoxes: 6 } }, { text: "b", lsg: { verticalBoxes: 6, horizontalBoxes: 7 } }, { text: "c", lsg: { verticalBoxes: 6, horizontalBoxes: 8 } } ] } } }; })(); squared-paper/lsgEditor.ls (function(){ return { name: "Squared Paper", 'default': { type: 'lsg', lsg: path('renderer.lsr'), w: 100, x: 51, y: 34, background: 'transparent', horizontalBoxes: 8, verticalBoxes: 5 } }; })(); squared-paper/renderer.lsr (function(){ return function(o){ var ref$, lsgWidth, lsgHeight, lsg, offset, i$, to$, i; o.overlap = (ref$ = o.overlap) != null ? ref$ : true; o.lineColor = o.lineColor || Color.grey[500]; lsgWidth = o.horizontalBoxes * 19 + 1; lsgHeight = o.verticalBoxes * 19 + 1; lsg = { width: lsgWidth, height: lsgHeight, requiredArguments: ["horizontalBoxes", "verticalBoxes"], objects: [] }; offset = o.overlap ? 9.5 : 0.5; for (i$ = 0, to$ = o.horizontalBoxes; i$ <= to$; ++i$) { i = i$; lsg.objects.push({ type: 'line', x1: 19 * i + offset, y1: 0, x2: 19 * i + offset, y2: lsgHeight, lineColor: o.lineColor, lineSize: 1 }); } for (i$ = 0, to$ = o.verticalBoxes; i$ <= to$; ++i$) { i = i$; lsg.objects.push({ type: 'line', x1: 0, y1: 19 * i + offset, x2: lsgWidth, y2: 19 * i + offset, lineColor: o.lineColor, lineSize: 1 }); } return lsg; }; })(); syllables/examples-renderer.lsg (function(){ return { version: 2, height: 500, width: 530, objects: { type: "lsg", lsg: path("/../c-renderer/syllables/renderer.lsr"), syllables: [["Cam", "Cem", "++Com", "Cim", "bla"], ["++pu", "pa"], ["ta", "to", "++ter"], ["ta", "to", "++ter"]] } }; })(); syllables/level.ls (function(){ return { uid: '7k0juc', title: "Silbentrainer Typ 4", voiceLang: 'de', trainers: { trainer: "findAll", instruction: { text: "Wähle die korrekten Silben aus.", speaker: true }, atoms: [ { lsg: { lsg: path("/../c-renderer/syllables/renderer.lsr"), width: 500, syllables: ["++Com", ["pa", "++pu"], ["tor", "tier", "++ter"]] }, objects: { 'class': "correct", correct: true, color: Color.green[200], lineColor: Color.black } }, { a: "", lsg: { lsg: path("/../c-renderer/syllables/renderer.lsr"), width: 500, syllables: [["keit", "dung", "++haft", "schein"], ["Frist", "ver", "++län", "ge", "++rung"], ["Schiff", "fahrts", "++ge", "sell", "schaft"], ["++Schlaf", "Fleiß", "Thron", "klamm", "stamm"]] }, objects: { 'class': "correct", correct: true, color: Color.green[200], lineColor: Color.black } } ] } }; })(); syllables/lsgEditor.ls (function(){ return { name: "Syllables", 'default': { type: 'lsg', lsg: path('renderer.lsr'), w: 100, x: 51, y: 34, background: 'transparent', syllables: ["keit", "dung", "++haft", "schein"] } }; })(); syllables/renderer.lsr (function(){ return function(o){ var syllables, lengths, n, boxW, boxH, boxPadding, unitW, horPadding, verPadding, sidePadding, maxHeight, width, height, lsg, i$, i, h, j$, to$, j; syllables = _.map(o.syllables, function(p){ return _.ensureArray(p); }); lengths = _.map(syllables, function(s){ return s.length; }); n = syllables.length; boxW = 105; boxH = 0.65 * boxW; boxPadding = 5; unitW = 2 * boxPadding + boxW; horPadding = 10; verPadding = 5; sidePadding = 20; maxHeight = _.max(lengths); width = n * unitW + (n - 1) * horPadding + 2 * sidePadding; height = maxHeight * boxH + (maxHeight + 1) * boxPadding + 2 * verPadding; lsg = { width: width, height: height, requiredArguments: "syllables", objects: [] }; for (i$ = 0; i$ < n; ++i$) { i = i$; h = lengths[i] * boxH + (lengths[i] + 1) * boxPadding; lsg.objects.push({ type: "rect", 'class': "rect", w: unitW, h: h, x: sidePadding + i * horPadding + i * unitW, y: (height - h) / 2, color: Color.white, lineSize: 1, lineColor: Color.grey[400] }); for (j$ = 0, to$ = lengths[i]; j$ < to$; ++j$) { j = j$; lsg.objects.push({ type: "rect", 'class': "rect", w: boxW, h: boxH, x: sidePadding + i * horPadding + i * unitW + boxPadding, y: (height - h) / 2 + (j + 1) * boxPadding + j * boxH, color: Color.white, lineSize: 1, lineColor: Color.grey[400] }); if (_.startsWith(syllables[i][j], "++")) { lsg.objects.push({ type: "rect", 'class': "correct", w: boxW, h: boxH, x: sidePadding + i * horPadding + i * unitW + boxPadding, y: (height - h) / 2 + (j + 1) * boxPadding + j * boxH, color: 'transparent', opacity: 0.7 }); } else { lsg.objects.push({ type: "rect", 'class': "wrong", w: boxW, h: boxH, x: sidePadding + i * horPadding + i * unitW + boxPadding, y: (height - h) / 2 + (j + 1) * boxPadding + j * boxH, color: 'transparent', opacity: 0.7 }); } lsg.objects.push({ type: 'text', text: _.replace(syllables[i][j], '++', ""), color: Color.black, size: 35, align: 'center', x: sidePadding + i * horPadding + i * unitW + boxPadding + boxW / 2, y: (height - h) / 2 + (j + 1) * boxPadding + j * boxH + boxPadding + 5 }); } } return lsg; }; })(); table/addLabels/add.ls (function(){ return function(o, lsg){ var x, xValues, i$, ref$, len$, colWidth, y, yValues, rowHeight, i, cell, row, col, size, ref1$, placeholder, newX, j$, to$, j; x = 0; xValues = []; for (i$ = 0, len$ = (ref$ = o.colWidths).length; i$ < len$; ++i$) { colWidth = ref$[i$]; xValues.push(x + colWidth / 2); x += colWidth; } y = 0; yValues = []; for (i$ = 0, len$ = (ref$ = o.rowHeights).length; i$ < len$; ++i$) { rowHeight = ref$[i$]; yValues.push(y + rowHeight / 2); y += rowHeight; } for (i$ = 0, len$ = (ref$ = o.cellsNormalized).length; i$ < len$; ++i$) { i = i$; cell = ref$[i$]; row = cell.y; col = cell.x; size = (ref1$ = cell.fontSize) != null ? ref1$ : o.fontSize; placeholder = xValues[col]; if (cell.mergeX > 0) { x = xValues[col] - o.colWidths[col] / 2; newX = 0; for (j$ = col, to$ = col + cell.mergeX; j$ <= to$; ++j$) { j = j$; if (j === o.colWidths.length) { break; } newX += o.colWidths[j]; } xValues[col] = x + newX / 2; } if (cell.unite !== true) { if (cell.text) { lsg.objects.push({ type: "text", text: cell.text, x: xValues[col] + ((ref1$ = cell.offsetX) != null ? ref1$ : o.textOffsetX), y: yValues[row] - size / 2 + ((ref1$ = cell.offsetY) != null ? ref1$ : o.textOffsetY), color: (ref1$ = cell.textColor) != null ? ref1$ : o.textColor, size: size, font: (ref1$ = cell.font) != null ? ref1$ : o.textFont, bold: (ref1$ = cell.bold) != null ? ref1$ : o.bold, italic: (ref1$ = cell.italic) != null ? ref1$ : o.italic, align: "center" }); } } xValues[col] = placeholder; } return lsg; }; })(); table/calcCellsNormalized/calc.ls (function(){ return function(o){ var cellsNormalized, i$, len$, col, j$, len1$, row, currentCell, ref$; cellsNormalized = []; for (i$ = 0, len$ = o.colWidths.length; i$ < len$; ++i$) { col = i$; for (j$ = 0, len1$ = o.rowHeights.length; j$ < len1$; ++j$) { row = j$; currentCell = _.find(o.cells.values, fn$); if (currentCell == null) { cellsNormalized.push({ x: col, y: row, mergeX: 0 }); } else { cellsNormalized.push(currentCell); if (currentCell.mergeX != null) { if (!_.isInteger(currentCell.mergeX) || !(0 <= (ref$ = currentCell.mergeX) && ref$ < o.colWidths.length - col)) { debug(currentCell); debug("mergeX has to be an integer between 0 and " + (o.colWidths.length - 1 - col)); } } } } } return cellsNormalized; function fn$(v){ return v.x === col && v.y === row; } }; })(); table/drawBackgroundColors/draw.ls (function(){ return function(o, lsg){ var x, y, i$, ref$, len$, i, cell, col, row, color, ref1$, width, height, j$, to$, countCell, u; x = 0; y = 0; for (i$ = 0, len$ = (ref$ = o.cellsNormalized).length; i$ < len$; ++i$) { i = i$; cell = ref$[i$]; col = cell.x; row = cell.y; color = (ref1$ = cell.background) != null ? ref1$ : o.cellBackgroundColor; width = o.colWidths[col]; height = o.rowHeights[row]; if (cell.mergeX > 0) { for (j$ = cell.x + 1, to$ = cell.x + cell.mergeX; j$ <= to$; ++j$) { countCell = j$; if (countCell === o.colWidths.length) { break; } u = _.find(o.cellsNormalized, fn$); u.unite = true; width += o.colWidths[countCell]; } } if (cell.unite !== true) { if (color) { lsg.objects.push({ type: "rect", color: color, x: x, y: y, w: width, h: height }); } } if ((i + 1) % o.rowHeights.length === 0) { x += o.colWidths[col]; y = 0; } else { y += o.rowHeights[row]; } } return lsg; function fn$(u){ return u.x === countCell && u.y === cell.y; } }; })(); table/drawBorder/draw.ls (function(){ return function(o, lsg){ lsg.objects.push({ type: "rect", color: "transparent", lineColor: o.borderColor, lineSize: o.borderWidth, x: 0, y: 0, w: o.width, h: o.height }); return lsg; }; })(); table/drawHorizontalLines/draw.ls (function(){ return function(o, lsg){ var y, i$, ref$, len$, row, rowHeight; y = 0; for (i$ = 0, len$ = (ref$ = o.rowHeights).length; i$ < len$; ++i$) { row = i$; rowHeight = ref$[i$]; if (row === o.rowHeights.length - 1) { break; } y += rowHeight; lsg.objects.push({ type: "line", lineColor: o.lineColor, lineSize: o.lineSize, x1: 0, y1: y, x2: o.width, y2: y }); } return lsg; }; })(); table/drawVerticalLines/draw.ls (function(){ return function(o, lsg){ var x, y1, y2, line, i$, ref$, len$, col, colWidth, j$, len1$, row, v, w; x = 0; y1 = 0; y2 = 0; line = 0; for (i$ = 0, len$ = (ref$ = o.colWidths).length; i$ < len$; ++i$) { col = i$; colWidth = ref$[i$]; if (col === o.colWidths.length - 1) { break; } x += colWidth; for (j$ = 0, len1$ = o.rowHeights.length; j$ < len1$; ++j$) { row = j$; v = _.find(o.cellsNormalized, fn$); if (v.skipLine === true) { if (row > 0) { w = _.find(o.cellsNormalized, fn1$); if (w.skipLine === true) { y1 += o.rowHeights[row]; y2 += o.rowHeights[row]; } else { lsg = inc("drawLine/draw")(o, lsg, x, y1, y2); y1 += (y2 - y1) + o.rowHeights[row]; y2 += o.rowHeights[row]; } } else { y1 += o.rowHeights[row]; y2 += o.rowHeights[row]; } } else { y2 += o.rowHeights[row]; } } if (y1 !== y2) { lsg = inc("drawLine/draw")(o, lsg, x, y1, y2); } line += 1; y1 = 0; y2 = 0; } return lsg; function fn$(v){ return v.x === line && v.y === row; } function fn1$(w){ return w.x === line && w.y === row - 1; } }; })(); table/drawVerticalLines/drawLine/draw.ls (function(){ return function(o, lsg, x, y1, y2){ lsg.objects.push({ type: "line", lineColor: o.lineColor, lineSize: o.lineSize, x1: x, y1: y1, x2: x, y2: y2 }); return lsg; }; })(); table/examples.lsg (function(){ return { version: 2, width: 300, height: 1000, background: Color.grey[100], objects: [ { type: 'lsg', lsg: path('renderer.lsr'), x: 53.12, y: 9.55, background: 'white', width: 200, height: 60, rows: 2, columns: [0.25, 0.125, 0.125, 0.125, 0.125, 0.125, 0.125], lines: { size: 1, color: Color.black }, border: true, cells: { fontSize: 10, textColor: Color.grey[800], offsetY: -1, values: [ { x: 0, y: 0, text: 'Zeit', offsetY: -1, background: Color.grey[300] }, { x: 1, y: 0, text: '20' }, { x: 2, y: 0, text: '40', bold: true }, { x: 3, y: 0, text: '60', bold: true }, { x: 4, y: 0, text: '80', italic: true }, { x: 5, y: 0, text: '100', bold: true, italic: true }, { x: 6, y: 0, text: '120' }, { x: 0, y: 1, text: 'Strecke', background: Color.grey[300], offsetY: -2 }, { x: 1, y: 1, text: '30' }, { x: 2, y: 1, text: '60' }, { x: 3, y: 1, text: '90' }, { x: 4, y: 1, text: '120' }, { x: 5, y: 1, text: '150' }, { x: 6, y: 1, text: '180' } ] } }, { type: 'lsg', lsg: path('renderer.lsr'), x: 104.7, y: 116.14, background: 'white', width: 100, height: 100, rows: 3, columns: 3, lines: { size: 1, color: Color.black }, border: true, cells: { fontSize: 10, textColor: Color.grey[800], offsetY: -1, values: [ { x: 0, y: 0, text: '0 0' }, { x: 1, y: 0, text: '1 0' }, { x: 2, y: 0, text: '2 0' }, { x: 0, y: 1, text: '0 1' }, { x: 1, y: 1, text: '1 1' }, { x: 2, y: 1, text: '2 1' }, { x: 0, y: 2, text: '0 2' }, { x: 1, y: 2, text: '1 2' }, { x: 2, y: 2, text: '2 2' } ] } }, { type: 'lsg', lsg: path('renderer.lsr'), x: 85.58, y: 268.17, background: 'white', width: 125, height: 100, rows: 3, columns: 4, lines: { size: 1, color: Color.black }, border: true, cells: { fontSize: 10, textColor: Color.grey[800], offsetY: -1, values: [ { x: 0, y: 0, mergeX: 1, text: '0 0mergeX = 1', offsetY: -5 }, { x: 2, y: 0, mergeX: 1, text: '2 0mergeX = 1', offsetY: -5 }, { x: 0, y: 1, text: '0 1' }, { x: 1, y: 1, text: '1 1' }, { x: 2, y: 1, text: '2 1' }, { x: 3, y: 1, text: '2 1' }, { x: 0, y: 2, mergeX: 3, text: '0 2 mit mergeX = 3' } ] } } ] }; })(); table/level-1.ls (function(){ return { uid: '7k0juc', title: "Silbentrainer Typ 4", voiceLang: 'de', trainers: { trainer: "buttons", atoms: { a: "", b: "2", lsg: { lsg: path("renderer.lsr"), width: 300, background: 'white', height: 300, rows: 3, columns: 3, lines: { size: 1, color: Color.black }, border: true, cells: { fontSize: 13, textColor: Color.grey[800], offsetY: -1, values: [ { x: 0, y: 0, text: '1', bold: true, mergeX: 1, offsetY: -1, background: Color.grey[300] }, { x: 0, y: 1, text: '4', bold: true, mergeX: 0, offsetY: -1 }, { x: 0, y: 2, text: '7', bold: true, mergeX: 0, offsetY: -1 }, { x: 1, y: 0, text: '2', bold: true, mergeX: 0, offsetY: -1 }, { x: 1, y: 1, text: '5', bold: true, mergeX: 1, offsetY: -1, background: Color.pink[50] }, { x: 1, y: 2, text: '8', bold: true, mergeX: 0, offsetY: -1 }, { x: 2, y: 0, text: '3', bold: true, mergeX: 0, offsetY: -1 }, { x: 2, y: 1, text: '6', bold: true, mergeX: 0, offsetY: -1 }, { x: 2, y: 2, text: '9', bold: true, mergeX: 0, offsetY: -1, background: Color.blue[100] } ] } } } } }; })(); table/lsgEditor.ls (function(){ return { name: "Table", 'default': { type: 'lsg', lsg: path('/../c-renderer/table/renderer.lsr'), x: 15, y: 120, background: 'white', width: 200, height: 60, rows: 2, columns: [0.25, 0.125, 0.125, 0.125, 0.125, 0.125, 0.125], lines: { size: 1, color: Color.black }, border: true, cells: { fontSize: 10, textColor: Color.grey[800], offsetY: -1, values: [ { x: 0, y: 0, text: 'Zeit', offsetY: -1, background: Color.grey[300] }, { x: 1, y: 0, text: '20', mergeX: 1 }, { x: 3, y: 0, text: '60', bold: true }, { x: 4, y: 0, text: '80', italic: true }, { x: 5, y: 0, text: '100', bold: true, italic: true }, { x: 6, y: 0, text: '120' }, { x: 0, y: 1, text: 'Strecke', background: Color.grey[300], offsetY: -2 }, { x: 1, y: 1, text: '30' }, { x: 2, y: 1, text: '60' }, { x: 3, y: 1, text: '90' }, { x: 4, y: 1, text: '120' }, { x: 5, y: 1, text: '150' }, { x: 6, y: 1, text: '180' } ] } } }; })(); table/markCellsForMerging/mark.ls (function(){ return function(o){ var i$, ref$, len$, cell, j$, to$, mergeCols, c; for (i$ = 0, len$ = (ref$ = o.cellsNormalized).length; i$ < len$; ++i$) { cell = ref$[i$]; if (cell.mergeX > 0) { for (j$ = 0, to$ = cell.mergeX - 1; j$ <= to$; ++j$) { mergeCols = j$; if (cell.x + mergeCols === o.colWidths.length) { break; } c = _.find(o.cellsNormalized, fn$); c.skipLine = true; } } } return o.cellsNormalized; function fn$(u){ return u.x === cell.x + mergeCols && u.y === cell.y; } }; })(); table/renderer.lsr (function(){ return function(param){ var o, ref$, ref1$, ref2$, ref3$, ref4$, lsg; o = {}; o.width = param.width; o.height = param.height; o.lineColor = ((ref$ = param.lines) != null ? ref$.color : void 8) || Color.grey[800]; o.lineSize = (ref1$ = (ref2$ = param.lines) != null ? ref2$.size : void 8) != null ? ref1$ : 1; o.borderWidth = (ref1$ = (ref3$ = param.border) != null ? ref3$.size : void 8) != null ? ref1$ : 1; o.borderColor = (ref1$ = (ref4$ = param.border) != null ? ref4$.color : void 8) != null ? ref1$ : Color.grey[800]; o.cells = param.cells; o.fontSize = (ref1$ = param.cells.fontSize) != null ? ref1$ : 10; o.textColor = param.cells.textColor || Color.grey[800]; o.bold = (ref1$ = param.cells.bold) != null ? ref1$ : false; o.italic = (ref1$ = param.cells.italic) != null ? ref1$ : false; o.textFont = param.cells.font; o.textOffsetY = (ref1$ = param.cells.offsetY) != null ? ref1$ : 0; o.textOffsetX = (ref1$ = param.cells.offsetX) != null ? ref1$ : 0; o.cellBackgroundColor = param.cells.background; o.rowHeights = _.isArray(param.rows) ? param.rows : _.isFinite(param.rows) ? repeatArray$([1 / param.rows], param.rows) : [1]; o.colWidths = _.isArray(param.columns) ? param.columns : _.isFinite(param.columns) ? repeatArray$([1 / param.columns], param.columns) : [1]; o.rowHeights = _.map(o.rowHeights, function(h){ return h * o.height; }); o.colWidths = _.map(o.colWidths, function(w){ return w * o.width; }); lsg = { width: o.width, height: o.height, objects: [] }; o.cellsNormalized = inc("calcCellsNormalized/calc")(o); o.cellsNormalized = inc("markCellsForMerging/mark")(o); lsg = inc("drawBackgroundColors/draw")(o, lsg); lsg = inc("drawHorizontalLines/draw")(o, lsg); lsg = inc("drawVerticalLines/draw")(o, lsg); if (param.border) { lsg = inc("drawBorder/draw")(o, lsg); } if (param.cells.values != null) { lsg = inc("addLabels/add")(o, lsg); } return lsg; }; })(); function repeatArray$(arr, n){ for (var r = []; n > 0; (n >>= 1) && (arr = arr.concat(arr))) if (n & 1) r.push.apply(r, arr); return r; } thermometer/examples.lsg (function(){ return { version: 2, width: 300, height: 1000, background: Color.grey[100], objects: [ { type: 'lsg', lsg: path('/../c-renderer/thermometer/renderer.lsr'), x: 14.1, y: 27.1, w: 116, value: 66, from: 0, to: 100, rotateNumbers: true, unit: 'kelvin', circleFill: Color.pink[100], circleBorder: Color.deepPurple[400], negativeFill: Color.green.A400, positiveFill: Color.yellow.A200, pointerColor: Color.white }, { type: 'lsg', lsg: path('/../c-renderer/thermometer/renderer.lsr'), x: 170, y: 121.7, w: 116, value: 66, style: 'vertical', from: 0, to: 100, unit: 'kelvin', circleFill: Color.pink[100], circleBorder: Color.deepPurple[400], negativeFill: Color.green.A400, positiveFill: Color.yellow.A200, pointerColor: Color.white } ] }; })(); thermometer/examplesVertical.lsg (function(){ return { version: 2, width: 300, height: 1100, background: Color.grey[100], objects: [ { type: 'text', text: 'vertical thermometer examples', x: 20, y: 10, color: 'black', size: 12, align: 'left' }, { type: 'lsg', lsg: path('/../c-renderer/thermometer/renderer.lsr'), x: 30, y: 50, w: 100, style: 'vertical', value: 27, from: -20, to: 100 }, { type: 'lsg', lsg: path('/../c-renderer/thermometer/renderer.lsr'), x: 150, y: 50, w: 100, style: 'vertical', circleFill: Color.pink[100], circleBorder: Color.deepPurple[400], innerFill: Color.yellow.A200, value: 66, from: 0, to: 100, unit: 'kelvin' }, { type: 'lsg', lsg: path('/../c-renderer/thermometer/renderer.lsr'), x: 30, y: 300, w: 100, style: 'vertical', value: -99, from: -100, to: 10 }, { type: 'lsg', lsg: path('/../c-renderer/thermometer/renderer.lsr'), x: 150, y: 300, w: 100, style: 'vertical', value: 14, from: 0, to: 50, unit: 'kelvin', step: 1 }, { type: 'lsg', lsg: path('/../c-renderer/thermometer/renderer.lsr'), x: 30, y: 550, w: 100, style: 'vertical', value: 27, from: 10, to: 110, circleFill: Color.orange.A400, positiveFill: Color.white, circleBorder: Color.black, unit: 'fahrenheit', step: 5 }, { type: 'lsg', lsg: path('/../c-renderer/thermometer/renderer.lsr'), x: 150, y: 550, w: 100, style: 'vertical', value: 27, from: -10, to: 40, circleFill: Color.pink.A200, innerFill: Color.lightBlue.A400, circleBorder: Color.white, step: 5 }, { type: 'lsg', lsg: path('/../c-renderer/thermometer/renderer.lsr'), x: 30, y: 800, w: 100, style: 'vertical', value: -60, from: -150, to: 0 } ] }; })(); thermometer/level.ls (function(){ return { uid: '3eyro5', trainers: { trainer: "buttons", instruction: { text: "instruction" }, lsg: { lsg: path("renderer.lsr"), width: 300, value: -200, from: -200, to: 10, step: 10, rotateNumbers: false, mode: "celsius" }, atoms: { a: "a", b: "a" } } }; })(); thermometer/lsgEditor.ls (function(){ return { name: "Thermometer", 'default': { type: 'lsg', lsg: path('renderer.lsr'), x: 20, y: 150, w: 100, value: 27, from: -10, to: 40, rotateNumbers: false } }; })(); thermometer/renderer.lsr (function(){ return function(o){ var value, vfrom, ref$, vto, rotateNumbers, unit, step, circleFill, circleBorder, negativeFill, positiveFill, pointerColor, lsg, dif, numLine, spacing, rotation, x, fontSize, yComp, i$, i, to$, numRotation, numValue, alpha, beta; if (o.style === "vertical") { return inc("vertical/vertical")(o); } value = o.value; vfrom = (ref$ = o.from) != null ? ref$ : -20; vto = (ref$ = o.to) != null ? ref$ : 100; rotateNumbers = (ref$ = o.rotateNumbers) != null ? ref$ : false; unit = o.unit || "celsius"; step = (ref$ = o.step) != null ? ref$ : 10; circleFill = o.circleFill || Color.grey[300]; circleBorder = o.circleBorder || Color.grey[600]; negativeFill = o.negativeFill || Color.blue[400]; positiveFill = o.positiveFill || Color.red[400]; pointerColor = o.pointerColor || Color.black; lsg = { width: 300, height: 300, objects: [], requiredArguments: ["value", "from", "to"], color: { pointer: pointerColor } }; if (value == null) { debug("value needs to be defined"); return lsg; } if (vfrom % 10 !== 0) { debug("value 'from' should be divisible by 10"); return lsg; } if (vto % 10 !== 0) { debug("value 'to' should be divisible by 10"); return lsg; } if (value < vfrom || value > vto) { debug("value must be between from and to"); return lsg; } if (!(step === 1 || step === 5 || step === 10)) { debug("step must be either 1, 5 or 10"); return lsg; } dif = vto - vfrom; numLine = dif / 10; spacing = 300 / numLine; rotation = -150 - spacing * vfrom / 10 + spacing * value / 10; x = Math.max(Math.abs(vfrom), Math.abs(vto)); if (x > 100) { fontSize = 30; yComp = 3; } else { fontSize = 40; yComp = -3; } lsg.objects.push({ type: 'oval', x: 0, y: 0, w: 300, h: 300, color: circleFill, lineSize: 8, lineColor: circleBorder }); if (vto < 0) { lsg.objects.push({ type: 'lsg', lsg: path('/angle/renderer.lsr'), x: 75, y: 75, w: 150, fill: 'transparent', fillOpacity: 0, border: negativeFill, borderSize: 20, from: -150, to: 150 }); } else if (vfrom < 0) { lsg.objects.push({ type: 'lsg', lsg: path('/angle/renderer.lsr'), x: 75, y: 75, w: 150, fill: 'transparent', fillOpacity: 0, border: positiveFill, borderSize: 20, from: -150, to: 150 }); lsg.objects.push({ type: 'lsg', lsg: path('/angle/renderer.lsr'), x: 75, y: 75, w: 150, fill: 'transparent', fillOpacity: 0, border: negativeFill, borderSize: 20, from: -150, to: -150 + spacing * (Math.abs(vfrom) / 10) }); } else { lsg.objects.push({ type: 'lsg', lsg: path('/angle/renderer.lsr'), x: 75, y: 75, w: 150, fill: 'transparent', fillOpacity: 0, border: positiveFill, borderSize: 20, from: -150, to: 150 }); } lsg.objects.push({ type: 'oval', x: 130.9, y: 130.9, w: 38, h: 38, color: circleFill, lineSize: 5, lineColor: circleBorder }); lsg.objects.push({ type: 'lsg', lsg: path('/angle/renderer.lsr'), x: 90, y: 90, w: 120, fill: 'transparent', fillOpacity: 0, border: Color.black, borderSize: 5, from: -151, to: 151 }); for (i$ = 0; i$ <= numLine; ++i$) { i = i$; x = 1 + (numLine - numLine % 15) / 15; if (i % x === 0) { lsg.objects.push({ type: 'lsg', lsg: path('/angle/renderer.lsr'), x: 65, y: 65, w: 170, fill: 'transparent', fillOpacity: 0, border: Color.black, borderSize: 30, from: -151.5 + spacing * i, to: -148.5 + spacing * i }); } else { lsg.objects.push({ type: 'lsg', lsg: path('/angle/renderer.lsr'), x: 70, y: 70, w: 160, fill: 'transparent', fillOpacity: 0, border: Color.black, borderSize: 26, from: -151 + spacing * i, to: -149 + spacing * i }); } } if (step === 1 || step === 5) { for (i$ = 0, to$ = numLine * 10; i$ <= to$; ++i$) { i = i$; if (i % 5 === 0) { lsg.objects.push({ type: 'lsg', lsg: path('/angle/renderer.lsr'), x: 70, y: 70, w: 160, fill: 'transparent', fillOpacity: 0, border: Color.black, borderSize: 26, from: -151 + spacing * i / 10, to: -149 + spacing * i / 10 }); } else if (step === 1) { lsg.objects.push({ type: 'lsg', lsg: path('/angle/renderer.lsr'), x: 75, y: 75, w: 150, fill: 'transparent', fillOpacity: 0, border: Color.black, borderSize: 24, from: -150.7 + spacing * i / 10, to: -149.3 + spacing * i / 10 }); } } } lsg.objects.push({ type: 'svg', svg: path("/../c-svg/2020/08/04-renderer-thermometer-pointer.svg"), 'class': "pointer", rotate: rotation, x: 0, y: 0, w: 300 }); if (unit === "fahrenheit") { lsg.objects.push({ type: 'text', text: '°F', x: 150, y: 200, color: Color.black, size: 40, align: 'center', font: 'Source Sans Pro' }); } else if (unit === "kelvin") { lsg.objects.push({ type: 'text', text: 'K', x: 150, y: 200, color: Color.black, size: 40, align: 'center', font: 'Source Sans Pro' }); } else { lsg.objects.push({ type: 'text', text: '°C', x: 150, y: 200, color: Color.black, size: 40, align: 'center', font: 'Source Sans Pro' }); } for (i$ = 0; i$ <= numLine; ++i$) { i = i$; x = 1 + (numLine - numLine % 15) / 15; if (i % x === 0) { numRotation = -150 + spacing * i; numValue = vfrom + 10 * i; if (-180 < numRotation && numRotation < -90) { alpha = (numRotation + 180) * (Math.PI / 180); beta = rotateNumbers ? numRotation : 0; lsg.objects.push({ type: 'text', text: numValue, x: 150 - Math.sin(alpha) * 115, y: 125 + yComp + Math.cos(alpha) * 112, rotate: beta, color: Color.black, size: fontSize, align: 'center', font: 'Source Sans Pro' }); } else if (-90 <= numRotation && numRotation < 0) { alpha = (numRotation + 90) * (Math.PI / 180); beta = rotateNumbers ? numRotation : 0; lsg.objects.push({ type: 'text', text: numValue, x: 150 - Math.cos(alpha) * 115, y: 125 + yComp - Math.sin(alpha) * 110, color: Color.black, size: fontSize, align: 'center', font: 'Source Sans Pro', rotate: beta }); } else if (0 <= numRotation && numRotation <= 90) { alpha = numRotation * (Math.PI / 180); beta = rotateNumbers ? numRotation : 0; lsg.objects.push({ type: 'text', text: numValue, x: 150 + Math.sin(alpha) * 115, y: 125 + yComp - Math.cos(alpha) * 110, color: Color.black, size: fontSize, align: 'center', font: 'Source Sans Pro', rotate: beta }); } else if (90 < numRotation && numRotation < 180) { alpha = (numRotation - 90) * (Math.PI / 180); beta = rotateNumbers ? numRotation : 0; lsg.objects.push({ type: 'text', text: numValue, x: 150 + Math.cos(alpha) * 115, y: 125 + yComp + Math.sin(alpha) * 112, color: Color.black, size: fontSize, align: 'center', font: 'Source Sans Pro', rotate: beta }); } } } return lsg; }; })(); thermometer/vertical/vertical.ls (function(){ return function(o){ var value, vfrom, ref$, vto, unit, step, circleFill, circleBorder, innerFill, lsg, lineSize, mainBarWidth, circleDiameter, innerSpacing, innerDiameter, innerBarWidth, minY, maxY, valuePercentage, innerY, numLines, x1, x2, x3, lineSpacing, i$, i, hasText, y, unitSize; value = o.value; vfrom = (ref$ = o.from) != null ? ref$ : -20; vto = (ref$ = o.to) != null ? ref$ : 100; unit = o.unit || "celsius"; step = (ref$ = o.step) != null ? ref$ : 10; circleFill = o.circleFill || Color.grey[300]; circleBorder = o.circleBorder || Color.grey[600]; innerFill = o.innerFill || o.positiveFill || o.negativeFill || Color.red[400]; if (value == null) { debug("value needs to be defined"); return lsg; } if (vfrom % 10 !== 0) { debug("value 'from' should be divisible by 10"); return lsg; } if (vto % 10 !== 0) { debug("value 'to' should be divisible by 10"); return lsg; } if (value < vfrom || value > vto) { debug("value must be between from and to"); return lsg; } if (!(step === 1 || step === 5 || step === 10)) { debug("step must be either 1, 5 or 10"); return lsg; } lsg = { width: 70, height: 150, objects: [], requiredArguments: ["value", "from", "to"] }; lineSize = 3; mainBarWidth = 22; circleDiameter = 50; innerSpacing = 2 * lineSize; innerDiameter = circleDiameter - 2 * innerSpacing; innerBarWidth = mainBarWidth - 2 * innerSpacing; minY = lsg.height - circleDiameter; maxY = lineSize * 3; valuePercentage = (value - vfrom) / (vto - vfrom); innerY = minY + valuePercentage * (maxY - minY); lsg.objects.push({ type: 'oval', x: 0, y: lsg.height - circleDiameter, w: circleDiameter, h: circleDiameter, color: circleFill, lineSize: lineSize, lineColor: circleBorder }); lsg.objects.push({ type: 'rect', x: (circleDiameter - mainBarWidth) / 2, y: 0, w: mainBarWidth, h: lsg.height - circleDiameter + lineSize * 1.5, color: circleFill, lineSize: lineSize, lineColor: circleBorder, rounded: 2 }); lsg.objects.push({ type: 'rect', x: (circleDiameter - mainBarWidth + 2 * lineSize) / 2, y: lineSize, w: mainBarWidth - 2 * lineSize, h: lsg.height - circleDiameter + lineSize, color: circleFill }); lsg.objects.push({ type: 'oval', x: innerSpacing, y: lsg.height - innerDiameter - innerSpacing, w: innerDiameter, h: innerDiameter, color: innerFill }); lsg.objects.push({ type: 'rect', x: (circleDiameter - innerBarWidth) / 2, y: innerY, w: innerBarWidth, h: (lsg.height - innerDiameter / 2) - innerY, color: innerFill }); numLines = (vto - vfrom) / step; x1 = (circleDiameter + mainBarWidth) / 2 + lineSize; x2 = x1 + 5; x3 = x1 + 3; lineSpacing = (maxY - minY) / numLines; for (i$ = 0; i$ <= numLines; ++i$) { i = i$; hasText = (i * step) % 10 === 0; y = minY + i * lineSpacing; lsg.objects.push({ type: 'line', x1: x1, y1: y, x2: hasText ? x2 : x3, y2: y, lineColor: Color.black, lineSize: hasText ? 1 : 0.5 }); if (hasText) { lsg.objects.push({ type: 'text', x: x2 + lineSize / 2, y: y - 5, color: Color.black, size: 7, text: Math.round(vfrom + i * (vto - vfrom) / numLines) }); } } unitSize = innerDiameter * 0.5; lsg.objects.push({ type: 'text', text: (function(){ switch (unit) { case "fahrenheit": return "°F"; case "kelvin": return "K"; default: return "°C"; } }()), x: unit === "kelvin" ? circleDiameter / 2 : circleDiameter / 2 - unitSize * 0.15, y: lsg.height - circleDiameter / 2 - unitSize * 0.666, color: Color.black, size: unitSize, align: 'center', font: 'Source Sans Pro' }); return lsg; }; })(); thousands-to-ones/block.ls (function(){ return { uid: 'n5eqi1', title: "dragMatch", levels: [path("level-test"), path("level-test-fast")] }; })(); thousands-to-ones/calcstripes/calcstripes.ls (function(){ return function(o){ var ref$, digits, lsgPadding, lsgWidth, lsgHeight, lsg, currentLeftPadding, currentValue, hundreds, i$, i, tens; if (!(0 < (ref$ = o.value) && ref$ <= 999)) { debug("the value must be between 1 and 999"); } digits = o.value + ""; while (digits.length < 3) { digits = "0" + digits; } lsgPadding = o.value > 500 ? 0 : (5 - _.ceil(o.value / 100)) * 170; lsgWidth = 830; lsgHeight = o.value > 500 ? 320 : 150; lsg = { width: lsgWidth, height: lsgHeight, background: "white", objects: [], requiredArguments: ["mode", "value"] }; currentLeftPadding = 0; currentValue = 0; hundreds = digits.slice(0, 1) * 1; if (hundreds > 0) { for (i$ = 0; i$ < hundreds; ++i$) { i = i$; lsg.objects.push({ type: 'lsg', lsg: path('/calcstripes/renderer.lsr'), dots: 100, x: currentLeftPadding + lsgPadding / 2, y: i < 5 ? 0 : 170, w: 150, color: o.color, circleBorder: o.circleBorder }); currentLeftPadding += 170; currentValue += 100; if (currentValue === 500) { currentLeftPadding = 0; } } } tens = digits.slice(1, 3) * 1; lsg.objects.push({ type: 'lsg', lsg: path('/calcstripes/renderer.lsr'), dots: tens, x: currentLeftPadding + lsgPadding / 2, y: o.value > 500 ? 170 : 0, w: 150, color: o.color, circleBorder: o.circleBorder }); return lsg; }; })(); thousands-to-ones/cubes/cubes.ls (function(){ return function(o){ var ref$, digits, digitPaddings, res$, i$, len$, i, d, lsgSidePadding, lsgWidth, t, lsgBottomPadding, lsgHeight, lsg, currentLeftPadding, thousands, hundreds, tens, ones; if (!(0 < (ref$ = o.value) && ref$ <= 9999)) { debug("the value must be between 1 and 9999"); } digits = _.padStart(o.value, 4, 0); res$ = []; for (i$ = 0, len$ = digits.length; i$ < len$; ++i$) { i = i$; d = digits[i$]; d = d * 1; switch (i) { case 0: if (d === 0) { res$.push(520); } else if (0 < d && d < 6) { res$.push(260); } else { res$.push(5); } break; case 1: if (d === 0) { res$.push(260); } else { res$.push(0); } break; case 2: if (o.tensHorizontal) { if (d === 0) { res$.push(260); } else { res$.push(0); } } else { res$.push(9 * 35 - d * 35); } break; case 3: if (d === 0) { res$.push(70); } else if (d < 6) { res$.push(35); } else { res$.push(0); } } } digitPaddings = res$; lsgSidePadding = _.sum(digitPaddings); lsgWidth = 1200; t = digits.slice(0, 1) * 1; if (t > 5) { t = 5; } lsgBottomPadding = (5 - t) * 185 + 200; lsgHeight = t === 0 ? 0 : t * 185 + 80; if (t < 2) { if (digits[1] === "9") { lsgHeight = 370; lsgBottomPadding = 835; } else { lsgHeight = 350; lsgBottomPadding = 855; } } lsg = { width: lsgWidth, height: lsgHeight, requiredArguments: ["mode", "value"], objects: [] }; currentLeftPadding = 0; thousands = digits.slice(0, 1) * 1; if (thousands > 0) { for (i$ = 0; i$ < thousands; ++i$) { i = i$; lsg.objects.push({ type: 'svg', svg: path("/../c-svg/2020/08/05-renderer-thousands-to-ones-thousand.svg"), x: _.floor(i / 5) * 250 + currentLeftPadding + lsgSidePadding / 2, y: 990 - lsgBottomPadding - (i % 5) * 195, w: 210, color: o.color }); } currentLeftPadding += _.ceil(thousands / 5) * 260; } hundreds = digits.slice(1, 2) * 1; if (hundreds > 0) { for (i$ = 0; i$ < hundreds; ++i$) { i = i$; lsg.objects.push({ type: 'svg', svg: path("/../c-svg/2020/08/05-renderer-thousands-to-ones-hundred.svg"), x: currentLeftPadding + lsgSidePadding / 2, y: 868 - lsgBottomPadding + 8 * 35 - i * 35 - Math.floor(i / 5) * 30, w: 210, color: o.color }); } currentLeftPadding += 260; } tens = digits.slice(2, 3) * 1; if (o.tensHorizontal) { if (tens > 0) { for (i$ = 0; i$ < tens; ++i$) { i = i$; lsg.objects.push({ type: 'svg', svg: path("/../c-svg/2020/08/05-renderer-thousands-to-ones-ten.svg"), x: 100 + currentLeftPadding + lsgSidePadding / 2, y: 1107 - lsgBottomPadding - i * 35 - _.floor(i / 5) * 30, w: 20, rotate: -90, flipY: true, color: o.color }); } currentLeftPadding += 260; } } else { for (i$ = 0; i$ < tens; ++i$) { i = i$; lsg.objects.push({ type: 'svg', svg: path("/../c-svg/2020/08/05-renderer-thousands-to-ones-ten.svg"), x: currentLeftPadding + lsgSidePadding / 2, y: 1033 - lsgBottomPadding, w: 20, color: o.color }); currentLeftPadding += 35; if (i % 5 === 4) { currentLeftPadding += 15; } } currentLeftPadding += 23; } ones = digits.slice(3, 4) * 1; for (i$ = 0; i$ < ones; ++i$) { i = i$; lsg.objects.push({ type: 'svg', svg: path("/../c-svg/2020/08/05-renderer-thousands-to-ones-cube.svg"), x: currentLeftPadding + _.floor(i / 5) * 45 + lsgSidePadding / 2, y: 1180 - lsgBottomPadding - (i % 5) * 40, w: 20, color: o.color }); } return lsg; }; })(); thousands-to-ones/examples-renderer.lsg (function(){ return { version: 2, width: 500, height: 500, background: Color.grey[100], objects: [ { type: 'lsg', lsg: path('/../c-renderer/thousands-to-ones/renderer.lsr'), x: -36.8, y: 3.7, w: 580, color: Color.grey[400], background: Color.blue[500], mode: 'cubes', value: 2123 }, { type: 'lsg', lsg: path('/../c-renderer/thousands-to-ones/renderer.lsr'), x: 3.8, y: 258.7, w: 500, color: Color.grey[900], background: Color.blue[100], mode: 'simple', value: 120 }, { type: 'lsg', lsg: path('/../c-renderer/thousands-to-ones/renderer.lsr'), x: 0, y: 385.4, w: 500, color: Color.grey[400], background: Color.red[100], mode: 'calcstripes', value: 120 } ] }; })(); thousands-to-ones/level-test.ls (function(){ return { uid: 's3wo7q', title: "renderer", lsg: { width: 400 }, trainers: [ { trainer: "buttons", instruction: { text: "instruction" }, lsg: { lsg: path("/../c-renderer/thousands-to-ones/renderer.lsr"), mode: "cubes", value: 283, background: "red" }, atoms: { a: "2", b: "1" } }, { trainer: "buttons", instruction: "instruction", lsg: { lsg: path("/../c-renderer/thousands-to-ones/renderer.lsr"), mode: "cubes", value: 9999, tensHorizontal: true, width: 500 }, atoms: { a: "Wieviele Würfel sind dargestellt?", b: "5999 999 ++9999" } }, { trainer: "buttons", instruction: "instruction", lsg: { lsg: path("/../c-renderer/thousands-to-ones/renderer.lsr"), mode: "cubes", value: 399 }, atoms: { a: "1", b: "1" } }, { trainer: "buttons", instruction: "instruction", lsg: { lsg: path("/../c-renderer/thousands-to-ones/renderer.lsr"), mode: "cubes", value: 309 }, atoms: { a: "1", b: "1" } }, { trainer: "buttons", instruction: "instruction", lsg: { lsg: path("/../c-renderer/thousands-to-ones/renderer.lsr"), mode: "cubes", value: 5 }, atoms: { a: "1", b: "1" } }, { trainer: "buttons", instruction: "instruction", lsg: { lsg: path("/../c-renderer/thousands-to-ones/renderer.lsr"), mode: "simple", value: 999 }, atoms: { a: "1", b: "1" } }, { trainer: "buttons", instruction: "instruction", lsg: { lsg: path("/../c-renderer/thousands-to-ones/renderer.lsr"), mode: "simple", value: 799 }, atoms: { a: "1", b: "1" } }, { trainer: "buttons", instruction: "instruction", lsg: { lsg: path("/../c-renderer/thousands-to-ones/renderer.lsr"), mode: "simple", value: 309 }, atoms: { a: "1", b: "1" } }, { trainer: "buttons", instruction: "instruction", lsg: { lsg: path("/../c-renderer/thousands-to-ones/renderer.lsr"), mode: "simple", value: 5 }, atoms: { a: "1", b: "1" } }, { trainer: "buttons", instruction: "instruction", lsg: { lsg: path("/../c-renderer/thousands-to-ones/renderer.lsr"), mode: "calcstripes", value: 999 }, atoms: { a: "1", b: "1" } }, { trainer: "buttons", instruction: "instruction", lsg: { lsg: path("/../c-renderer/thousands-to-ones/renderer.lsr"), mode: "calcstripes", value: 799 }, atoms: { a: "1", b: "1" } }, { trainer: "buttons", instruction: "instruction", lsg: { lsg: path("/../c-renderer/thousands-to-ones/renderer.lsr"), mode: "calcstripes", value: 309 }, atoms: { a: "1", b: "1" } }, { trainer: "buttons", instruction: "instruction", lsg: { lsg: path("/../c-renderer/thousands-to-ones/renderer.lsr"), mode: "calcstripes", value: 5 }, atoms: { a: "1", b: "1" } } ] }; })(); thousands-to-ones/lsgEditor.ls (function(){ return { name: "Thousands to Ones", 'default': { type: 'lsg', lsg: path('renderer.lsr'), x: 0, y: 0, w: 300, color: Color.teal[500], background: 'white', mode: 'cubes', value: 9999 } }; })(); thousands-to-ones/renderer.lsr (function(){ return function(o){ o.color = o.color || Color.teal[500]; if (o.mode === "simple") { return inc("simple/simple")(o); } else if (o.mode === "cubes") { return inc("cubes/cubes")(o); } else if (o.mode === "calcstripes") { return inc("calcstripes/calcstripes")(o); } }; })(); thousands-to-ones/simple/simple.ls (function(){ return function(o){ var ref$, digits, digitWidths, lsgPadding, lsgWidth, lsgHeight, secondRowOffset, secondRowAt, rowChanged, currentLeftPadding, index, calcRowBreak, rowSwitch, lsg, hundreds, i$, i, tens, ones; if (!(0 < (ref$ = o.value) && ref$ <= 999)) { debug("the value for the simple mode must be between 1 and 999"); } digits = _.padStart(o.value, 3, 0); digitWidths = [75, 20, 20]; lsgPadding = 15; lsgWidth = 600; lsgHeight = 85; secondRowOffset = 0; secondRowAt = 0; rowChanged = false; currentLeftPadding = 0; index = -1; calcRowBreak = function(){ var currentWidth, i$, ref$, len$, i, digit, value, width, j$, j; currentWidth = 2 * lsgPadding; for (i$ = 0, len$ = (ref$ = digits).length; i$ < len$; ++i$) { i = i$; digit = ref$[i$]; value = digit * 1; width = digitWidths[i]; for (j$ = 0; j$ < value; ++j$) { j = j$; if (currentWidth + width < lsgWidth) { currentWidth += width; secondRowAt++; } else { lsgHeight = 170; return; } } } }; calcRowBreak(); rowSwitch = function(){ secondRowOffset = 77; currentLeftPadding = 0; return rowChanged = true; }; lsg = { width: lsgWidth, height: lsgHeight, objects: [], requiredArguments: ["mode", "value"] }; if (digits.length === 3) { hundreds = digits.slice(0, 1) * 1; for (i$ = 0; i$ < hundreds; ++i$) { i = i$; index++; if (!rowChanged && index >= secondRowAt) { rowSwitch(); } lsg.objects.push({ type: 'rect', 'class': 'rect', x: currentLeftPadding + lsgPadding, y: secondRowOffset + lsgPadding, w: 60, h: 60, lineSize: 2.5, lineColor: o.color }); currentLeftPadding += 75; } currentLeftPadding += 15; } if (digits.length >= 2) { tens = digits.slice(1, 2) * 1; for (i$ = 0; i$ < tens; ++i$) { i = i$; index++; if (!rowChanged && index >= secondRowAt) { rowSwitch(); } lsg.objects.push({ type: 'line', 'class': 'line1', x1: lsgPadding + currentLeftPadding, y1: secondRowOffset + lsgPadding, x2: lsgPadding + currentLeftPadding, y2: secondRowOffset + lsgPadding + 60, lineColor: o.color, lineSize: 3 }); currentLeftPadding += 20; } currentLeftPadding += 15; } ones = digits.slice(2, 3) * 1; for (i$ = 0; i$ < ones; ++i$) { i = i$; index++; if (!rowChanged && index >= secondRowAt) { rowSwitch(); } lsg.objects.push({ type: 'rect', 'class': 'rect', x: lsgPadding + currentLeftPadding, y: secondRowOffset + lsgPadding + 24, w: 9, h: 9, color: o.color, lineSize: 2, lineColor: o.color }); currentLeftPadding += 20; } return lsg; }; })(); triangle/examples.lsg (function(){ return { version: 2, width: 500, height: 1500, background: Color.grey[100], objects: [ { type: 'lsg', lsg: path('/../c-renderer/triangle/renderer.lsr'), x: 0, y: 0, rotate: 346, background: 'white', width: 500, alpha: 45, beta: 45, gamma: 90 }, { type: 'lsg', lsg: path('/../c-renderer/triangle/renderer.lsr'), x: 27.4, y: 260.7, w: 467, h: 467, background: 'white', width: 500, alpha: 120, gamma: 20 }, { type: 'lsg', lsg: path('/../c-renderer/triangle/renderer.lsr'), x: 96.5, y: 843.4, w: 203, h: 133, lineColor: Color.red[500], lineSize: 10, background: 'transparent', fillColor: Color.red[100], width: 500, beta: 50, gamma: 90 } ] }; })(); triangle/renderer.lsr (function(){ return function(o){ var width, ref$, height, lineColor, fillColor, lineSize, alpha, beta, gamma, alphaRad, betaRad, gammaRad, c_length, b_length, a, b, c, minX, maxX, minY, maxY, scaleX, scaleY, scale, i$, len$, p, lsg, vec, cmid; width = (ref$ = o.width) != null ? ref$ : 500; height = o.height; lineColor = (ref$ = o.lineColor) != null ? ref$ : Color.grey[800]; fillColor = (ref$ = o.fillColor) != null ? ref$ : 'transparent'; lineSize = (ref$ = o.lineSize) != null ? ref$ : 1; alpha = o.alpha; beta = o.beta; gamma = o.gamma; if (!alpha) { alpha = 180 - beta - gamma; } else if (!beta) { beta = 180 - alpha - gamma; } else if (!gamma) { gamma = 180 - alpha - beta; } if (_.isNaN(alpha) || _.isNaN(beta) || _.isNaN(gamma) || alpha <= 0 || beta <= 0 || gamma <= 0) { debug("alpha + beta + gamma must sum up to 180, at least 2 angles must be defined"); return; } alphaRad = alpha * Math.PI / 180; betaRad = beta * Math.PI / 180; gammaRad = gamma * Math.PI / 180; c_length = 1; b_length = c_length * Math.sin(betaRad) / Math.sin(gammaRad); a = { x: 0, y: 0 }; b = { x: c_length, y: 0 }; c = { x: b_length * Math.cos(alphaRad), y: b_length * Math.sin(alphaRad) }; minX = _.minBy([a, b, c], "x").x; maxX = _.maxBy([a, b, c], "x").x; minY = _.minBy([a, b, c], "y").y; maxY = _.maxBy([a, b, c], "y").y; scaleX = (width - 2 * lineSize) / (maxX - minX); scaleY = height != null ? (height - 2 * lineSize) / (maxY - minY) : void 8; if (scaleY != null) { scale = Math.min(scaleX, scaleY); } else { scale = scaleX; } for (i$ = 0, len$ = (ref$ = [a, b, c]).length; i$ < len$; ++i$) { p = ref$[i$]; p.x = lineSize + (p.x - minX) * scale; p.y = (p.y - minY) * scale; } maxY = _.maxBy([a, b, c], "y").y; height == null && (height = maxY + 2 * lineSize); for (i$ = 0, len$ = (ref$ = [a, b, c]).length; i$ < len$; ++i$) { p = ref$[i$]; p.y = height - lineSize - p.y; } lsg = { width: width, height: height, objects: [] }; vec = { x: b.x - a.x, y: b.y - a.y }; cmid = { x: a.x + vec.x * 0.5, y: a.y + vec.y * 0.5 }; lsg.objects.push({ type: 'path', color: fillColor, lineColor: lineColor, lineSize: lineSize, path: "M" + cmid.x + "," + cmid.y + " L" + b.x + "," + b.y + " L" + c.x + "," + c.y + " L" + a.x + "," + a.y + " L" + cmid.x + "," + cmid.y }); return lsg; }; })(); value-chart/examples-renderer.lsg (function(){ return { 'class': 'rect', width: 300, height: 1000, background: Color.grey[100], objects: [ { type: 'lsg', lsg: path('/../c-renderer/value-chart/renderer.lsr'), x: 20, y: 30, w: 250, value: 22208, mode: 'dots' }, { type: 'lsg', lsg: path('/../c-renderer/value-chart/renderer.lsr'), x: 20, y: 200, w: 250, value: 901 }, { type: 'lsg', lsg: path('/../c-renderer/value-chart/renderer.lsr'), x: 20, y: 470, w: 250, value: 123402, rectColor: 'white', valueColor: 'green', mode: 'dots' }, { type: 'lsg', lsg: path('/../c-renderer/value-chart/renderer.lsr'), x: 20, y: 640, w: 250, value: 102.234 } ] }; })(); value-chart/examples.lsg (function(){ return { 'class': 'rect', width: 300, height: 1000, background: Color.grey[100], objects: [ { type: 'rect', x: 108, y: 65, w: 35, h: 35, lineSize: 1, lineColor: Color.deepOrange[200] }, { type: 'rect', x: 142, y: 65, w: 35, h: 35, lineSize: 1, lineColor: Color.deepOrange[200] }, { type: 'rect', x: 176, y: 65, w: 35, h: 35, lineSize: 1, lineColor: Color.deepOrange[200] }, { type: 'rect', x: 108, y: 99, w: 35, h: 70, color: Color.orange[100], lineSize: 1, lineColor: Color.deepOrange[200] }, { type: 'rect', x: 142, y: 99, w: 35, h: 70, color: Color.orange[100], lineSize: 1, lineColor: Color.deepOrange[200] }, { type: 'rect', x: 176, y: 99, w: 35, h: 70, color: Color.orange[100], lineSize: 1, lineColor: Color.deepOrange[200] }, { type: 'text', text: 'H', x: 126, y: 72, color: Color.deepOrange[700], size: 20, align: 'center', font: 'Solocode School' }, { type: 'text', text: 'Z', x: 160, y: 72, color: Color.blue[500], size: 20, align: 'center', font: 'Solocode School' }, { type: 'text', text: 'E', x: 194, y: 72, color: Color.green[500], size: 20, align: 'center', font: 'Solocode School' }, { type: 'oval', x: 114, y: 104, w: 10, h: 10, color: Color.red[500] }, { type: 'oval', x: 127, y: 104, w: 10, h: 10, color: Color.red[500] }, { type: 'oval', x: 127, y: 117, w: 10, h: 10, color: Color.red[500] }, { type: 'oval', x: 114, y: 117, w: 10, h: 10, color: Color.red[500] }, { type: 'oval', x: 114, y: 130, w: 10, h: 10, color: Color.red[500] }, { type: 'oval', x: 127, y: 130, w: 10, h: 10, color: Color.red[500] }, { type: 'oval', x: 114, y: 143, w: 10, h: 10, color: Color.red[500] }, { type: 'oval', x: 127, y: 143, w: 10, h: 10, color: Color.red[500] }, { type: 'oval', x: 114, y: 156, w: 10, h: 10, color: Color.red[500] }, { type: 'oval', x: 127, y: 156, w: 10, h: 10, color: Color.red[500] }, { type: 'oval', x: 148, y: 104, w: 10, h: 10, color: Color.red[500] }, { type: 'oval', x: 161, y: 104, w: 10, h: 10, color: Color.red[500] }, { type: 'oval', x: 161, y: 117, w: 10, h: 10, color: Color.red[500] }, { type: 'oval', x: 148, y: 117, w: 10, h: 10, color: Color.red[500] }, { type: 'oval', x: 148, y: 130, w: 10, h: 10, color: Color.red[500] }, { type: 'oval', x: 161, y: 130, w: 10, h: 10, color: Color.red[500] }, { type: 'oval', x: 148, y: 143, w: 10, h: 10, color: Color.red[500] }, { type: 'oval', x: 161, y: 143, w: 10, h: 10, color: Color.red[500] }, { type: 'oval', x: 148, y: 156, w: 10, h: 10, color: Color.red[500] }, { type: 'oval', x: 161, y: 156, w: 10, h: 10, color: Color.red[500] }, { type: 'oval', x: 182, y: 104, w: 10, h: 10, color: Color.red[500] }, { type: 'oval', x: 195, y: 104, w: 10, h: 10, color: Color.red[500] }, { type: 'oval', x: 195, y: 117, w: 10, h: 10, color: Color.red[500] }, { type: 'oval', x: 182, y: 117, w: 10, h: 10, color: Color.red[500] }, { type: 'oval', x: 182, y: 130, w: 10, h: 10, color: Color.red[500] }, { type: 'oval', x: 195, y: 130, w: 10, h: 10, color: Color.red[500] }, { type: 'oval', x: 182, y: 143, w: 10, h: 10, color: Color.red[500] }, { type: 'oval', x: 195, y: 143, w: 10, h: 10, color: Color.red[500] }, { type: 'oval', x: 182, y: 156, w: 10, h: 10, color: Color.red[500] }, { type: 'oval', x: 195, y: 156, w: 10, h: 10, color: Color.red[500] } ] }; })(); value-chart/level.ls (function(){ return { uid: '3eyro5', trainers: { trainer: "buttons", instruction: { text: "instruction" }, lsg: { lsg: path("renderer.lsr"), width: 300, value: 1234567 }, atoms: { a: "a", b: "a" } } }; })(); value-chart/lsgEditor.ls (function(){ return { name: "Value Chart", 'default': { type: 'lsg', lsg: path('renderer.lsr'), x: 20, y: 630, w: 250, rectColor: 'white', valueColor: 'green', mode: 'dots', value: '7128329' } }; })(); value-chart/renderer.lsr (function(){ return function(o){ var rectWidth, rectHeight, headerHeight, digits, value, leftDigits, rightDigits, ref$, lsgWidth, lsgHeight, lsg, i, di, i$, len$, v, isDecimal, dots, j$, j, colOffset, rowOffset; o.renderLanguage == null && (o.renderLanguage = "de"); o.mode == null && (o.mode = "numbers"); o.headerLabels = (function(){ switch (o.renderLanguage) { case "de": return ["M", "HT", "ZT", "T", "H", "Z", "E"]; case "en_gb": case "en_us": return ["M", "HTh", "TTh", "Th", "H", "T", "O"]; case "fr": return ["M", "HT", "ZT", "T", "H", "Z", "E"]; case "es": case "pt": return ["UMi", "CM", "DM", "UM", "C", "D", "U"]; } }()); o.headerLabelsDecimal = (function(){ switch (o.renderLanguage) { case "de": return ["z", "h", "t", "zt", "ht"]; case "en_gb": case "en_us": return ["t", "h", "th", "tth", "hth"]; case "fr": case "pt": return ["z", "h", "t", "zt", "ht"]; case "es": return ["d", "c", "um", "dm", "cm"]; } }()); o.valueColor == null && (o.valueColor = Color.red[500]); o.rectColor == null && (o.rectColor = "transparent"); o.headerColor == null && (o.headerColor = "transparent"); o.headerColors = [Color.green[500], Color.red[500], Color.blue[500], Color.green[500], Color.red[500], Color.blue[500], Color.green[500]]; o.headerColorsDecimal = o.headerColors.slice().reverse(); rectWidth = o.renderLanguage === "es" ? 40 : 35; rectHeight = 69; headerHeight = 35; digits = _.replace(o.value, ".", "").length; value = o.value + ""; leftDigits = value.split(".")[0].length; rightDigits = (ref$ = value.split(".")[1]) != null ? ref$.length : void 8; lsgWidth = rectWidth * digits - (digits - 1); lsgHeight = headerHeight + rectHeight - 1; lsg = { width: lsgWidth, height: lsgHeight, requiredArguments: "value", objects: [] }; i = -1; di = -1; for (i$ = 0, len$ = value.length; i$ < len$; ++i$) { v = value[i$]; if (v === ".") { isDecimal = true; continue; } i++; if (isDecimal) { di++; } lsg.objects.push({ type: "rect", x: rectWidth * i - i, y: 0, w: rectWidth, h: headerHeight, color: o.headerColor, lineSize: 1, lineColor: Color.deepOrange[200] }); lsg.objects.push({ type: "text", text: !isDecimal ? o.headerLabels.slice(-leftDigits)[i] : o.headerLabelsDecimal[di], x: rectWidth / 2 + rectWidth * i - i, y: 6, color: !isDecimal ? o.headerColors.slice(-leftDigits)[i] : o.headerColorsDecimal[di + 1], size: 20, align: "center", font: "Solocode School" }); lsg.objects.push({ type: "rect", x: rectWidth * i - i, y: headerHeight - 1, w: rectWidth, h: rectHeight, color: o.rectColor, lineSize: 1, lineColor: Color.deepOrange[200] }); if (isDecimal && di === 0) { lsg.objects.push({ type: "rect", x: rectWidth * i - i - 1, y: 0, w: 1, h: headerHeight + rectHeight - 1, color: o.rectColor, lineSize: 1, lineColor: Color.deepOrange[200] }); } if (o.mode === "numbers") { lsg.objects.push({ type: "text", text: v, x: 18 + rectWidth * i - i, y: 16 + headerHeight - 1, color: o.valueColor, size: 30, align: "center", font: "Solocode School" }); } else { dots = v * 1; for (j$ = 1; j$ <= dots; ++j$) { j = j$; colOffset = j % 2 === 0 ? 12 : 0; rowOffset = _.floor((j - 1) / 2) * 12; lsg.objects.push({ type: "oval", x: 6.5 + rectWidth * i + colOffset - i, y: 5 + headerHeight + rowOffset - 1, w: 10, h: 10, color: o.valueColor }); } } } return lsg; }; })(); vertical-sequence/examples.lsg (function(){ return { width: 300, height: 1000, background: Color.grey[100], objects: { type: 'lsg', lsg: path('/../c-renderer/vertical-sequence/renderer.lsr'), x: 20, y: 30, w: 250, background: 'white', boxes: 5, boxColor: Color.lime[400], boxBorderColor: Color.black, arrowColor: Color.amber[400] } }; })(); vertical-sequence/level.ls (function(){ return { uid: '3eyro5', trainers: { trainer: "buttons", instruction: { text: "instruction" }, lsg: { lsg: path("renderer.lsr"), boxes: 8, width: 300, arrowColor: "red", boxColor: "green", boxBorderColor: "orange" }, atoms: { a: "a", b: "a" } } }; })(); vertical-sequence/lsgEditor.ls (function(){ return { name: "Vertical Sequence", 'default': { type: 'lsg', lsg: path('renderer.lsr'), x: 20, y: 30, w: 250, background: 'white', boxes: 5 } }; })(); vertical-sequence/renderer.lsr (function(){ return function(o){ var boxColor, boxBorderColor, arrowColor, direction, isDebug, boxWidth, boxHeight, boxPadding, paddingLeft, paddingRight, arrowWidth, lsgHeight, lsgWidth, boxColors, lsg, i$, to$, i; boxColor = o.boxColor || "transparent"; boxBorderColor = o.boxBorderColor || Color.grey[500]; arrowColor = o.arrowColor || Color.grey[600]; direction = o.direction || "downRight"; isDebug = o.isDebug || false; boxWidth = 70; boxHeight = 50; boxPadding = 20; paddingLeft = 20; paddingRight = 120; arrowWidth = 28; lsgHeight = boxHeight * o.boxes + boxPadding * o.boxes - boxPadding; lsgWidth = paddingLeft + paddingRight + boxWidth; boxColors = [Color.blue[300], Color.red[600]]; lsg = { width: lsgWidth, height: lsgHeight, objects: [], requiredArguments: "boxes", color: { box1: "green", box2: "red" } }; for (i$ = 0, to$ = o.boxes; i$ < to$; ++i$) { i = i$; lsg.objects.push({ 'class': 'box boxLabel' + (i + 1), type: 'rect', color: boxColor, lineColor: boxBorderColor, lineSize: 1.5, x: paddingLeft, y: boxPadding * i + boxHeight * i, w: boxWidth, h: boxHeight }); } for (i$ = 0, to$ = o.boxes - 1; i$ < to$; ++i$) { i = i$; lsg.objects.push({ type: 'lsg', lsg: path("../ellipse-arrow/renderer.lsr"), lineSize: 1.5, x: paddingLeft + boxWidth - 10 + 1, y: boxPadding * i + boxHeight * i + boxHeight / 2 + 10 - 10, w: arrowWidth, h: boxHeight + 2 * boxPadding - 15, lineColor: arrowColor, direction: direction, shape: 0.4 }); lsg.objects.push({ type: 'rect', color: isDebug ? Color.grey[400] : "transparent", 'class': "label arrowLabel" + (i + 1), x: paddingLeft + boxWidth + arrowWidth + 8, y: boxPadding * (i + 1) + boxHeight * (i + 1) - 20, w: 20, h: 20 }); } return lsg; }; })(); wordgrid/examples.lsg (function(){ return { version: 2, width: 200, height: 200, objects: { type: 'lsg', lsg: path('/../c-renderer/wordgrid/renderer.lsr'), x: 0, y: 0, w: 200, grid: "X h l b c\nX k e j y\nu i Y Y z\nt o a u v\nh j Z Z Z", solutions: "c1: a1-a2\nc2: c5-e5\nc3: c3-d3", border: false, showSolutions: true } }; })(); wordgrid/level.ls (function(){ return { uid: 'b01yik', lsg: { width: 500 }, trainers: [ { trainer: "findAll", atoms: { a: "Test", lsg: { lsg: path("renderer.lsr"), grid: "X h l b c\nX k e j y\nu i Y Y z\nt o a u v\nh j Z Z Z", solutions: "c1: a1-a2\nc2: c5-e5\nc3: c3-d3", border: false }, objects: [ { 'class': "c1", correct: true, color: Color.lightGreen.A700 }, { 'class': "c2", correct: true, color: Color.red.A700 }, { 'class': "c3", correct: true, color: Color.blue.A700 } ] } }, { trainer: "findSequence", lsg: { lsg: path("renderer.lsr"), grid: "X h l b c\nX k e j y\nu i Y Y z\nt o a u v\nh j Z Z Z", solutions: "c1: a1-a2\nc2: c3-d3\nc3: c5-e5", border: false }, atoms: [ { 'class': "c1", correct: true, color: Color.lightGreen.A700 }, { 'class': "c2", correct: true, color: Color.red.A700 }, { 'class': "c3", correct: true, color: Color.blue.A700 } ] } ] }; })(); wordgrid/lsgEditor.ls (function(){ return { name: "Wordgrid", 'default': { type: 'lsg', lsg: path('renderer.lsr'), w: 100, x: 51, y: 34, background: 'transparent', grid: "X h l b c\nX k e j y\nu i Y Y z\nt o a u v\nh j Z Z Z", solutions: "c1: a1-a2\nc2: c5-e5\nc3: c3-d3" } }; })(); wordgrid/renderer.lsr (function(){ return function(o){ var boxSize, padding, rows, rowCount, columnCount, solutionLines, solutions, border, ref$, width, height, lsg, ri1, ri2, i$, i, ci1, ci2, to$, j$, to1$, j, sol, isVertical, letterPos0, letterPos1; boxSize = 50; padding = 2; rows = _.map(o.grid.split("\n"), function(r){ return r.split(" "); }); rowCount = rows.length; columnCount = rows[0].length; solutionLines = o.solutions.trim().split("\n"); solutions = _.map(solutionLines, function(s){ return { 'class': s.split(":")[0].trim(), cells: s.split(":")[1].trim() }; }); border = (ref$ = o.border) != null ? ref$ : true; width = columnCount * boxSize; height = rowCount * boxSize; lsg = { width: 2 * padding + width, height: 2 * padding + height, requiredArguments: "grid", objects: [] }; ri1 = border ? 0 : 1; ri2 = border ? rowCount : rowCount - 1; for (i$ = ri1; i$ <= ri2; ++i$) { i = i$; lsg.objects.push({ type: 'line', x1: padding, x2: padding + width, y1: padding + i * boxSize, y2: padding + i * boxSize, lineSize: 1, lineColor: 'black' }); } ci1 = border ? 0 : 1; ci2 = border ? columnCount : columnCount - 1; for (i$ = ci1; i$ <= ci2; ++i$) { i = i$; lsg.objects.push({ type: 'line', y1: padding, y2: padding + height, x1: padding + i * boxSize, x2: padding + i * boxSize, lineSize: 1, lineColor: 'black' }); } for (i$ = 0, to$ = rowCount - 1; i$ <= to$; ++i$) { i = i$; for (j$ = 0, to1$ = columnCount - 1; j$ <= to1$; ++j$) { j = j$; lsg.objects.push({ type: 'text', size: boxSize - 10, text: rows[i][j], x: padding + j * boxSize + boxSize / 2, y: padding + i * boxSize, align: 'center', font: 'Source Sans Pro', color: 'black' }); } } if (o.isDebug) { for (i$ = 0, to$ = rowCount - 1; i$ <= to$; ++i$) { i = i$; for (j$ = 0, to1$ = columnCount - 1; j$ <= to1$; ++j$) { j = j$; lsg.objects.push({ type: 'text', size: boxSize - 35, text: String.fromCharCode(97 + j) + (i + 1), x: 17 + padding + j * boxSize + boxSize / 2, y: 32 + padding + i * boxSize, align: 'center', font: 'Source Sans Pro', color: 'red' }); } } } lsg.objects.push({ type: 'rect', 'class': 'wrong', w: width, h: height, x: padding, y: padding, color: 'transparent' }); if (solutions) { for (i$ = 0, to$ = solutions.length - 1; i$ <= to$; ++i$) { i = i$; sol = solutions[i].cells.split('-'); sol = _.map(sol, fn$); isVertical = sol[0][0] === sol[1][0]; letterPos0 = sol[0][0].charCodeAt(0) - 97; letterPos1 = sol[1][0].charCodeAt(0) - 97; if (isVertical) { lsg.objects.push({ type: 'rect', 'class': solutions[i]['class'], w: boxSize, h: (sol[1][1] - sol[0][1] + 1) * boxSize, x: letterPos0 * boxSize + padding, y: padding + (sol[0][1] - 1) * boxSize, color: o.showSolutions ? Color.green[500] : 'transparent', opacity: 0.5 }); } else { lsg.objects.push({ type: 'rect', 'class': solutions[i]['class'], h: boxSize, w: (letterPos1 - letterPos0 + 1) * boxSize, y: (sol[0][1] - 1) * boxSize + padding, x: letterPos0 * boxSize + padding, color: o.showSolutions ? Color.green[500] : 'transparent', opacity: 0.5 }); } } } return lsg; function fn$(s){ return [s[0], s.slice(1)]; } }; })();