From 73f82edd93cfe65ec8be9565fafca377d46710b7 Mon Sep 17 00:00:00 2001 From: Claude Date: Fri, 30 Oct 2026 23:42:45 +0000 Subject: [PATCH 1/3] Web 0.14.2: Profiwissen java -version, javac, java; Grafiken in L20 repariert MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Neuer Kasten ::: profiwissen („Profiwissen mit Ludwig“), in Lektion 20 für die Konsolenbefehle. Die beiden Grafiken in „Wie Java auf jedem Computer läuft“ waren nicht mit ::: geschlossen; neuer Test prüft das. Co-Authored-By: Claude Opus 5.5 Claude-Session: https://claude.ai/code/session_01Ugz28WToQoMzLJgvHWUb3d --- CHANGELOG.md | 1 + node_modules/.vite/vitest/CACHEDIR.TAG | 3 + .../results.json | 1 + .../2685641e1680de19f98fa880c880363e3d9a5647 | 164 +++++ .../2e7e8c86acce9951f2c7f1e10275b55254f40698 | 27 + .../671ba0efec37747e02cf77c4dec09a7b139242a6 | 136 ++++ .../92afb3df989d8c4b3fbf8e596cd079aed22718e6 | 418 +++++++++++++ node_modules/.vitest-cache/CACHEDIR.TAG | 3 + node_modules/.vitest-cache/_metadata.json | 3 + .../a24f3c2d2711027964cf8cac3e5bdea117013f42 | 587 ++++++++++++++++++ .../a2bc6900de05952e637aa8c1bf773176a1051346 | 86 +++ .../c9e09693ee8175a114f4dbe1e385c70c5582fca5 | 567 +++++++++++++++++ .../e482c53abeaa5899f7e393b26fde791e2b456b18 | 382 ++++++++++++ .../e8414e1454c9436819af0b8d69e3557e442d9777 | 200 ++++++ .../ead0aad5e88b12ac47bd410f9cc055bc1ed9a667 | 83 +++ web/lessons/README.md | 9 + web/lessons/de/20-java.md | 20 + web/lessons/en/20-java.md | 20 + web/lessons/pt/20-java.md | 20 + web/package-lock.json | 4 +- web/package.json | 2 +- web/src/i18n/ar.strings | 1 + web/src/i18n/da.strings | 1 + web/src/i18n/de.strings | 1 + web/src/i18n/el.strings | 1 + web/src/i18n/en.strings | 1 + web/src/i18n/es.strings | 1 + web/src/i18n/fr.strings | 1 + web/src/i18n/he.strings | 1 + web/src/i18n/it.strings | 1 + web/src/i18n/ja.strings | 1 + web/src/i18n/ko.strings | 1 + web/src/i18n/nb.strings | 1 + web/src/i18n/nl.strings | 1 + web/src/i18n/pl.strings | 1 + web/src/i18n/pt-PT.strings | 1 + web/src/i18n/ru.strings | 1 + web/src/i18n/sv.strings | 1 + web/src/i18n/tr.strings | 1 + web/src/i18n/uk.strings | 1 + web/src/i18n/zh-Hans.strings | 1 + web/src/i18n/zh-Hant.strings | 1 + web/src/learn/lessonFormat.ts | 5 +- web/src/ui/learnPanel.ts | 8 +- web/test/lessons.test.ts | 6 + .../assets/{ar-DeE-RHam.js => ar-Dqb2o0I-.js} | 1 + .../assets/{da-D4INXE4p.js => da-ey_ipgDe.js} | 1 + .../assets/{de-NQF_CaEx.js => de-DMor0Vtb.js} | 1 + .../assets/{el-CtIZyj0I.js => el-DaQv4rR_.js} | 1 + .../assets/{en-DysVTM-W.js => en-CEwI5dlH.js} | 1 + .../assets/{es-BAduFB3L.js => es-BHz7jCrz.js} | 1 + ...lowApp-DkiXDJDe.js => flowApp-4s69NVPv.js} | 4 +- .../assets/{fr-C_mSEvw5.js => fr-CEc9fFV7.js} | 1 + .../assets/{he-BAg3LrWK.js => he-B1FDwOEu.js} | 1 + .../{index-BVzzpk4y.js => index-DqKA7YqL.js} | 79 ++- .../assets/{it-ClGS2uQV.js => it-Bsr1AlWk.js} | 1 + .../assets/{ja-JQ8MwNFB.js => ja-L0a84IMq.js} | 1 + .../assets/{ko-tfdKG8Fb.js => ko-U6EDne8i.js} | 1 + .../assets/{nb-BpibUAkX.js => nb-C9pwk403.js} | 1 + .../assets/{nl-HArZjiga.js => nl-D1JTb8Xr.js} | 1 + ...tApp-ZNEjA-0f.js => objectApp-exr4obxz.js} | 8 +- .../assets/{pl-C3HmQqUD.js => pl-DchXCt_R.js} | 1 + ...Zip-DEvwTDaN.js => projectZip-Dv_LmKlY.js} | 2 +- .../{pt-PT-2W9Vff48.js => pt-PT-Dq8KVIrs.js} | 1 + ...obot3d-B1TGngW1.js => robot3d-I0g91EHr.js} | 2 +- .../assets/{ru-B4vTuE57.js => ru-DGHs_3oc.js} | 1 + .../assets/{sv-Dau75zUV.js => sv-zO9ikvt0.js} | 1 + .../assets/{tr-DrZsTe-O.js => tr-zv5TxQHQ.js} | 1 + .../assets/{uk-DQrOpK2W.js => uk-D5KOtCBD.js} | 1 + ...h-Hans-CeIYjS3N.js => zh-Hans-C3na1U20.js} | 1 + ...h-Hant-7-ScZHAu.js => zh-Hant-BLjr78US.js} | 1 + website/app/index.html | 2 +- 72 files changed, 2868 insertions(+), 26 deletions(-) create mode 100644 node_modules/.vite/vitest/CACHEDIR.TAG create mode 100644 node_modules/.vite/vitest/da39a3ee5e6b4b0d3255bfef95601890afd80709/results.json create mode 100644 node_modules/.vitest-cache/2685641e1680de19f98fa880c880363e3d9a5647 create mode 100644 node_modules/.vitest-cache/2e7e8c86acce9951f2c7f1e10275b55254f40698 create mode 100644 node_modules/.vitest-cache/671ba0efec37747e02cf77c4dec09a7b139242a6 create mode 100644 node_modules/.vitest-cache/92afb3df989d8c4b3fbf8e596cd079aed22718e6 create mode 100644 node_modules/.vitest-cache/CACHEDIR.TAG create mode 100644 node_modules/.vitest-cache/_metadata.json create mode 100644 node_modules/.vitest-cache/a24f3c2d2711027964cf8cac3e5bdea117013f42 create mode 100644 node_modules/.vitest-cache/a2bc6900de05952e637aa8c1bf773176a1051346 create mode 100644 node_modules/.vitest-cache/c9e09693ee8175a114f4dbe1e385c70c5582fca5 create mode 100644 node_modules/.vitest-cache/e482c53abeaa5899f7e393b26fde791e2b456b18 create mode 100644 node_modules/.vitest-cache/e8414e1454c9436819af0b8d69e3557e442d9777 create mode 100644 node_modules/.vitest-cache/ead0aad5e88b12ac47bd410f9cc055bc1ed9a667 rename website/app/assets/{ar-DeE-RHam.js => ar-Dqb2o0I-.js} (99%) rename website/app/assets/{da-D4INXE4p.js => da-ey_ipgDe.js} (99%) rename website/app/assets/{de-NQF_CaEx.js => de-DMor0Vtb.js} (99%) rename website/app/assets/{el-CtIZyj0I.js => el-DaQv4rR_.js} (99%) rename website/app/assets/{en-DysVTM-W.js => en-CEwI5dlH.js} (99%) rename website/app/assets/{es-BAduFB3L.js => es-BHz7jCrz.js} (99%) rename website/app/assets/{flowApp-DkiXDJDe.js => flowApp-4s69NVPv.js} (99%) rename website/app/assets/{fr-C_mSEvw5.js => fr-CEc9fFV7.js} (99%) rename website/app/assets/{he-BAg3LrWK.js => he-B1FDwOEu.js} (99%) rename website/app/assets/{index-BVzzpk4y.js => index-DqKA7YqL.js} (99%) rename website/app/assets/{it-ClGS2uQV.js => it-Bsr1AlWk.js} (99%) rename website/app/assets/{ja-JQ8MwNFB.js => ja-L0a84IMq.js} (99%) rename website/app/assets/{ko-tfdKG8Fb.js => ko-U6EDne8i.js} (99%) rename website/app/assets/{nb-BpibUAkX.js => nb-C9pwk403.js} (99%) rename website/app/assets/{nl-HArZjiga.js => nl-D1JTb8Xr.js} (99%) rename website/app/assets/{objectApp-ZNEjA-0f.js => objectApp-exr4obxz.js} (99%) rename website/app/assets/{pl-C3HmQqUD.js => pl-DchXCt_R.js} (99%) rename website/app/assets/{projectZip-DEvwTDaN.js => projectZip-Dv_LmKlY.js} (99%) rename website/app/assets/{pt-PT-2W9Vff48.js => pt-PT-Dq8KVIrs.js} (99%) rename website/app/assets/{robot3d-B1TGngW1.js => robot3d-I0g91EHr.js} (99%) rename website/app/assets/{ru-B4vTuE57.js => ru-DGHs_3oc.js} (99%) rename website/app/assets/{sv-Dau75zUV.js => sv-zO9ikvt0.js} (99%) rename website/app/assets/{tr-DrZsTe-O.js => tr-zv5TxQHQ.js} (99%) rename website/app/assets/{uk-DQrOpK2W.js => uk-D5KOtCBD.js} (99%) rename website/app/assets/{zh-Hans-CeIYjS3N.js => zh-Hans-C3na1U20.js} (99%) rename website/app/assets/{zh-Hant-7-ScZHAu.js => zh-Hant-BLjr78US.js} (99%) diff --git a/CHANGELOG.md b/CHANGELOG.md index 6a64f296..69f8af96 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -15,6 +15,7 @@ The format is loosely inspired by Keep a Changelog. ### Added +- **Web 0.14.2, Profiwissen: Java in the console:** new box `::: profiwissen` („Profiwissen mit Ludwig“, looks like the Angeberwissen box, new string web_learn_pro in all 21 languages). Lesson 20 step „Wie Java auf jedem Computer läuft“ uses it for `java -version`, `javac Einmaleins.java` and `java Einmaleins`, plus the hint that a missing `javac -version` means only a JRE is installed (de/en/pt). Fix: the two diagrams in that step were missing their closing `:::`, so in 0.14.1 the text after the first diagram showed up as its caption; they now have short captions, and a new test flags overly long captions. - **Web 0.14.1, how Java runs on every computer:** lesson 20 has a new step „Wie Java auf jedem Computer läuft“ after „Snippet oder Class“: source code → compiler `javac` → bytecode (`.class`) → JVM on Windows/macOS/Linux, platform independence („Write once, run anywhere“), the JVM pictured as a small computer made of software (but a virtual machine, not an operating system), a table JRE vs. JDK, the JVM translating bytecode into machine code (JIT compiler), and a comparison with C++ (compiled directly to machine code, so once per system; second diagram l20-cpp.svg and a C++/Java table). New self-drawn diagram l20-jvm.svg (de/en/pt), the CAFEBABE Angeberwissen moved into the new step, three competences, three checklist lines and three quiz questions. Lesson 4 „Jetzt in Java“ points to lesson 20. New glossary entries Quellcode, Compiler, Bytecode, Maschinencode, JIT-Compiler, JVM, JRE, JDK, plattformunabhängig and Nachschlagen section „Java › Vom Code zum Programm“ (de/en/pt). - **Web 0.14.0, new world VisuFlow: draw flowcharts:** fourth world next to VisuStruct, VisuBot and VisuObject (…/app/?visuflow, colour violet, chosen at the start or in the gear menu; the world chooser now has two rows). Only drawing, no simulation and no code: drag the DIN 66001 symbols (Start, Anweisung, Ein-/Ausgabe, Verzweigung, Unterprogramm, Ende) from the bar onto the canvas, or tap a symbol to add it below the selected one, joined by an arrow; type the text right in the symbol (tap again or double click to change it). Drag an arrow from the dot at an exit to the next symbol; the diamond has the exits ja and nein (button „ja/nein tauschen“ swaps their sides), arrows run at right angles, loops go around on the right. Move with the mouse, finger or arrow keys on a 20 px grid, delete, undo/redo, title above the canvas, example „Tee kochen“ from lesson 1. Save and open as `.visuflow` file (the last plan stays in the browser), export as PNG, SVG or PDF (A4). Texts de/en/pt. - **Web 0.13.38, comments in Java:** lesson 6 has a new step „Kommentare im Code“ after „Jetzt in Java“: single-line `//` and multi-line `/* … */` comments, Java skips them and the structure chart stays the same; Javadoc `/** … */` is only mentioned. The IPO example (with „Im Editor öffnen“) shows the task in a multi-line comment, `// Eingabe`, `// Verarbeitung`, `// Ausgabe`, an explanation after a line, the expected output and a note for next time; plus a fill-in-the-gaps exercise, an Angeberwissen (PL/I 1964, BCPL 1967), a competence, a checklist line and two quiz questions. Lesson 14 marks closing brackets with `} // Ende if` / `} // Ende for`, lesson 20 the class frame with `} // Ende main` / `} // Ende Klasse`. New glossary entry Kommentar and Nachschlagen section „Java › Kommentare“ (de/en/pt). diff --git a/node_modules/.vite/vitest/CACHEDIR.TAG b/node_modules/.vite/vitest/CACHEDIR.TAG new file mode 100644 index 00000000..8c1ef4ce --- /dev/null +++ b/node_modules/.vite/vitest/CACHEDIR.TAG @@ -0,0 +1,3 @@ +Signature: 8a477f597d28d172789f06886806bc55 +# This file is a cache directory tag created by Vitest. +# For information about cache directory tags see https://bford.info/cachedir/ diff --git a/node_modules/.vite/vitest/da39a3ee5e6b4b0d3255bfef95601890afd80709/results.json b/node_modules/.vite/vitest/da39a3ee5e6b4b0d3255bfef95601890afd80709/results.json new file mode 100644 index 00000000..f75bae95 --- /dev/null +++ b/node_modules/.vite/vitest/da39a3ee5e6b4b0d3255bfef95601890afd80709/results.json @@ -0,0 +1 @@ +{"version":1,"projects":{"":{"files":{"web/test/zz_tmp.test.ts":{"failed":true,"duration":5.370806999999957,"lastRun":1793403670389}}}}} \ No newline at end of file diff --git a/node_modules/.vitest-cache/2685641e1680de19f98fa880c880363e3d9a5647 b/node_modules/.vitest-cache/2685641e1680de19f98fa880c880363e3d9a5647 new file mode 100644 index 00000000..2a3493a8 --- /dev/null +++ b/node_modules/.vitest-cache/2685641e1680de19f98fa880c880363e3d9a5647 @@ -0,0 +1,164 @@ +__vite_ssr_exportName__("RescueGameError", () => { try { return RescueGameError } catch {} }); +__vite_ssr_exportName__("gatePlaceholder", () => { try { return gatePlaceholder } catch {} }); +__vite_ssr_exportName__("crosswordGrid", () => { try { return crosswordGrid } catch {} }); +__vite_ssr_exportName__("parseRescueGame", () => { try { return parseRescueGame } catch {} }); +class RescueGameError extends Error {}; +const gatePlaceholder = "___"; +/** Das Rätsel als Gitter: `grid[zeile][spalte]` ist der Buchstabe oder `''`. */ +function crosswordGrid(game) { + const grid = Array.from({ length: game.rows }, () => Array(game.cols).fill("")); + for (const w of game.words) [...w.word].forEach((c, k) => grid[w.row + (w.across ? 0 : k)][w.col + (w.across ? k : 0)] = c); + return grid; +}; +function parseRescueGame(lines, file) { + const fail = (msg) => { + throw new RescueGameError(`${file}: ${msg}`); + }; + const cell = (text, where) => { + const m = /^(\d+)\s+(\d+)$/.exec(text.trim()); + if (!m || Number(m[1]) < 1 || Number(m[2]) < 1) return fail(`${where}: „${text}“ ist kein Feld (Zeile Spalte, ab 1).`); + return { + row: Number(m[1]) - 1, + col: Number(m[2]) - 1 + }; + }; + let title = ""; + let intro = ""; + let alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"; + let crosswordText = ""; + let gateText = ""; + let gateCode = ""; + let end = ""; + const stations = []; + const raw = []; + let solution = []; + /** Wohin eingerückte Zeilen gehören. */ + let codeTarget; + let section = "start"; + for (const line of lines) { + const text = line.trim(); + if (codeTarget && (/^( {4}|\t)/.test(line) || text === "")) { + const code = line.replace(/^( {4}|\t)/, ""); + if (codeTarget === "station") { + const s = stations[stations.length - 1]; + s.code += (s.code ? "\n" : "") + code; + } else gateCode += (gateCode ? "\n" : "") + code; + continue; + }; + codeTarget = undefined; + if (!text) continue; + const key = /^(titel|intro|alphabet|station|frage|zahl|feld|tipp|kreuzwort|lösung|loesung|tor|ende):\s*(.*)$/.exec(text); + if (key) { + const [, name, value] = key; + if (name === "station") { + stations.push({ + name: value, + code: "", + question: "", + hint: "", + explanation: "" + }); + section = "station"; + codeTarget = "station"; + } else if (name === "kreuzwort") { + crosswordText = value; + section = "crossword"; + } else if (name === "tor") { + gateText = value; + section = "gate"; + codeTarget = "gate"; + } else if (name === "titel") title = value; + else if (name === "intro") intro = value; + else if (name === "alphabet") alphabet = value; + else if (name === "ende") end = value; + else if (name === "lösung" || name === "loesung") { + if (section !== "crossword") fail("„lösung:“ gehört zum Kreuzworträtsel."); + solution = value.split(",").map((c) => cell(c, "lösung")); + } else { + if (section !== "station") fail(`„${name}:“ gehört in eine Station.`); + const s = stations[stations.length - 1]; + if (name === "frage") s.question = value; + else if (name === "tipp") s.hint = value; + else if (name === "zahl") s.answer = /^-?\d+$/.test(value) ? Number(value) : fail(`Station „${s.name}“: „zahl:“ muss eine ganze Zahl sein.`); + else Object.assign(s, cell(value, `Station „${s.name}“`)); + }; + continue; + }; + if (section === "crossword") { + const m = /^-\s+([→↓])\s+(\d+)\s+(\d+)\s+([A-ZÄÖÜ]+):\s*(.+)$/u.exec(text); + if (!m) fail(`Kreuzworträtsel: „${text}“ verstehe ich nicht (z. B. „- → 1 3 STRING: Hinweis“).`); + raw.push({ + across: m[1] === "→", + row: Number(m[2]) - 1, + col: Number(m[3]) - 1, + word: m[4], + clue: m[5] + }); + continue; + }; + if (section === "station" && text.startsWith(">")) { + const s = stations[stations.length - 1]; + s.explanation += (s.explanation ? " " : "") + text.slice(1).trim(); + continue; + }; + fail(`Unbekannte Zeile im Spiel: „${text}“`); + }; + if (!title) fail("Das Spiel braucht eine Zeile „titel:“."); + if (!stations.length) fail("Das Spiel braucht mindestens eine „station:“."); + if (!raw.length) fail("Das Spiel braucht ein „kreuzwort:“ mit Wörtern."); + if (!solution.length) fail("Das Kreuzworträtsel braucht eine Zeile „lösung:“."); + if (!gateCode.includes(gatePlaceholder)) fail(`Der Code bei „tor:“ braucht ${gatePlaceholder} für das Eingabefeld.`); + if (new Set(alphabet).size !== alphabet.length) fail("Im Alphabet kommt ein Zeichen doppelt vor."); + // Wörter ins Gitter legen: Kreuzungen müssen passen. + const rows = Math.max(...raw.map((w) => w.row + (w.across ? 1 : w.word.length))); + const cols = Math.max(...raw.map((w) => w.col + (w.across ? w.word.length : 1))); + const grid = Array.from({ length: rows }, () => Array(cols).fill("")); + for (const w of raw) { + ; + [...w.word].forEach((c, k) => { + const r = w.row + (w.across ? 0 : k); + const col = w.col + (w.across ? k : 0); + if (grid[r][col] && grid[r][col] !== c) fail(`Kreuzworträtsel: ${w.word} passt in Zeile ${r + 1}, Spalte ${col + 1} nicht (dort steht ${grid[r][col]}).`); + grid[r][col] = c; + }); + }; + // Nummern wie in der Zeitung: von oben nach unten, links nach rechts; zwei Wörter im selben Feld teilen sich eine. + const starts = [...new Set(raw.map((w) => w.row * cols + w.col))].sort((a, b) => a - b); + const words = raw.map((w) => ({ + ...w, + number: starts.indexOf(w.row * cols + w.col) + 1 + })); + const letterAt = (r, c) => grid[r]?.[c] ?? ""; + const keyword = solution.map(({ row, col }) => letterAt(row, col) || fail(`lösung: In Zeile ${row + 1}, Spalte ${col + 1} ist kein Feld.`)).join(""); + const checked = stations.map((s) => { + if (!s.code) fail(`Station „${s.name}“: Code fehlt.`); + if (!s.question) fail(`Station „${s.name}“: „frage:“ fehlt.`); + if (s.answer === undefined) fail(`Station „${s.name}“: „zahl:“ fehlt.`); + if (s.row === undefined) fail(`Station „${s.name}“: „feld:“ fehlt.`); + const letter = alphabet.charAt(s.answer); + if (!letter) fail(`Station „${s.name}“: alphabet.charAt(${s.answer}) gibt es nicht.`); + const target = letterAt(s.row, s.col); + if (target !== letter) fail(`Station „${s.name}“: alphabet.charAt(${s.answer}) ist ${letter}, im Feld ${s.row + 1} ${s.col + 1} steht aber „${target}“.`); + s.code = s.code.replace(/\n+$/, ""); + return s; + }); + return { + title, + intro, + alphabet, + stations: checked, + crosswordText, + rows, + cols, + words, + solution, + keyword, + gateText, + gateCode: gateCode.replace(/\n+$/, ""), + end + }; +} +//# sourceMappingSource=vite-generated +//# sourceMappingURL=data:application/json;base64,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c2N1ZUdhbWUudHMiXSwic291cmNlc0NvbnRlbnQiOlsiLyoqXG4gKiBTcGllbCDigJ5QcmluemVzc2luIHJldHRlbuKAnCAoQmxvY2sgYDo6OiBzcGllbCBwcmluemVzc2luYCk6IEFuIGplZGVyIFN0YXRpb24ga29tbXQgZWluZSBaYWhsIGhlcmF1cyxcbiAqIGBhbHBoYWJldC5jaGFyQXQoemFobClgIG1hY2h0IGRhcmF1cyBlaW5lbiBCdWNoc3RhYmVuLCBkZXIgZWluIEZlbGQgaW0gS3JldXp3b3J0csOkdHNlbCBmw7xsbHQuIERpZSBtYXJraWVydGVuXG4gKiBGZWxkZXIgZGVzIFLDpHRzZWxzIGVyZ2ViZW4gZGFzIGdlaGVpbWUgV29ydCwgZGFzIGFtIEVuZGUgZGFzIFRvciDDtmZmbmV0LlxuICpcbiAqIEZvcm1hdCAoU2NobMO8c3NlbHfDtnJ0ZXIgYXVmIERldXRzY2gsIGF1Y2ggaW4gZGVuIMOcYmVyc2V0enVuZ2VuKTpcbiAqXG4gKiAgICAgdGl0ZWw6IFNwaWVsOiBQcmluemVzc2luIHJldHRlblxuICogICAgIGludHJvOiBEZXIgRnVjaHMgaGF0IOKAplxuICogICAgIGFscGhhYmV0OiBBQkNERUZHSElKS0xNTk9QUVJTVFVWV1hZWiAgICAob2huZSBBbmdhYmUgQSBiaXMgWilcbiAqXG4gKiAgICAgc3RhdGlvbjogQW0gQnVyZ2dyYWJlbiAgICAgICAgICAgICAgICAgICAgKE5hbWUgZGVyIFN0YXRpb24pXG4gKiAgICAgICAgIFN0cmluZyBuYW1lID0gXCIgICBab3JhICAgXCI7ICAgICAgICAgIChDb2RlLCBtaXQgdmllciBMZWVyemVpY2hlbiBlaW5nZXLDvGNrdClcbiAqICAgICBmcmFnZTogV2VsY2hlIFphaGwgc3RlaHQgaW4gYHphaGxgP1xuICogICAgIHphaGw6IDRcbiAqICAgICBmZWxkOiA1IDEgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIChaZWlsZSB1bmQgU3BhbHRlIGltIFLDpHRzZWwsIGFiIDEpXG4gKiAgICAgdGlwcDog4oCmICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIChuYWNoIGVpbmVyIGZhbHNjaGVuIEFudHdvcnQpXG4gKiAgICAgPiBFcmtsw6RydW5nXG4gKlxuICogICAgIGtyZXV6d29ydDogTMO2c2UgZGFzIFLDpHRzZWwg4oCmICAgICAgICAgICAgIChUZXh0IMO8YmVyIGRlbSBSw6R0c2VsKVxuICogICAgIC0g4oaSIDEgMyBCT09MRUFOOiBEYXRlbnR5cCBmw7xyIHdhaHIgb2RlciBmYWxzY2ggICAgICjihpIgd2FhZ3JlY2h0LCDihpMgc2Vua3JlY2h0LCBaZWlsZSwgU3BhbHRlKVxuICogICAgIGzDtnN1bmc6IDEgMywgNCAzICAgICAgICAgICAgICAgICAgICAgICAgIChGZWxkZXIgZGVzIGdlaGVpbWVuIFdvcnRzIGluIHNlaW5lciBSZWloZW5mb2xnZSlcbiAqXG4gKiAgICAgdG9yOiBWb3IgZGlyIGlzdCBkYXMgVG9yIOKApiAgICAgICAgICAgICAgIChUZXh0IHZvciBkZW0gU2NobG9zcylcbiAqICAgICAgICAgaWYgKGVpbmdhYmUuZXF1YWxzKFwiPz8/XCIpKSB7ICAgICAgICAgKENvZGUsIF9fXyB3aXJkIHp1bSBFaW5nYWJlZmVsZClcbiAqICAgICBlbmRlOiBab3JhIGlzdCBmcmVpIVxuICovXG5cbmV4cG9ydCBpbnRlcmZhY2UgUmVzY3VlU3RhdGlvbiB7XG4gIG5hbWU6IHN0cmluZ1xuICBjb2RlOiBzdHJpbmdcbiAgcXVlc3Rpb246IHN0cmluZ1xuICBhbnN3ZXI6IG51bWJlclxuICAvKiogRmVsZCBpbSBSw6R0c2VsIChhYiAwKS4gKi9cbiAgcm93OiBudW1iZXJcbiAgY29sOiBudW1iZXJcbiAgaGludDogc3RyaW5nXG4gIGV4cGxhbmF0aW9uOiBzdHJpbmdcbn1cblxuZXhwb3J0IGludGVyZmFjZSBDcm9zc3dvcmRXb3JkIHtcbiAgLyoqIE51bW1lciBpbSBSw6R0c2VsLCB3aWUgc2llIGltIEZlbGQgc3RlaHQuICovXG4gIG51bWJlcjogbnVtYmVyXG4gIGFjcm9zczogYm9vbGVhblxuICByb3c6IG51bWJlclxuICBjb2w6IG51bWJlclxuICB3b3JkOiBzdHJpbmdcbiAgY2x1ZTogc3RyaW5nXG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgUmVzY3VlR2FtZSB7XG4gIHRpdGxlOiBzdHJpbmdcbiAgaW50cm86IHN0cmluZ1xuICBhbHBoYWJldDogc3RyaW5nXG4gIHN0YXRpb25zOiBSZXNjdWVTdGF0aW9uW11cbiAgY3Jvc3N3b3JkVGV4dDogc3RyaW5nXG4gIHJvd3M6IG51bWJlclxuICBjb2xzOiBudW1iZXJcbiAgd29yZHM6IENyb3Nzd29yZFdvcmRbXVxuICAvKiogRmVsZGVyIGRlcyBnZWhlaW1lbiBXb3J0cyAoYWIgMCkuICovXG4gIHNvbHV0aW9uOiB7IHJvdzogbnVtYmVyOyBjb2w6IG51bWJlciB9W11cbiAga2V5d29yZDogc3RyaW5nXG4gIGdhdGVUZXh0OiBzdHJpbmdcbiAgZ2F0ZUNvZGU6IHN0cmluZ1xuICBlbmQ6IHN0cmluZ1xufVxuXG5leHBvcnQgY2xhc3MgUmVzY3VlR2FtZUVycm9yIGV4dGVuZHMgRXJyb3Ige31cblxuZXhwb3J0IGNvbnN0IGdhdGVQbGFjZWhvbGRlciA9ICdfX18nXG5cbi8qKiBEYXMgUsOkdHNlbCBhbHMgR2l0dGVyOiBgZ3JpZFt6ZWlsZV1bc3BhbHRlXWAgaXN0IGRlciBCdWNoc3RhYmUgb2RlciBgJydgLiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGNyb3Nzd29yZEdyaWQoZ2FtZTogUGljazxSZXNjdWVHYW1lLCAncm93cycgfCAnY29scycgfCAnd29yZHMnPik6IHN0cmluZ1tdW10ge1xuICBjb25zdCBncmlkID0gQXJyYXkuZnJvbSh7IGxlbmd0aDogZ2FtZS5yb3dzIH0sICgpID0+IEFycmF5PHN0cmluZz4oZ2FtZS5jb2xzKS5maWxsKCcnKSlcbiAgZm9yIChjb25zdCB3IG9mIGdhbWUud29yZHMpIFsuLi53LndvcmRdLmZvckVhY2goKGMsIGspID0+IChncmlkW3cucm93ICsgKHcuYWNyb3NzID8gMCA6IGspXVt3LmNvbCArICh3LmFjcm9zcyA/IGsgOiAwKV0gPSBjKSlcbiAgcmV0dXJuIGdyaWRcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIHBhcnNlUmVzY3VlR2FtZShsaW5lczogc3RyaW5nW10sIGZpbGU6IHN0cmluZyk6IFJlc2N1ZUdhbWUge1xuICBjb25zdCBmYWlsID0gKG1zZzogc3RyaW5nKTogbmV2ZXIgPT4ge1xuICAgIHRocm93IG5ldyBSZXNjdWVHYW1lRXJyb3IoYCR7ZmlsZX06ICR7bXNnfWApXG4gIH1cbiAgY29uc3QgY2VsbCA9ICh0ZXh0OiBzdHJpbmcsIHdoZXJlOiBzdHJpbmcpID0+IHtcbiAgICBjb25zdCBtID0gL14oXFxkKylcXHMrKFxcZCspJC8uZXhlYyh0ZXh0LnRyaW0oKSlcbiAgICBpZiAoIW0gfHwgTnVtYmVyKG1bMV0pIDwgMSB8fCBOdW1iZXIobVsyXSkgPCAxKSByZXR1cm4gZmFpbChgJHt3aGVyZX06IOKAniR7dGV4dH3igJwgaXN0IGtlaW4gRmVsZCAoWmVpbGUgU3BhbHRlLCBhYiAxKS5gKVxuICAgIHJldHVybiB7IHJvdzogTnVtYmVyKG1bMV0pIC0gMSwgY29sOiBOdW1iZXIobVsyXSkgLSAxIH1cbiAgfVxuICBsZXQgdGl0bGUgPSAnJ1xuICBsZXQgaW50cm8gPSAnJ1xuICBsZXQgYWxwaGFiZXQgPSAnQUJDREVGR0hJSktMTU5PUFFSU1RVVldYWVonXG4gIGxldCBjcm9zc3dvcmRUZXh0ID0gJydcbiAgbGV0IGdhdGVUZXh0ID0gJydcbiAgbGV0IGdhdGVDb2RlID0gJydcbiAgbGV0IGVuZCA9ICcnXG4gIGNvbnN0IHN0YXRpb25zOiAoT21pdDxSZXNjdWVTdGF0aW9uLCAnYW5zd2VyJyB8ICdyb3cnIHwgJ2NvbCc+ICYgeyBhbnN3ZXI/OiBudW1iZXI7IHJvdz86IG51bWJlcjsgY29sPzogbnVtYmVyIH0pW10gPSBbXVxuICBjb25zdCByYXc6IHsgYWNyb3NzOiBib29sZWFuOyByb3c6IG51bWJlcjsgY29sOiBudW1iZXI7IHdvcmQ6IHN0cmluZzsgY2x1ZTogc3RyaW5nIH1bXSA9IFtdXG4gIGxldCBzb2x1dGlvbjogeyByb3c6IG51bWJlcjsgY29sOiBudW1iZXIgfVtdID0gW11cbiAgLyoqIFdvaGluIGVpbmdlcsO8Y2t0ZSBaZWlsZW4gZ2Vow7ZyZW4uICovXG4gIGxldCBjb2RlVGFyZ2V0OiAnc3RhdGlvbicgfCAnZ2F0ZScgfCB1bmRlZmluZWRcbiAgbGV0IHNlY3Rpb246ICdzdGFydCcgfCAnc3RhdGlvbicgfCAnY3Jvc3N3b3JkJyB8ICdnYXRlJyA9ICdzdGFydCdcbiAgZm9yIChjb25zdCBsaW5lIG9mIGxpbmVzKSB7XG4gICAgY29uc3QgdGV4dCA9IGxpbmUudHJpbSgpXG4gICAgaWYgKGNvZGVUYXJnZXQgJiYgKC9eKCB7NH18XFx0KS8udGVzdChsaW5lKSB8fCB0ZXh0ID09PSAnJykpIHtcbiAgICAgIGNvbnN0IGNvZGUgPSBsaW5lLnJlcGxhY2UoL14oIHs0fXxcXHQpLywgJycpXG4gICAgICBpZiAoY29kZVRhcmdldCA9PT0gJ3N0YXRpb24nKSB7XG4gICAgICAgIGNvbnN0IHMgPSBzdGF0aW9uc1tzdGF0aW9ucy5sZW5ndGggLSAxXVxuICAgICAgICBzLmNvZGUgKz0gKHMuY29kZSA/ICdcXG4nIDogJycpICsgY29kZVxuICAgICAgfSBlbHNlIGdhdGVDb2RlICs9IChnYXRlQ29kZSA/ICdcXG4nIDogJycpICsgY29kZVxuICAgICAgY29udGludWVcbiAgICB9XG4gICAgY29kZVRhcmdldCA9IHVuZGVmaW5lZFxuICAgIGlmICghdGV4dCkgY29udGludWVcbiAgICBjb25zdCBrZXkgPSAvXih0aXRlbHxpbnRyb3xhbHBoYWJldHxzdGF0aW9ufGZyYWdlfHphaGx8ZmVsZHx0aXBwfGtyZXV6d29ydHxsw7ZzdW5nfGxvZXN1bmd8dG9yfGVuZGUpOlxccyooLiopJC8uZXhlYyh0ZXh0KVxuICAgIGlmIChrZXkpIHtcbiAgICAgIGNvbnN0IFssIG5hbWUsIHZhbHVlXSA9IGtleVxuICAgICAgaWYgKG5hbWUgPT09ICdzdGF0aW9uJykge1xuICAgICAgICBzdGF0aW9ucy5wdXNoKHsgbmFtZTogdmFsdWUsIGNvZGU6ICcnLCBxdWVzdGlvbjogJycsIGhpbnQ6ICcnLCBleHBsYW5hdGlvbjogJycgfSlcbiAgICAgICAgc2VjdGlvbiA9ICdzdGF0aW9uJ1xuICAgICAgICBjb2RlVGFyZ2V0ID0gJ3N0YXRpb24nXG4gICAgICB9IGVsc2UgaWYgKG5hbWUgPT09ICdrcmV1endvcnQnKSB7XG4gICAgICAgIGNyb3Nzd29yZFRleHQgPSB2YWx1ZVxuICAgICAgICBzZWN0aW9uID0gJ2Nyb3Nzd29yZCdcbiAgICAgIH0gZWxzZSBpZiAobmFtZSA9PT0gJ3RvcicpIHtcbiAgICAgICAgZ2F0ZVRleHQgPSB2YWx1ZVxuICAgICAgICBzZWN0aW9uID0gJ2dhdGUnXG4gICAgICAgIGNvZGVUYXJnZXQgPSAnZ2F0ZSdcbiAgICAgIH0gZWxzZSBpZiAobmFtZSA9PT0gJ3RpdGVsJykgdGl0bGUgPSB2YWx1ZVxuICAgICAgZWxzZSBpZiAobmFtZSA9PT0gJ2ludHJvJykgaW50cm8gPSB2YWx1ZVxuICAgICAgZWxzZSBpZiAobmFtZSA9PT0gJ2FscGhhYmV0JykgYWxwaGFiZXQgPSB2YWx1ZVxuICAgICAgZWxzZSBpZiAobmFtZSA9PT0gJ2VuZGUnKSBlbmQgPSB2YWx1ZVxuICAgICAgZWxzZSBpZiAobmFtZSA9PT0gJ2zDtnN1bmcnIHx8IG5hbWUgPT09ICdsb2VzdW5nJykge1xuICAgICAgICBpZiAoc2VjdGlvbiAhPT0gJ2Nyb3Nzd29yZCcpIGZhaWwoJ+KAnmzDtnN1bmc64oCcIGdlaMO2cnQgenVtIEtyZXV6d29ydHLDpHRzZWwuJylcbiAgICAgICAgc29sdXRpb24gPSB2YWx1ZS5zcGxpdCgnLCcpLm1hcCgoYykgPT4gY2VsbChjLCAnbMO2c3VuZycpKVxuICAgICAgfSBlbHNlIHtcbiAgICAgICAgaWYgKHNlY3Rpb24gIT09ICdzdGF0aW9uJykgZmFpbChg4oCeJHtuYW1lfTrigJwgZ2Vow7ZydCBpbiBlaW5lIFN0YXRpb24uYClcbiAgICAgICAgY29uc3QgcyA9IHN0YXRpb25zW3N0YXRpb25zLmxlbmd0aCAtIDFdXG4gICAgICAgIGlmIChuYW1lID09PSAnZnJhZ2UnKSBzLnF1ZXN0aW9uID0gdmFsdWVcbiAgICAgICAgZWxzZSBpZiAobmFtZSA9PT0gJ3RpcHAnKSBzLmhpbnQgPSB2YWx1ZVxuICAgICAgICBlbHNlIGlmIChuYW1lID09PSAnemFobCcpIHMuYW5zd2VyID0gL14tP1xcZCskLy50ZXN0KHZhbHVlKSA/IE51bWJlcih2YWx1ZSkgOiBmYWlsKGBTdGF0aW9uIOKAniR7cy5uYW1lfeKAnDog4oCeemFobDrigJwgbXVzcyBlaW5lIGdhbnplIFphaGwgc2Vpbi5gKVxuICAgICAgICBlbHNlIE9iamVjdC5hc3NpZ24ocywgY2VsbCh2YWx1ZSwgYFN0YXRpb24g4oCeJHtzLm5hbWV94oCcYCkpXG4gICAgICB9XG4gICAgICBjb250aW51ZVxuICAgIH1cbiAgICBpZiAoc2VjdGlvbiA9PT0gJ2Nyb3Nzd29yZCcpIHtcbiAgICAgIGNvbnN0IG0gPSAvXi1cXHMrKFvihpLihpNdKVxccysoXFxkKylcXHMrKFxcZCspXFxzKyhbQS1aw4TDlsOcXSspOlxccyooLispJC91LmV4ZWModGV4dClcbiAgICAgIGlmICghbSkgZmFpbChgS3JldXp3b3J0csOkdHNlbDog4oCeJHt0ZXh0feKAnCB2ZXJzdGVoZSBpY2ggbmljaHQgKHouIEIuIOKAni0g4oaSIDEgMyBTVFJJTkc6IEhpbndlaXPigJwpLmApXG4gICAgICByYXcucHVzaCh7IGFjcm9zczogbSFbMV0gPT09ICfihpInLCByb3c6IE51bWJlcihtIVsyXSkgLSAxLCBjb2w6IE51bWJlcihtIVszXSkgLSAxLCB3b3JkOiBtIVs0XSwgY2x1ZTogbSFbNV0gfSlcbiAgICAgIGNvbnRpbnVlXG4gICAgfVxuICAgIGlmIChzZWN0aW9uID09PSAnc3RhdGlvbicgJiYgdGV4dC5zdGFydHNXaXRoKCc+JykpIHtcbiAgICAgIGNvbnN0IHMgPSBzdGF0aW9uc1tzdGF0aW9ucy5sZW5ndGggLSAxXVxuICAgICAgcy5leHBsYW5hdGlvbiArPSAocy5leHBsYW5hdGlvbiA/ICcgJyA6ICcnKSArIHRleHQuc2xpY2UoMSkudHJpbSgpXG4gICAgICBjb250aW51ZVxuICAgIH1cbiAgICBmYWlsKGBVbmJla2FubnRlIFplaWxlIGltIFNwaWVsOiDigJ4ke3RleHR94oCcYClcbiAgfVxuXG4gIGlmICghdGl0bGUpIGZhaWwoJ0RhcyBTcGllbCBicmF1Y2h0IGVpbmUgWmVpbGUg4oCedGl0ZWw64oCcLicpXG4gIGlmICghc3RhdGlvbnMubGVuZ3RoKSBmYWlsKCdEYXMgU3BpZWwgYnJhdWNodCBtaW5kZXN0ZW5zIGVpbmUg4oCec3RhdGlvbjrigJwuJylcbiAgaWYgKCFyYXcubGVuZ3RoKSBmYWlsKCdEYXMgU3BpZWwgYnJhdWNodCBlaW4g4oCea3JldXp3b3J0OuKAnCBtaXQgV8O2cnRlcm4uJylcbiAgaWYgKCFzb2x1dGlvbi5sZW5ndGgpIGZhaWwoJ0RhcyBLcmV1endvcnRyw6R0c2VsIGJyYXVjaHQgZWluZSBaZWlsZSDigJ5sw7ZzdW5nOuKAnC4nKVxuICBpZiAoIWdhdGVDb2RlLmluY2x1ZGVzKGdhdGVQbGFjZWhvbGRlcikpIGZhaWwoYERlciBDb2RlIGJlaSDigJ50b3I64oCcIGJyYXVjaHQgJHtnYXRlUGxhY2Vob2xkZXJ9IGbDvHIgZGFzIEVpbmdhYmVmZWxkLmApXG4gIGlmIChuZXcgU2V0KGFscGhhYmV0KS5zaXplICE9PSBhbHBoYWJldC5sZW5ndGgpIGZhaWwoJ0ltIEFscGhhYmV0IGtvbW10IGVpbiBaZWljaGVuIGRvcHBlbHQgdm9yLicpXG5cbiAgLy8gV8O2cnRlciBpbnMgR2l0dGVyIGxlZ2VuOiBLcmV1enVuZ2VuIG3DvHNzZW4gcGFzc2VuLlxuICBjb25zdCByb3dzID0gTWF0aC5tYXgoLi4ucmF3Lm1hcCgodykgPT4gdy5yb3cgKyAody5hY3Jvc3MgPyAxIDogdy53b3JkLmxlbmd0aCkpKVxuICBjb25zdCBjb2xzID0gTWF0aC5tYXgoLi4ucmF3Lm1hcCgodykgPT4gdy5jb2wgKyAody5hY3Jvc3MgPyB3LndvcmQubGVuZ3RoIDogMSkpKVxuICBjb25zdCBncmlkID0gQXJyYXkuZnJvbSh7IGxlbmd0aDogcm93cyB9LCAoKSA9PiBBcnJheTxzdHJpbmc+KGNvbHMpLmZpbGwoJycpKVxuICBmb3IgKGNvbnN0IHcgb2YgcmF3KSB7XG4gICAgO1suLi53LndvcmRdLmZvckVhY2goKGMsIGspID0+IHtcbiAgICAgIGNvbnN0IHIgPSB3LnJvdyArICh3LmFjcm9zcyA/IDAgOiBrKVxuICAgICAgY29uc3QgY29sID0gdy5jb2wgKyAody5hY3Jvc3MgPyBrIDogMClcbiAgICAgIGlmIChncmlkW3JdW2NvbF0gJiYgZ3JpZFtyXVtjb2xdICE9PSBjKSBmYWlsKGBLcmV1endvcnRyw6R0c2VsOiAke3cud29yZH0gcGFzc3QgaW4gWmVpbGUgJHtyICsgMX0sIFNwYWx0ZSAke2NvbCArIDF9IG5pY2h0IChkb3J0IHN0ZWh0ICR7Z3JpZFtyXVtjb2xdfSkuYClcbiAgICAgIGdyaWRbcl1bY29sXSA9IGNcbiAgICB9KVxuICB9XG4gIC8vIE51bW1lcm4gd2llIGluIGRlciBaZWl0dW5nOiB2b24gb2JlbiBuYWNoIHVudGVuLCBsaW5rcyBuYWNoIHJlY2h0czsgendlaSBXw7ZydGVyIGltIHNlbGJlbiBGZWxkIHRlaWxlbiBzaWNoIGVpbmUuXG4gIGNvbnN0IHN0YXJ0cyA9IFsuLi5uZXcgU2V0KHJhdy5tYXAoKHcpID0+IHcucm93ICogY29scyArIHcuY29sKSldLnNvcnQoKGEsIGIpID0+IGEgLSBiKVxuICBjb25zdCB3b3JkczogQ3Jvc3N3b3JkV29yZFtdID0gcmF3Lm1hcCgodykgPT4gKHsgLi4udywgbnVtYmVyOiBzdGFydHMuaW5kZXhPZih3LnJvdyAqIGNvbHMgKyB3LmNvbCkgKyAxIH0pKVxuICBjb25zdCBsZXR0ZXJBdCA9IChyOiBudW1iZXIsIGM6IG51bWJlcikgPT4gZ3JpZFtyXT8uW2NdID8/ICcnXG5cbiAgY29uc3Qga2V5d29yZCA9IHNvbHV0aW9uXG4gICAgLm1hcCgoeyByb3csIGNvbCB9KSA9PiBsZXR0ZXJBdChyb3csIGNvbCkgfHwgZmFpbChgbMO2c3VuZzogSW4gWmVpbGUgJHtyb3cgKyAxfSwgU3BhbHRlICR7Y29sICsgMX0gaXN0IGtlaW4gRmVsZC5gKSlcbiAgICAuam9pbignJylcblxuICBjb25zdCBjaGVja2VkID0gc3RhdGlvbnMubWFwKChzKSA9PiB7XG4gICAgaWYgKCFzLmNvZGUpIGZhaWwoYFN0YXRpb24g4oCeJHtzLm5hbWV94oCcOiBDb2RlIGZlaGx0LmApXG4gICAgaWYgKCFzLnF1ZXN0aW9uKSBmYWlsKGBTdGF0aW9uIOKAniR7cy5uYW1lfeKAnDog4oCeZnJhZ2U64oCcIGZlaGx0LmApXG4gICAgaWYgKHMuYW5zd2VyID09PSB1bmRlZmluZWQpIGZhaWwoYFN0YXRpb24g4oCeJHtzLm5hbWV94oCcOiDigJ56YWhsOuKAnCBmZWhsdC5gKVxuICAgIGlmIChzLnJvdyA9PT0gdW5kZWZpbmVkKSBmYWlsKGBTdGF0aW9uIOKAniR7cy5uYW1lfeKAnDog4oCeZmVsZDrigJwgZmVobHQuYClcbiAgICBjb25zdCBsZXR0ZXIgPSBhbHBoYWJldC5jaGFyQXQocy5hbnN3ZXIhKVxuICAgIGlmICghbGV0dGVyKSBmYWlsKGBTdGF0aW9uIOKAniR7cy5uYW1lfeKAnDogYWxwaGFiZXQuY2hhckF0KCR7cy5hbnN3ZXJ9KSBnaWJ0IGVzIG5pY2h0LmApXG4gICAgY29uc3QgdGFyZ2V0ID0gbGV0dGVyQXQocy5yb3chLCBzLmNvbCEpXG4gICAgaWYgKHRhcmdldCAhPT0gbGV0dGVyKSBmYWlsKGBTdGF0aW9uIOKAniR7cy5uYW1lfeKAnDogYWxwaGFiZXQuY2hhckF0KCR7cy5hbnN3ZXJ9KSBpc3QgJHtsZXR0ZXJ9LCBpbSBGZWxkICR7cy5yb3chICsgMX0gJHtzLmNvbCEgKyAxfSBzdGVodCBhYmVyIOKAniR7dGFyZ2V0feKAnC5gKVxuICAgIHMuY29kZSA9IHMuY29kZS5yZXBsYWNlKC9cXG4rJC8sICcnKVxuICAgIHJldHVybiBzIGFzIFJlc2N1ZVN0YXRpb25cbiAgfSlcbiAgcmV0dXJuIHsgdGl0bGUsIGludHJvLCBhbHBoYWJldCwgc3RhdGlvbnM6IGNoZWNrZWQsIGNyb3Nzd29yZFRleHQsIHJvd3MsIGNvbHMsIHdvcmRzLCBzb2x1dGlvbiwga2V5d29yZCwgZ2F0ZVRleHQsIGdhdGVDb2RlOiBnYXRlQ29kZS5yZXBsYWNlKC9cXG4rJC8sICcnKSwgZW5kIH1cbn1cbiJdLCJmaWxlIjoiL3dlYi9zcmMvbGVhcm4vcmVzY3VlR2FtZS50cyJ9 + +//# vitestCache=W3siZmlsZSI6IjEiLCJpZCI6IjEiLCJ1cmwiOiIyIiwiaW1wb3J0cyI6IjMiLCJtYXBwaW5ncyI6ZmFsc2UsImRlcHMiOiI0IiwiZHluYW1pY0RlcHMiOiI1Iiwic3RhdGljTW9ja3MiOm51bGx9LCIvaG9tZS91c2VyL3Zpc3VzdHJ1Y3Qtc3dpZnR1aS93ZWIvc3JjL2xlYXJuL3Jlc2N1ZUdhbWUudHMiLCIvd2ViL3NyYy9sZWFybi9yZXNjdWVHYW1lLnRzIix7InVybHMiOiI2IiwiaWRzIjoiNyJ9LFtdLFtdLFtdLHt9XQ== \ No newline at end of file diff --git a/node_modules/.vitest-cache/2e7e8c86acce9951f2c7f1e10275b55254f40698 b/node_modules/.vitest-cache/2e7e8c86acce9951f2c7f1e10275b55254f40698 new file mode 100644 index 00000000..9edc3f99 --- /dev/null +++ b/node_modules/.vitest-cache/2e7e8c86acce9951f2c7f1e10275b55254f40698 @@ -0,0 +1,27 @@ +const __vite_ssr_import_0__ = await __vite_ssr_import__("/@fs/root/.npm/_npx/69c381f8ad94b576/node_modules/vitest/dist/index.js", {"importedNames":["test"]}); +const __vite_ssr_import_1__ = await __vite_ssr_import__("fs", {"importedNames":["readFileSync"]}); +const __vite_ssr_import_2__ = await __vite_ssr_import__("/web/src/learn/lessonFormat.ts", {"importedNames":["parseBlocks"]}); +const __vite_ssr_import_3__ = await __vite_ssr_import__("/web/src/learn/markdown.ts", {"importedNames":["markdownToHTML"]}); + + + + +(0,__vite_ssr_import_0__.test)("x", () => { + for (const [l, h] of [ + ["de", "## Wie Java"], + ["en", "## How Java"], + ["pt", "## Como o Java"] + ]) { + const src = (0,__vite_ssr_import_1__.readFileSync)(`lessons/${l}/20-java.md`, "utf8"); + const body = src.split(h)[1].split("\n## ")[0]; + const bs = (0,__vite_ssr_import_2__.parseBlocks)(body, "x"); + console.log(l, bs.map((b) => b.kind + (b.pro ? "(pro)" : "") + (b.caption ? "[" + b.caption.slice(0, 25) + "]" : "")).join(" ")); + if (l === "de") { + for (const b of bs) if (b.pro) console.log((0,__vite_ssr_import_3__.markdownToHTML)(b.text)); + } + } +}); +//# sourceMappingSource=vite-generated +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJtYXBwaW5ncyI6IkFBQUE7QUFDQTtBQUNBO0FBQ0E7Ozs7O0FBQ0EsK0JBQUssV0FBVztDQUNkLEtBQUssTUFBTSxDQUFDLEdBQUcsTUFBTTtFQUFDLENBQUMsTUFBSyxhQUFhO0VBQUUsQ0FBQyxNQUFLLGFBQWE7RUFBRSxDQUFDLE1BQUssZ0JBQWdCO0NBQUMsR0FBRztFQUMxRixNQUFNLE1BQU0sdUNBQWEsV0FBVyxFQUFFLGNBQWMsTUFBTTtFQUMxRCxNQUFNLE9BQU8sSUFBSSxNQUFNLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxNQUFNLE9BQU8sQ0FBQyxDQUFDO0VBQzVDLE1BQU0sS0FBSyxzQ0FBWSxNQUFNLEdBQUc7RUFDaEMsUUFBUSxJQUFJLEdBQUcsR0FBRyxLQUFJLE1BQUssRUFBRSxRQUFRLEVBQUUsTUFBTSxVQUFVLE9BQU8sRUFBRSxVQUFVLE1BQUksRUFBRSxRQUFRLE1BQU0sR0FBRSxFQUFFLElBQUUsTUFBTSxHQUFHLENBQUMsQ0FBQyxLQUFLLEdBQUcsQ0FBQztFQUN4SCxJQUFJLE1BQU0sTUFBTTtRQUFLLE1BQU0sS0FBSyxJQUFJLElBQUksRUFBRSxLQUFLLFFBQVEsSUFBSSx5Q0FBZSxFQUFFLElBQUksQ0FBQzs7Q0FDakY7QUFDRixDQUFDIiwibmFtZXMiOltdLCJpZ25vcmVMaXN0IjpbXSwic291cmNlcyI6WyJ6el90bXAudGVzdC50cyJdLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyB0ZXN0IH0gZnJvbSAndml0ZXN0J1xuaW1wb3J0IHsgcmVhZEZpbGVTeW5jIH0gZnJvbSAnZnMnXG5pbXBvcnQgeyBwYXJzZUJsb2NrcyB9IGZyb20gJy4uL3NyYy9sZWFybi9sZXNzb25Gb3JtYXQnXG5pbXBvcnQgeyBtYXJrZG93blRvSFRNTCB9IGZyb20gJy4uL3NyYy9sZWFybi9tYXJrZG93bidcbnRlc3QoJ3gnLCAoKSA9PiB7XG4gIGZvciAoY29uc3QgW2wsIGhdIG9mIFtbJ2RlJywnIyMgV2llIEphdmEnXSxbJ2VuJywnIyMgSG93IEphdmEnXSxbJ3B0JywnIyMgQ29tbyBvIEphdmEnXV0pIHtcbiAgY29uc3Qgc3JjID0gcmVhZEZpbGVTeW5jKGBsZXNzb25zLyR7bH0vMjAtamF2YS5tZGAsICd1dGY4JylcbiAgY29uc3QgYm9keSA9IHNyYy5zcGxpdChoKVsxXS5zcGxpdCgnXFxuIyMgJylbMF1cbiAgY29uc3QgYnMgPSBwYXJzZUJsb2Nrcyhib2R5LCAneCcpIGFzIGFueVtdXG4gIGNvbnNvbGUubG9nKGwsIGJzLm1hcChiID0+IGIua2luZCArIChiLnBybyA/ICcocHJvKScgOiAnJykgKyAoYi5jYXB0aW9uID8gJ1snK2IuY2FwdGlvbi5zbGljZSgwLDI1KSsnXScgOiAnJykpLmpvaW4oJyAnKSlcbiAgaWYgKGwgPT09ICdkZScpIGZvciAoY29uc3QgYiBvZiBicykgaWYgKGIucHJvKSBjb25zb2xlLmxvZyhtYXJrZG93blRvSFRNTChiLnRleHQpKVxuICB9XG59KVxuIl0sImZpbGUiOiIvd2ViL3Rlc3QvenpfdG1wLnRlc3QudHMifQ== + +//# vitestCache=W3siZmlsZSI6IjEiLCJpZCI6IjEiLCJ1cmwiOiIyIiwiaW1wb3J0cyI6IjMiLCJtYXBwaW5ncyI6ZmFsc2UsImRlcHMiOiI0IiwiZHluYW1pY0RlcHMiOiI1Iiwic3RhdGljTW9ja3MiOm51bGx9LCIvaG9tZS91c2VyL3Zpc3VzdHJ1Y3Qtc3dpZnR1aS93ZWIvdGVzdC96el90bXAudGVzdC50cyIsIi93ZWIvdGVzdC96el90bXAudGVzdC50cyIseyJ1cmxzIjoiNiIsImlkcyI6IjcifSxbIjgiLCI5IiwiMTAiLCIxMSJdLFtdLFsiOCIsIjEwIiwiMTEiXSx7fSwiL0Bmcy9yb290Ly5ucG0vX25weC82OWMzODFmOGFkOTRiNTc2L25vZGVfbW9kdWxlcy92aXRlc3QvZGlzdC9pbmRleC5qcyIsImZzIiwiL3dlYi9zcmMvbGVhcm4vbGVzc29uRm9ybWF0LnRzIiwiL3dlYi9zcmMvbGVhcm4vbWFya2Rvd24udHMiXQ== \ No newline at end of file diff --git a/node_modules/.vitest-cache/671ba0efec37747e02cf77c4dec09a7b139242a6 b/node_modules/.vitest-cache/671ba0efec37747e02cf77c4dec09a7b139242a6 new file mode 100644 index 00000000..396b0fd3 --- /dev/null +++ b/node_modules/.vitest-cache/671ba0efec37747e02cf77c4dec09a7b139242a6 @@ -0,0 +1,136 @@ +__vite_ssr_exportName__("parsePap", () => { try { return parsePap } catch {} }); +__vite_ssr_exportName__("papFits", () => { try { return papFits } catch {} }); +__vite_ssr_exportName__("PAP_WIDTH", () => { try { return PAP_WIDTH } catch {} }); +__vite_ssr_exportName__("papHeight", () => { try { return papHeight } catch {} }); +__vite_ssr_exportName__("papLayout", () => { try { return papLayout } catch {} }); +__vite_ssr_exportName__("papLines", () => { try { return papLines } catch {} }); +const shapeOf = { + start: "oval", + ende: "oval", + anweisung: "rechteck", + eingabe: "parallelogramm", + ausgabe: "parallelogramm", + frage: "raute" +}; +function parsePap(inner, file) { + const pap = { + title: "", + task: "", + nodes: [] + }; + const pending = []; + for (const raw of inner) { + const line = raw.trim(); + if (!line) continue; + const m = /^([a-zäöü]+):\s*(.*)$/i.exec(line); + if (!m) throw new Error(`${file}: Unbekannte Zeile im PAP: „${line}“.`); + const key = m[1].toLowerCase(); + const value = m[2].trim(); + if (key === "titel") pap.title = value; + else if (key === "auftrag") pap.task = value; + else if (key === "erklärung" || key === "erklaerung") pap.explanation = value; + else if (key === "legende") pap.legend = /^(ja|yes|true|sim)$/i.test(value); + else if (key in shapeOf) { + const [text, exit] = value.split(/\s+\|\s+/); + if (!text) throw new Error(`${file}: Leeres Element im PAP: „${line}“.`); + const node = { + shape: shapeOf[key], + text: text.trim() + }; + pap.nodes.push(node); + if (key !== "frage") { + if (exit) throw new Error(`${file}: Nur eine Frage hat einen zweiten Ausgang: „${line}“.`); + continue; + }; + const e = /^(ja|nein)\s*(->|:)\s*(.+)$/i.exec(exit ?? ""); + if (!e) throw new Error(`${file}: Eine Frage braucht „| nein -> Text“ oder „| nein: Text“: „${line}“.`); + node.sideExit = e[1].toLowerCase(); + if (e[2] === ":") { + node.side = pap.nodes.length; + pap.nodes.push({ + shape: "rechteck", + text: e[3].trim(), + isSide: true + }); + } else { + pending.push({ + node: pap.nodes.length - 1, + target: e[3].trim(), + line + }); + } + } else throw new Error(`${file}: Unbekannter Schlüssel „${m[1]}“ im PAP.`); + }; + for (const p of pending) { + const target = pap.nodes.findIndex((n, i) => i < p.node && !n.isSide && n.text === p.target); + if (target < 0) throw new Error(`${file}: Rücksprung zu „${p.target}“: kein Element mit diesem Text weiter oben („${p.line}“).`); + pap.nodes[p.node].backTo = target; + }; + if (!pap.title) throw new Error(`${file}: Ein PAP braucht einen Titel.`); + if (pap.nodes.length < 3) throw new Error(`${file}: PAP „${pap.title}“ braucht mindestens drei Elemente.`); + return pap; +}; +/** Ein Element passt auf einen Platz, wenn Form und Text stimmen (zwei gleiche Elemente sind austauschbar). */ +function papFits(pap, slot, card) { + const a = pap.nodes[slot]; + const b = pap.nodes[card]; + return a.shape === b.shape && a.text === b.text; +}; +const PAP_WIDTH = 400; +const MAIN_X = 140; +const MAIN_W = 180; +const SIDE_X = 327; +const SIDE_W = 130; +const GAP = 20; +function papHeight(shape) { + return shape === "raute" ? 56 : shape === "oval" ? 30 : 36; +}; +/** Plätze der Elemente und Gesamthöhe; Seitenkästen stehen auf Höhe ihrer Raute. */ +function papLayout(pap) { + const boxes = []; + let y = 10; + pap.nodes.forEach((n, i) => { + if (n.isSide) return; + const h = papHeight(n.shape); + // Platz für den Pfeil, der von oben in eine Schleife zurückkommt. + if (pap.nodes.some((o) => o.backTo === i) || n.side !== undefined) y += 12; + boxes[i] = { + x: MAIN_X, + y: y + h / 2, + w: n.shape === "raute" ? 170 : n.shape === "oval" ? 110 : MAIN_W, + h + }; + if (n.side !== undefined) boxes[n.side] = { + x: SIDE_X, + y: y + h / 2, + w: SIDE_W, + h: 40 + }; + y += h + GAP; + }); + return { + boxes, + height: y - GAP + 10 + }; +}; +/** Text auf höchstens zwei Zeilen umbrechen, wenn er bei Schriftgröße 13 nicht in `width` passt. */ +function papLines(text, width) { + const fits = (s) => s.length * 6.6 <= width; + if (fits(text)) return [text]; + const words = text.split(" "); + let best = [text]; + let bestLong = Infinity; + for (let i = 1; i < words.length; i++) { + const lines = [words.slice(0, i).join(" "), words.slice(i).join(" ")]; + const long = Math.max(...lines.map((l) => l.length)); + if (long < bestLong) { + best = lines; + bestLong = long; + } + }; + return best; +} +//# sourceMappingSource=vite-generated +//# sourceMappingURL=data:application/json;base64,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V0FBVztDQUNmLEtBQUssSUFBSSxJQUFJLEdBQUcsSUFBSSxNQUFNLFFBQVEsS0FBSztFQUNyQyxNQUFNLFFBQVEsQ0FBQyxNQUFNLE1BQU0sR0FBRyxDQUFDLENBQUMsQ0FBQyxLQUFLLEdBQUcsR0FBRyxNQUFNLE1BQU0sQ0FBQyxDQUFDLENBQUMsS0FBSyxHQUFHLENBQUM7RUFDcEUsTUFBTSxPQUFPLEtBQUssSUFBSSxHQUFHLE1BQU0sS0FBSyxNQUFNLEVBQUUsTUFBTSxDQUFDO0VBQ25ELElBQUksT0FBTyxVQUFVO0dBQ25CLE9BQU87R0FDUCxXQUFXO0VBQ2I7Q0FDRjtDQUNBLE9BQU87QUFDVCIsIm5hbWVzIjpbXSwiaWdub3JlTGlzdCI6W10sInNvdXJjZXMiOlsicGFwLnRzIl0sInNvdXJjZXNDb250ZW50IjpbIi8qKlxuICogUEFQIGJhdWVuOiBFaW4gUHJvZ3JhbW1hYmxhdWZwbGFuIG1pdCBsZWVyZW4gUGzDpHR6ZW4sIGRpZSBmZXJ0aWdlbiBFbGVtZW50ZSBsZWd0IG1hbiBzZWxic3QgaGluZWluLlxuICpcbiAqICAgICA6OjogcGFwXG4gKiAgICAgdGl0ZWw6IMOcYnVuZzogS3VjaGVuIGJhY2tlbiBhbHMgUEFQXG4gKiAgICAgYXVmdHJhZzogTGVnZSBqZWRlcyBFbGVtZW50IGFuIHNlaW5lbiBQbGF0ei5cbiAqICAgICBzdGFydDogU3RhcnRcbiAqICAgICBhbndlaXN1bmc6IFRlaWcgcsO8aHJlblxuICogICAgIGZyYWdlOiBUZWlnIGdsYXR0PyB8IG5laW4gLT4gVGVpZyByw7xocmVuXG4gKiAgICAgZnJhZ2U6IFN0w6RiY2hlbiBzYXViZXI/IHwgbmVpbjogNSBNaW51dGVuIHdlaXRlcmJhY2tlblxuICogICAgIGF1c2dhYmU6IOKAnkZlcnRpZyHigJxcbiAqICAgICBlbmRlOiBFbmRlXG4gKiAgICAgZXJrbMOkcnVuZzogV2lyZCBnZXplaWd0LCB3ZW5uIGFsbGVzIHN0aW1tdC5cbiAqICAgICBsZWdlbmRlOiBqYVxuICogICAgIDo6OlxuICpcbiAqIERpZSBaZWlsZW4gc3RlaGVuIHZvbiBvYmVuIG5hY2ggdW50ZW4gaW4gZGVyIEhhdXB0c3BhbHRlLiBFaW5lIEZyYWdlIChSYXV0ZSkgaGF0IHp3ZWkgQXVzZ8OkbmdlOiBFaW5lciBnZWh0IG5hY2ggdW50ZW5cbiAqIHdlaXRlciwgZGVyIGFuZGVyZSBzdGVodCBoaW50ZXIgYHxgLiBgbmVpbiAtPiBUZXh0YCBmw7xocnQgbWl0IGVpbmVtIFBmZWlsIHp1csO8Y2sgbmFjaCBvYmVuIHp1IGRlbSBFbGVtZW50IG1pdCBkaWVzZW1cbiAqIFRleHQuIGBuZWluOiBUZXh0YCBmw7xocnQgenUgZWluZXIgQW53ZWlzdW5nIHJlY2h0cyBkYW5lYmVuLCB2b24gZG9ydCBnZWh0IGVpbiBQZmVpbCB6dXLDvGNrIHp1ciBSYXV0ZSAoU2NobGVpZmUgd2llXG4gKiDigJ4xIE1pbnV0ZSB3YXJ0ZW7igJwgaW4gTGVrdGlvbiAxKS4gU3RhdHQgYG5laW5gIGdlaHQgYXVjaCBgamFgOyBkZXIgYW5kZXJlIEF1c2dhbmcgaXN0IGRhbm4gZGVyIG5hY2ggdW50ZW4uXG4gKi9cbmV4cG9ydCB0eXBlIFBhcFNoYXBlID0gJ292YWwnIHwgJ3JlY2h0ZWNrJyB8ICdyYXV0ZScgfCAncGFyYWxsZWxvZ3JhbW0nXG5cbmV4cG9ydCBpbnRlcmZhY2UgUGFwTm9kZSB7XG4gIHNoYXBlOiBQYXBTaGFwZVxuICB0ZXh0OiBzdHJpbmdcbiAgLyoqIE51ciBSYXV0ZTogd2VsY2hlciBBdXNnYW5nIHp1ciBTZWl0ZSBnZWh0LiAqL1xuICBzaWRlRXhpdD86ICdqYScgfCAnbmVpbidcbiAgLyoqIFLDvGNrc3BydW5nIG5hY2ggb2JlbjogSW5kZXggZGVzIFppZWxzIGluIGBub2Rlc2AuICovXG4gIGJhY2tUbz86IG51bWJlclxuICAvKiogQW53ZWlzdW5nIHJlY2h0cyBuZWJlbiBkZXIgUmF1dGUgKFNjaGxlaWZlKSwgSW5kZXggaW4gYG5vZGVzYC4gKi9cbiAgc2lkZT86IG51bWJlclxuICAvKiogU3RlaHQgcmVjaHRzIG5lYmVuIGVpbmVyIFJhdXRlIHN0YXR0IGluIGRlciBIYXVwdHNwYWx0ZS4gKi9cbiAgaXNTaWRlPzogYm9vbGVhblxufVxuXG5leHBvcnQgaW50ZXJmYWNlIFBhcCB7XG4gIHRpdGxlOiBzdHJpbmdcbiAgdGFzazogc3RyaW5nXG4gIG5vZGVzOiBQYXBOb2RlW11cbiAgZXhwbGFuYXRpb24/OiBzdHJpbmdcbiAgLyoqIGBsZWdlbmRlOiBqYWAgemVpZ3QgdW50ZXIgZGVtIFBsYW4sIHdhcyBkaWUgU3ltYm9sZSBiZWRldXRlbi4gKi9cbiAgbGVnZW5kPzogYm9vbGVhblxufVxuXG5jb25zdCBzaGFwZU9mOiBSZWNvcmQ8c3RyaW5nLCBQYXBTaGFwZT4gPSB7XG4gIHN0YXJ0OiAnb3ZhbCcsXG4gIGVuZGU6ICdvdmFsJyxcbiAgYW53ZWlzdW5nOiAncmVjaHRlY2snLFxuICBlaW5nYWJlOiAncGFyYWxsZWxvZ3JhbW0nLFxuICBhdXNnYWJlOiAncGFyYWxsZWxvZ3JhbW0nLFxuICBmcmFnZTogJ3JhdXRlJyxcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIHBhcnNlUGFwKGlubmVyOiBzdHJpbmdbXSwgZmlsZTogc3RyaW5nKTogUGFwIHtcbiAgY29uc3QgcGFwOiBQYXAgPSB7IHRpdGxlOiAnJywgdGFzazogJycsIG5vZGVzOiBbXSB9XG4gIGNvbnN0IHBlbmRpbmc6IHsgbm9kZTogbnVtYmVyOyB0YXJnZXQ6IHN0cmluZzsgbGluZTogc3RyaW5nIH1bXSA9IFtdXG4gIGZvciAoY29uc3QgcmF3IG9mIGlubmVyKSB7XG4gICAgY29uc3QgbGluZSA9IHJhdy50cmltKClcbiAgICBpZiAoIWxpbmUpIGNvbnRpbnVlXG4gICAgY29uc3QgbSA9IC9eKFthLXrDpMO2w7xdKyk6XFxzKiguKikkL2kuZXhlYyhsaW5lKVxuICAgIGlmICghbSkgdGhyb3cgbmV3IEVycm9yKGAke2ZpbGV9OiBVbmJla2FubnRlIFplaWxlIGltIFBBUDog4oCeJHtsaW5lfeKAnC5gKVxuICAgIGNvbnN0IGtleSA9IG1bMV0udG9Mb3dlckNhc2UoKVxuICAgIGNvbnN0IHZhbHVlID0gbVsyXS50cmltKClcbiAgICBpZiAoa2V5ID09PSAndGl0ZWwnKSBwYXAudGl0bGUgPSB2YWx1ZVxuICAgIGVsc2UgaWYgKGtleSA9PT0gJ2F1ZnRyYWcnKSBwYXAudGFzayA9IHZhbHVlXG4gICAgZWxzZSBpZiAoa2V5ID09PSAnZXJrbMOkcnVuZycgfHwga2V5ID09PSAnZXJrbGFlcnVuZycpIHBhcC5leHBsYW5hdGlvbiA9IHZhbHVlXG4gICAgZWxzZSBpZiAoa2V5ID09PSAnbGVnZW5kZScpIHBhcC5sZWdlbmQgPSAvXihqYXx5ZXN8dHJ1ZXxzaW0pJC9pLnRlc3QodmFsdWUpXG4gICAgZWxzZSBpZiAoa2V5IGluIHNoYXBlT2YpIHtcbiAgICAgIGNvbnN0IFt0ZXh0LCBleGl0XSA9IHZhbHVlLnNwbGl0KC9cXHMrXFx8XFxzKy8pXG4gICAgICBpZiAoIXRleHQpIHRocm93IG5ldyBFcnJvcihgJHtmaWxlfTogTGVlcmVzIEVsZW1lbnQgaW0gUEFQOiDigJ4ke2xpbmV94oCcLmApXG4gICAgICBjb25zdCBub2RlOiBQYXBOb2RlID0geyBzaGFwZTogc2hhcGVPZltrZXldLCB0ZXh0OiB0ZXh0LnRyaW0oKSB9XG4gICAgICBwYXAubm9kZXMucHVzaChub2RlKVxuICAgICAgaWYgKGtleSAhPT0gJ2ZyYWdlJykge1xuICAgICAgICBpZiAoZXhpdCkgdGhyb3cgbmV3IEVycm9yKGAke2ZpbGV9OiBOdXIgZWluZSBGcmFnZSBoYXQgZWluZW4gendlaXRlbiBBdXNnYW5nOiDigJ4ke2xpbmV94oCcLmApXG4gICAgICAgIGNvbnRpbnVlXG4gICAgICB9XG4gICAgICBjb25zdCBlID0gL14oamF8bmVpbilcXHMqKC0+fDopXFxzKiguKykkL2kuZXhlYyhleGl0ID8/ICcnKVxuICAgICAgaWYgKCFlKSB0aHJvdyBuZXcgRXJyb3IoYCR7ZmlsZX06IEVpbmUgRnJhZ2UgYnJhdWNodCDigJ58IG5laW4gLT4gVGV4dOKAnCBvZGVyIOKAnnwgbmVpbjogVGV4dOKAnDog4oCeJHtsaW5lfeKAnC5gKVxuICAgICAgbm9kZS5zaWRlRXhpdCA9IGVbMV0udG9Mb3dlckNhc2UoKSBhcyAnamEnIHwgJ25laW4nXG4gICAgICBpZiAoZVsyXSA9PT0gJzonKSB7XG4gICAgICAgIG5vZGUuc2lkZSA9IHBhcC5ub2Rlcy5sZW5ndGhcbiAgICAgICAgcGFwLm5vZGVzLnB1c2goeyBzaGFwZTogJ3JlY2h0ZWNrJywgdGV4dDogZVszXS50cmltKCksIGlzU2lkZTogdHJ1ZSB9KVxuICAgICAgfSBlbHNlIHtcbiAgICAgICAgcGVuZGluZy5wdXNoKHsgbm9kZTogcGFwLm5vZGVzLmxlbmd0aCAtIDEsIHRhcmdldDogZVszXS50cmltKCksIGxpbmUgfSlcbiAgICAgIH1cbiAgICB9IGVsc2UgdGhyb3cgbmV3IEVycm9yKGAke2ZpbGV9OiBVbmJla2FubnRlciBTY2hsw7xzc2VsIOKAniR7bVsxXX3igJwgaW0gUEFQLmApXG4gIH1cbiAgZm9yIChjb25zdCBwIG9mIHBlbmRpbmcpIHtcbiAgICBjb25zdCB0YXJnZXQgPSBwYXAubm9kZXMuZmluZEluZGV4KChuLCBpKSA9PiBpIDwgcC5ub2RlICYmICFuLmlzU2lkZSAmJiBuLnRleHQgPT09IHAudGFyZ2V0KVxuICAgIGlmICh0YXJnZXQgPCAwKSB0aHJvdyBuZXcgRXJyb3IoYCR7ZmlsZX06IFLDvGNrc3BydW5nIHp1IOKAniR7cC50YXJnZXR94oCcOiBrZWluIEVsZW1lbnQgbWl0IGRpZXNlbSBUZXh0IHdlaXRlciBvYmVuICjigJ4ke3AubGluZX3igJwpLmApXG4gICAgcGFwLm5vZGVzW3Aubm9kZV0uYmFja1RvID0gdGFyZ2V0XG4gIH1cbiAgaWYgKCFwYXAudGl0bGUpIHRocm93IG5ldyBFcnJvcihgJHtmaWxlfTogRWluIFBBUCBicmF1Y2h0IGVpbmVuIFRpdGVsLmApXG4gIGlmIChwYXAubm9kZXMubGVuZ3RoIDwgMykgdGhyb3cgbmV3IEVycm9yKGAke2ZpbGV9OiBQQVAg4oCeJHtwYXAudGl0bGV94oCcIGJyYXVjaHQgbWluZGVzdGVucyBkcmVpIEVsZW1lbnRlLmApXG4gIHJldHVybiBwYXBcbn1cblxuLyoqIEVpbiBFbGVtZW50IHBhc3N0IGF1ZiBlaW5lbiBQbGF0eiwgd2VubiBGb3JtIHVuZCBUZXh0IHN0aW1tZW4gKHp3ZWkgZ2xlaWNoZSBFbGVtZW50ZSBzaW5kIGF1c3RhdXNjaGJhcikuICovXG5leHBvcnQgZnVuY3Rpb24gcGFwRml0cyhwYXA6IFBhcCwgc2xvdDogbnVtYmVyLCBjYXJkOiBudW1iZXIpOiBib29sZWFuIHtcbiAgY29uc3QgYSA9IHBhcC5ub2Rlc1tzbG90XVxuICBjb25zdCBiID0gcGFwLm5vZGVzW2NhcmRdXG4gIHJldHVybiBhLnNoYXBlID09PSBiLnNoYXBlICYmIGEudGV4dCA9PT0gYi50ZXh0XG59XG5cbi8qKiBMYWdlIGltIEJpbGQgKHZpZXdCb3ggNDAwIGJyZWl0KTogTWl0dGVscHVua3QsIEJyZWl0ZSwgSMO2aGUuICovXG5leHBvcnQgaW50ZXJmYWNlIFBhcEJveCB7XG4gIHg6IG51bWJlclxuICB5OiBudW1iZXJcbiAgdzogbnVtYmVyXG4gIGg6IG51bWJlclxufVxuXG5leHBvcnQgY29uc3QgUEFQX1dJRFRIID0gNDAwXG5jb25zdCBNQUlOX1ggPSAxNDBcbmNvbnN0IE1BSU5fVyA9IDE4MFxuY29uc3QgU0lERV9YID0gMzI3XG5jb25zdCBTSURFX1cgPSAxMzBcbmNvbnN0IEdBUCA9IDIwXG5cbmV4cG9ydCBmdW5jdGlvbiBwYXBIZWlnaHQoc2hhcGU6IFBhcFNoYXBlKTogbnVtYmVyIHtcbiAgcmV0dXJuIHNoYXBlID09PSAncmF1dGUnID8gNTYgOiBzaGFwZSA9PT0gJ292YWwnID8gMzAgOiAzNlxufVxuXG4vKiogUGzDpHR6ZSBkZXIgRWxlbWVudGUgdW5kIEdlc2FtdGjDtmhlOyBTZWl0ZW5rw6RzdGVuIHN0ZWhlbiBhdWYgSMO2aGUgaWhyZXIgUmF1dGUuICovXG5leHBvcnQgZnVuY3Rpb24gcGFwTGF5b3V0KHBhcDogUGFwKTogeyBib3hlczogUGFwQm94W107IGhlaWdodDogbnVtYmVyIH0ge1xuICBjb25zdCBib3hlczogUGFwQm94W10gPSBbXVxuICBsZXQgeSA9IDEwXG4gIHBhcC5ub2Rlcy5mb3JFYWNoKChuLCBpKSA9PiB7XG4gICAgaWYgKG4uaXNTaWRlKSByZXR1cm5cbiAgICBjb25zdCBoID0gcGFwSGVpZ2h0KG4uc2hhcGUpXG4gICAgLy8gUGxhdHogZsO8ciBkZW4gUGZlaWwsIGRlciB2b24gb2JlbiBpbiBlaW5lIFNjaGxlaWZlIHp1csO8Y2trb21tdC5cbiAgICBpZiAocGFwLm5vZGVzLnNvbWUoKG8pID0+IG8uYmFja1RvID09PSBpKSB8fCBuLnNpZGUgIT09IHVuZGVmaW5lZCkgeSArPSAxMlxuICAgIGJveGVzW2ldID0geyB4OiBNQUlOX1gsIHk6IHkgKyBoIC8gMiwgdzogbi5zaGFwZSA9PT0gJ3JhdXRlJyA/IDE3MCA6IG4uc2hhcGUgPT09ICdvdmFsJyA/IDExMCA6IE1BSU5fVywgaCB9XG4gICAgaWYgKG4uc2lkZSAhPT0gdW5kZWZpbmVkKSBib3hlc1tuLnNpZGVdID0geyB4OiBTSURFX1gsIHk6IHkgKyBoIC8gMiwgdzogU0lERV9XLCBoOiA0MCB9XG4gICAgeSArPSBoICsgR0FQXG4gIH0pXG4gIHJldHVybiB7IGJveGVzLCBoZWlnaHQ6IHkgLSBHQVAgKyAxMCB9XG59XG5cbi8qKiBUZXh0IGF1ZiBow7ZjaHN0ZW5zIHp3ZWkgWmVpbGVuIHVtYnJlY2hlbiwgd2VubiBlciBiZWkgU2NocmlmdGdyw7bDn2UgMTMgbmljaHQgaW4gYHdpZHRoYCBwYXNzdC4gKi9cbmV4cG9ydCBmdW5jdGlvbiBwYXBMaW5lcyh0ZXh0OiBzdHJpbmcsIHdpZHRoOiBudW1iZXIpOiBzdHJpbmdbXSB7XG4gIGNvbnN0IGZpdHMgPSAoczogc3RyaW5nKSA9PiBzLmxlbmd0aCAqIDYuNiA8PSB3aWR0aFxuICBpZiAoZml0cyh0ZXh0KSkgcmV0dXJuIFt0ZXh0XVxuICBjb25zdCB3b3JkcyA9IHRleHQuc3BsaXQoJyAnKVxuICBsZXQgYmVzdDogc3RyaW5nW10gPSBbdGV4dF1cbiAgbGV0IGJlc3RMb25nID0gSW5maW5pdHlcbiAgZm9yIChsZXQgaSA9IDE7IGkgPCB3b3Jkcy5sZW5ndGg7IGkrKykge1xuICAgIGNvbnN0IGxpbmVzID0gW3dvcmRzLnNsaWNlKDAsIGkpLmpvaW4oJyAnKSwgd29yZHMuc2xpY2UoaSkuam9pbignICcpXVxuICAgIGNvbnN0IGxvbmcgPSBNYXRoLm1heCguLi5saW5lcy5tYXAoKGwpID0+IGwubGVuZ3RoKSlcbiAgICBpZiAobG9uZyA8IGJlc3RMb25nKSB7XG4gICAgICBiZXN0ID0gbGluZXNcbiAgICAgIGJlc3RMb25nID0gbG9uZ1xuICAgIH1cbiAgfVxuICByZXR1cm4gYmVzdFxufVxuIl0sImZpbGUiOiIvd2ViL3NyYy9sZWFybi9wYXAudHMifQ== + +//# vitestCache=W3siZmlsZSI6IjEiLCJpZCI6IjEiLCJ1cmwiOiIyIiwiaW1wb3J0cyI6IjMiLCJtYXBwaW5ncyI6ZmFsc2UsImRlcHMiOiI0IiwiZHluYW1pY0RlcHMiOiI1Iiwic3RhdGljTW9ja3MiOm51bGx9LCIvaG9tZS91c2VyL3Zpc3VzdHJ1Y3Qtc3dpZnR1aS93ZWIvc3JjL2xlYXJuL3BhcC50cyIsIi93ZWIvc3JjL2xlYXJuL3BhcC50cyIseyJ1cmxzIjoiNiIsImlkcyI6IjcifSxbXSxbXSxbXSx7fV0= \ No newline at end of file diff --git a/node_modules/.vitest-cache/92afb3df989d8c4b3fbf8e596cd079aed22718e6 b/node_modules/.vitest-cache/92afb3df989d8c4b3fbf8e596cd079aed22718e6 new file mode 100644 index 00000000..f06102c6 --- /dev/null +++ b/node_modules/.vitest-cache/92afb3df989d8c4b3fbf8e596cd079aed22718e6 @@ -0,0 +1,418 @@ +__vite_ssr_exportName__("RoundGameError", () => { try { return RoundGameError } catch {} }); +__vite_ssr_exportName__("isRoundGameKind", () => { try { return isRoundGameKind } catch {} }); +__vite_ssr_exportName__("parseRoundGame", () => { try { return parseRoundGame } catch {} }); +__vite_ssr_exportName__("parseLayoutPicture", () => { try { return parseLayoutPicture } catch {} }); +__vite_ssr_exportName__("parseSwingWindow", () => { try { return parseSwingWindow } catch {} }); +__vite_ssr_exportName__("startState", () => { try { return startState } catch {} }); +__vite_ssr_exportName__("click", () => { try { return click } catch {} }); +__vite_ssr_exportName__("clickButton", () => { try { return clickButton } catch {} }); +__vite_ssr_exportName__("simulate", () => { try { return simulate } catch {} }); +class RoundGameError extends Error {}; +function isRoundGameKind(arg) { + return arg === "zuhoerer" || arg === "vertrag" || arg === "layout" || arg === "bombe" || arg === "frage" || arg === "reihenfolge"; +}; +function parseRoundGame(kind, lines, file) { + const fail = (msg) => { + throw new RoundGameError(`${file}: ${msg}`); + }; + let title = ""; + let intro = ""; + let question = ""; + let answers = []; + let seconds; + let data; + const rounds = []; + let current; + let inCode = false; + for (const raw of lines) { + const line = raw.trim(); + if (current && inCode && (/^ {4}|^\t/.test(raw) || line === "")) { + current.code += (current.code ? "\n" : "") + raw.replace(/^( {4}|\t)/, ""); + continue; + }; + inCode = false; + if (!line) continue; + const key = /^(titel|intro|antworten|frage|runde|klicks|richtig|zeit|fehler|besser|daten):\s*(.*)$/.exec(line); + if (key) { + const [, name, value] = key; + if (name === "runde") { + current = { + code: "", + question, + options: [], + explanation: "", + clicks: [] + }; + rounds.push(current); + inCode = true; + } else if (!current) { + if (name === "titel") title = value; + else if (name === "intro") intro = value; + else if (name === "antworten") answers = value.split("|").map((a) => a.trim()); + else if (name === "frage") question = value; + else if (name === "zeit") seconds = Number(value); + else if (name === "daten") data = value === "csv" ? value : fail(`„daten:“ kennt nur „csv“.`); + else fail(`„${name}:“ gehört in eine Runde.`); + } else if (name === "frage") current.question = value; + else if (name === "fehler") current.wrongLine = Number(value); + else if (name === "besser") current.fix = value; + else if (name === "klicks") current.clicks = value.split(",").map((c) => c.trim()).filter(Boolean); + else if (name === "richtig") current.rightText = value; + else fail(`„${name}:“ gehört vor die erste Runde.`); + continue; + }; + if (!current) fail(`Unbekannte Zeile vor der ersten Runde: „${line}“`); + const round = current; + const option = /^-\s+(\[x\]\s+)?(.+)$/.exec(line); + if (option) round.options.push({ + text: option[2].trim().replaceAll("\\n", "\n"), + right: !!option[1] + }); + else if (line.startsWith(">")) round.explanation += (round.explanation ? " " : "") + line.slice(1).trim(); + else fail(`Unbekannte Zeile im Spiel: „${line}“`); + }; + if (!title) fail("Das Spiel braucht eine Zeile „titel:“."); + if (!rounds.length) fail("Das Spiel braucht mindestens eine „runde:“."); + rounds.forEach((round, i) => { + round.code = round.code.replace(/\n+$/, ""); + if (kind === "bombe") { + const lines = round.code.split("\n"); + const n = round.wrongLine; + if (!n || !Number.isInteger(n) || n < 1 || n > lines.length || !lines[n - 1].trim()) fail(`Runde ${i + 1}: „fehler:“ muss eine Zeile des Codes sein.`); + if (!round.fix) fail(`Runde ${i + 1}: „besser:“ fehlt.`); + if (round.options.length) fail(`Runde ${i + 1}: Bei „bombe“ gibt es keine Antworten, man tippt auf die Zeile.`); + if (!round.question) fail(`Runde ${i + 1}: keine Frage.`); + return; + }; + if (kind === "reihenfolge") { + if (round.options.length < 3) fail(`Runde ${i + 1}: „reihenfolge“ braucht mindestens drei Schritte.`); + if (round.options.some((o) => o.right)) fail(`Runde ${i + 1}: Bei „reihenfolge“ gibt es kein [x], die Schritte stehen der Reihe nach da.`); + if (new Set(round.options.map((o) => o.text)).size !== round.options.length) fail(`Runde ${i + 1}: zwei Schritte sind gleich.`); + if (!round.question) fail(`Runde ${i + 1}: keine Frage.`); + return; + }; + if (!round.options.length) { + if (!answers.length) fail(`Runde ${i + 1}: keine Antworten.`); + if (!round.rightText || !answers.includes(round.rightText)) fail(`Runde ${i + 1}: „richtig:“ muss eine der Antworten sein.`); + round.options = answers.map((text) => ({ + text, + right: text === round.rightText + })); + }; + if (round.options.filter((o) => o.right).length !== 1) fail(`Runde ${i + 1}: genau eine Antwort muss richtig sein.`); + if (!round.question) fail(`Runde ${i + 1}: keine Frage.`); + if (kind === "layout") round.options.forEach((o) => parseLayoutPicture(o.text, `Runde ${i + 1}`, fail)); + if (kind === "zuhoerer") { + try { + const window = parseSwingWindow(round.code); + for (const c of round.clicks) if (!window.buttons.some((b) => b.caption === c)) fail(`Runde ${i + 1}: Knopf „${c}“ gibt es nicht.`); + simulate(window, round.clicks); + } catch (err) { + if (err instanceof RoundGameError) throw err; + fail(`Runde ${i + 1}: ${err.message}`); + } + }; + delete round.rightText; + }); + if (kind === "bombe" && !(seconds && seconds > 0)) fail("„bombe“ braucht „zeit:“ mit den Sekunden je Runde."); + return { + kind, + title, + intro, + ...kind === "bombe" ? { + seconds, + ...data ? { data } : {} + } : {}, + rounds + }; +}; +/** `grid: A B / C D`, `flow: A B C`, `border: N=A C=B S=C`. */ +function parseLayoutPicture(text, where = "", fail = (m) => { + throw new RoundGameError(m); +}) { + const m = /^(grid|flow|border):\s*(.+)$/.exec(text); + if (!m) return fail(`${where}: Antwort „${text}“ ist kein Fensterbild (grid:, flow: oder border:).`); + if (m[1] === "border") { + const areas = {}; + for (const part of m[2].split(/\s+/)) { + const a = /^([NSWEC])=(.+)$/.exec(part); + if (!a) fail(`${where}: „${part}“ im BorderLayout-Bild verstehe ich nicht (z. B. N=A).`); + areas[a[1]] = a[2]; + }; + return { + kind: "border", + areas + }; + }; + const rows = m[2].split("/").map((r) => r.trim().split(/\s+/).filter(Boolean)); + return { + kind: m[1], + rows + }; +}; +const str = "\"((?:[^\"\\\\]|\\\\.)*)\""; +/** +* Liest Knöpfe, Beschriftungen, int-Variablen und Zuhörer aus einfachem Swing-Code. Ein Zuhörer steht direkt am +* Knopf (`knopf.addActionListener(e -> …)`) oder als Variable (`ActionListener z = e -> …;`), die mit +* `knopf.addActionListener(z);` an mehreren Knöpfen hängen kann. +*/ +function parseSwingWindow(code) { + const lines = code.split("\n"); + const win = { + title: "", + buttons: [], + labels: [], + ints: {}, + listeners: [] + }; + const named = new Map(); + /** Zuhörer ab Zeile i, `rest` ist der Text hinter dem Pfeil; `end` schließt einen Block ab (`});` oder `};`). */ + const lambda = (i, rest, end) => { + if (rest.startsWith("{")) { + let j = i + 1; + const body = []; + while (j < lines.length && lines[j].trim() !== end) body.push(lines[j++].trim()); + if (j >= lines.length) throw new Error(`Dem Zuhörer fehlt „${end}“.`); + return { + from: i, + to: j, + statements: parseStatements(body.join(" ")) + }; + }; + const inner = end === "});" ? rest.replace(/\)\s*;\s*$/, "") : rest.replace(/;\s*$/, ""); + return { + from: i, + to: i, + statements: parseStatements(inner) + }; + }; + const button = (name) => { + if (!win.buttons.some((b) => b.name === name)) throw new Error(`Knopf ${name} ist nicht angelegt.`); + return name; + }; + for (let i = 0; i < lines.length; i++) { + const line = lines[i].trim(); + let m; + if (m = new RegExp(`^JFrame\\s+\\w+\\s*=\\s*new JFrame\\(${str}\\)`).exec(line)) win.title = m[1]; + else if (m = new RegExp(`^JButton\\s+(\\w+)\\s*=\\s*new JButton\\(${str}\\)`).exec(line)) win.buttons.push({ + name: m[1], + caption: m[2] + }); + else if (m = new RegExp(`^JLabel\\s+(\\w+)\\s*=\\s*new JLabel\\(${str}`).exec(line)) win.labels.push({ + name: m[1], + text: m[2] + }); + else if (m = /^(?:static\s+)?int\s+(\w+)\s*=\s*(-?\d+)\s*;/.exec(line)) win.ints[m[1]] = Number(m[2]); + else if (m = /^ActionListener\s+(\w+)\s*=\s*\w+\s*->\s*(.*)$/.exec(line)) { + const listener = lambda(i, m[2], "};"); + named.set(m[1], listener); + i = listener.to; + } else if (m = /^(\w+)\.addActionListener\(\s*(\w+)\s*\)\s*;$/.exec(line)) { + const listener = named.get(m[2]); + if (!listener) throw new Error(`Zuhörer ${m[2]} ist nicht angelegt.`); + win.listeners.push({ + button: button(m[1]), + ...listener + }); + } else if (m = /^(\w+)\.addActionListener\(\s*\w+\s*->\s*(.*)$/.exec(line)) { + const listener = lambda(i, m[2], "});"); + win.listeners.push({ + button: button(m[1]), + ...listener + }); + i = listener.to; + } + }; + return win; +}; +/** Zerlegt den Rumpf eines Zuhörers in Anweisungen, `if`/`else` mit oder ohne geschweifte Klammern. */ +function parseStatements(text) { + const out = []; + let pos = 0; + const skip = () => { + while (pos < text.length && /\s/.test(text[pos])) pos++; + }; + /** Text bis zur passenden schließenden Klammer; `pos` steht auf der öffnenden. */ + const balanced = (open, close) => { + let depth = 0; + let quote = false; + const start = pos + 1; + for (; pos < text.length; pos++) { + const c = text[pos]; + if (quote) { + if (c === "\\") pos++; + else if (c === "\"") quote = false; + } else if (c === "\"") quote = true; + else if (c === open) depth++; + else if (c === close && --depth === 0) return text.slice(start, pos++); + }; + throw new Error(`Es fehlt „${close}“.`); + }; + /** Eine einfache Anweisung bis zum Semikolon außerhalb von Klammern und Text. */ + const simple = () => { + let depth = 0; + let quote = false; + const start = pos; + for (; pos < text.length; pos++) { + const c = text[pos]; + if (quote) { + if (c === "\\") pos++; + else if (c === "\"") quote = false; + } else if (c === "\"") quote = true; + else if (c === "(") depth++; + else if (c === ")") depth--; + else if (c === ";" && depth === 0) return text.slice(start, pos++).trim(); + }; + return text.slice(start).trim(); + }; + const one = () => { + skip(); + if (text[pos] === "{") return parseStatements(balanced("{", "}")); + if (/^if\s*\(/.test(text.slice(pos))) { + pos = text.indexOf("(", pos); + const condition = balanced("(", ")").trim(); + const then = one(); + skip(); + let otherwise = []; + if (/^else\b/.test(text.slice(pos))) { + pos += 4; + otherwise = one(); + }; + return [{ + condition, + then, + otherwise + }]; + }; + const s = simple(); + return s ? [s] : []; + }; + for (skip(); pos < text.length; skip()) out.push(...one()); + return out; +} +function startState(win) { + const texts = {}; + for (const b of win.buttons) texts[b.name] = b.caption; + for (const l of win.labels) texts[l.name] = l.text; + return { + texts, + ints: { ...win.ints } + }; +}; +/** Ein Klick auf den Knopf mit dieser Beschriftung (verändert `state`). */ +function click(win, state, caption) { + const button = win.buttons.find((b) => b.caption === caption) ?? win.buttons.find((b) => state.texts[b.name] === caption); + if (!button) throw new Error(`Knopf „${caption}“ gibt es nicht.`); + return clickButton(win, state, button.name); +}; +/** Klick auf den Knopf mit diesem Variablennamen. */ +function clickButton(win, state, name) { + const listener = win.listeners.find((l) => l.button === name); + const output = []; + // `e.getActionCommand()` ist wie in Java die Beschriftung des Knopfs beim Klick. + const event = { + source: name, + command: state.texts[name] + }; + for (const s of listener?.statements ?? []) run(s, state, output, event); + return { + button: name, + listener, + texts: { ...state.texts }, + console: output + }; +}; +function simulate(win, clicks) { + const state = startState(win); + return clicks.map((c) => click(win, state, c)); +}; +function run(statement, state, output, event) { + if (typeof statement !== "string") { + for (const s of condition(statement.condition, state, event) ? statement.then : statement.otherwise) run(s, state, output, event); + return; + }; + let m; + if (m = /^(\w+)\.setText\((.*)\)$/.exec(statement)) { + if (!(m[1] in state.texts)) throw new Error(`${m[1]} ist keine Beschriftung und kein Knopf.`); + state.texts[m[1]] = String(evaluate(m[2], state, event)); + } else if (m = /^System\.out\.println\((.*)\)$/.exec(statement)) output.push(String(evaluate(m[1], state, event))); + else if (m = /^(\w+)\s*(\+\+|--)$/.exec(statement)) state.ints[intName(m[1], state)] += m[2] === "++" ? 1 : -1; + else if (m = /^(\w+)\s*([+-]?=)\s*(.+)$/.exec(statement)) { + const name = intName(m[1], state); + const value = Number(evaluate(m[3], state, event)); + state.ints[name] = m[2] === "=" ? value : m[2] === "+=" ? state.ints[name] + value : state.ints[name] - value; + } else throw new Error(`Diese Anweisung kann das Spiel nicht nachspielen: „${statement}“`); +} +/** `e.getSource() == knopf`, `text.equals("+")`, `zahl > 3` */ +function condition(text, state, event) { + let m; + if (m = /^e\.getSource\(\)\s*(==|!=)\s*(\w+)$/.exec(text)) { + if (!(m[2] in state.texts)) throw new Error(`${m[2]} ist kein Knopf.`); + return event.source === m[2] === (m[1] === "=="); + }; + if (m = /^(!?)(.+)\.equals\((.+)\)$/.exec(text)) return String(evaluate(m[2], state, event)) === String(evaluate(m[3], state, event)) !== (m[1] === "!"); + if (m = /^(.+?)\s*(==|!=|<=|>=|<|>)\s*(.+)$/.exec(text)) { + const a = Number(evaluate(m[1], state, event)); + const b = Number(evaluate(m[3], state, event)); + return { + "==": a === b, + "!=": a !== b, + "<=": a <= b, + ">=": a >= b, + "<": a < b, + ">": a > b + }[m[2]]; + }; + throw new Error(`Diese Bedingung kann das Spiel nicht nachspielen: „${text}“`); +} +function intName(name, state) { + if (!(name in state.ints)) throw new Error(`Variable ${name} ist nicht angelegt.`); + return name; +} +/** `"Text" + zahl`, `"" + (a + b)`, `zahl * 2`, `e.getActionCommand()`: von links nach rechts wie in Java. */ +function evaluate(expr, state, event) { + const tokens = expr.match(new RegExp(`${str}|\\d+|e\\.getActionCommand\\(\\)|\\w+(?:\\.getText\\(\\))?|[-+*/()]`, "g")) ?? []; + let pos = 0; + const atom = () => { + const tok = tokens[pos++]; + if (tok === undefined) throw new Error(`Unvollständiger Ausdruck „${expr}“`); + if (tok === "(") { + const v = sum(); + pos++; + return v; + }; + if (tok.startsWith("\"")) return JSON.parse(tok); + if (/^\d+$/.test(tok)) return Number(tok); + if (tok === "e.getActionCommand()") { + if (!event) throw new Error("e.getActionCommand() gibt es nur im Zuhörer."); + return event.command; + }; + if (tok.endsWith(".getText()")) return state.texts[tok.slice(0, -10)] ?? ""; + if (tok in state.ints) return state.ints[tok]; + throw new Error(`Unbekannt: „${tok}“`); + }; + const product = () => { + let v = atom(); + while (tokens[pos] === "*" || tokens[pos] === "/") { + const op = tokens[pos++]; + const r = Number(atom()); + v = op === "*" ? Number(v) * r : Math.trunc(Number(v) / r); + }; + return v; + }; + const sum = () => { + let v = product(); + while (tokens[pos] === "+" || tokens[pos] === "-") { + const op = tokens[pos++]; + const r = product(); + if (op === "+") v = typeof v === "string" || typeof r === "string" ? `${v}${r}` : v + r; + else v = Number(v) - Number(r); + }; + return v; + }; + return sum(); +} +//# sourceMappingSource=vite-generated +//# sourceMappingURL=data:application/json;base64,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IjpbXSwic291cmNlcyI6WyJyb3VuZEdhbWUudHMiXSwic291cmNlc0NvbnRlbnQiOlsiLyoqXG4gKiBSdW5kZW5zcGllbGUgenUgU3dpbmcgKEJsb2NrIGA6Ojogc3BpZWwgenVob2VyZXJ8dmVydHJhZ3xsYXlvdXRgKTogSW4gamVkZXIgUnVuZGUgQ29kZSB6ZWlnZW4sIGVpbmVcbiAqIEZyYWdlIG1pdCBBbnR3b3J0ZW4gc3RlbGxlbiB1bmQgZGllIHJpY2h0aWdlIEFudHdvcnQgZXJrbMOkcmVuLlxuICpcbiAqIC0gYHp1aG9lcmVyYCAo4oCeV2VyIGjDtnJ0IHp1P+KAnCk6IEVpbiBuYWNoZ2ViYXV0ZXMgRmVuc3RlciBtaXQgZGVuIEtuw7ZwZmVuIGF1cyBkZW0gQ29kZS4gTmFjaCBkZXIgQW50d29ydFxuICogICB3ZXJkZW4gZGllIEtsaWNrcyBhYmdlc3BpZWx0OiBEYXMgRXJlaWduaXMgbMOkdWZ0IHp1bSBadWjDtnJlciwgZGVzc2VuIFplaWxlbiBsZXVjaHRlbiBhdWYuXG4gKiAtIGB2ZXJ0cmFnYCAo4oCeVmVydHJhZyBlcmbDvGxsdD/igJwpOiBLbGFzc2VuLCBkaWUgZWluIEludGVyZmFjZSBlcmbDvGxsZW4gc29sbGVuLlxuICogLSBgbGF5b3V0YCAo4oCeV28gbGFuZGV0IGRlciBLbm9wZj/igJwpOiBEaWUgQW50d29ydGVuIHNpbmQga2xlaW5lIEZlbnN0ZXIgKGBncmlkOiBBIEIgLyBDIERgLCDigKYpLlxuICogLSBgYm9tYmVgICjigJ5Cb21iZSBlbnRzY2jDpHJmZW7igJwpOiBDb2RlIG1pdCBnZW5hdSBlaW5lciBmYWxzY2hlbiBaZWlsZSB1bmQgZWluIENvdW50ZG93biAoYHplaXQ6YCBTZWt1bmRlbiBqZVxuICogICBSdW5kZSkuIE1hbiB0aXBwdCBhdWYgZGllIFplaWxlOyBgZmVobGVyOmAgaXN0IGlocmUgTnVtbWVyIChhYiAxKSwgYGJlc3NlcjpgIGRpZSByaWNodGlnZSBaZWlsZS4gTWl0IGBkYXRlbjogY3N2YFxuICogICBpc3QgZGVyIOKAnkNvZGXigJwgZWluZSBDU1YtRGF0ZWkgc3RhdHQgSmF2YS5cbiAqIC0gYGZyYWdlYDogQ29kZSAoYXVjaCBsZWVyKSB1bmQgZWluZSBGcmFnZSBtaXQgQW50d29ydGVuLiBgXFxuYCBpbiBlaW5lciBBbnR3b3J0IGJlZ2lubnQgZWluZSBuZXVlIFplaWxlOyBzb2xjaGVcbiAqICAgQW50d29ydGVuIGVyc2NoZWluZW4gYWxzIGtsZWluZSBEYXRlaS5cbiAqIC0gYHJlaWhlbmZvbGdlYCAo4oCeV2VyIGlzdCBkcmFuP+KAnCk6IERpZSBBbnR3b3J0ZW4gc3RlaGVuIGluIGRlciByaWNodGlnZW4gUmVpaGVuZm9sZ2UgZGEgKG9obmUgYFt4XWApLCBkYXMgU3BpZWxcbiAqICAgbWlzY2h0IHNpZS4gTWFuIHRpcHB0IHNpZSBkZXIgUmVpaGUgbmFjaCBhbjsgZWluIGZhbHNjaGVyIFRpcHAgYmVlbmRldCBkaWUgUnVuZGUuXG4gKlxuICogRm9ybWF0IChTY2hsw7xzc2Vsd8O2cnRlciB3aWUgaW4gZGVuIGFuZGVyZW4gQmzDtmNrZW4gYXVmIERldXRzY2gsIGF1Y2ggaW4gZGVuIMOcYmVyc2V0enVuZ2VuKTpcbiAqXG4gKiAgICAgdGl0ZWw6IFNwaWVsOiBWZXJ0cmFnIGVyZsO8bGx0P1xuICogICAgIGludHJvOiBMdWR3aWcgemVpZ3QgZGlyIOKAplxuICogICAgIGFudHdvcnRlbjogZXJmw7xsbHQgfCBuaWNodCBlcmbDvGxsdCAgICAgIChmw7xyIGFsbGUgUnVuZGVuLCBkYW5uIGplIFJ1bmRlIGByaWNodGlnOiDigKZgKVxuICogICAgIGZyYWdlOiDigKYgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoZsO8ciBhbGxlIFJ1bmRlbiwgamUgUnVuZGUgw7xiZXJzY2hyZWliYmFyKVxuICpcbiAqICAgICBydW5kZTpcbiAqICAgICAgICAgQ29kZSwgbWl0IHZpZXIgTGVlcnplaWNoZW4gZWluZ2Vyw7xja3RcbiAqICAgICBrbGlja3M6IEEsIEIgICAgICAgICAgICAgICAgICAgICAgICAgICAgIChudXIgenVob2VyZXI6IEJlc2NocmlmdHVuZ2VuIGRlciBLbsO2cGZlKVxuICogICAgIGZlaGxlcjogMiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKG51ciBib21iZSwgc3RhdHQgQW50d29ydGVuKVxuICogICAgIGJlc3NlcjogU3lzdGVtLm91dC5wcmludGxuKGkpOyAgICAgICAgICAgKG51ciBib21iZSlcbiAqICAgICAtIEFudHdvcnRcbiAqICAgICAtIFt4XSByaWNodGlnZSBBbnR3b3J0XG4gKiAgICAgPiBFcmtsw6RydW5nXG4gKi9cblxuZXhwb3J0IHR5cGUgUm91bmRHYW1lS2luZCA9ICd6dWhvZXJlcicgfCAndmVydHJhZycgfCAnbGF5b3V0JyB8ICdib21iZScgfCAnZnJhZ2UnIHwgJ3JlaWhlbmZvbGdlJ1xuXG5leHBvcnQgaW50ZXJmYWNlIFJvdW5kT3B0aW9uIHtcbiAgdGV4dDogc3RyaW5nXG4gIHJpZ2h0OiBib29sZWFuXG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgUm91bmQge1xuICBjb2RlOiBzdHJpbmdcbiAgcXVlc3Rpb246IHN0cmluZ1xuICBvcHRpb25zOiBSb3VuZE9wdGlvbltdXG4gIGV4cGxhbmF0aW9uOiBzdHJpbmdcbiAgLyoqIEJlc2NocmlmdHVuZ2VuIGRlciBnZWtsaWNrdGVuIEtuw7ZwZmUgKG51ciBgenVob2VyZXJgKS4gKi9cbiAgY2xpY2tzOiBzdHJpbmdbXVxuICAvKiogTnVyIGBib21iZWA6IE51bW1lciBkZXIgZmFsc2NoZW4gWmVpbGUgKGFiIDEpIHVuZCBkaWUgcmljaHRpZ2UgWmVpbGUuICovXG4gIHdyb25nTGluZT86IG51bWJlclxuICBmaXg/OiBzdHJpbmdcbn1cblxuZXhwb3J0IGludGVyZmFjZSBSb3VuZEdhbWUge1xuICBraW5kOiBSb3VuZEdhbWVLaW5kXG4gIHRpdGxlOiBzdHJpbmdcbiAgaW50cm86IHN0cmluZ1xuICAvKiogTnVyIGBib21iZWA6IFNla3VuZGVuIGplIFJ1bmRlLiAqL1xuICBzZWNvbmRzPzogbnVtYmVyXG4gIC8qKiBOdXIgYGJvbWJlYDogV2FzIGluIGRlbiBSdW5kZW4gc3RlaHQsIEphdmEgKFN0YW5kYXJkKSBvZGVyIGVpbmUgQ1NWLURhdGVpLiAqL1xuICBkYXRhPzogJ2NzdidcbiAgcm91bmRzOiBSb3VuZFtdXG59XG5cbmV4cG9ydCBjbGFzcyBSb3VuZEdhbWVFcnJvciBleHRlbmRzIEVycm9yIHt9XG5cbmV4cG9ydCBmdW5jdGlvbiBpc1JvdW5kR2FtZUtpbmQoYXJnOiBzdHJpbmcpOiBhcmcgaXMgUm91bmRHYW1lS2luZCB7XG4gIHJldHVybiBhcmcgPT09ICd6dWhvZXJlcicgfHwgYXJnID09PSAndmVydHJhZycgfHwgYXJnID09PSAnbGF5b3V0JyB8fCBhcmcgPT09ICdib21iZScgfHwgYXJnID09PSAnZnJhZ2UnIHx8IGFyZyA9PT0gJ3JlaWhlbmZvbGdlJ1xufVxuXG5leHBvcnQgZnVuY3Rpb24gcGFyc2VSb3VuZEdhbWUoa2luZDogUm91bmRHYW1lS2luZCwgbGluZXM6IHN0cmluZ1tdLCBmaWxlOiBzdHJpbmcpOiBSb3VuZEdhbWUge1xuICBjb25zdCBmYWlsID0gKG1zZzogc3RyaW5nKTogbmV2ZXIgPT4ge1xuICAgIHRocm93IG5ldyBSb3VuZEdhbWVFcnJvcihgJHtmaWxlfTogJHttc2d9YClcbiAgfVxuICBsZXQgdGl0bGUgPSAnJ1xuICBsZXQgaW50cm8gPSAnJ1xuICBsZXQgcXVlc3Rpb24gPSAnJ1xuICBsZXQgYW5zd2Vyczogc3RyaW5nW10gPSBbXVxuICBsZXQgc2Vjb25kczogbnVtYmVyIHwgdW5kZWZpbmVkXG4gIGxldCBkYXRhOiAnY3N2JyB8IHVuZGVmaW5lZFxuICBjb25zdCByb3VuZHM6IChSb3VuZCAmIHsgcmlnaHRUZXh0Pzogc3RyaW5nIH0pW10gPSBbXVxuICBsZXQgY3VycmVudDogKFJvdW5kICYgeyByaWdodFRleHQ/OiBzdHJpbmcgfSkgfCB1bmRlZmluZWRcbiAgbGV0IGluQ29kZSA9IGZhbHNlXG4gIGZvciAoY29uc3QgcmF3IG9mIGxpbmVzKSB7XG4gICAgY29uc3QgbGluZSA9IHJhdy50cmltKClcbiAgICBpZiAoY3VycmVudCAmJiBpbkNvZGUgJiYgKC9eIHs0fXxeXFx0Ly50ZXN0KHJhdykgfHwgbGluZSA9PT0gJycpKSB7XG4gICAgICBjdXJyZW50LmNvZGUgKz0gKGN1cnJlbnQuY29kZSA/ICdcXG4nIDogJycpICsgcmF3LnJlcGxhY2UoL14oIHs0fXxcXHQpLywgJycpXG4gICAgICBjb250aW51ZVxuICAgIH1cbiAgICBpbkNvZGUgPSBmYWxzZVxuICAgIGlmICghbGluZSkgY29udGludWVcbiAgICBjb25zdCBrZXkgPSAvXih0aXRlbHxpbnRyb3xhbnR3b3J0ZW58ZnJhZ2V8cnVuZGV8a2xpY2tzfHJpY2h0aWd8emVpdHxmZWhsZXJ8YmVzc2VyfGRhdGVuKTpcXHMqKC4qKSQvLmV4ZWMobGluZSlcbiAgICBpZiAoa2V5KSB7XG4gICAgICBjb25zdCBbLCBuYW1lLCB2YWx1ZV0gPSBrZXlcbiAgICAgIGlmIChuYW1lID09PSAncnVuZGUnKSB7XG4gICAgICAgIGN1cnJlbnQgPSB7IGNvZGU6ICcnLCBxdWVzdGlvbiwgb3B0aW9uczogW10sIGV4cGxhbmF0aW9uOiAnJywgY2xpY2tzOiBbXSB9XG4gICAgICAgIHJvdW5kcy5wdXNoKGN1cnJlbnQpXG4gICAgICAgIGluQ29kZSA9IHRydWVcbiAgICAgIH0gZWxzZSBpZiAoIWN1cnJlbnQpIHtcbiAgICAgICAgaWYgKG5hbWUgPT09ICd0aXRlbCcpIHRpdGxlID0gdmFsdWVcbiAgICAgICAgZWxzZSBpZiAobmFtZSA9PT0gJ2ludHJvJykgaW50cm8gPSB2YWx1ZVxuICAgICAgICBlbHNlIGlmIChuYW1lID09PSAnYW50d29ydGVuJykgYW5zd2VycyA9IHZhbHVlLnNwbGl0KCd8JykubWFwKChhKSA9PiBhLnRyaW0oKSlcbiAgICAgICAgZWxzZSBpZiAobmFtZSA9PT0gJ2ZyYWdlJykgcXVlc3Rpb24gPSB2YWx1ZVxuICAgICAgICBlbHNlIGlmIChuYW1lID09PSAnemVpdCcpIHNlY29uZHMgPSBOdW1iZXIodmFsdWUpXG4gICAgICAgIGVsc2UgaWYgKG5hbWUgPT09ICdkYXRlbicpIGRhdGEgPSB2YWx1ZSA9PT0gJ2NzdicgPyB2YWx1ZSA6IGZhaWwoYOKAnmRhdGVuOuKAnCBrZW5udCBudXIg4oCeY3N24oCcLmApXG4gICAgICAgIGVsc2UgZmFpbChg4oCeJHtuYW1lfTrigJwgZ2Vow7ZydCBpbiBlaW5lIFJ1bmRlLmApXG4gICAgICB9IGVsc2UgaWYgKG5hbWUgPT09ICdmcmFnZScpIGN1cnJlbnQucXVlc3Rpb24gPSB2YWx1ZVxuICAgICAgZWxzZSBpZiAobmFtZSA9PT0gJ2ZlaGxlcicpIGN1cnJlbnQud3JvbmdMaW5lID0gTnVtYmVyKHZhbHVlKVxuICAgICAgZWxzZSBpZiAobmFtZSA9PT0gJ2Jlc3NlcicpIGN1cnJlbnQuZml4ID0gdmFsdWVcbiAgICAgIGVsc2UgaWYgKG5hbWUgPT09ICdrbGlja3MnKSBjdXJyZW50LmNsaWNrcyA9IHZhbHVlLnNwbGl0KCcsJykubWFwKChjKSA9PiBjLnRyaW0oKSkuZmlsdGVyKEJvb2xlYW4pXG4gICAgICBlbHNlIGlmIChuYW1lID09PSAncmljaHRpZycpIGN1cnJlbnQucmlnaHRUZXh0ID0gdmFsdWVcbiAgICAgIGVsc2UgZmFpbChg4oCeJHtuYW1lfTrigJwgZ2Vow7ZydCB2b3IgZGllIGVyc3RlIFJ1bmRlLmApXG4gICAgICBjb250aW51ZVxuICAgIH1cbiAgICBpZiAoIWN1cnJlbnQpIGZhaWwoYFVuYmVrYW5udGUgWmVpbGUgdm9yIGRlciBlcnN0ZW4gUnVuZGU6IOKAniR7bGluZX3igJxgKVxuICAgIGNvbnN0IHJvdW5kID0gY3VycmVudCFcbiAgICBjb25zdCBvcHRpb24gPSAvXi1cXHMrKFxcW3hcXF1cXHMrKT8oLispJC8uZXhlYyhsaW5lKVxuICAgIGlmIChvcHRpb24pIHJvdW5kLm9wdGlvbnMucHVzaCh7IHRleHQ6IG9wdGlvblsyXS50cmltKCkucmVwbGFjZUFsbCgnXFxcXG4nLCAnXFxuJyksIHJpZ2h0OiAhIW9wdGlvblsxXSB9KVxuICAgIGVsc2UgaWYgKGxpbmUuc3RhcnRzV2l0aCgnPicpKSByb3VuZC5leHBsYW5hdGlvbiArPSAocm91bmQuZXhwbGFuYXRpb24gPyAnICcgOiAnJykgKyBsaW5lLnNsaWNlKDEpLnRyaW0oKVxuICAgIGVsc2UgZmFpbChgVW5iZWthbm50ZSBaZWlsZSBpbSBTcGllbDog4oCeJHtsaW5lfeKAnGApXG4gIH1cbiAgaWYgKCF0aXRsZSkgZmFpbCgnRGFzIFNwaWVsIGJyYXVjaHQgZWluZSBaZWlsZSDigJ50aXRlbDrigJwuJylcbiAgaWYgKCFyb3VuZHMubGVuZ3RoKSBmYWlsKCdEYXMgU3BpZWwgYnJhdWNodCBtaW5kZXN0ZW5zIGVpbmUg4oCecnVuZGU64oCcLicpXG4gIHJvdW5kcy5mb3JFYWNoKChyb3VuZCwgaSkgPT4ge1xuICAgIHJvdW5kLmNvZGUgPSByb3VuZC5jb2RlLnJlcGxhY2UoL1xcbiskLywgJycpXG4gICAgaWYgKGtpbmQgPT09ICdib21iZScpIHtcbiAgICAgIGNvbnN0IGxpbmVzID0gcm91bmQuY29kZS5zcGxpdCgnXFxuJylcbiAgICAgIGNvbnN0IG4gPSByb3VuZC53cm9uZ0xpbmVcbiAgICAgIGlmICghbiB8fCAhTnVtYmVyLmlzSW50ZWdlcihuKSB8fCBuIDwgMSB8fCBuID4gbGluZXMubGVuZ3RoIHx8ICFsaW5lc1tuIC0gMV0udHJpbSgpKSBmYWlsKGBSdW5kZSAke2kgKyAxfTog4oCeZmVobGVyOuKAnCBtdXNzIGVpbmUgWmVpbGUgZGVzIENvZGVzIHNlaW4uYClcbiAgICAgIGlmICghcm91bmQuZml4KSBmYWlsKGBSdW5kZSAke2kgKyAxfTog4oCeYmVzc2VyOuKAnCBmZWhsdC5gKVxuICAgICAgaWYgKHJvdW5kLm9wdGlvbnMubGVuZ3RoKSBmYWlsKGBSdW5kZSAke2kgKyAxfTogQmVpIOKAnmJvbWJl4oCcIGdpYnQgZXMga2VpbmUgQW50d29ydGVuLCBtYW4gdGlwcHQgYXVmIGRpZSBaZWlsZS5gKVxuICAgICAgaWYgKCFyb3VuZC5xdWVzdGlvbikgZmFpbChgUnVuZGUgJHtpICsgMX06IGtlaW5lIEZyYWdlLmApXG4gICAgICByZXR1cm5cbiAgICB9XG4gICAgaWYgKGtpbmQgPT09ICdyZWloZW5mb2xnZScpIHtcbiAgICAgIGlmIChyb3VuZC5vcHRpb25zLmxlbmd0aCA8IDMpIGZhaWwoYFJ1bmRlICR7aSArIDF9OiDigJ5yZWloZW5mb2xnZeKAnCBicmF1Y2h0IG1pbmRlc3RlbnMgZHJlaSBTY2hyaXR0ZS5gKVxuICAgICAgaWYgKHJvdW5kLm9wdGlvbnMuc29tZSgobykgPT4gby5yaWdodCkpIGZhaWwoYFJ1bmRlICR7aSArIDF9OiBCZWkg4oCecmVpaGVuZm9sZ2XigJwgZ2lidCBlcyBrZWluIFt4XSwgZGllIFNjaHJpdHRlIHN0ZWhlbiBkZXIgUmVpaGUgbmFjaCBkYS5gKVxuICAgICAgaWYgKG5ldyBTZXQocm91bmQub3B0aW9ucy5tYXAoKG8pID0+IG8udGV4dCkpLnNpemUgIT09IHJvdW5kLm9wdGlvbnMubGVuZ3RoKSBmYWlsKGBSdW5kZSAke2kgKyAxfTogendlaSBTY2hyaXR0ZSBzaW5kIGdsZWljaC5gKVxuICAgICAgaWYgKCFyb3VuZC5xdWVzdGlvbikgZmFpbChgUnVuZGUgJHtpICsgMX06IGtlaW5lIEZyYWdlLmApXG4gICAgICByZXR1cm5cbiAgICB9XG4gICAgaWYgKCFyb3VuZC5vcHRpb25zLmxlbmd0aCkge1xuICAgICAgaWYgKCFhbnN3ZXJzLmxlbmd0aCkgZmFpbChgUnVuZGUgJHtpICsgMX06IGtlaW5lIEFudHdvcnRlbi5gKVxuICAgICAgaWYgKCFyb3VuZC5yaWdodFRleHQgfHwgIWFuc3dlcnMuaW5jbHVkZXMocm91bmQucmlnaHRUZXh0KSkgZmFpbChgUnVuZGUgJHtpICsgMX06IOKAnnJpY2h0aWc64oCcIG11c3MgZWluZSBkZXIgQW50d29ydGVuIHNlaW4uYClcbiAgICAgIHJvdW5kLm9wdGlvbnMgPSBhbnN3ZXJzLm1hcCgodGV4dCkgPT4gKHsgdGV4dCwgcmlnaHQ6IHRleHQgPT09IHJvdW5kLnJpZ2h0VGV4dCB9KSlcbiAgICB9XG4gICAgaWYgKHJvdW5kLm9wdGlvbnMuZmlsdGVyKChvKSA9PiBvLnJpZ2h0KS5sZW5ndGggIT09IDEpIGZhaWwoYFJ1bmRlICR7aSArIDF9OiBnZW5hdSBlaW5lIEFudHdvcnQgbXVzcyByaWNodGlnIHNlaW4uYClcbiAgICBpZiAoIXJvdW5kLnF1ZXN0aW9uKSBmYWlsKGBSdW5kZSAke2kgKyAxfToga2VpbmUgRnJhZ2UuYClcbiAgICBpZiAoa2luZCA9PT0gJ2xheW91dCcpIHJvdW5kLm9wdGlvbnMuZm9yRWFjaCgobykgPT4gcGFyc2VMYXlvdXRQaWN0dXJlKG8udGV4dCwgYFJ1bmRlICR7aSArIDF9YCwgZmFpbCkpXG4gICAgaWYgKGtpbmQgPT09ICd6dWhvZXJlcicpIHtcbiAgICAgIHRyeSB7XG4gICAgICAgIGNvbnN0IHdpbmRvdyA9IHBhcnNlU3dpbmdXaW5kb3cocm91bmQuY29kZSlcbiAgICAgICAgZm9yIChjb25zdCBjIG9mIHJvdW5kLmNsaWNrcykgaWYgKCF3aW5kb3cuYnV0dG9ucy5zb21lKChiKSA9PiBiLmNhcHRpb24gPT09IGMpKSBmYWlsKGBSdW5kZSAke2kgKyAxfTogS25vcGYg4oCeJHtjfeKAnCBnaWJ0IGVzIG5pY2h0LmApXG4gICAgICAgIHNpbXVsYXRlKHdpbmRvdywgcm91bmQuY2xpY2tzKVxuICAgICAgfSBjYXRjaCAoZXJyKSB7XG4gICAgICAgIGlmIChlcnIgaW5zdGFuY2VvZiBSb3VuZEdhbWVFcnJvcikgdGhyb3cgZXJyXG4gICAgICAgIGZhaWwoYFJ1bmRlICR7aSArIDF9OiAkeyhlcnIgYXMgRXJyb3IpLm1lc3NhZ2V9YClcbiAgICAgIH1cbiAgICB9XG4gICAgZGVsZXRlIHJvdW5kLnJpZ2h0VGV4dFxuICB9KVxuICBpZiAoa2luZCA9PT0gJ2JvbWJlJyAmJiAhKHNlY29uZHMgJiYgc2Vjb25kcyA+IDApKSBmYWlsKCfigJ5ib21iZeKAnCBicmF1Y2h0IOKAnnplaXQ64oCcIG1pdCBkZW4gU2VrdW5kZW4gamUgUnVuZGUuJylcbiAgcmV0dXJuIHsga2luZCwgdGl0bGUsIGludHJvLCAuLi4oa2luZCA9PT0gJ2JvbWJlJyA/IHsgc2Vjb25kcywgLi4uKGRhdGEgPyB7IGRhdGEgfSA6IHt9KSB9IDoge30pLCByb3VuZHMgfVxufVxuXG4vLyBNQVJLOiAtIExheW91dC1CaWxkZXJcblxuZXhwb3J0IHR5cGUgTGF5b3V0UGljdHVyZSA9XG4gIHwgeyBraW5kOiAnZ3JpZCc7IHJvd3M6IHN0cmluZ1tdW10gfVxuICB8IHsga2luZDogJ2Zsb3cnOyByb3dzOiBzdHJpbmdbXVtdIH1cbiAgfCB7IGtpbmQ6ICdib3JkZXInOyBhcmVhczogUGFydGlhbDxSZWNvcmQ8J04nIHwgJ1MnIHwgJ1cnIHwgJ0UnIHwgJ0MnLCBzdHJpbmc+PiB9XG5cbi8qKiBgZ3JpZDogQSBCIC8gQyBEYCwgYGZsb3c6IEEgQiBDYCwgYGJvcmRlcjogTj1BIEM9QiBTPUNgLiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHBhcnNlTGF5b3V0UGljdHVyZSh0ZXh0OiBzdHJpbmcsIHdoZXJlID0gJycsIGZhaWw6IChtc2c6IHN0cmluZykgPT4gbmV2ZXIgPSAobSkgPT4geyB0aHJvdyBuZXcgUm91bmRHYW1lRXJyb3IobSkgfSk6IExheW91dFBpY3R1cmUge1xuICBjb25zdCBtID0gL14oZ3JpZHxmbG93fGJvcmRlcik6XFxzKiguKykkLy5leGVjKHRleHQpXG4gIGlmICghbSkgcmV0dXJuIGZhaWwoYCR7d2hlcmV9OiBBbnR3b3J0IOKAniR7dGV4dH3igJwgaXN0IGtlaW4gRmVuc3RlcmJpbGQgKGdyaWQ6LCBmbG93OiBvZGVyIGJvcmRlcjopLmApXG4gIGlmIChtWzFdID09PSAnYm9yZGVyJykge1xuICAgIGNvbnN0IGFyZWFzOiBQYXJ0aWFsPFJlY29yZDwnTicgfCAnUycgfCAnVycgfCAnRScgfCAnQycsIHN0cmluZz4+ID0ge31cbiAgICBmb3IgKGNvbnN0IHBhcnQgb2YgbVsyXS5zcGxpdCgvXFxzKy8pKSB7XG4gICAgICBjb25zdCBhID0gL14oW05TV0VDXSk9KC4rKSQvLmV4ZWMocGFydClcbiAgICAgIGlmICghYSkgZmFpbChgJHt3aGVyZX06IOKAniR7cGFydH3igJwgaW0gQm9yZGVyTGF5b3V0LUJpbGQgdmVyc3RlaGUgaWNoIG5pY2h0ICh6LiBCLiBOPUEpLmApXG4gICAgICBhcmVhc1thIVsxXSBhcyAnTiddID0gYSFbMl1cbiAgICB9XG4gICAgcmV0dXJuIHsga2luZDogJ2JvcmRlcicsIGFyZWFzIH1cbiAgfVxuICBjb25zdCByb3dzID0gbVsyXS5zcGxpdCgnLycpLm1hcCgocikgPT4gci50cmltKCkuc3BsaXQoL1xccysvKS5maWx0ZXIoQm9vbGVhbikpXG4gIHJldHVybiB7IGtpbmQ6IG1bMV0gYXMgJ2dyaWQnIHwgJ2Zsb3cnLCByb3dzIH1cbn1cblxuLy8gTUFSSzogLSBOYWNoZ2ViYXV0ZXMgRmVuc3RlciBmw7xyIOKAnldlciBow7ZydCB6dT/igJxcblxuZXhwb3J0IGludGVyZmFjZSBTd2luZ0J1dHRvbiB7XG4gIG5hbWU6IHN0cmluZ1xuICBjYXB0aW9uOiBzdHJpbmdcbn1cblxuZXhwb3J0IGludGVyZmFjZSBTd2luZ0xpc3RlbmVyIHtcbiAgYnV0dG9uOiBzdHJpbmdcbiAgLyoqIFplaWxlbiBkZXMgWnVow7ZyZXJzIGltIENvZGUgKGFiIDAsIGVpbnNjaGxpZcOfbGljaCkuICovXG4gIGZyb206IG51bWJlclxuICB0bzogbnVtYmVyXG4gIHN0YXRlbWVudHM6IFN3aW5nU3RhdGVtZW50W11cbn1cblxuLyoqIEVpbmUgQW53ZWlzdW5nIGltIFp1aMO2cmVyOiBlaW5mYWNoIChgdGV4dC5zZXRUZXh0KOKApilgKSBvZGVyIGBpZiAo4oCmKSB7IOKApiB9IGVsc2UgeyDigKYgfWAuICovXG5leHBvcnQgdHlwZSBTd2luZ1N0YXRlbWVudCA9IHN0cmluZyB8IHsgY29uZGl0aW9uOiBzdHJpbmc7IHRoZW46IFN3aW5nU3RhdGVtZW50W107IG90aGVyd2lzZTogU3dpbmdTdGF0ZW1lbnRbXSB9XG5cbmV4cG9ydCBpbnRlcmZhY2UgU3dpbmdXaW5kb3cge1xuICB0aXRsZTogc3RyaW5nXG4gIGJ1dHRvbnM6IFN3aW5nQnV0dG9uW11cbiAgLyoqIEJlc2NocmlmdHVuZ2VuIChKTGFiZWwpIG1pdCBpaHJlbSBTdGFydHRleHQsIGluIGRlciBSZWloZW5mb2xnZSBpbSBDb2RlLiAqL1xuICBsYWJlbHM6IHsgbmFtZTogc3RyaW5nOyB0ZXh0OiBzdHJpbmcgfVtdXG4gIGludHM6IFJlY29yZDxzdHJpbmcsIG51bWJlcj5cbiAgbGlzdGVuZXJzOiBTd2luZ0xpc3RlbmVyW11cbn1cblxuY29uc3Qgc3RyID0gJ1wiKCg/OlteXCJcXFxcXFxcXF18XFxcXFxcXFwuKSopXCInXG5cbi8qKlxuICogTGllc3QgS27DtnBmZSwgQmVzY2hyaWZ0dW5nZW4sIGludC1WYXJpYWJsZW4gdW5kIFp1aMO2cmVyIGF1cyBlaW5mYWNoZW0gU3dpbmctQ29kZS4gRWluIFp1aMO2cmVyIHN0ZWh0IGRpcmVrdCBhbVxuICogS25vcGYgKGBrbm9wZi5hZGRBY3Rpb25MaXN0ZW5lcihlIC0+IOKApilgKSBvZGVyIGFscyBWYXJpYWJsZSAoYEFjdGlvbkxpc3RlbmVyIHogPSBlIC0+IOKApjtgKSwgZGllIG1pdFxuICogYGtub3BmLmFkZEFjdGlvbkxpc3RlbmVyKHopO2AgYW4gbWVocmVyZW4gS27DtnBmZW4gaMOkbmdlbiBrYW5uLlxuICovXG5leHBvcnQgZnVuY3Rpb24gcGFyc2VTd2luZ1dpbmRvdyhjb2RlOiBzdHJpbmcpOiBTd2luZ1dpbmRvdyB7XG4gIGNvbnN0IGxpbmVzID0gY29kZS5zcGxpdCgnXFxuJylcbiAgY29uc3Qgd2luOiBTd2luZ1dpbmRvdyA9IHsgdGl0bGU6ICcnLCBidXR0b25zOiBbXSwgbGFiZWxzOiBbXSwgaW50czoge30sIGxpc3RlbmVyczogW10gfVxuICBjb25zdCBuYW1lZCA9IG5ldyBNYXA8c3RyaW5nLCBPbWl0PFN3aW5nTGlzdGVuZXIsICdidXR0b24nPj4oKVxuICAvKiogWnVow7ZyZXIgYWIgWmVpbGUgaSwgYHJlc3RgIGlzdCBkZXIgVGV4dCBoaW50ZXIgZGVtIFBmZWlsOyBgZW5kYCBzY2hsaWXDn3QgZWluZW4gQmxvY2sgYWIgKGB9KTtgIG9kZXIgYH07YCkuICovXG4gIGNvbnN0IGxhbWJkYSA9IChpOiBudW1iZXIsIHJlc3Q6IHN0cmluZywgZW5kOiBzdHJpbmcpOiBPbWl0PFN3aW5nTGlzdGVuZXIsICdidXR0b24nPiA9PiB7XG4gICAgaWYgKHJlc3Quc3RhcnRzV2l0aCgneycpKSB7XG4gICAgICBsZXQgaiA9IGkgKyAxXG4gICAgICBjb25zdCBib2R5OiBzdHJpbmdbXSA9IFtdXG4gICAgICB3aGlsZSAoaiA8IGxpbmVzLmxlbmd0aCAmJiBsaW5lc1tqXS50cmltKCkgIT09IGVuZCkgYm9keS5wdXNoKGxpbmVzW2orK10udHJpbSgpKVxuICAgICAgaWYgKGogPj0gbGluZXMubGVuZ3RoKSB0aHJvdyBuZXcgRXJyb3IoYERlbSBadWjDtnJlciBmZWhsdCDigJ4ke2VuZH3igJwuYClcbiAgICAgIHJldHVybiB7IGZyb206IGksIHRvOiBqLCBzdGF0ZW1lbnRzOiBwYXJzZVN0YXRlbWVudHMoYm9keS5qb2luKCcgJykpIH1cbiAgICB9XG4gICAgY29uc3QgaW5uZXIgPSBlbmQgPT09ICd9KTsnID8gcmVzdC5yZXBsYWNlKC9cXClcXHMqO1xccyokLywgJycpIDogcmVzdC5yZXBsYWNlKC87XFxzKiQvLCAnJylcbiAgICByZXR1cm4geyBmcm9tOiBpLCB0bzogaSwgc3RhdGVtZW50czogcGFyc2VTdGF0ZW1lbnRzKGlubmVyKSB9XG4gIH1cbiAgY29uc3QgYnV0dG9uID0gKG5hbWU6IHN0cmluZykgPT4ge1xuICAgIGlmICghd2luLmJ1dHRvbnMuc29tZSgoYikgPT4gYi5uYW1lID09PSBuYW1lKSkgdGhyb3cgbmV3IEVycm9yKGBLbm9wZiAke25hbWV9IGlzdCBuaWNodCBhbmdlbGVndC5gKVxuICAgIHJldHVybiBuYW1lXG4gIH1cbiAgZm9yIChsZXQgaSA9IDA7IGkgPCBsaW5lcy5sZW5ndGg7IGkrKykge1xuICAgIGNvbnN0IGxpbmUgPSBsaW5lc1tpXS50cmltKClcbiAgICBsZXQgbTogUmVnRXhwRXhlY0FycmF5IHwgbnVsbFxuICAgIGlmICgobSA9IG5ldyBSZWdFeHAoYF5KRnJhbWVcXFxccytcXFxcdytcXFxccyo9XFxcXHMqbmV3IEpGcmFtZVxcXFwoJHtzdHJ9XFxcXClgKS5leGVjKGxpbmUpKSkgd2luLnRpdGxlID0gbVsxXVxuICAgIGVsc2UgaWYgKChtID0gbmV3IFJlZ0V4cChgXkpCdXR0b25cXFxccysoXFxcXHcrKVxcXFxzKj1cXFxccypuZXcgSkJ1dHRvblxcXFwoJHtzdHJ9XFxcXClgKS5leGVjKGxpbmUpKSkgd2luLmJ1dHRvbnMucHVzaCh7IG5hbWU6IG1bMV0sIGNhcHRpb246IG1bMl0gfSlcbiAgICBlbHNlIGlmICgobSA9IG5ldyBSZWdFeHAoYF5KTGFiZWxcXFxccysoXFxcXHcrKVxcXFxzKj1cXFxccypuZXcgSkxhYmVsXFxcXCgke3N0cn1gKS5leGVjKGxpbmUpKSkgd2luLmxhYmVscy5wdXNoKHsgbmFtZTogbVsxXSwgdGV4dDogbVsyXSB9KVxuICAgIGVsc2UgaWYgKChtID0gL14oPzpzdGF0aWNcXHMrKT9pbnRcXHMrKFxcdyspXFxzKj1cXHMqKC0/XFxkKylcXHMqOy8uZXhlYyhsaW5lKSkpIHdpbi5pbnRzW21bMV1dID0gTnVtYmVyKG1bMl0pXG4gICAgZWxzZSBpZiAoKG0gPSAvXkFjdGlvbkxpc3RlbmVyXFxzKyhcXHcrKVxccyo9XFxzKlxcdytcXHMqLT5cXHMqKC4qKSQvLmV4ZWMobGluZSkpKSB7XG4gICAgICBjb25zdCBsaXN0ZW5lciA9IGxhbWJkYShpLCBtWzJdLCAnfTsnKVxuICAgICAgbmFtZWQuc2V0KG1bMV0sIGxpc3RlbmVyKVxuICAgICAgaSA9IGxpc3RlbmVyLnRvXG4gICAgfSBlbHNlIGlmICgobSA9IC9eKFxcdyspXFwuYWRkQWN0aW9uTGlzdGVuZXJcXChcXHMqKFxcdyspXFxzKlxcKVxccyo7JC8uZXhlYyhsaW5lKSkpIHtcbiAgICAgIGNvbnN0IGxpc3RlbmVyID0gbmFtZWQuZ2V0KG1bMl0pXG4gICAgICBpZiAoIWxpc3RlbmVyKSB0aHJvdyBuZXcgRXJyb3IoYFp1aMO2cmVyICR7bVsyXX0gaXN0IG5pY2h0IGFuZ2VsZWd0LmApXG4gICAgICB3aW4ubGlzdGVuZXJzLnB1c2goeyBidXR0b246IGJ1dHRvbihtWzFdKSwgLi4ubGlzdGVuZXIgfSlcbiAgICB9IGVsc2UgaWYgKChtID0gL14oXFx3KylcXC5hZGRBY3Rpb25MaXN0ZW5lclxcKFxccypcXHcrXFxzKi0+XFxzKiguKikkLy5leGVjKGxpbmUpKSkge1xuICAgICAgY29uc3QgbGlzdGVuZXIgPSBsYW1iZGEoaSwgbVsyXSwgJ30pOycpXG4gICAgICB3aW4ubGlzdGVuZXJzLnB1c2goeyBidXR0b246IGJ1dHRvbihtWzFdKSwgLi4ubGlzdGVuZXIgfSlcbiAgICAgIGkgPSBsaXN0ZW5lci50b1xuICAgIH1cbiAgfVxuICByZXR1cm4gd2luXG59XG5cbi8qKiBaZXJsZWd0IGRlbiBSdW1wZiBlaW5lcyBadWjDtnJlcnMgaW4gQW53ZWlzdW5nZW4sIGBpZmAvYGVsc2VgIG1pdCBvZGVyIG9obmUgZ2VzY2h3ZWlmdGUgS2xhbW1lcm4uICovXG5mdW5jdGlvbiBwYXJzZVN0YXRlbWVudHModGV4dDogc3RyaW5nKTogU3dpbmdTdGF0ZW1lbnRbXSB7XG4gIGNvbnN0IG91dDogU3dpbmdTdGF0ZW1lbnRbXSA9IFtdXG4gIGxldCBwb3MgPSAwXG4gIGNvbnN0IHNraXAgPSAoKSA9PiB7XG4gICAgd2hpbGUgKHBvcyA8IHRleHQubGVuZ3RoICYmIC9cXHMvLnRlc3QodGV4dFtwb3NdKSkgcG9zKytcbiAgfVxuICAvKiogVGV4dCBiaXMgenVyIHBhc3NlbmRlbiBzY2hsaWXDn2VuZGVuIEtsYW1tZXI7IGBwb3NgIHN0ZWh0IGF1ZiBkZXIgw7ZmZm5lbmRlbi4gKi9cbiAgY29uc3QgYmFsYW5jZWQgPSAob3Blbjogc3RyaW5nLCBjbG9zZTogc3RyaW5nKTogc3RyaW5nID0+IHtcbiAgICBsZXQgZGVwdGggPSAwXG4gICAgbGV0IHF1b3RlID0gZmFsc2VcbiAgICBjb25zdCBzdGFydCA9IHBvcyArIDFcbiAgICBmb3IgKDsgcG9zIDwgdGV4dC5sZW5ndGg7IHBvcysrKSB7XG4gICAgICBjb25zdCBjID0gdGV4dFtwb3NdXG4gICAgICBpZiAocXVvdGUpIHtcbiAgICAgICAgaWYgKGMgPT09ICdcXFxcJykgcG9zKytcbiAgICAgICAgZWxzZSBpZiAoYyA9PT0gJ1wiJykgcXVvdGUgPSBmYWxzZVxuICAgICAgfSBlbHNlIGlmIChjID09PSAnXCInKSBxdW90ZSA9IHRydWVcbiAgICAgIGVsc2UgaWYgKGMgPT09IG9wZW4pIGRlcHRoKytcbiAgICAgIGVsc2UgaWYgKGMgPT09IGNsb3NlICYmIC0tZGVwdGggPT09IDApIHJldHVybiB0ZXh0LnNsaWNlKHN0YXJ0LCBwb3MrKylcbiAgICB9XG4gICAgdGhyb3cgbmV3IEVycm9yKGBFcyBmZWhsdCDigJ4ke2Nsb3NlfeKAnC5gKVxuICB9XG4gIC8qKiBFaW5lIGVpbmZhY2hlIEFud2Vpc3VuZyBiaXMgenVtIFNlbWlrb2xvbiBhdcOfZXJoYWxiIHZvbiBLbGFtbWVybiB1bmQgVGV4dC4gKi9cbiAgY29uc3Qgc2ltcGxlID0gKCk6IHN0cmluZyA9PiB7XG4gICAgbGV0IGRlcHRoID0gMFxuICAgIGxldCBxdW90ZSA9IGZhbHNlXG4gICAgY29uc3Qgc3RhcnQgPSBwb3NcbiAgICBmb3IgKDsgcG9zIDwgdGV4dC5sZW5ndGg7IHBvcysrKSB7XG4gICAgICBjb25zdCBjID0gdGV4dFtwb3NdXG4gICAgICBpZiAocXVvdGUpIHtcbiAgICAgICAgaWYgKGMgPT09ICdcXFxcJykgcG9zKytcbiAgICAgICAgZWxzZSBpZiAoYyA9PT0gJ1wiJykgcXVvdGUgPSBmYWxzZVxuICAgICAgfSBlbHNlIGlmIChjID09PSAnXCInKSBxdW90ZSA9IHRydWVcbiAgICAgIGVsc2UgaWYgKGMgPT09ICcoJykgZGVwdGgrK1xuICAgICAgZWxzZSBpZiAoYyA9PT0gJyknKSBkZXB0aC0tXG4gICAgICBlbHNlIGlmIChjID09PSAnOycgJiYgZGVwdGggPT09IDApIHJldHVybiB0ZXh0LnNsaWNlKHN0YXJ0LCBwb3MrKykudHJpbSgpXG4gICAgfVxuICAgIHJldHVybiB0ZXh0LnNsaWNlKHN0YXJ0KS50cmltKClcbiAgfVxuICBjb25zdCBvbmUgPSAoKTogU3dpbmdTdGF0ZW1lbnRbXSA9PiB7XG4gICAgc2tpcCgpXG4gICAgaWYgKHRleHRbcG9zXSA9PT0gJ3snKSByZXR1cm4gcGFyc2VTdGF0ZW1lbnRzKGJhbGFuY2VkKCd7JywgJ30nKSlcbiAgICBpZiAoL15pZlxccypcXCgvLnRlc3QodGV4dC5zbGljZShwb3MpKSkge1xuICAgICAgcG9zID0gdGV4dC5pbmRleE9mKCcoJywgcG9zKVxuICAgICAgY29uc3QgY29uZGl0aW9uID0gYmFsYW5jZWQoJygnLCAnKScpLnRyaW0oKVxuICAgICAgY29uc3QgdGhlbiA9IG9uZSgpXG4gICAgICBza2lwKClcbiAgICAgIGxldCBvdGhlcndpc2U6IFN3aW5nU3RhdGVtZW50W10gPSBbXVxuICAgICAgaWYgKC9eZWxzZVxcYi8udGVzdCh0ZXh0LnNsaWNlKHBvcykpKSB7XG4gICAgICAgIHBvcyArPSA0XG4gICAgICAgIG90aGVyd2lzZSA9IG9uZSgpXG4gICAgICB9XG4gICAgICByZXR1cm4gW3sgY29uZGl0aW9uLCB0aGVuLCBvdGhlcndpc2UgfV1cbiAgICB9XG4gICAgY29uc3QgcyA9IHNpbXBsZSgpXG4gICAgcmV0dXJuIHMgPyBbc10gOiBbXVxuICB9XG4gIGZvciAoc2tpcCgpOyBwb3MgPCB0ZXh0Lmxlbmd0aDsgc2tpcCgpKSBvdXQucHVzaCguLi5vbmUoKSlcbiAgcmV0dXJuIG91dFxufVxuXG5leHBvcnQgaW50ZXJmYWNlIENsaWNrU3RlcCB7XG4gIGJ1dHRvbjogc3RyaW5nXG4gIC8qKiBadWjDtnJlciwgZGVyIGxpZWY7IGB1bmRlZmluZWRgOiBOaWVtYW5kIGjDtnJ0IHp1LiAqL1xuICBsaXN0ZW5lcj86IFN3aW5nTGlzdGVuZXJcbiAgLyoqIFRleHRlIGFsbGVyIEJlc2NocmlmdHVuZ2VuIHVuZCBLbsO2cGZlIG5hY2ggZGVtIEtsaWNrIChOYW1lIOKGkiBUZXh0KS4gKi9cbiAgdGV4dHM6IFJlY29yZDxzdHJpbmcsIHN0cmluZz5cbiAgY29uc29sZTogc3RyaW5nW11cbn1cblxuZXhwb3J0IGludGVyZmFjZSBTd2luZ1N0YXRlIHtcbiAgdGV4dHM6IFJlY29yZDxzdHJpbmcsIHN0cmluZz5cbiAgaW50czogUmVjb3JkPHN0cmluZywgbnVtYmVyPlxufVxuXG5leHBvcnQgZnVuY3Rpb24gc3RhcnRTdGF0ZSh3aW46IFN3aW5nV2luZG93KTogU3dpbmdTdGF0ZSB7XG4gIGNvbnN0IHRleHRzOiBSZWNvcmQ8c3RyaW5nLCBzdHJpbmc+ID0ge31cbiAgZm9yIChjb25zdCBiIG9mIHdpbi5idXR0b25zKSB0ZXh0c1tiLm5hbWVdID0gYi5jYXB0aW9uXG4gIGZvciAoY29uc3QgbCBvZiB3aW4ubGFiZWxzKSB0ZXh0c1tsLm5hbWVdID0gbC50ZXh0XG4gIHJldHVybiB7IHRleHRzLCBpbnRzOiB7IC4uLndpbi5pbnRzIH0gfVxufVxuXG4vKiogRWluIEtsaWNrIGF1ZiBkZW4gS25vcGYgbWl0IGRpZXNlciBCZXNjaHJpZnR1bmcgKHZlcsOkbmRlcnQgYHN0YXRlYCkuICovXG5leHBvcnQgZnVuY3Rpb24gY2xpY2sod2luOiBTd2luZ1dpbmRvdywgc3RhdGU6IFN3aW5nU3RhdGUsIGNhcHRpb246IHN0cmluZyk6IENsaWNrU3RlcCB7XG4gIGNvbnN0IGJ1dHRvbiA9IHdpbi5idXR0b25zLmZpbmQoKGIpID0+IGIuY2FwdGlvbiA9PT0gY2FwdGlvbikgPz8gd2luLmJ1dHRvbnMuZmluZCgoYikgPT4gc3RhdGUudGV4dHNbYi5uYW1lXSA9PT0gY2FwdGlvbilcbiAgaWYgKCFidXR0b24pIHRocm93IG5ldyBFcnJvcihgS25vcGYg4oCeJHtjYXB0aW9ufeKAnCBnaWJ0IGVzIG5pY2h0LmApXG4gIHJldHVybiBjbGlja0J1dHRvbih3aW4sIHN0YXRlLCBidXR0b24ubmFtZSlcbn1cblxuLyoqIEtsaWNrIGF1ZiBkZW4gS25vcGYgbWl0IGRpZXNlbSBWYXJpYWJsZW5uYW1lbi4gKi9cbmV4cG9ydCBmdW5jdGlvbiBjbGlja0J1dHRvbih3aW46IFN3aW5nV2luZG93LCBzdGF0ZTogU3dpbmdTdGF0ZSwgbmFtZTogc3RyaW5nKTogQ2xpY2tTdGVwIHtcbiAgY29uc3QgbGlzdGVuZXIgPSB3aW4ubGlzdGVuZXJzLmZpbmQoKGwpID0+IGwuYnV0dG9uID09PSBuYW1lKVxuICBjb25zdCBvdXRwdXQ6IHN0cmluZ1tdID0gW11cbiAgLy8gYGUuZ2V0QWN0aW9uQ29tbWFuZCgpYCBpc3Qgd2llIGluIEphdmEgZGllIEJlc2NocmlmdHVuZyBkZXMgS25vcGZzIGJlaW0gS2xpY2suXG4gIGNvbnN0IGV2ZW50OiBTd2luZ0V2ZW50ID0geyBzb3VyY2U6IG5hbWUsIGNvbW1hbmQ6IHN0YXRlLnRleHRzW25hbWVdIH1cbiAgZm9yIChjb25zdCBzIG9mIGxpc3RlbmVyPy5zdGF0ZW1lbnRzID8/IFtdKSBydW4ocywgc3RhdGUsIG91dHB1dCwgZXZlbnQpXG4gIHJldHVybiB7IGJ1dHRvbjogbmFtZSwgbGlzdGVuZXIsIHRleHRzOiB7IC4uLnN0YXRlLnRleHRzIH0sIGNvbnNvbGU6IG91dHB1dCB9XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBzaW11bGF0ZSh3aW46IFN3aW5nV2luZG93LCBjbGlja3M6IHN0cmluZ1tdKTogQ2xpY2tTdGVwW10ge1xuICBjb25zdCBzdGF0ZSA9IHN0YXJ0U3RhdGUod2luKVxuICByZXR1cm4gY2xpY2tzLm1hcCgoYykgPT4gY2xpY2sod2luLCBzdGF0ZSwgYykpXG59XG5cbmludGVyZmFjZSBTd2luZ0V2ZW50IHtcbiAgc291cmNlOiBzdHJpbmdcbiAgY29tbWFuZDogc3RyaW5nXG59XG5cbmZ1bmN0aW9uIHJ1bihzdGF0ZW1lbnQ6IFN3aW5nU3RhdGVtZW50LCBzdGF0ZTogU3dpbmdTdGF0ZSwgb3V0cHV0OiBzdHJpbmdbXSwgZXZlbnQ6IFN3aW5nRXZlbnQpIHtcbiAgaWYgKHR5cGVvZiBzdGF0ZW1lbnQgIT09ICdzdHJpbmcnKSB7XG4gICAgZm9yIChjb25zdCBzIG9mIGNvbmRpdGlvbihzdGF0ZW1lbnQuY29uZGl0aW9uLCBzdGF0ZSwgZXZlbnQpID8gc3RhdGVtZW50LnRoZW4gOiBzdGF0ZW1lbnQub3RoZXJ3aXNlKSBydW4ocywgc3RhdGUsIG91dHB1dCwgZXZlbnQpXG4gICAgcmV0dXJuXG4gIH1cbiAgbGV0IG06IFJlZ0V4cEV4ZWNBcnJheSB8IG51bGxcbiAgaWYgKChtID0gL14oXFx3KylcXC5zZXRUZXh0XFwoKC4qKVxcKSQvLmV4ZWMoc3RhdGVtZW50KSkpIHtcbiAgICBpZiAoIShtWzFdIGluIHN0YXRlLnRleHRzKSkgdGhyb3cgbmV3IEVycm9yKGAke21bMV19IGlzdCBrZWluZSBCZXNjaHJpZnR1bmcgdW5kIGtlaW4gS25vcGYuYClcbiAgICBzdGF0ZS50ZXh0c1ttWzFdXSA9IFN0cmluZyhldmFsdWF0ZShtWzJdLCBzdGF0ZSwgZXZlbnQpKVxuICB9IGVsc2UgaWYgKChtID0gL15TeXN0ZW1cXC5vdXRcXC5wcmludGxuXFwoKC4qKVxcKSQvLmV4ZWMoc3RhdGVtZW50KSkpIG91dHB1dC5wdXNoKFN0cmluZyhldmFsdWF0ZShtWzFdLCBzdGF0ZSwgZXZlbnQpKSlcbiAgZWxzZSBpZiAoKG0gPSAvXihcXHcrKVxccyooXFwrXFwrfC0tKSQvLmV4ZWMoc3RhdGVtZW50KSkpIHN0YXRlLmludHNbaW50TmFtZShtWzFdLCBzdGF0ZSldICs9IG1bMl0gPT09ICcrKycgPyAxIDogLTFcbiAgZWxzZSBpZiAoKG0gPSAvXihcXHcrKVxccyooWystXT89KVxccyooLispJC8uZXhlYyhzdGF0ZW1lbnQpKSkge1xuICAgIGNvbnN0IG5hbWUgPSBpbnROYW1lKG1bMV0sIHN0YXRlKVxuICAgIGNvbnN0IHZhbHVlID0gTnVtYmVyKGV2YWx1YXRlKG1bM10sIHN0YXRlLCBldmVudCkpXG4gICAgc3RhdGUuaW50c1tuYW1lXSA9IG1bMl0gPT09ICc9JyA/IHZhbHVlIDogbVsyXSA9PT0gJys9JyA/IHN0YXRlLmludHNbbmFtZV0gKyB2YWx1ZSA6IHN0YXRlLmludHNbbmFtZV0gLSB2YWx1ZVxuICB9IGVsc2UgdGhyb3cgbmV3IEVycm9yKGBEaWVzZSBBbndlaXN1bmcga2FubiBkYXMgU3BpZWwgbmljaHQgbmFjaHNwaWVsZW46IOKAniR7c3RhdGVtZW50feKAnGApXG59XG5cbi8qKiBgZS5nZXRTb3VyY2UoKSA9PSBrbm9wZmAsIGB0ZXh0LmVxdWFscyhcIitcIilgLCBgemFobCA+IDNgICovXG5mdW5jdGlvbiBjb25kaXRpb24odGV4dDogc3RyaW5nLCBzdGF0ZTogU3dpbmdTdGF0ZSwgZXZlbnQ6IFN3aW5nRXZlbnQpOiBib29sZWFuIHtcbiAgbGV0IG06IFJlZ0V4cEV4ZWNBcnJheSB8IG51bGxcbiAgaWYgKChtID0gL15lXFwuZ2V0U291cmNlXFwoXFwpXFxzKig9PXwhPSlcXHMqKFxcdyspJC8uZXhlYyh0ZXh0KSkpIHtcbiAgICBpZiAoIShtWzJdIGluIHN0YXRlLnRleHRzKSkgdGhyb3cgbmV3IEVycm9yKGAke21bMl19IGlzdCBrZWluIEtub3BmLmApXG4gICAgcmV0dXJuIChldmVudC5zb3VyY2UgPT09IG1bMl0pID09PSAobVsxXSA9PT0gJz09JylcbiAgfVxuICBpZiAoKG0gPSAvXighPykoLispXFwuZXF1YWxzXFwoKC4rKVxcKSQvLmV4ZWModGV4dCkpKSByZXR1cm4gKFN0cmluZyhldmFsdWF0ZShtWzJdLCBzdGF0ZSwgZXZlbnQpKSA9PT0gU3RyaW5nKGV2YWx1YXRlKG1bM10sIHN0YXRlLCBldmVudCkpKSAhPT0gKG1bMV0gPT09ICchJylcbiAgaWYgKChtID0gL14oLis/KVxccyooPT18IT18PD18Pj18PHw+KVxccyooLispJC8uZXhlYyh0ZXh0KSkpIHtcbiAgICBjb25zdCBhID0gTnVtYmVyKGV2YWx1YXRlKG1bMV0sIHN0YXRlLCBldmVudCkpXG4gICAgY29uc3QgYiA9IE51bWJlcihldmFsdWF0ZShtWzNdLCBzdGF0ZSwgZXZlbnQpKVxuICAgIHJldHVybiB7ICc9PSc6IGEgPT09IGIsICchPSc6IGEgIT09IGIsICc8PSc6IGEgPD0gYiwgJz49JzogYSA+PSBiLCAnPCc6IGEgPCBiLCAnPic6IGEgPiBiIH1bbVsyXV0hXG4gIH1cbiAgdGhyb3cgbmV3IEVycm9yKGBEaWVzZSBCZWRpbmd1bmcga2FubiBkYXMgU3BpZWwgbmljaHQgbmFjaHNwaWVsZW46IOKAniR7dGV4dH3igJxgKVxufVxuXG5mdW5jdGlvbiBpbnROYW1lKG5hbWU6IHN0cmluZywgc3RhdGU6IFN3aW5nU3RhdGUpOiBzdHJpbmcge1xuICBpZiAoIShuYW1lIGluIHN0YXRlLmludHMpKSB0aHJvdyBuZXcgRXJyb3IoYFZhcmlhYmxlICR7bmFtZX0gaXN0IG5pY2h0IGFuZ2VsZWd0LmApXG4gIHJldHVybiBuYW1lXG59XG5cbi8qKiBgXCJUZXh0XCIgKyB6YWhsYCwgYFwiXCIgKyAoYSArIGIpYCwgYHphaGwgKiAyYCwgYGUuZ2V0QWN0aW9uQ29tbWFuZCgpYDogdm9uIGxpbmtzIG5hY2ggcmVjaHRzIHdpZSBpbiBKYXZhLiAqL1xuZnVuY3Rpb24gZXZhbHVhdGUoZXhwcjogc3RyaW5nLCBzdGF0ZTogU3dpbmdTdGF0ZSwgZXZlbnQ/OiBTd2luZ0V2ZW50KTogc3RyaW5nIHwgbnVtYmVyIHtcbiAgY29uc3QgdG9rZW5zID0gZXhwci5tYXRjaChuZXcgUmVnRXhwKGAke3N0cn18XFxcXGQrfGVcXFxcLmdldEFjdGlvbkNvbW1hbmRcXFxcKFxcXFwpfFxcXFx3Kyg/OlxcXFwuZ2V0VGV4dFxcXFwoXFxcXCkpP3xbLSsqLygpXWAsICdnJykpID8/IFtdXG4gIGxldCBwb3MgPSAwXG4gIGNvbnN0IGF0b20gPSAoKTogc3RyaW5nIHwgbnVtYmVyID0+IHtcbiAgICBjb25zdCB0b2sgPSB0b2tlbnNbcG9zKytdXG4gICAgaWYgKHRvayA9PT0gdW5kZWZpbmVkKSB0aHJvdyBuZXcgRXJyb3IoYFVudm9sbHN0w6RuZGlnZXIgQXVzZHJ1Y2sg4oCeJHtleHByfeKAnGApXG4gICAgaWYgKHRvayA9PT0gJygnKSB7XG4gICAgICBjb25zdCB2ID0gc3VtKClcbiAgICAgIHBvcysrXG4gICAgICByZXR1cm4gdlxuICAgIH1cbiAgICBpZiAodG9rLnN0YXJ0c1dpdGgoJ1wiJykpIHJldHVybiBKU09OLnBhcnNlKHRvaylcbiAgICBpZiAoL15cXGQrJC8udGVzdCh0b2spKSByZXR1cm4gTnVtYmVyKHRvaylcbiAgICBpZiAodG9rID09PSAnZS5nZXRBY3Rpb25Db21tYW5kKCknKSB7XG4gICAgICBpZiAoIWV2ZW50KSB0aHJvdyBuZXcgRXJyb3IoJ2UuZ2V0QWN0aW9uQ29tbWFuZCgpIGdpYnQgZXMgbnVyIGltIFp1aMO2cmVyLicpXG4gICAgICByZXR1cm4gZXZlbnQuY29tbWFuZFxuICAgIH1cbiAgICBpZiAodG9rLmVuZHNXaXRoKCcuZ2V0VGV4dCgpJykpIHJldHVybiBzdGF0ZS50ZXh0c1t0b2suc2xpY2UoMCwgLTEwKV0gPz8gJydcbiAgICBpZiAodG9rIGluIHN0YXRlLmludHMpIHJldHVybiBzdGF0ZS5pbnRzW3Rva11cbiAgICB0aHJvdyBuZXcgRXJyb3IoYFVuYmVrYW5udDog4oCeJHt0b2t94oCcYClcbiAgfVxuICBjb25zdCBwcm9kdWN0ID0gKCk6IHN0cmluZyB8IG51bWJlciA9PiB7XG4gICAgbGV0IHYgPSBhdG9tKClcbiAgICB3aGlsZSAodG9rZW5zW3Bvc10gPT09ICcqJyB8fCB0b2tlbnNbcG9zXSA9PT0gJy8nKSB7XG4gICAgICBjb25zdCBvcCA9IHRva2Vuc1twb3MrK11cbiAgICAgIGNvbnN0IHIgPSBOdW1iZXIoYXRvbSgpKVxuICAgICAgdiA9IG9wID09PSAnKicgPyBOdW1iZXIodikgKiByIDogTWF0aC50cnVuYyhOdW1iZXIodikgLyByKVxuICAgIH1cbiAgICByZXR1cm4gdlxuICB9XG4gIGNvbnN0IHN1bSA9ICgpOiBzdHJpbmcgfCBudW1iZXIgPT4ge1xuICAgIGxldCB2ID0gcHJvZHVjdCgpXG4gICAgd2hpbGUgKHRva2Vuc1twb3NdID09PSAnKycgfHwgdG9rZW5zW3Bvc10gPT09ICctJykge1xuICAgICAgY29uc3Qgb3AgPSB0b2tlbnNbcG9zKytdXG4gICAgICBjb25zdCByID0gcHJvZHVjdCgpXG4gICAgICBpZiAob3AgPT09ICcrJykgdiA9IHR5cGVvZiB2ID09PSAnc3RyaW5nJyB8fCB0eXBlb2YgciA9PT0gJ3N0cmluZycgPyBgJHt2fSR7cn1gIDogdiArIHJcbiAgICAgIGVsc2UgdiA9IE51bWJlcih2KSAtIE51bWJlcihyKVxuICAgIH1cbiAgICByZXR1cm4gdlxuICB9XG4gIHJldHVybiBzdW0oKVxufVxuIl0sImZpbGUiOiIvd2ViL3NyYy9sZWFybi9yb3VuZEdhbWUudHMifQ== + +//# vitestCache=W3siZmlsZSI6IjEiLCJpZCI6IjEiLCJ1cmwiOiIyIiwiaW1wb3J0cyI6IjMiLCJtYXBwaW5ncyI6ZmFsc2UsImRlcHMiOiI0IiwiZHluYW1pY0RlcHMiOiI1Iiwic3RhdGljTW9ja3MiOm51bGx9LCIvaG9tZS91c2VyL3Zpc3VzdHJ1Y3Qtc3dpZnR1aS93ZWIvc3JjL2xlYXJuL3JvdW5kR2FtZS50cyIsIi93ZWIvc3JjL2xlYXJuL3JvdW5kR2FtZS50cyIseyJ1cmxzIjoiNiIsImlkcyI6IjcifSxbXSxbXSxbXSx7fV0= \ No newline at end of file diff --git a/node_modules/.vitest-cache/CACHEDIR.TAG b/node_modules/.vitest-cache/CACHEDIR.TAG new file mode 100644 index 00000000..8c1ef4ce --- /dev/null +++ b/node_modules/.vitest-cache/CACHEDIR.TAG @@ -0,0 +1,3 @@ +Signature: 8a477f597d28d172789f06886806bc55 +# This file is a cache directory tag created by Vitest. +# For information about cache directory tags see https://bford.info/cachedir/ diff --git a/node_modules/.vitest-cache/_metadata.json b/node_modules/.vitest-cache/_metadata.json new file mode 100644 index 00000000..9ee9061a --- /dev/null +++ b/node_modules/.vitest-cache/_metadata.json @@ -0,0 +1,3 @@ +{ + "lockfileHash": "e3b0c442" +} \ No newline at end of file diff --git a/node_modules/.vitest-cache/a24f3c2d2711027964cf8cac3e5bdea117013f42 b/node_modules/.vitest-cache/a24f3c2d2711027964cf8cac3e5bdea117013f42 new file mode 100644 index 00000000..83c183a5 --- /dev/null +++ b/node_modules/.vitest-cache/a24f3c2d2711027964cf8cac3e5bdea117013f42 @@ -0,0 +1,587 @@ +__vite_ssr_exportName__("MBOT_LED_COUNT", () => { try { return MBOT_LED_COUNT } catch {} }); +__vite_ssr_exportName__("MBOT_LED_COLORS", () => { try { return MBOT_LED_COLORS } catch {} }); +__vite_ssr_exportName__("MBOT_EMOTIONS", () => { try { return MBOT_EMOTIONS } catch {} }); +__vite_ssr_exportName__("MBOT_STEP_CM", () => { try { return MBOT_STEP_CM } catch {} }); +__vite_ssr_exportName__("MBOT_COMMANDS", () => { try { return MBOT_COMMANDS } catch {} }); +__vite_ssr_exportName__("MBOT_COLORS", () => { try { return MBOT_COLORS } catch {} }); +__vite_ssr_exportName__("setMBotColorLanguage", () => { try { return setMBotColorLanguage } catch {} }); +__vite_ssr_exportName__("mbotColorLanguage", () => { try { return mbotColorLanguage } catch {} }); +__vite_ssr_exportName__("mbotColorName", () => { try { return mbotColorName } catch {} }); +__vite_ssr_exportName__("MBOT_SENSORS", () => { try { return MBOT_SENSORS } catch {} }); +__vite_ssr_exportName__("usedMBotSensors", () => { try { return usedMBotSensors } catch {} }); +__vite_ssr_exportName__("parseMBotCommand", () => { try { return parseMBotCommand } catch {} }); +__vite_ssr_exportName__("mbotArguments", () => { try { return mbotArguments } catch {} }); +__vite_ssr_exportName__("makeMBotAction", () => { try { return makeMBotAction } catch {} }); +__vite_ssr_exportName__("actionSignature", () => { try { return actionSignature } catch {} }); +__vite_ssr_exportName__("parseActionSpec", () => { try { return parseActionSpec } catch {} }); +__vite_ssr_exportName__("substituteMBotSensors", () => { try { return substituteMBotSensors } catch {} }); +__vite_ssr_exportName__("driveSignature", () => { try { return driveSignature } catch {} }); +__vite_ssr_exportName__("parseDriveSpec", () => { try { return parseDriveSpec } catch {} }); +__vite_ssr_exportName__("compressDrive", () => { try { return compressDrive } catch {} }); +__vite_ssr_exportName__("MBOT_PARTS", () => { try { return MBOT_PARTS } catch {} }); +__vite_ssr_exportName__("isMBotPart", () => { try { return isMBotPart } catch {} }); +const __vite_ssr_import_0__ = await __vite_ssr_import__("/web/src/core/mbotLink.ts", {"importedNames":["showLabel"]}); + +/** Der CyberPi hat fünf LEDs; in Java zählen sie wie Arrays ab 0 (`mbot.led(0)` bis `mbot.led(4)`), die Firmware ab 1. */ +const MBOT_LED_COUNT = 5; +const ledNumber = (nr) => Number.isInteger(nr) && nr >= 0 && nr < MBOT_LED_COUNT; +/** Farben für `mbot.led(i).setColor("grün")`, deutsch und englisch; „aus“ schaltet die LED aus. */ +const MBOT_LED_COLORS = { + rot: [ + 255, + 0, + 0 + ], + red: [ + 255, + 0, + 0 + ], + orange: [ + 255, + 100, + 0 + ], + gelb: [ + 255, + 200, + 0 + ], + yellow: [ + 255, + 200, + 0 + ], + grün: [ + 0, + 255, + 0 + ], + green: [ + 0, + 255, + 0 + ], + türkis: [ + 0, + 200, + 200 + ], + cyan: [ + 0, + 200, + 200 + ], + blau: [ + 0, + 0, + 255 + ], + blue: [ + 0, + 0, + 255 + ], + lila: [ + 160, + 0, + 255 + ], + purple: [ + 160, + 0, + 255 + ], + pink: [ + 255, + 0, + 120 + ], + weiß: [ + 255, + 255, + 255 + ], + white: [ + 255, + 255, + 255 + ], + aus: [ + 0, + 0, + 0 + ], + off: [ + 0, + 0, + 0 + ] +}; +/** +* Vorführungen der Firmware (`cyberpi.emotion.*`): LEDs, Ton und kleine Bewegungen, am echten mBot2 getestet mit `smile`. +* `sprint` fehlt absichtlich, weil der Roboter dabei losfährt. +*/ +const MBOT_EMOTIONS = [ + "smile", + "hello", + "yeah", + "proud", + "wow", + "yummy", + "naughty", + "uh_oh", + "hurt", + "sad", + "angry", + "startle", + "shiver", + "dizzy", + "sleepy", + "zzz", + "wake_up", + "blink", + "yes", + "no", + "look_up", + "look_down", + "look_left", + "look_right", + "look_around" +]; +/** Ein Schritt von `mbot.forward()` ohne Zahl. */ +const MBOT_STEP_CM = 10; +const n = (v) => String(Math.round(v * 100) / 100); +/** Befehle (Anweisungen). Drehen: positiver Winkel bei `mbot2.turn` dreht nach rechts. */ +const MBOT_COMMANDS = { + forward: { + args: 1, + defaults: [MBOT_STEP_CM], + python: ([cm]) => `mbot2.straight(${n(cm)})`, + label: ([cm]) => `${n(cm)} cm vorwärts` + }, + backward: { + args: 1, + defaults: [MBOT_STEP_CM], + python: ([cm]) => `mbot2.straight(${n(-cm)})`, + label: ([cm]) => `${n(cm)} cm rückwärts` + }, + turnLeft: { + args: 1, + defaults: [90], + python: ([deg]) => `mbot2.turn(${n(-deg)})`, + label: ([deg]) => `${n(deg)}° nach links drehen` + }, + turnRight: { + args: 1, + defaults: [90], + python: ([deg]) => `mbot2.turn(${n(deg)})`, + label: ([deg]) => `${n(deg)}° nach rechts drehen` + }, + stop: { + args: 0, + python: () => `mbot2.EM_stop("ALL")`, + label: () => "anhalten" + }, + /** + * Räder einzeln, Leistung in Prozent (−100 … 100); er fährt weiter, bis ein anderer Fahrbefehl oder `stop()` kommt. + * Der rechte Motor ist am mBot2 gespiegelt eingebaut, deshalb das Minus. + */ + drive: { + args: 2, + python: ([l, r]) => `mbot2.drive_power(${n(l)}, ${n(-r)})`, + label: ([l, r]) => `Räder links ${n(l)} %, rechts ${n(r)} %` + }, + setLed: { + args: 3, + python: ([r, g, b]) => `cyberpi.led.on(${n(r)}, ${n(g)}, ${n(b)})`, + label: ([r, g, b]) => `LEDs (${n(r)}, ${n(g)}, ${n(b)})` + }, + ledOff: { + args: 0, + python: () => "cyberpi.led.off()", + label: () => "LEDs aus" + }, + /** `mbot.led(i).setColor("grün")`: eine LED (0–4); aus ist `on(0, 0, 0)`. */ + ledColor: { + args: 1, + text: true, + choices: Object.keys(MBOT_LED_COLORS), + valid: ([nr]) => ledNumber(nr), + python: ([nr], color) => `cyberpi.led.on(${MBOT_LED_COLORS[color].join(", ")}, id=${nr + 1})`, + label: ([nr], color) => `LED ${nr}: ${color}` + }, + playTone: { + args: 2, + python: ([hz, ms]) => `cyberpi.audio.play_tone(${n(hz)}, ${n(ms / 1e3)})`, + label: ([hz, ms]) => `Ton ${n(hz)} Hz, ${n(ms)} ms` + }, + pause: { + args: 1, + label: ([ms]) => `${n(ms)} ms warten` + }, + resetTimer: { + args: 0, + python: () => "cyberpi.timer.reset()", + label: () => "Stoppuhr auf 0" + }, + emotion: { + args: 0, + text: true, + choices: MBOT_EMOTIONS, + python: (_, name) => `cyberpi.emotion.${name}()`, + label: (_, name) => `Gefühl: ${name}` + }, + showText: { + args: 0, + text: true, + python: (_, text) => (0,__vite_ssr_import_0__.showLabel)(text), + label: (_, text) => `Bildschirm: ${text}` + } +}; +/** Farben, die der Quad-RGB-Sensor im Simulator erkennt (Felder `r g b y` in einer Weltkarte). */ +const MBOT_COLORS = [ + "red", + "green", + "blue", + "yellow" +]; +/** Farbnamen von `mbot.getColor()`: wie bei `setColor`, Deutsch oder Englisch je nach Sprache der Lektionen. */ +const COLOR_NAMES = { + red: { + de: "rot", + en: "red" + }, + green: { + de: "grün", + en: "green" + }, + blue: { + de: "blau", + en: "blue" + }, + yellow: { + de: "gelb", + en: "yellow" + }, + cyan: { + de: "türkis", + en: "cyan" + }, + purple: { + de: "lila", + en: "purple" + }, + white: { + de: "weiß", + en: "white" + }, + black: { + de: "schwarz", + en: "black" + } +}; +let colorLanguage = "en"; +/** Sprache der Farbnamen, die `mbot.getColor()` liefert (Deutsch nur bei deutschen Lektionen). */ +function setMBotColorLanguage(language) { + colorLanguage = language === "de" ? "de" : "en"; +}; +const mbotColorLanguage = () => colorLanguage; +/** `red`, `rot` oder eine Antwort des echten Sensors → Farbname in der aktuellen Sprache. */ +function mbotColorName(color) { + const key = color.trim().toLowerCase(); + const entry = COLOR_NAMES[key] ?? Object.values(COLOR_NAMES).find((e) => e.de === key); + return entry ? entry[colorLanguage] : key; +}; +const press = (key) => ({ + python: `cyberpi.controller.is_press('${key}')`, + simulated: false +}); +/** +* Sensoren (Ausdrücke ohne Argumente): Zahlen oder Wahrheitswerte. +* Der Python-Text liest den Wert am echten mBot2 (Modus 1, Antwort `{"ret":…}`). +*/ +const MBOT_SENSORS = { + getDistance: { + python: "mbuild.ultrasonic2.get(1)", + simulated: 100 + }, + getLine: { + python: "mbuild.quad_rgb_sensor.get_line_sta('all', 1)", + simulated: 0 + }, + // die beiden mittleren Fühler (L1, R1) des Liniensensors + isLineLeft: { + python: "mbuild.quad_rgb_sensor.is_line('L1', 1)", + simulated: false + }, + isLineRight: { + python: "mbuild.quad_rgb_sensor.is_line('R1', 1)", + simulated: false + }, + /** Farbe unter dem mBot2 als Text: `mbot.getColor().equals("rot")` */ + getColor: { + python: "mbuild.quad_rgb_sensor.get_color_sta('L1', 1)", + simulated: "white" + }, + isButtonA: press("a"), + isButtonB: press("b"), + isJoystickUp: press("up"), + isJoystickDown: press("down"), + isJoystickLeft: press("left"), + isJoystickRight: press("right"), + getBrightness: { + python: "cyberpi.get_bri()", + simulated: 50 + }, + getLoudness: { + python: "cyberpi.get_loudness('maximum')", + simulated: 0 + }, + getPitch: { + python: "cyberpi.get_pitch()", + simulated: 0 + }, + getRoll: { + python: "cyberpi.get_roll()", + simulated: 0 + }, + isShaken: { + python: "cyberpi.is_shake()", + simulated: false + }, + getBattery: { + python: "cyberpi.get_battery()", + simulated: 100 + }, + /** Sekunden seit dem Start bzw. seit `resetTimer()` */ + getTimer: { + python: "cyberpi.timer.get()", + simulated: 0 + } +}; +/** Welche Sensoren kommen in diesem Text vor (z. B. im ganzen Diagramm)? */ +function usedMBotSensors(text) { + const found = new Set(); + for (const m of text.matchAll(/\bmbot\s*\.\s*([A-Za-z_]\w*)\s*\(\s*\)/gu)) if (m[1] in MBOT_SENSORS) found.add(m[1]); + return [...found]; +}; +/** `mbot.forward(10)` → Name und Argumenttexte; `undefined`, wenn es kein mBot-Befehl ist. */ +function parseMBotCommand(text) { + // `mbot.led(i).setColor("grün")` wird zu `ledColor(i, "grün")` + const led = /^mbot\s*\.\s*led\s*\(([^()]*(?:\([^()]*\)[^()]*)*)\)\s*\.\s*setColor\s*\(([\s\S]*)\)\s*;?$/u.exec(text.trim()); + if (led) return { + method: "ledColor", + args: [led[1].trim(), led[2].trim()] + }; + const m = /^mbot\s*\.\s*([A-Za-z_]\w*)\s*\(([\s\S]*)\)\s*;?$/u.exec(text.trim()); + if (!m) return undefined; + const inner = m[2].trim(); + return { + method: m[1], + args: inner === "" ? [] : splitArgs(inner) + }; +}; +/** Argumente prüfen und leere Klammern mit den Standardwerten füllen; `undefined` bei falscher Anzahl. */ +function mbotArguments(method, args) { + const spec = MBOT_COMMANDS[method]; + if (!spec) return undefined; + const values = args.length === 0 && spec.defaults ? spec.defaults : args; + if (values.length !== spec.args) return undefined; + return !spec.valid || spec.valid(values) ? values : undefined; +}; +function makeMBotAction(method, args, text = "") { + const spec = MBOT_COMMANDS[method]; + return { + method, + args, + python: spec.python?.(args, text), + waitMs: method === "pause" ? Math.max(0, args[0]) : undefined, + label: spec.label(args, text), + ...spec.text ? { text } : {} + }; +}; +/** +* Alle Befehle als Liste wie `setLed 255 0 0`, `pause 500`, `showText "Hallo"` (zum Prüfen von LEDs, Tönen und Bildschirm). +* Anders als `driveSignature` wird nichts zusammengefasst. +*/ +function actionSignature(actions) { + return actions.map((a) => [ + a.method, + ...a.args.map(n), + ...a.text !== undefined ? [JSON.stringify(a.text)] : [] + ].join(" ")); +}; +/** Erwartete Befehle einer Übung, z. B. `befehle: 3 x (setLed 255 0 0, pause 500, ledOff, pause 500)`; Texte in Anführungszeichen. */ +function parseActionSpec(spec) { + let i = 0; + const src = spec.trim(); + const list = () => { + const items = []; + for (;;) { + while (src[i] === " " || src[i] === ",") i++; + if (i >= src.length || src[i] === ")") return items; + const rep = /^(\d+)\s*[x×]\s*\(/u.exec(src.slice(i)); + if (rep) { + i += rep[0].length; + const inner = list(); + if (src[i] !== ")") throw new Error(`„)“ fehlt in „${spec}“`); + i++; + for (let k = 0; k < Number(rep[1]); k++) items.push(...inner); + continue; + }; + const step = /^([A-Za-z]+)((?:\s+-?\d+(?:\.\d+)?)*)(?:\s+("(?:[^"\\]|\\.)*"))?/u.exec(src.slice(i)); + if (!step) throw new Error(`Unbekannt in „${spec}“: ${src.slice(i)}`); + i += step[0].length; + const spec_ = MBOT_COMMANDS[step[1]]; + if (!spec_) throw new Error(`Unbekannter Befehl in „${spec}“: ${step[1]}`); + const nums = step[2].trim() === "" ? [] : step[2].trim().split(/\s+/).map(Number); + const args = mbotArguments(step[1], nums); + if (!args) throw new Error(`Falsche Anzahl Zahlen in „${spec}“: ${step[1]}`); + items.push(actionSignature([{ + method: step[1], + args, + text: spec_.text ? JSON.parse(step[3] ?? "\"\"") : undefined + }])[0]); + } + }; + const items = list(); + if (i < src.length) throw new Error(`Zu viele „)“ in „${spec}“`); + return items; +}; +/** Ersetzt `mbot.getDistance()` usw. durch Zahlen, damit der Rechner sie wie Literale liest. */ +function substituteMBotSensors(expression, read) { + if (!expression.includes("mbot")) return expression; + return expression.replace(/\bmbot\s*\.\s*([A-Za-z_]\w*)\s*\(\s*\)/gu, (all, name) => { + if (!(name in MBOT_SENSORS)) return all; + const value = read(name); + return typeof value === "string" ? JSON.stringify(name === "getColor" ? mbotColorName(value) : value) : String(value); + }); +}; +/** Argumente an Kommas auf oberster Ebene trennen (nicht in Klammern oder Texten). */ +function splitArgs(text) { + const parts = []; + let depth = 0; + let quote = false; + let start = 0; + for (let i = 0; i < text.length; i++) { + const c = text[i]; + if (quote) { + if (c === "\\") i++; + else if (c === "\"") quote = false; + } else if (c === "\"") quote = true; + else if (c === "(" || c === "[") depth++; + else if (c === ")" || c === "]") depth--; + else if (c === "," && depth === 0) { + parts.push(text.slice(start, i).trim()); + start = i + 1; + } + }; + parts.push(text.slice(start).trim()); + return parts; +} +/** +* Gefahrene Strecke als Liste wie `forward 50`, `turnRight 90`: aufeinanderfolgende Fahrten bzw. Drehungen +* zusammengefasst, LEDs und Töne zählen nicht. So ist `5 × forward()` dasselbe wie `forward(50)`. +*/ +function driveSignature(actions) { + const out = []; + for (const a of actions) { + const value = { + forward: a.args[0], + backward: -a.args[0], + turnRight: a.args[0], + turnLeft: -a.args[0] + }[a.method]; + if (value === undefined) continue; + const kind = a.method === "forward" || a.method === "backward" ? "drive" : "turn"; + const last = out[out.length - 1]; + if (last && last.kind === kind) last.value += value; + else out.push({ + kind, + value + }); + }; + return out.flatMap(({ kind, value }) => { + const v = kind === "turn" ? ((value + 180) % 360 + 360) % 360 - 180 : value; + if (Math.abs(v) < 1e-6) return []; + const r = Math.round(Math.abs(v) * 100) / 100; + if (kind === "drive") return [`${v > 0 ? "forward" : "backward"} ${r}`]; + return [v === -180 ? "turnRight 180" : `${v > 0 ? "turnRight" : "turnLeft"} ${r}`]; + }); +}; +/** +* Erwartete Fahrt einer Übung, z. B. `fahrt: 4 x (forward 50, turnRight 90)`. Teile durch Kommas getrennt, +* `n x (…)` wiederholt; ohne Zahl gelten die Werte von `mbot.forward()` bzw. `turnRight()`. +*/ +function parseDriveSpec(spec) { + let i = 0; + const src = spec.trim(); + const list = () => { + const items = []; + for (;;) { + while (src[i] === " " || src[i] === ",") i++; + if (i >= src.length || src[i] === ")") return items; + const rep = /^(\d+)\s*[x×]\s*\(/u.exec(src.slice(i)); + if (rep) { + i += rep[0].length; + const inner = list(); + if (src[i] !== ")") throw new Error(`„)“ fehlt in „${spec}“`); + i++; + for (let k = 0; k < Number(rep[1]); k++) items.push(...inner); + continue; + }; + const step = /^([A-Za-z]+)(?:\s+(-?\d+(?:\.\d+)?))?/u.exec(src.slice(i)); + if (!step) throw new Error(`Unbekannt in „${spec}“: ${src.slice(i)}`); + i += step[0].length; + const args = mbotArguments(step[1], step[2] === undefined ? [] : [Number(step[2])]); + if (!args) throw new Error(`Unbekannter Befehl in „${spec}“: ${step[1]}`); + items.push({ + method: step[1], + args + }); + } + }; + const items = list(); + if (i < src.length) throw new Error(`Zu viele „)“ in „${spec}“`); + return items; +}; +/** Fahrt kurz zum Anzeigen: Wiederholungen als `4 x (forward 50, turnRight 90)`, auch verschachtelt. */ +function compressDrive(drive) { + const n = drive.length; + for (let unit = 1; unit <= n / 2; unit++) { + if (n % unit !== 0) continue; + const times = n / unit; + if (drive.every((s, i) => s === drive[i % unit])) { + const inner = compressDrive(drive.slice(0, unit)); + return `${times} x ${unit === 1 ? inner : `(${inner})`}`; + } + }; + return drive.join(", "); +}; +/** +* Teile des mBot2 im 3D-Modell, z. B. für `fokus:` im Lektionsblock `::: mbot2` und `[Wort]{teil=cyberpi}` im Text. +* Die ersten acht gehören zum CyberPi; `cyberpi` allein ist sein Gehäuse. +*/ +const MBOT_PARTS = [ + "cyberpi", + "screen", + "joystick", + "buttons", + "leds", + "lightSensor", + "microphone", + "shield", + "powerSwitch", + "motors", + "wheels", + "ultrasonic", + "lineSensor", + "caster", + "chassis" +]; +const isMBotPart = (name) => MBOT_PARTS.includes(name); +//# sourceMappingSource=vite-generated +//# sourceMappingURL=data:application/json;base64,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O0NBQ0E7Q0FDQTtDQUNBO0NBQ0E7Q0FDQTtDQUNBO0NBQ0E7Q0FDQTtDQUNBO0FBQ0Y7QUFJTyxNQUFNLGNBQWMsU0FBb0MsV0FBaUMsU0FBUyxJQUFJIiwibmFtZXMiOltdLCJpZ25vcmVMaXN0IjpbXSwic291cmNlcyI6WyJtYm90LnRzIl0sInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IHNob3dMYWJlbCB9IGZyb20gJy4vbWJvdExpbmsnXG5cbi8qKlxuICogbUJvdDIgKE1ha2VibG9jaywgbWl0IEN5YmVyUGkpIGltIFN0cnVrdG9ncmFtbS4gQmVmZWhsZSBzdGVoZW4gYWxzIEFud2Vpc3VuZyBgbWJvdC5mb3J3YXJkKDEwKWAsXG4gKiBTZW5zb3JlbiBhbHMgQXVzZHJ1Y2sgYG1ib3QuZ2V0RGlzdGFuY2UoKWAuIERpZSBTaW11bGF0aW9uIG1lcmt0IHNpY2ggamVkZW4gQmVmZWhsIGFscyBgTUJvdEFjdGlvbmA7XG4gKiBtaXQgYW5nZXNjaGxvc3NlbmVtIFJvYm90ZXIgc2NoaWNrdCBkaWUgT2JlcmZsw6RjaGUgZGVuIFB5dGhvbi1UZXh0IGFuIGRlbiBDeWJlclBpLlxuICovXG5cbmV4cG9ydCBpbnRlcmZhY2UgTUJvdEFjdGlvbiB7XG4gIG1ldGhvZDogc3RyaW5nXG4gIGFyZ3M6IG51bWJlcltdXG4gIC8qKiBaZWlsZSBmw7xyIGRpZSBNYWtlYmxvY2stRmlybXdhcmU7IGB1bmRlZmluZWRgLCB3ZW5uIGRlciBCcm93c2VyIHNlbGJzdCB3YXJ0ZXQgKGBwYXVzZWApLiAqL1xuICBweXRob24/OiBzdHJpbmdcbiAgLyoqIFdhcnRlemVpdCBpbSBCcm93c2VyIGluIE1pbGxpc2VrdW5kZW4gKG51ciBgcGF1c2VgKS4gKi9cbiAgd2FpdE1zPzogbnVtYmVyXG4gIC8qKiBLdXJ6IGbDvHIgZGllIEtvbnNvbGUsIHouIEIuIOKAnjEwIGNtIHZvcnfDpHJ0c+KAnC4gKi9cbiAgbGFiZWw6IHN0cmluZ1xuICAvKiogVGV4dCBmw7xyIGRlbiBCaWxkc2NoaXJtIChgc2hvd1RleHRgKS4gKi9cbiAgdGV4dD86IHN0cmluZ1xufVxuXG5pbnRlcmZhY2UgQ29tbWFuZFNwZWMge1xuICBhcmdzOiBudW1iZXJcbiAgLyoqIFdlcnRlLCB3ZW5uIGRpZSBLbGFtbWVybiBsZWVyIGJsZWliZW46IGBtYm90LmZvcndhcmQoKWAgZsOkaHJ0IGVpbmVuIFNjaHJpdHQgKDEwIGNtKSwgYHR1cm5SaWdodCgpYCBkcmVodCA5MMKwLiAqL1xuICBkZWZhdWx0cz86IG51bWJlcltdXG4gIHB5dGhvbj86IChhOiBudW1iZXJbXSwgdGV4dDogc3RyaW5nKSA9PiBzdHJpbmdcbiAgbGFiZWw6IChhOiBudW1iZXJbXSwgdGV4dDogc3RyaW5nKSA9PiBzdHJpbmdcbiAgLyoqIERhcyBsZXR6dGUgQXJndW1lbnQgaXN0IGVpbiBUZXh0LCB6LiBCLiBgbWJvdC5zaG93VGV4dChcIkhhbGxvXCIpYDsgYGFyZ3NgIHrDpGhsdCBudXIgZGllIFphaGxlbiBkYXZvci4gKi9cbiAgdGV4dD86IGJvb2xlYW5cbiAgLyoqIEVybGF1YnRlIFRleHRlIChzb25zdCBpc3QgZGVyIEJlZmVobCB1bmfDvGx0aWcpLiAqL1xuICBjaG9pY2VzPzogcmVhZG9ubHkgc3RyaW5nW11cbiAgLyoqIFNpbmQgZGllIFphaGxlbiBlcmxhdWJ0PyAoei4gQi4gTEVELU51bW1lciAx4oCTNSkgKi9cbiAgdmFsaWQ/OiAoYTogbnVtYmVyW10pID0+IGJvb2xlYW5cbn1cblxuLyoqIERlciBDeWJlclBpIGhhdCBmw7xuZiBMRURzOyBpbiBKYXZhIHrDpGhsZW4gc2llIHdpZSBBcnJheXMgYWIgMCAoYG1ib3QubGVkKDApYCBiaXMgYG1ib3QubGVkKDQpYCksIGRpZSBGaXJtd2FyZSBhYiAxLiAqL1xuZXhwb3J0IGNvbnN0IE1CT1RfTEVEX0NPVU5UID0gNVxuY29uc3QgbGVkTnVtYmVyID0gKG5yOiBudW1iZXIpID0+IE51bWJlci5pc0ludGVnZXIobnIpICYmIG5yID49IDAgJiYgbnIgPCBNQk9UX0xFRF9DT1VOVFxuXG4vKiogRmFyYmVuIGbDvHIgYG1ib3QubGVkKGkpLnNldENvbG9yKFwiZ3LDvG5cIilgLCBkZXV0c2NoIHVuZCBlbmdsaXNjaDsg4oCeYXVz4oCcIHNjaGFsdGV0IGRpZSBMRUQgYXVzLiAqL1xuZXhwb3J0IGNvbnN0IE1CT1RfTEVEX0NPTE9SUzogUmVjb3JkPHN0cmluZywgW251bWJlciwgbnVtYmVyLCBudW1iZXJdPiA9IHtcbiAgcm90OiBbMjU1LCAwLCAwXSwgcmVkOiBbMjU1LCAwLCAwXSxcbiAgb3JhbmdlOiBbMjU1LCAxMDAsIDBdLFxuICBnZWxiOiBbMjU1LCAyMDAsIDBdLCB5ZWxsb3c6IFsyNTUsIDIwMCwgMF0sXG4gIGdyw7xuOiBbMCwgMjU1LCAwXSwgZ3JlZW46IFswLCAyNTUsIDBdLFxuICB0w7xya2lzOiBbMCwgMjAwLCAyMDBdLCBjeWFuOiBbMCwgMjAwLCAyMDBdLFxuICBibGF1OiBbMCwgMCwgMjU1XSwgYmx1ZTogWzAsIDAsIDI1NV0sXG4gIGxpbGE6IFsxNjAsIDAsIDI1NV0sIHB1cnBsZTogWzE2MCwgMCwgMjU1XSxcbiAgcGluazogWzI1NSwgMCwgMTIwXSxcbiAgd2Vpw586IFsyNTUsIDI1NSwgMjU1XSwgd2hpdGU6IFsyNTUsIDI1NSwgMjU1XSxcbiAgYXVzOiBbMCwgMCwgMF0sIG9mZjogWzAsIDAsIDBdLFxufVxuXG4vKipcbiAqIFZvcmbDvGhydW5nZW4gZGVyIEZpcm13YXJlIChgY3liZXJwaS5lbW90aW9uLipgKTogTEVEcywgVG9uIHVuZCBrbGVpbmUgQmV3ZWd1bmdlbiwgYW0gZWNodGVuIG1Cb3QyIGdldGVzdGV0IG1pdCBgc21pbGVgLlxuICogYHNwcmludGAgZmVobHQgYWJzaWNodGxpY2gsIHdlaWwgZGVyIFJvYm90ZXIgZGFiZWkgbG9zZsOkaHJ0LlxuICovXG5leHBvcnQgY29uc3QgTUJPVF9FTU9USU9OUyA9IFsnc21pbGUnLCAnaGVsbG8nLCAneWVhaCcsICdwcm91ZCcsICd3b3cnLCAneXVtbXknLCAnbmF1Z2h0eScsICd1aF9vaCcsICdodXJ0JywgJ3NhZCcsICdhbmdyeScsICdzdGFydGxlJywgJ3NoaXZlcicsICdkaXp6eScsICdzbGVlcHknLCAnenp6JywgJ3dha2VfdXAnLCAnYmxpbmsnLCAneWVzJywgJ25vJywgJ2xvb2tfdXAnLCAnbG9va19kb3duJywgJ2xvb2tfbGVmdCcsICdsb29rX3JpZ2h0JywgJ2xvb2tfYXJvdW5kJ10gYXMgY29uc3RcblxuLyoqIEVpbiBTY2hyaXR0IHZvbiBgbWJvdC5mb3J3YXJkKClgIG9obmUgWmFobC4gKi9cbmV4cG9ydCBjb25zdCBNQk9UX1NURVBfQ00gPSAxMFxuXG5jb25zdCBuID0gKHY6IG51bWJlcikgPT4gU3RyaW5nKE1hdGgucm91bmQodiAqIDEwMCkgLyAxMDApXG5cbi8qKiBCZWZlaGxlIChBbndlaXN1bmdlbikuIERyZWhlbjogcG9zaXRpdmVyIFdpbmtlbCBiZWkgYG1ib3QyLnR1cm5gIGRyZWh0IG5hY2ggcmVjaHRzLiAqL1xuZXhwb3J0IGNvbnN0IE1CT1RfQ09NTUFORFM6IFJlY29yZDxzdHJpbmcsIENvbW1hbmRTcGVjPiA9IHtcbiAgZm9yd2FyZDogeyBhcmdzOiAxLCBkZWZhdWx0czogW01CT1RfU1RFUF9DTV0sIHB5dGhvbjogKFtjbV0pID0+IGBtYm90Mi5zdHJhaWdodCgke24oY20pfSlgLCBsYWJlbDogKFtjbV0pID0+IGAke24oY20pfSBjbSB2b3J3w6RydHNgIH0sXG4gIGJhY2t3YXJkOiB7IGFyZ3M6IDEsIGRlZmF1bHRzOiBbTUJPVF9TVEVQX0NNXSwgcHl0aG9uOiAoW2NtXSkgPT4gYG1ib3QyLnN0cmFpZ2h0KCR7bigtY20pfSlgLCBsYWJlbDogKFtjbV0pID0+IGAke24oY20pfSBjbSByw7xja3fDpHJ0c2AgfSxcbiAgdHVybkxlZnQ6IHsgYXJnczogMSwgZGVmYXVsdHM6IFs5MF0sIHB5dGhvbjogKFtkZWddKSA9PiBgbWJvdDIudHVybigke24oLWRlZyl9KWAsIGxhYmVsOiAoW2RlZ10pID0+IGAke24oZGVnKX3CsCBuYWNoIGxpbmtzIGRyZWhlbmAgfSxcbiAgdHVyblJpZ2h0OiB7IGFyZ3M6IDEsIGRlZmF1bHRzOiBbOTBdLCBweXRob246IChbZGVnXSkgPT4gYG1ib3QyLnR1cm4oJHtuKGRlZyl9KWAsIGxhYmVsOiAoW2RlZ10pID0+IGAke24oZGVnKX3CsCBuYWNoIHJlY2h0cyBkcmVoZW5gIH0sXG4gIHN0b3A6IHsgYXJnczogMCwgcHl0aG9uOiAoKSA9PiBgbWJvdDIuRU1fc3RvcChcIkFMTFwiKWAsIGxhYmVsOiAoKSA9PiAnYW5oYWx0ZW4nIH0sXG4gIC8qKlxuICAgKiBSw6RkZXIgZWluemVsbiwgTGVpc3R1bmcgaW4gUHJvemVudCAo4oiSMTAwIOKApiAxMDApOyBlciBmw6RocnQgd2VpdGVyLCBiaXMgZWluIGFuZGVyZXIgRmFocmJlZmVobCBvZGVyIGBzdG9wKClgIGtvbW10LlxuICAgKiBEZXIgcmVjaHRlIE1vdG9yIGlzdCBhbSBtQm90MiBnZXNwaWVnZWx0IGVpbmdlYmF1dCwgZGVzaGFsYiBkYXMgTWludXMuXG4gICAqL1xuICBkcml2ZTogeyBhcmdzOiAyLCBweXRob246IChbbCwgcl0pID0+IGBtYm90Mi5kcml2ZV9wb3dlcigke24obCl9LCAke24oLXIpfSlgLCBsYWJlbDogKFtsLCByXSkgPT4gYFLDpGRlciBsaW5rcyAke24obCl9ICUsIHJlY2h0cyAke24ocil9ICVgIH0sXG4gIHNldExlZDogeyBhcmdzOiAzLCBweXRob246IChbciwgZywgYl0pID0+IGBjeWJlcnBpLmxlZC5vbigke24ocil9LCAke24oZyl9LCAke24oYil9KWAsIGxhYmVsOiAoW3IsIGcsIGJdKSA9PiBgTEVEcyAoJHtuKHIpfSwgJHtuKGcpfSwgJHtuKGIpfSlgIH0sXG4gIGxlZE9mZjogeyBhcmdzOiAwLCBweXRob246ICgpID0+ICdjeWJlcnBpLmxlZC5vZmYoKScsIGxhYmVsOiAoKSA9PiAnTEVEcyBhdXMnIH0sXG4gIC8qKiBgbWJvdC5sZWQoaSkuc2V0Q29sb3IoXCJncsO8blwiKWA6IGVpbmUgTEVEICgw4oCTNCk7IGF1cyBpc3QgYG9uKDAsIDAsIDApYC4gKi9cbiAgbGVkQ29sb3I6IHtcbiAgICBhcmdzOiAxLFxuICAgIHRleHQ6IHRydWUsXG4gICAgY2hvaWNlczogT2JqZWN0LmtleXMoTUJPVF9MRURfQ09MT1JTKSxcbiAgICB2YWxpZDogKFtucl0pID0+IGxlZE51bWJlcihuciksXG4gICAgcHl0aG9uOiAoW25yXSwgY29sb3IpID0+IGBjeWJlcnBpLmxlZC5vbigke01CT1RfTEVEX0NPTE9SU1tjb2xvcl0uam9pbignLCAnKX0sIGlkPSR7bnIgKyAxfSlgLFxuICAgIGxhYmVsOiAoW25yXSwgY29sb3IpID0+IGBMRUQgJHtucn06ICR7Y29sb3J9YCxcbiAgfSxcbiAgcGxheVRvbmU6IHsgYXJnczogMiwgcHl0aG9uOiAoW2h6LCBtc10pID0+IGBjeWJlcnBpLmF1ZGlvLnBsYXlfdG9uZSgke24oaHopfSwgJHtuKG1zIC8gMTAwMCl9KWAsIGxhYmVsOiAoW2h6LCBtc10pID0+IGBUb24gJHtuKGh6KX0gSHosICR7bihtcyl9IG1zYCB9LFxuICBwYXVzZTogeyBhcmdzOiAxLCBsYWJlbDogKFttc10pID0+IGAke24obXMpfSBtcyB3YXJ0ZW5gIH0sXG4gIHJlc2V0VGltZXI6IHsgYXJnczogMCwgcHl0aG9uOiAoKSA9PiAnY3liZXJwaS50aW1lci5yZXNldCgpJywgbGFiZWw6ICgpID0+ICdTdG9wcHVociBhdWYgMCcgfSxcbiAgZW1vdGlvbjogeyBhcmdzOiAwLCB0ZXh0OiB0cnVlLCBjaG9pY2VzOiBNQk9UX0VNT1RJT05TLCBweXRob246IChfLCBuYW1lKSA9PiBgY3liZXJwaS5lbW90aW9uLiR7bmFtZX0oKWAsIGxhYmVsOiAoXywgbmFtZSkgPT4gYEdlZsO8aGw6ICR7bmFtZX1gIH0sXG4gIHNob3dUZXh0OiB7IGFyZ3M6IDAsIHRleHQ6IHRydWUsIHB5dGhvbjogKF8sIHRleHQpID0+IHNob3dMYWJlbCh0ZXh0KSwgbGFiZWw6IChfLCB0ZXh0KSA9PiBgQmlsZHNjaGlybTogJHt0ZXh0fWAgfSxcbn1cblxuLyoqIE1lc3N3ZXJ0IGVpbmVzIFNlbnNvcnM6IFphaGwsIHdhaHIvZmFsc2NoIG9kZXIgVGV4dCAoRmFyYm5hbWUgYmVpIGBnZXRDb2xvcigpYCkuICovXG5leHBvcnQgdHlwZSBNQm90U2Vuc29yVmFsdWUgPSBudW1iZXIgfCBib29sZWFuIHwgc3RyaW5nXG5cbmludGVyZmFjZSBTZW5zb3JTcGVjIHtcbiAgcHl0aG9uOiBzdHJpbmdcbiAgLyoqIFdlcnQgaW4gZGVyIFNpbXVsYXRpb24sIHdlbm4gd2VkZXIgV2VsdCBub2NoIFJlZ2xlciBpaG4gbGllZmVybiAqL1xuICBzaW11bGF0ZWQ6IE1Cb3RTZW5zb3JWYWx1ZVxufVxuXG4vKiogRmFyYmVuLCBkaWUgZGVyIFF1YWQtUkdCLVNlbnNvciBpbSBTaW11bGF0b3IgZXJrZW5udCAoRmVsZGVyIGByIGcgYiB5YCBpbiBlaW5lciBXZWx0a2FydGUpLiAqL1xuZXhwb3J0IGNvbnN0IE1CT1RfQ09MT1JTID0gWydyZWQnLCAnZ3JlZW4nLCAnYmx1ZScsICd5ZWxsb3cnXSBhcyBjb25zdFxuZXhwb3J0IHR5cGUgTUJvdENvbG9yID0gKHR5cGVvZiBNQk9UX0NPTE9SUylbbnVtYmVyXVxuXG4vKiogRmFyYm5hbWVuIHZvbiBgbWJvdC5nZXRDb2xvcigpYDogd2llIGJlaSBgc2V0Q29sb3JgLCBEZXV0c2NoIG9kZXIgRW5nbGlzY2ggamUgbmFjaCBTcHJhY2hlIGRlciBMZWt0aW9uZW4uICovXG5jb25zdCBDT0xPUl9OQU1FUzogUmVjb3JkPHN0cmluZywgeyBkZTogc3RyaW5nOyBlbjogc3RyaW5nIH0+ID0ge1xuICByZWQ6IHsgZGU6ICdyb3QnLCBlbjogJ3JlZCcgfSxcbiAgZ3JlZW46IHsgZGU6ICdncsO8bicsIGVuOiAnZ3JlZW4nIH0sXG4gIGJsdWU6IHsgZGU6ICdibGF1JywgZW46ICdibHVlJyB9LFxuICB5ZWxsb3c6IHsgZGU6ICdnZWxiJywgZW46ICd5ZWxsb3cnIH0sXG4gIGN5YW46IHsgZGU6ICd0w7xya2lzJywgZW46ICdjeWFuJyB9LFxuICBwdXJwbGU6IHsgZGU6ICdsaWxhJywgZW46ICdwdXJwbGUnIH0sXG4gIHdoaXRlOiB7IGRlOiAnd2Vpw58nLCBlbjogJ3doaXRlJyB9LFxuICBibGFjazogeyBkZTogJ3NjaHdhcnonLCBlbjogJ2JsYWNrJyB9LFxufVxubGV0IGNvbG9yTGFuZ3VhZ2U6ICdkZScgfCAnZW4nID0gJ2VuJ1xuXG4vKiogU3ByYWNoZSBkZXIgRmFyYm5hbWVuLCBkaWUgYG1ib3QuZ2V0Q29sb3IoKWAgbGllZmVydCAoRGV1dHNjaCBudXIgYmVpIGRldXRzY2hlbiBMZWt0aW9uZW4pLiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHNldE1Cb3RDb2xvckxhbmd1YWdlKGxhbmd1YWdlOiBzdHJpbmcpIHtcbiAgY29sb3JMYW5ndWFnZSA9IGxhbmd1YWdlID09PSAnZGUnID8gJ2RlJyA6ICdlbidcbn1cblxuZXhwb3J0IGNvbnN0IG1ib3RDb2xvckxhbmd1YWdlID0gKCkgPT4gY29sb3JMYW5ndWFnZVxuXG4vKiogYHJlZGAsIGByb3RgIG9kZXIgZWluZSBBbnR3b3J0IGRlcyBlY2h0ZW4gU2Vuc29ycyDihpIgRmFyYm5hbWUgaW4gZGVyIGFrdHVlbGxlbiBTcHJhY2hlLiAqL1xuZXhwb3J0IGZ1bmN0aW9uIG1ib3RDb2xvck5hbWUoY29sb3I6IHN0cmluZyk6IHN0cmluZyB7XG4gIGNvbnN0IGtleSA9IGNvbG9yLnRyaW0oKS50b0xvd2VyQ2FzZSgpXG4gIGNvbnN0IGVudHJ5ID0gQ09MT1JfTkFNRVNba2V5XSA/PyBPYmplY3QudmFsdWVzKENPTE9SX05BTUVTKS5maW5kKChlKSA9PiBlLmRlID09PSBrZXkpXG4gIHJldHVybiBlbnRyeSA/IGVudHJ5W2NvbG9yTGFuZ3VhZ2VdIDoga2V5XG59XG5jb25zdCBwcmVzcyA9IChrZXk6IHN0cmluZyk6IFNlbnNvclNwZWMgPT4gKHsgcHl0aG9uOiBgY3liZXJwaS5jb250cm9sbGVyLmlzX3ByZXNzKCcke2tleX0nKWAsIHNpbXVsYXRlZDogZmFsc2UgfSlcblxuLyoqXG4gKiBTZW5zb3JlbiAoQXVzZHLDvGNrZSBvaG5lIEFyZ3VtZW50ZSk6IFphaGxlbiBvZGVyIFdhaHJoZWl0c3dlcnRlLlxuICogRGVyIFB5dGhvbi1UZXh0IGxpZXN0IGRlbiBXZXJ0IGFtIGVjaHRlbiBtQm90MiAoTW9kdXMgMSwgQW50d29ydCBge1wicmV0XCI64oCmfWApLlxuICovXG5leHBvcnQgY29uc3QgTUJPVF9TRU5TT1JTOiBSZWNvcmQ8c3RyaW5nLCBTZW5zb3JTcGVjPiA9IHtcbiAgZ2V0RGlzdGFuY2U6IHsgcHl0aG9uOiAnbWJ1aWxkLnVsdHJhc29uaWMyLmdldCgxKScsIHNpbXVsYXRlZDogMTAwIH0sXG4gIGdldExpbmU6IHsgcHl0aG9uOiBcIm1idWlsZC5xdWFkX3JnYl9zZW5zb3IuZ2V0X2xpbmVfc3RhKCdhbGwnLCAxKVwiLCBzaW11bGF0ZWQ6IDAgfSxcbiAgLy8gZGllIGJlaWRlbiBtaXR0bGVyZW4gRsO8aGxlciAoTDEsIFIxKSBkZXMgTGluaWVuc2Vuc29yc1xuICBpc0xpbmVMZWZ0OiB7IHB5dGhvbjogXCJtYnVpbGQucXVhZF9yZ2Jfc2Vuc29yLmlzX2xpbmUoJ0wxJywgMSlcIiwgc2ltdWxhdGVkOiBmYWxzZSB9LFxuICBpc0xpbmVSaWdodDogeyBweXRob246IFwibWJ1aWxkLnF1YWRfcmdiX3NlbnNvci5pc19saW5lKCdSMScsIDEpXCIsIHNpbXVsYXRlZDogZmFsc2UgfSxcbiAgLyoqIEZhcmJlIHVudGVyIGRlbSBtQm90MiBhbHMgVGV4dDogYG1ib3QuZ2V0Q29sb3IoKS5lcXVhbHMoXCJyb3RcIilgICovXG4gIGdldENvbG9yOiB7IHB5dGhvbjogXCJtYnVpbGQucXVhZF9yZ2Jfc2Vuc29yLmdldF9jb2xvcl9zdGEoJ0wxJywgMSlcIiwgc2ltdWxhdGVkOiAnd2hpdGUnIH0sXG4gIGlzQnV0dG9uQTogcHJlc3MoJ2EnKSxcbiAgaXNCdXR0b25COiBwcmVzcygnYicpLFxuICBpc0pveXN0aWNrVXA6IHByZXNzKCd1cCcpLFxuICBpc0pveXN0aWNrRG93bjogcHJlc3MoJ2Rvd24nKSxcbiAgaXNKb3lzdGlja0xlZnQ6IHByZXNzKCdsZWZ0JyksXG4gIGlzSm95c3RpY2tSaWdodDogcHJlc3MoJ3JpZ2h0JyksXG4gIGdldEJyaWdodG5lc3M6IHsgcHl0aG9uOiAnY3liZXJwaS5nZXRfYnJpKCknLCBzaW11bGF0ZWQ6IDUwIH0sXG4gIGdldExvdWRuZXNzOiB7IHB5dGhvbjogXCJjeWJlcnBpLmdldF9sb3VkbmVzcygnbWF4aW11bScpXCIsIHNpbXVsYXRlZDogMCB9LFxuICBnZXRQaXRjaDogeyBweXRob246ICdjeWJlcnBpLmdldF9waXRjaCgpJywgc2ltdWxhdGVkOiAwIH0sXG4gIGdldFJvbGw6IHsgcHl0aG9uOiAnY3liZXJwaS5nZXRfcm9sbCgpJywgc2ltdWxhdGVkOiAwIH0sXG4gIGlzU2hha2VuOiB7IHB5dGhvbjogJ2N5YmVycGkuaXNfc2hha2UoKScsIHNpbXVsYXRlZDogZmFsc2UgfSxcbiAgZ2V0QmF0dGVyeTogeyBweXRob246ICdjeWJlcnBpLmdldF9iYXR0ZXJ5KCknLCBzaW11bGF0ZWQ6IDEwMCB9LFxuICAvKiogU2VrdW5kZW4gc2VpdCBkZW0gU3RhcnQgYnp3LiBzZWl0IGByZXNldFRpbWVyKClgICovXG4gIGdldFRpbWVyOiB7IHB5dGhvbjogJ2N5YmVycGkudGltZXIuZ2V0KCknLCBzaW11bGF0ZWQ6IDAgfSxcbn1cblxuLyoqIE1lc3N3ZXJ0ZSBkZXMgUm9ib3RlcnMgbmFjaCBOYW1lbiAoYGdldERpc3RhbmNlYCDihpIgMzgsIGBpc0J1dHRvbkFgIOKGkiB0cnVlKS4gKi9cbmV4cG9ydCB0eXBlIE1Cb3RTZW5zb3JWYWx1ZXMgPSBQYXJ0aWFsPFJlY29yZDxzdHJpbmcsIE1Cb3RTZW5zb3JWYWx1ZT4+XG5cbi8qKiBXZWxjaGUgU2Vuc29yZW4ga29tbWVuIGluIGRpZXNlbSBUZXh0IHZvciAoei4gQi4gaW0gZ2FuemVuIERpYWdyYW1tKT8gKi9cbmV4cG9ydCBmdW5jdGlvbiB1c2VkTUJvdFNlbnNvcnModGV4dDogc3RyaW5nKTogc3RyaW5nW10ge1xuICBjb25zdCBmb3VuZCA9IG5ldyBTZXQ8c3RyaW5nPigpXG4gIGZvciAoY29uc3QgbSBvZiB0ZXh0Lm1hdGNoQWxsKC9cXGJtYm90XFxzKlxcLlxccyooW0EtWmEtel9dXFx3KilcXHMqXFwoXFxzKlxcKS9ndSkpIGlmIChtWzFdIGluIE1CT1RfU0VOU09SUykgZm91bmQuYWRkKG1bMV0pXG4gIHJldHVybiBbLi4uZm91bmRdXG59XG5cbi8qKiBgbWJvdC5mb3J3YXJkKDEwKWAg4oaSIE5hbWUgdW5kIEFyZ3VtZW50dGV4dGU7IGB1bmRlZmluZWRgLCB3ZW5uIGVzIGtlaW4gbUJvdC1CZWZlaGwgaXN0LiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHBhcnNlTUJvdENvbW1hbmQodGV4dDogc3RyaW5nKTogeyBtZXRob2Q6IHN0cmluZzsgYXJnczogc3RyaW5nW10gfSB8IHVuZGVmaW5lZCB7XG4gIC8vIGBtYm90LmxlZChpKS5zZXRDb2xvcihcImdyw7xuXCIpYCB3aXJkIHp1IGBsZWRDb2xvcihpLCBcImdyw7xuXCIpYFxuICBjb25zdCBsZWQgPSAvXm1ib3RcXHMqXFwuXFxzKmxlZFxccypcXCgoW14oKV0qKD86XFwoW14oKV0qXFwpW14oKV0qKSopXFwpXFxzKlxcLlxccypzZXRDb2xvclxccypcXCgoW1xcc1xcU10qKVxcKVxccyo7PyQvdS5leGVjKHRleHQudHJpbSgpKVxuICBpZiAobGVkKSByZXR1cm4geyBtZXRob2Q6ICdsZWRDb2xvcicsIGFyZ3M6IFtsZWRbMV0udHJpbSgpLCBsZWRbMl0udHJpbSgpXSB9XG4gIGNvbnN0IG0gPSAvXm1ib3RcXHMqXFwuXFxzKihbQS1aYS16X11cXHcqKVxccypcXCgoW1xcc1xcU10qKVxcKVxccyo7PyQvdS5leGVjKHRleHQudHJpbSgpKVxuICBpZiAoIW0pIHJldHVybiB1bmRlZmluZWRcbiAgY29uc3QgaW5uZXIgPSBtWzJdLnRyaW0oKVxuICByZXR1cm4geyBtZXRob2Q6IG1bMV0sIGFyZ3M6IGlubmVyID09PSAnJyA/IFtdIDogc3BsaXRBcmdzKGlubmVyKSB9XG59XG5cbi8qKiBBcmd1bWVudGUgcHLDvGZlbiB1bmQgbGVlcmUgS2xhbW1lcm4gbWl0IGRlbiBTdGFuZGFyZHdlcnRlbiBmw7xsbGVuOyBgdW5kZWZpbmVkYCBiZWkgZmFsc2NoZXIgQW56YWhsLiAqL1xuZXhwb3J0IGZ1bmN0aW9uIG1ib3RBcmd1bWVudHMobWV0aG9kOiBzdHJpbmcsIGFyZ3M6IG51bWJlcltdKTogbnVtYmVyW10gfCB1bmRlZmluZWQge1xuICBjb25zdCBzcGVjID0gTUJPVF9DT01NQU5EU1ttZXRob2RdXG4gIGlmICghc3BlYykgcmV0dXJuIHVuZGVmaW5lZFxuICBjb25zdCB2YWx1ZXMgPSBhcmdzLmxlbmd0aCA9PT0gMCAmJiBzcGVjLmRlZmF1bHRzID8gc3BlYy5kZWZhdWx0cyA6IGFyZ3NcbiAgaWYgKHZhbHVlcy5sZW5ndGggIT09IHNwZWMuYXJncykgcmV0dXJuIHVuZGVmaW5lZFxuICByZXR1cm4gIXNwZWMudmFsaWQgfHwgc3BlYy52YWxpZCh2YWx1ZXMpID8gdmFsdWVzIDogdW5kZWZpbmVkXG59XG5cbmV4cG9ydCBmdW5jdGlvbiBtYWtlTUJvdEFjdGlvbihtZXRob2Q6IHN0cmluZywgYXJnczogbnVtYmVyW10sIHRleHQgPSAnJyk6IE1Cb3RBY3Rpb24ge1xuICBjb25zdCBzcGVjID0gTUJPVF9DT01NQU5EU1ttZXRob2RdXG4gIHJldHVybiB7XG4gICAgbWV0aG9kLFxuICAgIGFyZ3MsXG4gICAgcHl0aG9uOiBzcGVjLnB5dGhvbj8uKGFyZ3MsIHRleHQpLFxuICAgIHdhaXRNczogbWV0aG9kID09PSAncGF1c2UnID8gTWF0aC5tYXgoMCwgYXJnc1swXSkgOiB1bmRlZmluZWQsXG4gICAgbGFiZWw6IHNwZWMubGFiZWwoYXJncywgdGV4dCksXG4gICAgLi4uKHNwZWMudGV4dCA/IHsgdGV4dCB9IDoge30pLFxuICB9XG59XG5cbi8qKlxuICogQWxsZSBCZWZlaGxlIGFscyBMaXN0ZSB3aWUgYHNldExlZCAyNTUgMCAwYCwgYHBhdXNlIDUwMGAsIGBzaG93VGV4dCBcIkhhbGxvXCJgICh6dW0gUHLDvGZlbiB2b24gTEVEcywgVMO2bmVuIHVuZCBCaWxkc2NoaXJtKS5cbiAqIEFuZGVycyBhbHMgYGRyaXZlU2lnbmF0dXJlYCB3aXJkIG5pY2h0cyB6dXNhbW1lbmdlZmFzc3QuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBhY3Rpb25TaWduYXR1cmUoYWN0aW9uczogeyBtZXRob2Q6IHN0cmluZzsgYXJnczogbnVtYmVyW107IHRleHQ/OiBzdHJpbmcgfVtdKTogc3RyaW5nW10ge1xuICByZXR1cm4gYWN0aW9ucy5tYXAoKGEpID0+IFthLm1ldGhvZCwgLi4uYS5hcmdzLm1hcChuKSwgLi4uKGEudGV4dCAhPT0gdW5kZWZpbmVkID8gW0pTT04uc3RyaW5naWZ5KGEudGV4dCldIDogW10pXS5qb2luKCcgJykpXG59XG5cbi8qKiBFcndhcnRldGUgQmVmZWhsZSBlaW5lciDDnGJ1bmcsIHouIEIuIGBiZWZlaGxlOiAzIHggKHNldExlZCAyNTUgMCAwLCBwYXVzZSA1MDAsIGxlZE9mZiwgcGF1c2UgNTAwKWA7IFRleHRlIGluIEFuZsO8aHJ1bmdzemVpY2hlbi4gKi9cbmV4cG9ydCBmdW5jdGlvbiBwYXJzZUFjdGlvblNwZWMoc3BlYzogc3RyaW5nKTogc3RyaW5nW10ge1xuICBsZXQgaSA9IDBcbiAgY29uc3Qgc3JjID0gc3BlYy50cmltKClcbiAgY29uc3QgbGlzdCA9ICgpOiBzdHJpbmdbXSA9PiB7XG4gICAgY29uc3QgaXRlbXM6IHN0cmluZ1tdID0gW11cbiAgICBmb3IgKDs7KSB7XG4gICAgICB3aGlsZSAoc3JjW2ldID09PSAnICcgfHwgc3JjW2ldID09PSAnLCcpIGkrK1xuICAgICAgaWYgKGkgPj0gc3JjLmxlbmd0aCB8fCBzcmNbaV0gPT09ICcpJykgcmV0dXJuIGl0ZW1zXG4gICAgICBjb25zdCByZXAgPSAvXihcXGQrKVxccypbeMOXXVxccypcXCgvdS5leGVjKHNyYy5zbGljZShpKSlcbiAgICAgIGlmIChyZXApIHtcbiAgICAgICAgaSArPSByZXBbMF0ubGVuZ3RoXG4gICAgICAgIGNvbnN0IGlubmVyID0gbGlzdCgpXG4gICAgICAgIGlmIChzcmNbaV0gIT09ICcpJykgdGhyb3cgbmV3IEVycm9yKGDigJ4p4oCcIGZlaGx0IGluIOKAniR7c3BlY33igJxgKVxuICAgICAgICBpKytcbiAgICAgICAgZm9yIChsZXQgayA9IDA7IGsgPCBOdW1iZXIocmVwWzFdKTsgaysrKSBpdGVtcy5wdXNoKC4uLmlubmVyKVxuICAgICAgICBjb250aW51ZVxuICAgICAgfVxuICAgICAgY29uc3Qgc3RlcCA9IC9eKFtBLVphLXpdKykoKD86XFxzKy0/XFxkKyg/OlxcLlxcZCspPykqKSg/OlxccysoXCIoPzpbXlwiXFxcXF18XFxcXC4pKlwiKSk/L3UuZXhlYyhzcmMuc2xpY2UoaSkpXG4gICAgICBpZiAoIXN0ZXApIHRocm93IG5ldyBFcnJvcihgVW5iZWthbm50IGluIOKAniR7c3BlY33igJw6ICR7c3JjLnNsaWNlKGkpfWApXG4gICAgICBpICs9IHN0ZXBbMF0ubGVuZ3RoXG4gICAgICBjb25zdCBzcGVjXyA9IE1CT1RfQ09NTUFORFNbc3RlcFsxXV1cbiAgICAgIGlmICghc3BlY18pIHRocm93IG5ldyBFcnJvcihgVW5iZWthbm50ZXIgQmVmZWhsIGluIOKAniR7c3BlY33igJw6ICR7c3RlcFsxXX1gKVxuICAgICAgY29uc3QgbnVtcyA9IHN0ZXBbMl0udHJpbSgpID09PSAnJyA/IFtdIDogc3RlcFsyXS50cmltKCkuc3BsaXQoL1xccysvKS5tYXAoTnVtYmVyKVxuICAgICAgY29uc3QgYXJncyA9IG1ib3RBcmd1bWVudHMoc3RlcFsxXSwgbnVtcylcbiAgICAgIGlmICghYXJncykgdGhyb3cgbmV3IEVycm9yKGBGYWxzY2hlIEFuemFobCBaYWhsZW4gaW4g4oCeJHtzcGVjfeKAnDogJHtzdGVwWzFdfWApXG4gICAgICBpdGVtcy5wdXNoKGFjdGlvblNpZ25hdHVyZShbeyBtZXRob2Q6IHN0ZXBbMV0sIGFyZ3MsIHRleHQ6IHNwZWNfLnRleHQgPyBKU09OLnBhcnNlKHN0ZXBbM10gPz8gJ1wiXCInKSA6IHVuZGVmaW5lZCB9XSlbMF0pXG4gICAgfVxuICB9XG4gIGNvbnN0IGl0ZW1zID0gbGlzdCgpXG4gIGlmIChpIDwgc3JjLmxlbmd0aCkgdGhyb3cgbmV3IEVycm9yKGBadSB2aWVsZSDigJ4p4oCcIGluIOKAniR7c3BlY33igJxgKVxuICByZXR1cm4gaXRlbXNcbn1cblxuLyoqIEVyc2V0enQgYG1ib3QuZ2V0RGlzdGFuY2UoKWAgdXN3LiBkdXJjaCBaYWhsZW4sIGRhbWl0IGRlciBSZWNobmVyIHNpZSB3aWUgTGl0ZXJhbGUgbGllc3QuICovXG5leHBvcnQgZnVuY3Rpb24gc3Vic3RpdHV0ZU1Cb3RTZW5zb3JzKGV4cHJlc3Npb246IHN0cmluZywgcmVhZDogKG5hbWU6IHN0cmluZykgPT4gTUJvdFNlbnNvclZhbHVlKTogc3RyaW5nIHtcbiAgaWYgKCFleHByZXNzaW9uLmluY2x1ZGVzKCdtYm90JykpIHJldHVybiBleHByZXNzaW9uXG4gIHJldHVybiBleHByZXNzaW9uLnJlcGxhY2UoL1xcYm1ib3RcXHMqXFwuXFxzKihbQS1aYS16X11cXHcqKVxccypcXChcXHMqXFwpL2d1LCAoYWxsLCBuYW1lOiBzdHJpbmcpID0+IHtcbiAgICBpZiAoIShuYW1lIGluIE1CT1RfU0VOU09SUykpIHJldHVybiBhbGxcbiAgICBjb25zdCB2YWx1ZSA9IHJlYWQobmFtZSlcbiAgICByZXR1cm4gdHlwZW9mIHZhbHVlID09PSAnc3RyaW5nJyA/IEpTT04uc3RyaW5naWZ5KG5hbWUgPT09ICdnZXRDb2xvcicgPyBtYm90Q29sb3JOYW1lKHZhbHVlKSA6IHZhbHVlKSA6IFN0cmluZyh2YWx1ZSlcbiAgfSlcbn1cblxuLyoqIEFyZ3VtZW50ZSBhbiBLb21tYXMgYXVmIG9iZXJzdGVyIEViZW5lIHRyZW5uZW4gKG5pY2h0IGluIEtsYW1tZXJuIG9kZXIgVGV4dGVuKS4gKi9cbmZ1bmN0aW9uIHNwbGl0QXJncyh0ZXh0OiBzdHJpbmcpOiBzdHJpbmdbXSB7XG4gIGNvbnN0IHBhcnRzOiBzdHJpbmdbXSA9IFtdXG4gIGxldCBkZXB0aCA9IDBcbiAgbGV0IHF1b3RlID0gZmFsc2VcbiAgbGV0IHN0YXJ0ID0gMFxuICBmb3IgKGxldCBpID0gMDsgaSA8IHRleHQubGVuZ3RoOyBpKyspIHtcbiAgICBjb25zdCBjID0gdGV4dFtpXVxuICAgIGlmIChxdW90ZSkge1xuICAgICAgaWYgKGMgPT09ICdcXFxcJykgaSsrXG4gICAgICBlbHNlIGlmIChjID09PSAnXCInKSBxdW90ZSA9IGZhbHNlXG4gICAgfSBlbHNlIGlmIChjID09PSAnXCInKSBxdW90ZSA9IHRydWVcbiAgICBlbHNlIGlmIChjID09PSAnKCcgfHwgYyA9PT0gJ1snKSBkZXB0aCsrXG4gICAgZWxzZSBpZiAoYyA9PT0gJyknIHx8IGMgPT09ICddJykgZGVwdGgtLVxuICAgIGVsc2UgaWYgKGMgPT09ICcsJyAmJiBkZXB0aCA9PT0gMCkge1xuICAgICAgcGFydHMucHVzaCh0ZXh0LnNsaWNlKHN0YXJ0LCBpKS50cmltKCkpXG4gICAgICBzdGFydCA9IGkgKyAxXG4gICAgfVxuICB9XG4gIHBhcnRzLnB1c2godGV4dC5zbGljZShzdGFydCkudHJpbSgpKVxuICByZXR1cm4gcGFydHNcbn1cblxuLyoqXG4gKiBHZWZhaHJlbmUgU3RyZWNrZSBhbHMgTGlzdGUgd2llIGBmb3J3YXJkIDUwYCwgYHR1cm5SaWdodCA5MGA6IGF1ZmVpbmFuZGVyZm9sZ2VuZGUgRmFocnRlbiBiencuIERyZWh1bmdlblxuICogenVzYW1tZW5nZWZhc3N0LCBMRURzIHVuZCBUw7ZuZSB6w6RobGVuIG5pY2h0LiBTbyBpc3QgYDUgw5cgZm9yd2FyZCgpYCBkYXNzZWxiZSB3aWUgYGZvcndhcmQoNTApYC5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGRyaXZlU2lnbmF0dXJlKGFjdGlvbnM6IHsgbWV0aG9kOiBzdHJpbmc7IGFyZ3M6IG51bWJlcltdIH1bXSk6IHN0cmluZ1tdIHtcbiAgY29uc3Qgb3V0OiB7IGtpbmQ6ICdkcml2ZScgfCAndHVybic7IHZhbHVlOiBudW1iZXIgfVtdID0gW11cbiAgZm9yIChjb25zdCBhIG9mIGFjdGlvbnMpIHtcbiAgICBjb25zdCB2YWx1ZSA9IHsgZm9yd2FyZDogYS5hcmdzWzBdLCBiYWNrd2FyZDogLWEuYXJnc1swXSwgdHVyblJpZ2h0OiBhLmFyZ3NbMF0sIHR1cm5MZWZ0OiAtYS5hcmdzWzBdIH1bYS5tZXRob2RdXG4gICAgaWYgKHZhbHVlID09PSB1bmRlZmluZWQpIGNvbnRpbnVlXG4gICAgY29uc3Qga2luZCA9IGEubWV0aG9kID09PSAnZm9yd2FyZCcgfHwgYS5tZXRob2QgPT09ICdiYWNrd2FyZCcgPyAnZHJpdmUnIDogJ3R1cm4nXG4gICAgY29uc3QgbGFzdCA9IG91dFtvdXQubGVuZ3RoIC0gMV1cbiAgICBpZiAobGFzdCAmJiBsYXN0LmtpbmQgPT09IGtpbmQpIGxhc3QudmFsdWUgKz0gdmFsdWVcbiAgICBlbHNlIG91dC5wdXNoKHsga2luZCwgdmFsdWUgfSlcbiAgfVxuICByZXR1cm4gb3V0LmZsYXRNYXAoKHsga2luZCwgdmFsdWUgfSkgPT4ge1xuICAgIGNvbnN0IHYgPSBraW5kID09PSAndHVybicgPyAoKCgodmFsdWUgKyAxODApICUgMzYwKSArIDM2MCkgJSAzNjApIC0gMTgwIDogdmFsdWVcbiAgICBpZiAoTWF0aC5hYnModikgPCAxZS02KSByZXR1cm4gW11cbiAgICBjb25zdCByID0gTWF0aC5yb3VuZChNYXRoLmFicyh2KSAqIDEwMCkgLyAxMDBcbiAgICBpZiAoa2luZCA9PT0gJ2RyaXZlJykgcmV0dXJuIFtgJHt2ID4gMCA/ICdmb3J3YXJkJyA6ICdiYWNrd2FyZCd9ICR7cn1gXVxuICAgIHJldHVybiBbdiA9PT0gLTE4MCA/ICd0dXJuUmlnaHQgMTgwJyA6IGAke3YgPiAwID8gJ3R1cm5SaWdodCcgOiAndHVybkxlZnQnfSAke3J9YF1cbiAgfSlcbn1cblxuLyoqXG4gKiBFcndhcnRldGUgRmFocnQgZWluZXIgw5xidW5nLCB6LiBCLiBgZmFocnQ6IDQgeCAoZm9yd2FyZCA1MCwgdHVyblJpZ2h0IDkwKWAuIFRlaWxlIGR1cmNoIEtvbW1hcyBnZXRyZW5udCxcbiAqIGBuIHggKOKApilgIHdpZWRlcmhvbHQ7IG9obmUgWmFobCBnZWx0ZW4gZGllIFdlcnRlIHZvbiBgbWJvdC5mb3J3YXJkKClgIGJ6dy4gYHR1cm5SaWdodCgpYC5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHBhcnNlRHJpdmVTcGVjKHNwZWM6IHN0cmluZyk6IHsgbWV0aG9kOiBzdHJpbmc7IGFyZ3M6IG51bWJlcltdIH1bXSB7XG4gIGxldCBpID0gMFxuICBjb25zdCBzcmMgPSBzcGVjLnRyaW0oKVxuICBjb25zdCBsaXN0ID0gKCk6IHsgbWV0aG9kOiBzdHJpbmc7IGFyZ3M6IG51bWJlcltdIH1bXSA9PiB7XG4gICAgY29uc3QgaXRlbXM6IHsgbWV0aG9kOiBzdHJpbmc7IGFyZ3M6IG51bWJlcltdIH1bXSA9IFtdXG4gICAgZm9yICg7Oykge1xuICAgICAgd2hpbGUgKHNyY1tpXSA9PT0gJyAnIHx8IHNyY1tpXSA9PT0gJywnKSBpKytcbiAgICAgIGlmIChpID49IHNyYy5sZW5ndGggfHwgc3JjW2ldID09PSAnKScpIHJldHVybiBpdGVtc1xuICAgICAgY29uc3QgcmVwID0gL14oXFxkKylcXHMqW3jDl11cXHMqXFwoL3UuZXhlYyhzcmMuc2xpY2UoaSkpXG4gICAgICBpZiAocmVwKSB7XG4gICAgICAgIGkgKz0gcmVwWzBdLmxlbmd0aFxuICAgICAgICBjb25zdCBpbm5lciA9IGxpc3QoKVxuICAgICAgICBpZiAoc3JjW2ldICE9PSAnKScpIHRocm93IG5ldyBFcnJvcihg4oCeKeKAnCBmZWhsdCBpbiDigJ4ke3NwZWN94oCcYClcbiAgICAgICAgaSsrXG4gICAgICAgIGZvciAobGV0IGsgPSAwOyBrIDwgTnVtYmVyKHJlcFsxXSk7IGsrKykgaXRlbXMucHVzaCguLi5pbm5lcilcbiAgICAgICAgY29udGludWVcbiAgICAgIH1cbiAgICAgIGNvbnN0IHN0ZXAgPSAvXihbQS1aYS16XSspKD86XFxzKygtP1xcZCsoPzpcXC5cXGQrKT8pKT8vdS5leGVjKHNyYy5zbGljZShpKSlcbiAgICAgIGlmICghc3RlcCkgdGhyb3cgbmV3IEVycm9yKGBVbmJla2FubnQgaW4g4oCeJHtzcGVjfeKAnDogJHtzcmMuc2xpY2UoaSl9YClcbiAgICAgIGkgKz0gc3RlcFswXS5sZW5ndGhcbiAgICAgIGNvbnN0IGFyZ3MgPSBtYm90QXJndW1lbnRzKHN0ZXBbMV0sIHN0ZXBbMl0gPT09IHVuZGVmaW5lZCA/IFtdIDogW051bWJlcihzdGVwWzJdKV0pXG4gICAgICBpZiAoIWFyZ3MpIHRocm93IG5ldyBFcnJvcihgVW5iZWthbm50ZXIgQmVmZWhsIGluIOKAniR7c3BlY33igJw6ICR7c3RlcFsxXX1gKVxuICAgICAgaXRlbXMucHVzaCh7IG1ldGhvZDogc3RlcFsxXSwgYXJncyB9KVxuICAgIH1cbiAgfVxuICBjb25zdCBpdGVtcyA9IGxpc3QoKVxuICBpZiAoaSA8IHNyYy5sZW5ndGgpIHRocm93IG5ldyBFcnJvcihgWnUgdmllbGUg4oCeKeKAnCBpbiDigJ4ke3NwZWN94oCcYClcbiAgcmV0dXJuIGl0ZW1zXG59XG5cbi8qKiBGYWhydCBrdXJ6IHp1bSBBbnplaWdlbjogV2llZGVyaG9sdW5nZW4gYWxzIGA0IHggKGZvcndhcmQgNTAsIHR1cm5SaWdodCA5MClgLCBhdWNoIHZlcnNjaGFjaHRlbHQuICovXG5leHBvcnQgZnVuY3Rpb24gY29tcHJlc3NEcml2ZShkcml2ZTogc3RyaW5nW10pOiBzdHJpbmcge1xuICBjb25zdCBuID0gZHJpdmUubGVuZ3RoXG4gIGZvciAobGV0IHVuaXQgPSAxOyB1bml0IDw9IG4gLyAyOyB1bml0KyspIHtcbiAgICBpZiAobiAlIHVuaXQgIT09IDApIGNvbnRpbnVlXG4gICAgY29uc3QgdGltZXMgPSBuIC8gdW5pdFxuICAgIGlmIChkcml2ZS5ldmVyeSgocywgaSkgPT4gcyA9PT0gZHJpdmVbaSAlIHVuaXRdKSkge1xuICAgICAgY29uc3QgaW5uZXIgPSBjb21wcmVzc0RyaXZlKGRyaXZlLnNsaWNlKDAsIHVuaXQpKVxuICAgICAgcmV0dXJuIGAke3RpbWVzfSB4ICR7dW5pdCA9PT0gMSA/IGlubmVyIDogYCgke2lubmVyfSlgfWBcbiAgICB9XG4gIH1cbiAgcmV0dXJuIGRyaXZlLmpvaW4oJywgJylcbn1cblxuLyoqXG4gKiBUZWlsZSBkZXMgbUJvdDIgaW0gM0QtTW9kZWxsLCB6LiBCLiBmw7xyIGBmb2t1czpgIGltIExla3Rpb25zYmxvY2sgYDo6OiBtYm90MmAgdW5kIGBbV29ydF17dGVpbD1jeWJlcnBpfWAgaW0gVGV4dC5cbiAqIERpZSBlcnN0ZW4gYWNodCBnZWjDtnJlbiB6dW0gQ3liZXJQaTsgYGN5YmVycGlgIGFsbGVpbiBpc3Qgc2VpbiBHZWjDpHVzZS5cbiAqL1xuZXhwb3J0IGNvbnN0IE1CT1RfUEFSVFMgPSBbXG4gICdjeWJlcnBpJyxcbiAgJ3NjcmVlbicsXG4gICdqb3lzdGljaycsXG4gICdidXR0b25zJyxcbiAgJ2xlZHMnLFxuICAnbGlnaHRTZW5zb3InLFxuICAnbWljcm9waG9uZScsXG4gICdzaGllbGQnLFxuICAncG93ZXJTd2l0Y2gnLFxuICAnbW90b3JzJyxcbiAgJ3doZWVscycsXG4gICd1bHRyYXNvbmljJyxcbiAgJ2xpbmVTZW5zb3InLFxuICAnY2FzdGVyJyxcbiAgJ2NoYXNzaXMnLFxuXSBhcyBjb25zdFxuXG5leHBvcnQgdHlwZSBNQm90UGFydCA9ICh0eXBlb2YgTUJPVF9QQVJUUylbbnVtYmVyXVxuXG5leHBvcnQgY29uc3QgaXNNQm90UGFydCA9IChuYW1lOiBzdHJpbmcpOiBuYW1lIGlzIE1Cb3RQYXJ0ID0+IChNQk9UX1BBUlRTIGFzIHJlYWRvbmx5IHN0cmluZ1tdKS5pbmNsdWRlcyhuYW1lKVxuIl0sImZpbGUiOiIvd2ViL3NyYy9jb3JlL21ib3QudHMifQ== + +//# vitestCache=W3siZmlsZSI6IjEiLCJpZCI6IjEiLCJ1cmwiOiIyIiwiaW1wb3J0cyI6IjMiLCJtYXBwaW5ncyI6ZmFsc2UsImRlcHMiOiI0IiwiZHluYW1pY0RlcHMiOiI1Iiwic3RhdGljTW9ja3MiOm51bGx9LCIvaG9tZS91c2VyL3Zpc3VzdHJ1Y3Qtc3dpZnR1aS93ZWIvc3JjL2NvcmUvbWJvdC50cyIsIi93ZWIvc3JjL2NvcmUvbWJvdC50cyIseyJ1cmxzIjoiNiIsImlkcyI6IjcifSxbIjgiXSxbXSxbIjgiXSx7fSwiL3dlYi9zcmMvY29yZS9tYm90TGluay50cyJd \ No newline at end of file diff --git a/node_modules/.vitest-cache/a2bc6900de05952e637aa8c1bf773176a1051346 b/node_modules/.vitest-cache/a2bc6900de05952e637aa8c1bf773176a1051346 new file mode 100644 index 00000000..10e201b1 --- /dev/null +++ b/node_modules/.vitest-cache/a2bc6900de05952e637aa8c1bf773176a1051346 @@ -0,0 +1,86 @@ +__vite_ssr_exportName__("inline", () => { try { return inline } catch {} }); +__vite_ssr_exportName__("markdownToHTML", () => { try { return markdownToHTML } catch {} }); +/** Kleines Markdown für Lektionstexte: Absätze, ## bis ####, Listen, Zitat als Hinweis, Code, Tabellen, **fett**, *kursiv*, `code`, [Link](url), +* [Wort]{.blau} als farbige Markierung (blau, orange, gruen) passend zu farbigen Kästen, [Wort]{teil=cyberpi} zeigt auf ein Teil des mBot2. */ +const escape = (s) => s.replace(/&/g, "&").replace(//g, ">").replace(/"/g, """); +function inline(text) { + const codes = []; + let s = escape(text).replace(/`([^`]+)`/g, (_, c) => { + codes.push(c); + return `\u0000${codes.length - 1}\u0000`; + }); + s = s.replace(/\*\*(.+?)\*\*/g, "$1").replace(/(^|[^*])\*([^*\s][^*]*?)\*/g, "$1$2").replace(/\[([^\]]+)\]\(([^)\s]+)\)/g, (_, label, url) => { + const safe = /^(https?:|mailto:|#|\.{0,2}\/)/.test(url) ? url : "#"; + const external = /^https?:/.test(safe) ? " target=\"_blank\" rel=\"noopener noreferrer\"" : ""; + return `${label}`; + }).replace(/\[([^\]]+)\]\{\.(blau|orange|gruen|gelb|rosa)\}/g, "$1").replace(/\[([^\]]+)\]\{(?:teil|part)=([\w,]+)\}/g, "$1"); + return s.replace(/\u0000(\d+)\u0000/g, (_, i) => `${codes[Number(i)]}`); +}; +function markdownToHTML(source) { + const out = []; + const lines = source.replace(/\r\n/g, "\n").split("\n"); + let i = 0; + while (i < lines.length) { + const line = lines[i]; + if (line.trim() === "") { + i++; + continue; + }; + if (line.startsWith("```")) { + // ```java editor: Unter dem Beispiel steht „Im Editor öffnen“, dann kann man es in Programmieren ausprobieren. + const [lang, extra] = line.slice(3).trim().split(/\s+/); + const java = lang === "java"; + const open = java && extra === "editor"; + const code = []; + i++; + while (i < lines.length && !lines[i].startsWith("```")) code.push(lines[i++]); + i++; + out.push(`
${escape(code.join("\n"))}
`); + continue; + }; + const heading = /^(#{2,4})\s+(.*)$/.exec(line); + if (heading) { + const level = heading[1].length; + out.push(`${inline(heading[2])}`); + i++; + continue; + }; + if (/^\s*([-*]|\d+\.)\s+/.test(line)) { + const ordered = /^\s*\d+\./.test(line); + const items = []; + while (i < lines.length && /^\s*([-*]|\d+\.)\s+/.test(lines[i])) { + let item = lines[i].replace(/^\s*([-*]|\d+\.)\s+/, ""); + i++; + while (i < lines.length && /^\s{2,}\S/.test(lines[i]) && !/^\s*([-*]|\d+\.)\s+/.test(lines[i])) item += " " + lines[i++].trim(); + items.push(`
  • ${inline(item)}
  • `); + }; + out.push(ordered ? `
      ${items.join("")}
    ` : ``); + continue; + }; + if (line.startsWith("|") && /^\|?[\s:|-]*-{3,}[\s:|-]*$/.test(lines[i + 1] ?? "")) { + const cells = (row) => row.trim().replace(/^\|/, "").replace(/\|$/, "").split("|").map((c) => inline(c.trim())); + const head = cells(line); + i += 2; + const rows = []; + while (i < lines.length && lines[i].startsWith("|")) rows.push(cells(lines[i++])); + out.push(`
    ${head.map((c) => ``).join("")}${rows.map((r) => `${r.map((c) => ``).join("")}`).join("")}
    ${c}
    ${c}
    `); + continue; + }; + if (line.startsWith(">")) { + const quote = []; + while (i < lines.length && lines[i].startsWith(">")) quote.push(lines[i++].replace(/^>\s?/, "")); + out.push(``); + continue; + }; + const para = []; + while (i < lines.length && lines[i].trim() !== "" && !/^(```|#{3,4}\s|>|\||\s*([-*]|\d+\.)\s+)/.test(lines[i])) { + para.push(lines[i++].trim()); + }; + out.push(`

    ${inline(para.join(" "))}

    `); + }; + return out.join("\n"); +} +//# sourceMappingSource=vite-generated +//# sourceMappingURL=data:application/json;base64,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QUFNLFVBQ1YsTUFBTSxFQUFFLENBQUMsS0FBSyxNQUFNLE1BQ3BCLENBQUMsMENBQTBDLEtBQUssTUFBTSxFQUFFLEdBQ3hEO0dBQ0EsS0FBSyxLQUFLLE1BQU0sSUFBSSxDQUFDLEtBQUssQ0FBQztFQUM3QjtFQUNBLElBQUksS0FBSyxNQUFNLE9BQU8sS0FBSyxLQUFLLEdBQUcsQ0FBQyxFQUFFLEtBQUs7Q0FDN0M7Q0FDQSxPQUFPLElBQUksS0FBSyxJQUFJO0FBQ3RCIiwibmFtZXMiOltdLCJpZ25vcmVMaXN0IjpbXSwic291cmNlcyI6WyJtYXJrZG93bi50cyJdLCJzb3VyY2VzQ29udGVudCI6WyIvKiogS2xlaW5lcyBNYXJrZG93biBmw7xyIExla3Rpb25zdGV4dGU6IEFic8OkdHplLCAjIyBiaXMgIyMjIywgTGlzdGVuLCBaaXRhdCBhbHMgSGlud2VpcywgQ29kZSwgVGFiZWxsZW4sICoqZmV0dCoqLCAqa3Vyc2l2KiwgYGNvZGVgLCBbTGlua10odXJsKSxcbiAqIFtXb3J0XXsuYmxhdX0gYWxzIGZhcmJpZ2UgTWFya2llcnVuZyAoYmxhdSwgb3JhbmdlLCBncnVlbikgcGFzc2VuZCB6dSBmYXJiaWdlbiBLw6RzdGVuLCBbV29ydF17dGVpbD1jeWJlcnBpfSB6ZWlndCBhdWYgZWluIFRlaWwgZGVzIG1Cb3QyLiAqL1xuXG5jb25zdCBlc2NhcGUgPSAoczogc3RyaW5nKSA9PiBzLnJlcGxhY2UoLyYvZywgJyZhbXA7JykucmVwbGFjZSgvPC9nLCAnJmx0OycpLnJlcGxhY2UoLz4vZywgJyZndDsnKS5yZXBsYWNlKC9cIi9nLCAnJnF1b3Q7JylcblxuZXhwb3J0IGZ1bmN0aW9uIGlubGluZSh0ZXh0OiBzdHJpbmcpOiBzdHJpbmcge1xuICBjb25zdCBjb2Rlczogc3RyaW5nW10gPSBbXVxuICBsZXQgcyA9IGVzY2FwZSh0ZXh0KS5yZXBsYWNlKC9gKFteYF0rKWAvZywgKF8sIGM6IHN0cmluZykgPT4ge1xuICAgIGNvZGVzLnB1c2goYylcbiAgICByZXR1cm4gYFxcdTAwMDAke2NvZGVzLmxlbmd0aCAtIDF9XFx1MDAwMGBcbiAgfSlcbiAgcyA9IHNcbiAgICAucmVwbGFjZSgvXFwqXFwqKC4rPylcXCpcXCovZywgJzxzdHJvbmc+JDE8L3N0cm9uZz4nKVxuICAgIC5yZXBsYWNlKC8oXnxbXipdKVxcKihbXipcXHNdW14qXSo/KVxcKi9nLCAnJDE8ZW0+JDI8L2VtPicpXG4gICAgLnJlcGxhY2UoL1xcWyhbXlxcXV0rKVxcXVxcKChbXilcXHNdKylcXCkvZywgKF8sIGxhYmVsOiBzdHJpbmcsIHVybDogc3RyaW5nKSA9PiB7XG4gICAgICBjb25zdCBzYWZlID0gL14oaHR0cHM/OnxtYWlsdG86fCN8XFwuezAsMn1cXC8pLy50ZXN0KHVybCkgPyB1cmwgOiAnIydcbiAgICAgIGNvbnN0IGV4dGVybmFsID0gL15odHRwcz86Ly50ZXN0KHNhZmUpID8gJyB0YXJnZXQ9XCJfYmxhbmtcIiByZWw9XCJub29wZW5lciBub3JlZmVycmVyXCInIDogJydcbiAgICAgIHJldHVybiBgPGEgaHJlZj1cIiR7c2FmZX1cIiR7ZXh0ZXJuYWx9PiR7bGFiZWx9PC9hPmBcbiAgICB9KVxuICAgIC5yZXBsYWNlKC9cXFsoW15cXF1dKylcXF1cXHtcXC4oYmxhdXxvcmFuZ2V8Z3J1ZW58Z2VsYnxyb3NhKVxcfS9nLCAnPG1hcmsgY2xhc3M9XCJsZWFybi1tYXJrICQyXCI+JDE8L21hcms+JylcbiAgICAvLyBWaXN1Qm90OiBbVWx0cmFzY2hhbGxzZW5zb3Jde3RlaWw9dWx0cmFzb25pY30gbGV1Y2h0ZXQgaW0gM0QtTW9kZWxsIGF1Ziwgd2VubiBtYW4gZGFyYXVmIHplaWd0LlxuICAgIC5yZXBsYWNlKC9cXFsoW15cXF1dKylcXF1cXHsoPzp0ZWlsfHBhcnQpPShbXFx3LF0rKVxcfS9nLCAnPHNwYW4gY2xhc3M9XCJyb2JvdC1wYXJ0LWxpbmtcIiBkYXRhLXJvYm90LXBhcnQ9XCIkMlwiIHRhYmluZGV4PVwiMFwiPiQxPC9zcGFuPicpXG4gIHJldHVybiBzLnJlcGxhY2UoL1xcdTAwMDAoXFxkKylcXHUwMDAwL2csIChfLCBpOiBzdHJpbmcpID0+IGA8Y29kZT4ke2NvZGVzW051bWJlcihpKV19PC9jb2RlPmApXG59XG5cbmV4cG9ydCBmdW5jdGlvbiBtYXJrZG93blRvSFRNTChzb3VyY2U6IHN0cmluZyk6IHN0cmluZyB7XG4gIGNvbnN0IG91dDogc3RyaW5nW10gPSBbXVxuICBjb25zdCBsaW5lcyA9IHNvdXJjZS5yZXBsYWNlKC9cXHJcXG4vZywgJ1xcbicpLnNwbGl0KCdcXG4nKVxuICBsZXQgaSA9IDBcbiAgd2hpbGUgKGkgPCBsaW5lcy5sZW5ndGgpIHtcbiAgICBjb25zdCBsaW5lID0gbGluZXNbaV1cbiAgICBpZiAobGluZS50cmltKCkgPT09ICcnKSB7XG4gICAgICBpKytcbiAgICAgIGNvbnRpbnVlXG4gICAgfVxuICAgIGlmIChsaW5lLnN0YXJ0c1dpdGgoJ2BgYCcpKSB7XG4gICAgICAvLyBgYGBqYXZhIGVkaXRvcjogVW50ZXIgZGVtIEJlaXNwaWVsIHN0ZWh0IOKAnkltIEVkaXRvciDDtmZmbmVu4oCcLCBkYW5uIGthbm4gbWFuIGVzIGluIFByb2dyYW1taWVyZW4gYXVzcHJvYmllcmVuLlxuICAgICAgY29uc3QgW2xhbmcsIGV4dHJhXSA9IGxpbmUuc2xpY2UoMykudHJpbSgpLnNwbGl0KC9cXHMrLylcbiAgICAgIGNvbnN0IGphdmEgPSBsYW5nID09PSAnamF2YSdcbiAgICAgIGNvbnN0IG9wZW4gPSBqYXZhICYmIGV4dHJhID09PSAnZWRpdG9yJ1xuICAgICAgY29uc3QgY29kZTogc3RyaW5nW10gPSBbXVxuICAgICAgaSsrXG4gICAgICB3aGlsZSAoaSA8IGxpbmVzLmxlbmd0aCAmJiAhbGluZXNbaV0uc3RhcnRzV2l0aCgnYGBgJykpIGNvZGUucHVzaChsaW5lc1tpKytdKVxuICAgICAgaSsrXG4gICAgICBvdXQucHVzaChgPHByZSBjbGFzcz1cImxlc3Nvbi1jb2RlXCIke2phdmEgPyAnIGRhdGEtbGFuZz1cImphdmFcIicgOiAnJ30ke29wZW4gPyAnIGRhdGEtb3Blbj1cImVkaXRvclwiJyA6ICcnfSBkaXI9XCJsdHJcIj48Y29kZT4ke2VzY2FwZShjb2RlLmpvaW4oJ1xcbicpKX08L2NvZGU+PC9wcmU+YClcbiAgICAgIGNvbnRpbnVlXG4gICAgfVxuICAgIGNvbnN0IGhlYWRpbmcgPSAvXigjezIsNH0pXFxzKyguKikkLy5leGVjKGxpbmUpXG4gICAgaWYgKGhlYWRpbmcpIHtcbiAgICAgIGNvbnN0IGxldmVsID0gaGVhZGluZ1sxXS5sZW5ndGhcbiAgICAgIG91dC5wdXNoKGA8aCR7bGV2ZWx9PiR7aW5saW5lKGhlYWRpbmdbMl0pfTwvaCR7bGV2ZWx9PmApXG4gICAgICBpKytcbiAgICAgIGNvbnRpbnVlXG4gICAgfVxuICAgIGlmICgvXlxccyooWy0qXXxcXGQrXFwuKVxccysvLnRlc3QobGluZSkpIHtcbiAgICAgIGNvbnN0IG9yZGVyZWQgPSAvXlxccypcXGQrXFwuLy50ZXN0KGxpbmUpXG4gICAgICBjb25zdCBpdGVtczogc3RyaW5nW10gPSBbXVxuICAgICAgd2hpbGUgKGkgPCBsaW5lcy5sZW5ndGggJiYgL15cXHMqKFstKl18XFxkK1xcLilcXHMrLy50ZXN0KGxpbmVzW2ldKSkge1xuICAgICAgICBsZXQgaXRlbSA9IGxpbmVzW2ldLnJlcGxhY2UoL15cXHMqKFstKl18XFxkK1xcLilcXHMrLywgJycpXG4gICAgICAgIGkrK1xuICAgICAgICB3aGlsZSAoaSA8IGxpbmVzLmxlbmd0aCAmJiAvXlxcc3syLH1cXFMvLnRlc3QobGluZXNbaV0pICYmICEvXlxccyooWy0qXXxcXGQrXFwuKVxccysvLnRlc3QobGluZXNbaV0pKSBpdGVtICs9ICcgJyArIGxpbmVzW2krK10udHJpbSgpXG4gICAgICAgIGl0ZW1zLnB1c2goYDxsaT4ke2lubGluZShpdGVtKX08L2xpPmApXG4gICAgICB9XG4gICAgICBvdXQucHVzaChvcmRlcmVkID8gYDxvbD4ke2l0ZW1zLmpvaW4oJycpfTwvb2w+YCA6IGA8dWw+JHtpdGVtcy5qb2luKCcnKX08L3VsPmApXG4gICAgICBjb250aW51ZVxuICAgIH1cbiAgICBpZiAobGluZS5zdGFydHNXaXRoKCd8JykgJiYgL15cXHw/W1xcczp8LV0qLXszLH1bXFxzOnwtXSokLy50ZXN0KGxpbmVzW2kgKyAxXSA/PyAnJykpIHtcbiAgICAgIGNvbnN0IGNlbGxzID0gKHJvdzogc3RyaW5nKSA9PiByb3cudHJpbSgpLnJlcGxhY2UoL15cXHwvLCAnJykucmVwbGFjZSgvXFx8JC8sICcnKS5zcGxpdCgnfCcpLm1hcCgoYykgPT4gaW5saW5lKGMudHJpbSgpKSlcbiAgICAgIGNvbnN0IGhlYWQgPSBjZWxscyhsaW5lKVxuICAgICAgaSArPSAyXG4gICAgICBjb25zdCByb3dzOiBzdHJpbmdbXVtdID0gW11cbiAgICAgIHdoaWxlIChpIDwgbGluZXMubGVuZ3RoICYmIGxpbmVzW2ldLnN0YXJ0c1dpdGgoJ3wnKSkgcm93cy5wdXNoKGNlbGxzKGxpbmVzW2krK10pKVxuICAgICAgb3V0LnB1c2goXG4gICAgICAgIGA8ZGl2IGNsYXNzPVwibGVzc29uLXRhYmxlXCI+PHRhYmxlPjx0aGVhZD48dHI+JHtoZWFkLm1hcCgoYykgPT4gYDx0aD4ke2N9PC90aD5gKS5qb2luKCcnKX08L3RyPjwvdGhlYWQ+PHRib2R5PiR7cm93c1xuICAgICAgICAgIC5tYXAoKHIpID0+IGA8dHI+JHtyLm1hcCgoYykgPT4gYDx0ZD4ke2N9PC90ZD5gKS5qb2luKCcnKX08L3RyPmApXG4gICAgICAgICAgLmpvaW4oJycpfTwvdGJvZHk+PC90YWJsZT48L2Rpdj5gLFxuICAgICAgKVxuICAgICAgY29udGludWVcbiAgICB9XG4gICAgaWYgKGxpbmUuc3RhcnRzV2l0aCgnPicpKSB7XG4gICAgICBjb25zdCBxdW90ZTogc3RyaW5nW10gPSBbXVxuICAgICAgd2hpbGUgKGkgPCBsaW5lcy5sZW5ndGggJiYgbGluZXNbaV0uc3RhcnRzV2l0aCgnPicpKSBxdW90ZS5wdXNoKGxpbmVzW2krK10ucmVwbGFjZSgvXj5cXHM/LywgJycpKVxuICAgICAgb3V0LnB1c2goYDxhc2lkZSBjbGFzcz1cImxlc3Nvbi1ub3RlXCI+JHttYXJrZG93blRvSFRNTChxdW90ZS5qb2luKCdcXG4nKSl9PC9hc2lkZT5gKVxuICAgICAgY29udGludWVcbiAgICB9XG4gICAgY29uc3QgcGFyYTogc3RyaW5nW10gPSBbXVxuICAgIHdoaWxlIChcbiAgICAgIGkgPCBsaW5lcy5sZW5ndGggJiZcbiAgICAgIGxpbmVzW2ldLnRyaW0oKSAhPT0gJycgJiZcbiAgICAgICEvXihgYGB8I3szLDR9XFxzfD58XFx8fFxccyooWy0qXXxcXGQrXFwuKVxccyspLy50ZXN0KGxpbmVzW2ldKVxuICAgICkge1xuICAgICAgcGFyYS5wdXNoKGxpbmVzW2krK10udHJpbSgpKVxuICAgIH1cbiAgICBvdXQucHVzaChgPHA+JHtpbmxpbmUocGFyYS5qb2luKCcgJykpfTwvcD5gKVxuICB9XG4gIHJldHVybiBvdXQuam9pbignXFxuJylcbn1cbiJdLCJmaWxlIjoiL3dlYi9zcmMvbGVhcm4vbWFya2Rvd24udHMifQ== + +//# vitestCache=W3siZmlsZSI6IjEiLCJpZCI6IjEiLCJ1cmwiOiIyIiwiaW1wb3J0cyI6IjMiLCJtYXBwaW5ncyI6ZmFsc2UsImRlcHMiOiI0IiwiZHluYW1pY0RlcHMiOiI1Iiwic3RhdGljTW9ja3MiOm51bGx9LCIvaG9tZS91c2VyL3Zpc3VzdHJ1Y3Qtc3dpZnR1aS93ZWIvc3JjL2xlYXJuL21hcmtkb3duLnRzIiwiL3dlYi9zcmMvbGVhcm4vbWFya2Rvd24udHMiLHsidXJscyI6IjYiLCJpZHMiOiI3In0sW10sW10sW10se31d \ No newline at end of file diff --git a/node_modules/.vitest-cache/c9e09693ee8175a114f4dbe1e385c70c5582fca5 b/node_modules/.vitest-cache/c9e09693ee8175a114f4dbe1e385c70c5582fca5 new file mode 100644 index 00000000..c4d4930c --- /dev/null +++ b/node_modules/.vitest-cache/c9e09693ee8175a114f4dbe1e385c70c5582fca5 @@ -0,0 +1,567 @@ +__vite_ssr_exportName__("FormatError", () => { try { return FormatError } catch {} }); +__vite_ssr_exportName__("parseTest", () => { try { return parseTest } catch {} }); +__vite_ssr_exportName__("parseSensorTest", () => { try { return parseSensorTest } catch {} }); +__vite_ssr_exportName__("parseBlocks", () => { try { return parseBlocks } catch {} }); +__vite_ssr_exportName__("parseLesson", () => { try { return parseLesson } catch {} }); +__vite_ssr_exportName__("parseTask", () => { try { return parseTask } catch {} }); +const __vite_ssr_import_0__ = await __vite_ssr_import__("/web/src/core/mbot.ts", {"importedNames":["driveSignature","isMBotPart","MBOT_PARTS","MBOT_SENSORS","parseActionSpec","parseDriveSpec"]}); +const __vite_ssr_import_1__ = await __vite_ssr_import__("/web/src/learn/boolGame.ts", {"importedNames":["parseBoolGame"]}); +const __vite_ssr_import_2__ = await __vite_ssr_import__("/web/src/learn/roundGame.ts", {"importedNames":["isRoundGameKind","parseRoundGame"]}); +const __vite_ssr_import_3__ = await __vite_ssr_import__("/web/src/learn/rescueGame.ts", {"importedNames":["parseRescueGame"]}); +const __vite_ssr_import_4__ = await __vite_ssr_import__("/web/src/learn/cloze.ts", {"importedNames":["parseCloze"]}); +const __vite_ssr_import_5__ = await __vite_ssr_import__("/web/src/learn/pap.ts", {"importedNames":["parsePap"]}); + + + + + + +class FormatError extends Error {}; +function frontMatter(source, file) { + const m = /^---\n([\s\S]*?)\n---\n?/.exec(source.replace(/\r\n/g, "\n")); + if (!m) throw new FormatError(`${file}: Kopfzeilen (--- … ---) fehlen.`); + const meta = new Map(); + for (const line of m[1].split("\n")) { + const kv = /^([a-zäöüß]+):\s*(.*)$/i.exec(line.trim()); + if (kv) meta.set(kv[1].toLowerCase(), kv[2].trim()); + }; + return { + meta, + body: source.replace(/\r\n/g, "\n").slice(m[0].length) + }; +} +/** `3, 4 -> 7 | 8` = Eingaben 3 und 4, erwartete Ausgabezeilen 7 und 8. */ +function parseTest(spec, file) { + const parts = spec.split(/\s*(?:->|→)\s*/); + if (parts.length !== 2) throw new FormatError(`${file}: Test „${spec}“ braucht genau ein „->“.`); + const list = (s, sep) => s.trim() === "" || s.trim() === "-" ? [] : s.split(sep).map((x) => x.trim()); + return { + inputs: list(parts[0], /\s*,\s*/), + expected: list(parts[1], /\s*\|\s*/) + }; +}; +/** `getLoudness=0/80, isButtonA=true -> forward 30, ledOn` (siehe `messwerte:`). */ +function parseSensorTest(value) { + const arrow = /^(.*?)\s*(?:->|→)\s*(.*)$/.exec(value.trim()); + if (!arrow) throw new Error(`„messwerte: ${value}“ braucht ein „->“.`); + const sensors = {}; + for (const part of arrow[1].split(/\s*,\s*/).filter(Boolean)) { + const m = /^(\w+)\s*=\s*(.+)$/.exec(part); + if (!m || !(m[1] in __vite_ssr_import_0__.MBOT_SENSORS)) throw new Error(`Unbekannter Sensor in „${part}“.`); + sensors[m[1]] = m[2].split("/").map((v) => { + const t = v.trim(); + if (t === "true" || t === "false") return t === "true"; + if (/^-?\d+(\.\d+)?$/.test(t)) return Number(t); + // Text, z. B. eine Farbe: getColor=rot + if (typeof __vite_ssr_import_0__.MBOT_SENSORS[m[1]].simulated === "string") return t; + throw new Error(`Messwert „${t}“ ist keine Zahl und nicht true/false.`); + }); + }; + return robotExpectation({ + inputs: [], + expected: [], + sensors + }, arrow[2]); +}; +/** Rechte Seite von `welt: … ->` und `messwerte: … ->`: Fahrt sowie `ledOn`, `ledOff`, `tone`, `noTone`, `none` (fährt nicht), `drives` (fährt irgendwie), `screen "Text"`. */ +function robotExpectation(test, spec) { + const drive = []; + // `screen "Abstand: 42 cm"`: dieser Text steht am Ende auf dem Bildschirm (darf Kommas enthalten) + spec = spec.replace(/\bscreen\s+("(?:[^"\\]|\\.)*")/u, (_, text) => { + test.screen = JSON.parse(text); + return ""; + }); + for (const token of spec.split(/\s*,\s*/).filter(Boolean)) { + if (token === "ledOn" || token === "ledOff") test.led = token === "ledOn"; + else if (token === "tone" || token === "noTone") test.tone = token === "tone"; + else if (token === "none") test.drive = []; + else if (token === "drives") test.drives = true; + else drive.push(token); + }; + if (drive.length) test.drive = (0,__vite_ssr_import_0__.driveSignature)((0,__vite_ssr_import_0__.parseDriveSpec)(drive.join(", "))); + return test; +} +function parseExercise(id, lines, file) { + const ex = { + id, + title: "", + task: "", + tests: [], + requires: [], + hints: [], + subprograms: [] + }; + let last; + for (const raw of lines) { + const kv = /^(titel|auftrag|start|test|datei|fahrt|befehle|welt|messwerte|schleifentiefe|braucht|tipp|lösung|loesung|unterprogramm|code):\s*(.*)$/i.exec(raw.trim()); + if (kv) { + const [, key, value] = kv; + last = undefined; + switch (key.toLowerCase()) { + case "titel": + ex.title = value; + break; + case "auftrag": + ex.task = value; + last = "task"; + break; + case "start": + ex.start = value; + break; + case "test": + ex.tests.push(parseTest(value, file)); + break; + case "datei": { + // `datei: neu.txt -> Heu | Äpfel`: Diese Datei soll das Programm im letzten Test speichern. + const m = /^([\w.-]+)\s*(?:->|→)\s*(.*)$/.exec(value.trim()); + if (!m || !ex.tests.length) throw new FormatError(`${file}: Übung „${id}“: „datei:“ braucht vorher einen Test und die Form „name.txt -> Zeile | Zeile“.`); + const expected = ex.tests[ex.tests.length - 1]; + expected.files = [...expected.files ?? [], { + name: m[1], + lines: m[2].trim() === "" ? [] : m[2].split(/\s*\|\s*/).map((x) => x.trim()) + }]; + break; + } + case "fahrt": + // VisuBot: `fahrt: 4 x (forward 50, turnRight 90)` – so soll der Roboter fahren (ohne Ausgabe, ohne Eingabe). + try { + ex.tests.push({ + inputs: [], + expected: [], + drive: (0,__vite_ssr_import_0__.driveSignature)((0,__vite_ssr_import_0__.parseDriveSpec)(value)) + }); + } catch (err) { + throw new FormatError(`${file}: Übung „${id}“: ${err.message}`); + }; + break; + case "welt": { + // VisuBot: `welt: wand-nah, wand-weit` – in jeder dieser Welten muss der Roboter ohne Anstoßen ins Ziel. + // `welt: wand-nah -> turnRight` – in dieser Welt soll er genau so fahren (für Verzweigungen mit Sensoren). + const arrow = /^([\w-]+)\s*(?:->|→)\s*(.+)$/.exec(value.trim()); + if (arrow) { + try { + ex.tests.push(robotExpectation({ + inputs: [], + expected: [], + world: arrow[1] + }, arrow[2])); + } catch (err) { + throw new FormatError(`${file}: Übung „${id}“: ${err.message}`); + }; + break; + }; + for (const name of value.split(/\s*,\s*/).filter(Boolean)) { + if (!/^[\w-]+$/.test(name)) throw new FormatError(`${file}: Übung „${id}“: Weltname „${name}“ (nur Buchstaben, Ziffern, -).`); + ex.tests.push({ + inputs: [], + expected: [], + world: name + }); + }; + break; + } + case "befehle": + // VisuBot: `befehle: 3 x (setLed 255 0 0, pause 500, ledOff, pause 500)` – genau diese Befehle für LEDs, Ton und Bildschirm. + try { + ex.tests.push({ + inputs: [], + expected: [], + actions: (0,__vite_ssr_import_0__.parseActionSpec)(value) + }); + } catch (err) { + throw new FormatError(`${file}: Übung „${id}“: ${err.message}`); + }; + break; + case "messwerte": + // VisuBot: `messwerte: getLoudness=0/80, isButtonA=false -> forward, ledOn` – mit diesen Sensorwerten + // (nacheinander, durch / getrennt) soll der Roboter so fahren bzw. leuchten (`ledOn`, `ledOff`, `tone`, `noTone`, `none`). + try { + ex.tests.push(parseSensorTest(value)); + } catch (err) { + throw new FormatError(`${file}: Übung „${id}“: ${err.message}`); + }; + break; + case "schleifentiefe": + ex.loopDepth = Number(value); + if (!Number.isInteger(ex.loopDepth) || ex.loopDepth < 1) throw new FormatError(`${file}: Übung „${id}“: „schleifentiefe:“ braucht eine Zahl ab 1.`); + break; + case "braucht": + ex.requires.push(...value.split(/\s*,\s*/).filter(Boolean)); + break; + case "tipp": + ex.hints.push(value); + last = "hint"; + break; + case "lösung": + case "loesung": + ex.solution = value; + break; + case "unterprogramm": + ex.subprograms.push(...value.split(/\s*,\s*/).filter(Boolean)); + break; + case "code": + if (value.trim().toLowerCase() !== "java") throw new FormatError(`${file}: Übung „${id}“: „code:“ kennt nur „java“.`); + ex.code = "java"; + break; + } + } else if (last && raw.trim() !== "") { + // Fortsetzungszeilen für Auftrag und Tipp + if (last === "task") ex.task += "\n" + raw.trim(); + else ex.hints[ex.hints.length - 1] += "\n" + raw.trim(); + } else if (raw.trim() === "" && last === "task") { + ex.task += "\n"; + } + }; + if (!ex.title) throw new FormatError(`${file}: Übung „${id}“ hat keinen Titel.`); + if (!ex.task.trim()) throw new FormatError(`${file}: Übung „${id}“ hat keinen Auftrag.`); + ex.task = ex.task.trim(); + return ex; +} +function parseQuiz(lines, file) { + const questions = []; + for (const raw of lines) { + const line = raw.trim(); + if (line.startsWith("?")) { + questions.push({ + question: line.slice(1).trim(), + options: [] + }); + } else if (/^- \[[ xX]\]/.test(line)) { + const q = questions.at(-1); + if (!q) throw new FormatError(`${file}: Antwort ohne Frage im Quiz.`); + q.options.push({ + text: line.slice(5).trim(), + correct: line[3].toLowerCase() === "x" + }); + } else if (line.startsWith("= ")) { + const q = questions.at(-1); + const m = /^=\s+(.+?)\s+->\s+(.+)$/.exec(line); + if (!q || !m) throw new FormatError(`${file}: Zuordnung „${line}“ braucht die Form „= links -> rechts“ nach einer Frage.`); + (q.pairs ??= []).push({ + left: m[1].trim(), + right: m[2].trim() + }); + } else if (line.startsWith("→")) { + const q = questions.at(-1); + if (!q) throw new FormatError(`${file}: „→ Schritt“ ohne Frage im Quiz.`); + q.ref = line.slice(1).trim(); + } else if (line.startsWith(">")) { + const q = questions.at(-1); + if (q) q.explanation = ((q.explanation ? q.explanation + " " : "") + line.slice(1).trim()).trim(); + } + }; + for (const q of questions) { + if (q.pairs) { + const rights = new Set(q.pairs.map((p) => p.right)); + if (q.options.length > 0 || q.pairs.length < 2 || rights.size !== q.pairs.length) { + throw new FormatError(`${file}: Zuordnung „${q.question}“ braucht mindestens zwei Paare mit verschiedenen rechten Seiten und keine Antworten.`); + }; + continue; + }; + if (q.options.length < 2 || !q.options.some((o) => o.correct)) { + throw new FormatError(`${file}: Quizfrage „${q.question}“ braucht mindestens zwei Antworten, davon eine richtige.`); + } + }; + return questions; +} +/** Text in Blöcke zerlegen: normales Markdown und `::: art …` bis `:::`. */ +function parseBlocks(body, file) { + const blocks = []; + const lines = body.split("\n"); + let markdown = []; + const flush = () => { + const text = markdown.join("\n").trim(); + if (text) blocks.push({ + kind: "markdown", + text + }); + markdown = []; + }; + for (let i = 0; i < lines.length; i++) { + const open = /^:::\s*([a-zäöüß][a-zäöüß0-9]*)\s*(.*)$/i.exec(lines[i].trim()); + if (!open) { + markdown.push(lines[i]); + continue; + }; + flush(); + const inner = []; + let j = i + 1; + while (j < lines.length && lines[j].trim() !== ":::") inner.push(lines[j++]); + if (j >= lines.length) throw new FormatError(`${file}: Block „::: ${open[1]}“ wird nicht mit „:::“ geschlossen.`); + const kind = open[1].toLowerCase(); + const arg = open[2].trim(); + switch (kind) { + case "diagramm": + if (!arg) throw new FormatError(`${file}: „::: diagramm“ braucht einen Dateinamen.`); + blocks.push({ + kind: "diagram", + file: arg, + caption: inner.join(" ").trim() + }); + break; + case "übung": + case "uebung": + if (!arg) throw new FormatError(`${file}: „::: übung“ braucht eine Kennung.`); + blocks.push({ + kind: "exercise", + exercise: parseExercise(arg, inner, file) + }); + break; + case "checkliste": + blocks.push({ + kind: "checklist", + items: inner.map((l) => l.trim()).filter((l) => l.startsWith("- ")).map((l) => checklistItem(l.slice(2).trim())) + }); + break; + case "kompetenzen": + blocks.push({ + kind: "competences", + items: inner.map((l) => l.trim()).filter((l) => l.startsWith("- ")).map((l) => l.slice(2).trim()) + }); + break; + case "quiz": + blocks.push({ + kind: "quiz", + questions: parseQuiz(inner, file) + }); + break; + case "bild": + if (!arg) throw new FormatError(`${file}: „::: bild“ braucht einen Dateinamen.`); + blocks.push({ + kind: "images", + files: arg.split(/\s+/), + caption: inner.join(" ").trim() + }); + break; + case "grafik": + if (!arg) throw new FormatError(`${file}: „::: grafik“ braucht einen Dateinamen.`); + { + const [graphic, labeled] = arg.split(/\s+/); + blocks.push({ + kind: "graphic", + file: graphic, + ...labeled ? { labeled } : {}, + caption: inner.join(" ").trim() + }); + } + break; + case "angeberwissen": + blocks.push({ + kind: "brag", + text: inner.join("\n").trim() + }); + break; + case "spiel": + try { + if ((0,__vite_ssr_import_2__.isRoundGameKind)(arg)) blocks.push({ + kind: "roundGame", + game: (0,__vite_ssr_import_2__.parseRoundGame)(arg, inner, file) + }); + else if (arg === "prinzessin") blocks.push({ + kind: "rescueGame", + game: (0,__vite_ssr_import_3__.parseRescueGame)(inner, file) + }); + else if (arg) throw new FormatError(`${file}: Unbekanntes Spiel „${arg}“ (zuhoerer, vertrag, layout, bombe, frage, reihenfolge oder prinzessin).`); + else blocks.push({ + kind: "game", + game: (0,__vite_ssr_import_1__.parseBoolGame)(inner, file) + }); + } catch (err) { + throw new FormatError(err.message); + }; + break; + case "lückentext": + case "lueckentext": + try { + blocks.push({ + kind: "cloze", + cloze: (0,__vite_ssr_import_4__.parseCloze)(inner, file) + }); + } catch (err) { + throw new FormatError(err.message); + }; + break; + case "pap": + try { + blocks.push({ + kind: "pap", + pap: (0,__vite_ssr_import_5__.parsePap)(inner, file) + }); + } catch (err) { + throw new FormatError(err.message); + }; + break; + case "profiwissen": + blocks.push({ + kind: "brag", + text: inner.join("\n").trim(), + pro: true + }); + break; + case "ludwig": + blocks.push({ + kind: "brag", + text: inner.join("\n").trim(), + tip: true + }); + break; + case "caesar": { + const key = arg ? Number(arg) : 3; + if (!Number.isInteger(key) || key < 0 || key > 25) throw new FormatError(`${file}: „::: caesar“ braucht einen Schlüssel von 0 bis 25.`); + blocks.push({ + kind: "caesar", + key, + text: inner.join(" ").trim() + }); + break; + } + case "mbot2": { + // `fokus: cyberpi, screen`, `ansicht: unten`, `drehen: ja` + const block = { + kind: "robotModel", + focus: [] + }; + for (const line of inner.filter((l) => l.trim())) { + const m = /^\s*(fokus|focus|ansicht|view|drehen|spin):\s*(.*)$/i.exec(line); + if (!m) throw new FormatError(`${file}: „::: mbot2“ kennt nur Zeilen „fokus:“, „ansicht:“ und „drehen:“.`); + const key = m[1].toLowerCase(); + if (key === "fokus" || key === "focus") block.focus = robotParts(m[2], file); + else if (key === "ansicht" || key === "view") block.view = m[2].trim().toLowerCase(); + else block.spin = /^(ja|yes|true|sim)$/i.test(m[2].trim()); + }; + blocks.push(block); + break; + } + case "mbot2quiz": { + // `- ultrasonic: Wo ist der **Ultraschallsensor**?` und `fertig: Super!` + const block = { + kind: "robotQuiz", + tasks: [] + }; + for (const line of inner.filter((l) => l.trim())) { + const task = /^\s*-\s*(\w+)\s*:\s*(.+)$/.exec(line); + const done = /^\s*(fertig|done):\s*(.+)$/i.exec(line); + if (task) block.tasks.push({ + part: robotParts(task[1], file)[0], + question: task[2].trim() + }); + else if (done) block.done = done[2].trim(); + else throw new FormatError(`${file}: „::: mbot2quiz“ braucht Zeilen „- teil: Frage“ und optional „fertig: Text“.`); + }; + if (!block.tasks.length) throw new FormatError(`${file}: „::: mbot2quiz“ hat keine Fragen.`); + blocks.push(block); + break; + } + case "datei": { + if (!/^[\w.-]+\.(txt|csv|json)$/u.test(arg)) throw new FormatError(`${file}: „::: datei“ braucht einen Dateinamen wie brief.txt, liste.csv oder daten.json.`); + // Der Inhalt bleibt genau so, wie er dasteht, nur ohne Leerzeilen am Anfang und Ende. + while (inner.length && inner[0].trim() === "") inner.shift(); + while (inner.length && inner[inner.length - 1].trim() === "") inner.pop(); + blocks.push({ + kind: "textFile", + name: arg, + content: inner.join("\n") + }); + break; + } + default: throw new FormatError(`${file}: Unbekannter Block „::: ${open[1]}“.`); + }; + i = j; + }; + flush(); + return blocks; +}; +function checklistItem(line) { + const m = /^(.*?)\s+→\s+(.+)$/.exec(line); + return m ? { + text: m[1], + ref: m[2].trim() + } : { text: line }; +} +/** Verweise aus Checklisten auf den erklärenden Schritt auflösen. */ +function resolveChecklistRefs(steps, file) { + const index = new Map(steps.map((s, i) => [s.title.toLowerCase(), i])); + for (const block of steps.flatMap((s) => s.blocks)) { + if (block.kind !== "checklist") continue; + for (const item of block.items) { + if (item.ref === undefined) continue; + item.step = index.get(item.ref.toLowerCase()); + if (item.step === undefined) throw new FormatError(`${file}: Checkliste verweist auf unbekannten Schritt „${item.ref}“.`); + } + }; + const checked = new Set(steps.flatMap((s) => s.blocks).flatMap((b) => b.kind === "checklist" ? b.items.map((i) => i.step) : [])); + for (const block of steps.flatMap((s) => s.blocks)) { + if (block.kind !== "quiz") continue; + for (const q of block.questions) { + if (q.ref === undefined) continue; + q.step = index.get(q.ref.toLowerCase()); + if (q.step === undefined) throw new FormatError(`${file}: Quizfrage „${q.question}“ verweist auf unbekannten Schritt „${q.ref}“.`); + if (!checked.has(q.step)) throw new FormatError(`${file}: Zu „${q.ref}“ (Quizfrage „${q.question}“) gibt es keinen Checklistenpunkt.`); + } + } +} +function parseLesson(source, file) { + const { meta, body } = frontMatter(source, file); + const name = file.replace(/^.*\//, "").replace(/\.md$/, ""); + const number = Number(/^(\d+)/.exec(name)?.[1]); + if (!Number.isFinite(number)) throw new FormatError(`${file}: Dateiname muss mit der Nummer beginnen (z. B. 01-…).`); + const steps = []; + let intro = []; + let current; + const close = () => { + if (current) steps.push({ + title: current.title, + blocks: parseBlocks(current.lines.join("\n"), file) + }); + }; + for (const line of body.split("\n")) { + const h = /^##\s+(.*)$/.exec(line); + if (h) { + close(); + current = { + title: h[1].trim(), + lines: [] + }; + } else if (current) { + current.lines.push(line); + } else { + intro.push(line); + } + }; + close(); + if (steps.length === 0) throw new FormatError(`${file}: Keine Schritte (## Überschrift) gefunden.`); + resolveChecklistRefs(steps, file); + const title = meta.get("titel"); + if (!title) throw new FormatError(`${file}: „titel:“ fehlt.`); + return { + id: name, + number, + title, + section: meta.get("bereich") ?? "", + summary: meta.get("kurz") ?? intro.join(" ").trim(), + steps + }; +}; +function parseTask(source, file) { + const { meta, body } = frontMatter(source, file); + const title = meta.get("titel"); + if (!title) throw new FormatError(`${file}: „titel:“ fehlt.`); + const after = meta.get("nach"); + return { + id: file.replace(/^.*\//, "").replace(/\.md$/, ""), + title, + after: after ? Number(after) : undefined, + level: Number(meta.get("stufe") ?? "1") || 1, + blocks: parseBlocks(body, file) + }; +}; +/** `cyberpi, screen` → geprüfte Teilnamen des mBot2-Modells. */ +function robotParts(list, file) { + const names = list.split(/\s*,\s*/).map((x) => x.trim()).filter(Boolean); + for (const n of names) if (!(0,__vite_ssr_import_0__.isMBotPart)(n)) throw new FormatError(`${file}: Unbekanntes Teil „${n}“. Bekannt: ${__vite_ssr_import_0__.MBOT_PARTS.join(", ")}.`); + return names; +} +//# sourceMappingSource=vite-generated +//# sourceMappingURL=data:application/json;base64,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LEtBQUs7RUFDaEMsU0FBUyxLQUFLLElBQUksTUFBTSxLQUFLLE1BQU0sS0FBSyxHQUFHLENBQUMsQ0FBQyxLQUFLO0VBQ2xEO0NBQ0Y7QUFDRjtBQUVPLFNBQVMsVUFBVSxRQUFnQixNQUFvQjtDQUM1RCxNQUFNLEVBQUUsTUFBTSxTQUFTLFlBQVksUUFBUSxJQUFJO0NBQy9DLE1BQU0sUUFBUSxLQUFLLElBQUksT0FBTztDQUM5QixJQUFJLENBQUMsT0FBTyxNQUFNLElBQUksWUFBWSxHQUFHLEtBQUssa0JBQWtCO0NBQzVELE1BQU0sUUFBUSxLQUFLLElBQUksTUFBTTtDQUM3QixPQUFPO0VBQ0wsSUFBSSxLQUFLLFFBQVEsU0FBUyxFQUFFLENBQUMsQ0FBQyxRQUFRLFNBQVMsRUFBRTtFQUNqRDtFQUNBLE9BQU8sUUFBUSxPQUFPLEtBQUssSUFBSTtFQUMvQixPQUFPLE9BQU8sS0FBSyxJQUFJLE9BQU8sS0FBSyxHQUFHLEtBQUs7RUFDM0MsUUFBUSxZQUFZLE1BQU0sSUFBSTtDQUNoQztBQUNGOztBQUdBLFNBQVMsV0FBVyxNQUFjLE1BQTBCO0NBQzFELE1BQU0sUUFBUSxLQUFLLE1BQU0sU0FBUyxDQUFDLENBQUMsS0FBSyxNQUFNLEVBQUUsS0FBSyxDQUFDLENBQUMsQ0FBQyxPQUFPLE9BQU87Q0FDdkUsS0FBSyxNQUFNLEtBQUssT0FBTyxJQUFJLENBQUMscUNBQVcsQ0FBQyxHQUFHLE1BQU0sSUFBSSxZQUFZLEdBQUcsS0FBSyxzQkFBc0IsRUFBRSxjQUFjLGlDQUFXLEtBQUssSUFBSSxFQUFFLEVBQUU7Q0FDdkksT0FBTztBQUNUIiwibmFtZXMiOltdLCJpZ25vcmVMaXN0IjpbXSwic291cmNlcyI6WyJsZXNzb25Gb3JtYXQudHMiXSwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHR5cGUgeyBFeGVyY2lzZVRlc3QgfSBmcm9tICcuLi9jb3JlL2V4ZXJjaXNlQ2hlY2snXG5pbXBvcnQgeyBkcml2ZVNpZ25hdHVyZSwgaXNNQm90UGFydCwgTUJPVF9QQVJUUywgTUJPVF9TRU5TT1JTLCBwYXJzZUFjdGlvblNwZWMsIHBhcnNlRHJpdmVTcGVjLCB0eXBlIE1Cb3RQYXJ0LCB0eXBlIE1Cb3RTZW5zb3JWYWx1ZSB9IGZyb20gJy4uL2NvcmUvbWJvdCdcbmltcG9ydCB7IHBhcnNlQm9vbEdhbWUsIHR5cGUgQm9vbEdhbWUgfSBmcm9tICcuL2Jvb2xHYW1lJ1xuaW1wb3J0IHsgaXNSb3VuZEdhbWVLaW5kLCBwYXJzZVJvdW5kR2FtZSwgdHlwZSBSb3VuZEdhbWUgfSBmcm9tICcuL3JvdW5kR2FtZSdcbmltcG9ydCB7IHBhcnNlUmVzY3VlR2FtZSwgdHlwZSBSZXNjdWVHYW1lIH0gZnJvbSAnLi9yZXNjdWVHYW1lJ1xuaW1wb3J0IHsgcGFyc2VDbG96ZSwgdHlwZSBDbG96ZSB9IGZyb20gJy4vY2xvemUnXG5pbXBvcnQgeyBwYXJzZVBhcCwgdHlwZSBQYXAgfSBmcm9tICcuL3BhcCdcblxuLyoqXG4gKiBMZWt0aW9uZW4gdW5kIEF1ZmdhYmVuIGFscyBNYXJrZG93biBtaXQgS29wZnplaWxlbiB1bmQgYDo6OmAtQmzDtmNrZW4gKHNpZWhlIGBsZXNzb25zL1JFQURNRS5tZGApLlxuICogSmVkZSBgIyMgw5xiZXJzY2hyaWZ0YCBiZWdpbm50IGVpbmVuIG5ldWVuIFNjaHJpdHQuXG4gKi9cblxuZXhwb3J0IHR5cGUgQmxvY2sgPVxuICB8IHsga2luZDogJ21hcmtkb3duJzsgdGV4dDogc3RyaW5nIH1cbiAgfCB7IGtpbmQ6ICdkaWFncmFtJzsgZmlsZTogc3RyaW5nOyBjYXB0aW9uOiBzdHJpbmcgfVxuICB8IHsga2luZDogJ2V4ZXJjaXNlJzsgZXhlcmNpc2U6IEV4ZXJjaXNlIH1cbiAgfCB7IGtpbmQ6ICdjaGVja2xpc3QnOyBpdGVtczogQ2hlY2tsaXN0SXRlbVtdIH1cbiAgLyoqIEtvbXBldGVuemVuIGFtIEFuZmFuZyBkZXIgTGVrdGlvbiAo4oCeRGllc2UgS29tcGV0ZW56ZW4gZXJ3ZXJiZSBpY2ggamV0enTigJwpLiAqL1xuICB8IHsga2luZDogJ2NvbXBldGVuY2VzJzsgaXRlbXM6IHN0cmluZ1tdIH1cbiAgfCB7IGtpbmQ6ICdxdWl6JzsgcXVlc3Rpb25zOiBRdWl6UXVlc3Rpb25bXSB9XG4gIHwgeyBraW5kOiAnYnJhZyc7IHRleHQ6IHN0cmluZzsgdGlwPzogYm9vbGVhbjsgcHJvPzogYm9vbGVhbiB9XG4gIHwgeyBraW5kOiAnaW1hZ2VzJzsgZmlsZXM6IHN0cmluZ1tdOyBjYXB0aW9uOiBzdHJpbmcgfVxuICAvKiogYGxhYmVsZWRgOiBiZXNjaHJpZnRldGUgRmFzc3VuZywgZGllIGVpbiBLbGljayBhdWYgZGllIEdyYWZpayBlaW4tIHVuZCBhdXNibGVuZGV0LiAqL1xuICB8IHsga2luZDogJ2dyYXBoaWMnOyBmaWxlOiBzdHJpbmc7IGxhYmVsZWQ/OiBzdHJpbmc7IGNhcHRpb246IHN0cmluZyB9XG4gIHwgeyBraW5kOiAnZ2FtZSc7IGdhbWU6IEJvb2xHYW1lIH1cbiAgfCB7IGtpbmQ6ICdyb3VuZEdhbWUnOyBnYW1lOiBSb3VuZEdhbWUgfVxuICB8IHsga2luZDogJ3Jlc2N1ZUdhbWUnOyBnYW1lOiBSZXNjdWVHYW1lIH1cbiAgfCB7IGtpbmQ6ICdjYWVzYXInOyBrZXk6IG51bWJlcjsgdGV4dDogc3RyaW5nIH1cbiAgLyoqIFZpc3VCb3Q6IGRyZWhiYXJlcyAzRC1Nb2RlbGwgZGVzIG1Cb3QyLCBUZWlsZSBhbnRpcHBlbiB6ZWlndCBpaHJlIEVya2zDpHJ1bmcuICovXG4gIC8qKiBWaXN1Qm90OiBkZXIgbUJvdDIgaW4gM0Q7IGRpZSBLYW1lcmEgZsOkaHJ0IHp1IGRlbiBUZWlsZW4gaW4gYGZvY3VzYCAoVG91ciB3aWUgYmVpIEphdmFQaWNvR29hdCkuICovXG4gIHwgeyBraW5kOiAncm9ib3RNb2RlbCc7IGZvY3VzOiBNQm90UGFydFtdOyB2aWV3Pzogc3RyaW5nOyBzcGluPzogYm9vbGVhbiB9XG4gIC8qKiBWaXN1Qm90OiBUZWlsZSBpbSBNb2RlbGwgYW5rbGlja2VuICjigJ5XbyBpc3QgZGVyIFVsdHJhc2NoYWxsc2Vuc29yP+KAnCkuICovXG4gIHwgeyBraW5kOiAncm9ib3RRdWl6JzsgdGFza3M6IHsgcGFydDogTUJvdFBhcnQ7IHF1ZXN0aW9uOiBzdHJpbmcgfVtdOyBkb25lPzogc3RyaW5nIH1cbiAgLyoqIEZlcnRpZ2VyIENvZGUgbWl0IEzDvGNrZW4gZsO8ciBlaW56ZWxuZSBXw7ZydGVyLiAqL1xuICB8IHsga2luZDogJ2Nsb3plJzsgY2xvemU6IENsb3plIH1cbiAgLyoqIFByb2dyYW1tYWJsYXVmcGxhbiBtaXQgbGVlcmVuIFBsw6R0emVuLCBkaWUgZmVydGlnZW4gRWxlbWVudGUgbGVndCBtYW4gaGluZWluLiAqL1xuICB8IHsga2luZDogJ3BhcCc7IHBhcDogUGFwIH1cbiAgLyoqIEVpbmUgVGV4dGRhdGVpIHp1bSBFaW5sZXNlbjogYEZpbGVzLnJlYWRTdHJpbmcoUGF0aC5vZihcIm5hbWVcIikpYCBsaWVmZXJ0IGlocmVuIEluaGFsdC4gKi9cbiAgfCB7IGtpbmQ6ICd0ZXh0RmlsZSc7IG5hbWU6IHN0cmluZzsgY29udGVudDogc3RyaW5nIH1cblxuZXhwb3J0IGludGVyZmFjZSBFeGVyY2lzZSB7XG4gIGlkOiBzdHJpbmdcbiAgdGl0bGU6IHN0cmluZ1xuICB0YXNrOiBzdHJpbmdcbiAgLyoqIFN0YXJ0ZGlhZ3JhbW0gKERhdGVpIGluIGBsZXNzb25zL2RpYWdyYW1tZWApOyBzb25zdCBsZWVyZXMgRGlhZ3JhbW0uICovXG4gIHN0YXJ0Pzogc3RyaW5nXG4gIHRlc3RzOiBFeGVyY2lzZVRlc3RbXVxuICAvKiogRWxlbWVudGFydGVuLCBkaWUgdm9ya29tbWVuIG3DvHNzZW4gKFNjaGzDvHNzZWwgd2llIGluIGRlciBQYWxldHRlLCB6LiBCLiBgdmVyendlaWd1bmdgKS4gKi9cbiAgcmVxdWlyZXM6IHN0cmluZ1tdXG4gIC8qKiBHZXN0dWZ0ZSBUaXBwcyAoZWluZSBgdGlwcDpgLVplaWxlIGplIFRpcHApLCB2b20gYWxsZ2VtZWluZW4genVtIGdlbmF1ZW4uICovXG4gIGhpbnRzOiBzdHJpbmdbXVxuICAvKiogTXVzdGVybMO2c3VuZyAoRGF0ZWkgaW4gYGxlc3NvbnMvZGlhZ3JhbW1lYCksIG51ciBpbSBMZWhyZXJtb2R1cyBzaWNodGJhci4gKi9cbiAgc29sdXRpb24/OiBzdHJpbmdcbiAgLyoqIFVudGVycHJvZ3JhbW1lIHp1ciBNdXN0ZXJsw7ZzdW5nIChEYXRlaWVuIGluIGBsZXNzb25zL2RpYWdyYW1tZWApLCBqZSBlaW5zIHBybyBSZWl0ZXIuICovXG4gIHN1YnByb2dyYW1zOiBzdHJpbmdbXVxuICAvKiogYGNvZGU6IGphdmFgOiBEaWUgw5xidW5nIHdpcmQgaW4gQ29kZSBsaXZlIGF1ZiBKYXZhIGdlbMO2c3Q7IOKAnsOcYnVuZyDDtmZmbmVu4oCcIMO2ZmZuZXQgZGllIFNwYWx0ZSBnbGVpY2ggbWl0LiAqL1xuICBjb2RlPzogJ2phdmEnXG4gIC8qKiBWaXN1Qm90OiBTY2hsZWlmZW4gbcO8c3NlbiBtaW5kZXN0ZW5zIHNvIHRpZWYgaW5laW5hbmRlciBzdGVja2VuIChgc2NobGVpZmVudGllZmU6IDJgKS4gKi9cbiAgbG9vcERlcHRoPzogbnVtYmVyXG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgQ2hlY2tsaXN0SXRlbSB7XG4gIHRleHQ6IHN0cmluZ1xuICAvKiogVGl0ZWwgZGVzIFNjaHJpdHRzLCBpbiBkZW0gZGVyIFB1bmt0IGVya2zDpHJ0IHdpcmQgKGAtIFRleHQg4oaSIFNjaHJpdHRgKS4gKi9cbiAgcmVmPzogc3RyaW5nXG4gIC8qKiBJbmRleCBkaWVzZXMgU2Nocml0dHMgaW4gZGVyIExla3Rpb24sIHZvbiBgcGFyc2VMZXNzb25gIGF1ZmdlbMO2c3QuICovXG4gIHN0ZXA/OiBudW1iZXJcbn1cblxuZXhwb3J0IGludGVyZmFjZSBRdWl6UXVlc3Rpb24ge1xuICBxdWVzdGlvbjogc3RyaW5nXG4gIG9wdGlvbnM6IHsgdGV4dDogc3RyaW5nOyBjb3JyZWN0OiBib29sZWFuIH1bXVxuICAvKiogWnVvcmRudW5nOiBadSBqZWRlbSBsaW5rZW4gQmVncmlmZiB3aXJkIGRlciBwYXNzZW5kZSByZWNodGUgZ2V3w6RobHQuICovXG4gIHBhaXJzPzogeyBsZWZ0OiBzdHJpbmc7IHJpZ2h0OiBzdHJpbmcgfVtdXG4gIGV4cGxhbmF0aW9uPzogc3RyaW5nXG4gIC8qKiBTY2hyaXR0LCBkZW4gZGllIEZyYWdlIHByw7xmdCAoYOKGkiBUaXRlbGApOyB2ZXJiaW5kZXQgc2llIG1pdCBkZW0gQ2hlY2tsaXN0ZW5wdW5rdCB6dSBkaWVzZW0gU2Nocml0dC4gKi9cbiAgcmVmPzogc3RyaW5nXG4gIHN0ZXA/OiBudW1iZXJcbn1cblxuZXhwb3J0IGludGVyZmFjZSBTdGVwIHtcbiAgdGl0bGU6IHN0cmluZ1xuICBibG9ja3M6IEJsb2NrW11cbn1cblxuZXhwb3J0IGludGVyZmFjZSBMZXNzb24ge1xuICBpZDogc3RyaW5nXG4gIG51bWJlcjogbnVtYmVyXG4gIHRpdGxlOiBzdHJpbmdcbiAgc2VjdGlvbjogc3RyaW5nXG4gIHN1bW1hcnk6IHN0cmluZ1xuICBzdGVwczogU3RlcFtdXG4gIC8qKiBWaXN1Qm90LUxla3Rpb24gaW4gZGVyIGR1cmNoZ2VoZW5kZW4gUmVpaGUgZGVyIFZpc3VCb3QtV2VsdCAoYmVrb21tdCBlaW4g8J+kliBpbiBkZXIgTGlzdGUpLiAqL1xuICByb2JvdD86IGJvb2xlYW5cbn1cblxuZXhwb3J0IGludGVyZmFjZSBUYXNrIHtcbiAgaWQ6IHN0cmluZ1xuICB0aXRsZTogc3RyaW5nXG4gIC8qKiBOdW1tZXIgZGVyIExla3Rpb24sIGRpZSBtYW4gdm9yaGVyIGFiZ2VzY2hsb3NzZW4gaGFiZW4gc29sbHRlLiAqL1xuICBhZnRlcj86IG51bWJlclxuICBsZXZlbDogbnVtYmVyXG4gIGJsb2NrczogQmxvY2tbXVxuICAvKiogVmlzdUJvdC1BdWZnYWJlIGluIGRlciBkdXJjaGdlaGVuZGVuIFJlaWhlIGRlciBWaXN1Qm90LVdlbHQuICovXG4gIHJvYm90PzogYm9vbGVhblxufVxuXG5leHBvcnQgY2xhc3MgRm9ybWF0RXJyb3IgZXh0ZW5kcyBFcnJvciB7fVxuXG5mdW5jdGlvbiBmcm9udE1hdHRlcihzb3VyY2U6IHN0cmluZywgZmlsZTogc3RyaW5nKTogeyBtZXRhOiBNYXA8c3RyaW5nLCBzdHJpbmc+OyBib2R5OiBzdHJpbmcgfSB7XG4gIGNvbnN0IG0gPSAvXi0tLVxcbihbXFxzXFxTXSo/KVxcbi0tLVxcbj8vLmV4ZWMoc291cmNlLnJlcGxhY2UoL1xcclxcbi9nLCAnXFxuJykpXG4gIGlmICghbSkgdGhyb3cgbmV3IEZvcm1hdEVycm9yKGAke2ZpbGV9OiBLb3BmemVpbGVuICgtLS0g4oCmIC0tLSkgZmVobGVuLmApXG4gIGNvbnN0IG1ldGEgPSBuZXcgTWFwPHN0cmluZywgc3RyaW5nPigpXG4gIGZvciAoY29uc3QgbGluZSBvZiBtWzFdLnNwbGl0KCdcXG4nKSkge1xuICAgIGNvbnN0IGt2ID0gL14oW2EtesOkw7bDvMOfXSspOlxccyooLiopJC9pLmV4ZWMobGluZS50cmltKCkpXG4gICAgaWYgKGt2KSBtZXRhLnNldChrdlsxXS50b0xvd2VyQ2FzZSgpLCBrdlsyXS50cmltKCkpXG4gIH1cbiAgcmV0dXJuIHsgbWV0YSwgYm9keTogc291cmNlLnJlcGxhY2UoL1xcclxcbi9nLCAnXFxuJykuc2xpY2UobVswXS5sZW5ndGgpIH1cbn1cblxuLyoqIGAzLCA0IC0+IDcgfCA4YCA9IEVpbmdhYmVuIDMgdW5kIDQsIGVyd2FydGV0ZSBBdXNnYWJlemVpbGVuIDcgdW5kIDguICovXG5leHBvcnQgZnVuY3Rpb24gcGFyc2VUZXN0KHNwZWM6IHN0cmluZywgZmlsZTogc3RyaW5nKTogRXhlcmNpc2VUZXN0IHtcbiAgY29uc3QgcGFydHMgPSBzcGVjLnNwbGl0KC9cXHMqKD86LT584oaSKVxccyovKVxuICBpZiAocGFydHMubGVuZ3RoICE9PSAyKSB0aHJvdyBuZXcgRm9ybWF0RXJyb3IoYCR7ZmlsZX06IFRlc3Qg4oCeJHtzcGVjfeKAnCBicmF1Y2h0IGdlbmF1IGVpbiDigJ4tPuKAnC5gKVxuICBjb25zdCBsaXN0ID0gKHM6IHN0cmluZywgc2VwOiBSZWdFeHApID0+IChzLnRyaW0oKSA9PT0gJycgfHwgcy50cmltKCkgPT09ICctJyA/IFtdIDogcy5zcGxpdChzZXApLm1hcCgoeCkgPT4geC50cmltKCkpKVxuICByZXR1cm4geyBpbnB1dHM6IGxpc3QocGFydHNbMF0sIC9cXHMqLFxccyovKSwgZXhwZWN0ZWQ6IGxpc3QocGFydHNbMV0sIC9cXHMqXFx8XFxzKi8pIH1cbn1cblxuLyoqIGBnZXRMb3VkbmVzcz0wLzgwLCBpc0J1dHRvbkE9dHJ1ZSAtPiBmb3J3YXJkIDMwLCBsZWRPbmAgKHNpZWhlIGBtZXNzd2VydGU6YCkuICovXG5leHBvcnQgZnVuY3Rpb24gcGFyc2VTZW5zb3JUZXN0KHZhbHVlOiBzdHJpbmcpOiBFeGVyY2lzZVRlc3Qge1xuICBjb25zdCBhcnJvdyA9IC9eKC4qPylcXHMqKD86LT584oaSKVxccyooLiopJC8uZXhlYyh2YWx1ZS50cmltKCkpXG4gIGlmICghYXJyb3cpIHRocm93IG5ldyBFcnJvcihg4oCebWVzc3dlcnRlOiAke3ZhbHVlfeKAnCBicmF1Y2h0IGVpbiDigJ4tPuKAnC5gKVxuICBjb25zdCBzZW5zb3JzOiBSZWNvcmQ8c3RyaW5nLCBNQm90U2Vuc29yVmFsdWVbXT4gPSB7fVxuICBmb3IgKGNvbnN0IHBhcnQgb2YgYXJyb3dbMV0uc3BsaXQoL1xccyosXFxzKi8pLmZpbHRlcihCb29sZWFuKSkge1xuICAgIGNvbnN0IG0gPSAvXihcXHcrKVxccyo9XFxzKiguKykkLy5leGVjKHBhcnQpXG4gICAgaWYgKCFtIHx8ICEobVsxXSBpbiBNQk9UX1NFTlNPUlMpKSB0aHJvdyBuZXcgRXJyb3IoYFVuYmVrYW5udGVyIFNlbnNvciBpbiDigJ4ke3BhcnR94oCcLmApXG4gICAgc2Vuc29yc1ttWzFdXSA9IG1bMl0uc3BsaXQoJy8nKS5tYXAoKHYpID0+IHtcbiAgICAgIGNvbnN0IHQgPSB2LnRyaW0oKVxuICAgICAgaWYgKHQgPT09ICd0cnVlJyB8fCB0ID09PSAnZmFsc2UnKSByZXR1cm4gdCA9PT0gJ3RydWUnXG4gICAgICBpZiAoL14tP1xcZCsoXFwuXFxkKyk/JC8udGVzdCh0KSkgcmV0dXJuIE51bWJlcih0KVxuICAgICAgLy8gVGV4dCwgei4gQi4gZWluZSBGYXJiZTogZ2V0Q29sb3I9cm90XG4gICAgICBpZiAodHlwZW9mIE1CT1RfU0VOU09SU1ttWzFdXS5zaW11bGF0ZWQgPT09ICdzdHJpbmcnKSByZXR1cm4gdFxuICAgICAgdGhyb3cgbmV3IEVycm9yKGBNZXNzd2VydCDigJ4ke3R94oCcIGlzdCBrZWluZSBaYWhsIHVuZCBuaWNodCB0cnVlL2ZhbHNlLmApXG4gICAgfSlcbiAgfVxuICByZXR1cm4gcm9ib3RFeHBlY3RhdGlvbih7IGlucHV0czogW10sIGV4cGVjdGVkOiBbXSwgc2Vuc29ycyB9LCBhcnJvd1syXSlcbn1cblxuLyoqIFJlY2h0ZSBTZWl0ZSB2b24gYHdlbHQ6IOKApiAtPmAgdW5kIGBtZXNzd2VydGU6IOKApiAtPmA6IEZhaHJ0IHNvd2llIGBsZWRPbmAsIGBsZWRPZmZgLCBgdG9uZWAsIGBub1RvbmVgLCBgbm9uZWAgKGbDpGhydCBuaWNodCksIGBkcml2ZXNgIChmw6RocnQgaXJnZW5kd2llKSwgYHNjcmVlbiBcIlRleHRcImAuICovXG5mdW5jdGlvbiByb2JvdEV4cGVjdGF0aW9uKHRlc3Q6IEV4ZXJjaXNlVGVzdCwgc3BlYzogc3RyaW5nKTogRXhlcmNpc2VUZXN0IHtcbiAgY29uc3QgZHJpdmU6IHN0cmluZ1tdID0gW11cbiAgLy8gYHNjcmVlbiBcIkFic3RhbmQ6IDQyIGNtXCJgOiBkaWVzZXIgVGV4dCBzdGVodCBhbSBFbmRlIGF1ZiBkZW0gQmlsZHNjaGlybSAoZGFyZiBLb21tYXMgZW50aGFsdGVuKVxuICBzcGVjID0gc3BlYy5yZXBsYWNlKC9cXGJzY3JlZW5cXHMrKFwiKD86W15cIlxcXFxdfFxcXFwuKSpcIikvdSwgKF8sIHRleHQ6IHN0cmluZykgPT4ge1xuICAgIHRlc3Quc2NyZWVuID0gSlNPTi5wYXJzZSh0ZXh0KSBhcyBzdHJpbmdcbiAgICByZXR1cm4gJydcbiAgfSlcbiAgZm9yIChjb25zdCB0b2tlbiBvZiBzcGVjLnNwbGl0KC9cXHMqLFxccyovKS5maWx0ZXIoQm9vbGVhbikpIHtcbiAgICBpZiAodG9rZW4gPT09ICdsZWRPbicgfHwgdG9rZW4gPT09ICdsZWRPZmYnKSB0ZXN0LmxlZCA9IHRva2VuID09PSAnbGVkT24nXG4gICAgZWxzZSBpZiAodG9rZW4gPT09ICd0b25lJyB8fCB0b2tlbiA9PT0gJ25vVG9uZScpIHRlc3QudG9uZSA9IHRva2VuID09PSAndG9uZSdcbiAgICBlbHNlIGlmICh0b2tlbiA9PT0gJ25vbmUnKSB0ZXN0LmRyaXZlID0gW11cbiAgICBlbHNlIGlmICh0b2tlbiA9PT0gJ2RyaXZlcycpIHRlc3QuZHJpdmVzID0gdHJ1ZVxuICAgIGVsc2UgZHJpdmUucHVzaCh0b2tlbilcbiAgfVxuICBpZiAoZHJpdmUubGVuZ3RoKSB0ZXN0LmRyaXZlID0gZHJpdmVTaWduYXR1cmUocGFyc2VEcml2ZVNwZWMoZHJpdmUuam9pbignLCAnKSkpXG4gIHJldHVybiB0ZXN0XG59XG5cbmZ1bmN0aW9uIHBhcnNlRXhlcmNpc2UoaWQ6IHN0cmluZywgbGluZXM6IHN0cmluZ1tdLCBmaWxlOiBzdHJpbmcpOiBFeGVyY2lzZSB7XG4gIGNvbnN0IGV4OiBFeGVyY2lzZSA9IHsgaWQsIHRpdGxlOiAnJywgdGFzazogJycsIHRlc3RzOiBbXSwgcmVxdWlyZXM6IFtdLCBoaW50czogW10sIHN1YnByb2dyYW1zOiBbXSB9XG4gIGxldCBsYXN0OiAndGFzaycgfCAnaGludCcgfCB1bmRlZmluZWRcbiAgZm9yIChjb25zdCByYXcgb2YgbGluZXMpIHtcbiAgICBjb25zdCBrdiA9IC9eKHRpdGVsfGF1ZnRyYWd8c3RhcnR8dGVzdHxkYXRlaXxmYWhydHxiZWZlaGxlfHdlbHR8bWVzc3dlcnRlfHNjaGxlaWZlbnRpZWZlfGJyYXVjaHR8dGlwcHxsw7ZzdW5nfGxvZXN1bmd8dW50ZXJwcm9ncmFtbXxjb2RlKTpcXHMqKC4qKSQvaS5leGVjKHJhdy50cmltKCkpXG4gICAgaWYgKGt2KSB7XG4gICAgICBjb25zdCBbLCBrZXksIHZhbHVlXSA9IGt2XG4gICAgICBsYXN0ID0gdW5kZWZpbmVkXG4gICAgICBzd2l0Y2ggKGtleS50b0xvd2VyQ2FzZSgpKSB7XG4gICAgICAgIGNhc2UgJ3RpdGVsJzogZXgudGl0bGUgPSB2YWx1ZTsgYnJlYWtcbiAgICAgICAgY2FzZSAnYXVmdHJhZyc6IGV4LnRhc2sgPSB2YWx1ZTsgbGFzdCA9ICd0YXNrJzsgYnJlYWtcbiAgICAgICAgY2FzZSAnc3RhcnQnOiBleC5zdGFydCA9IHZhbHVlOyBicmVha1xuICAgICAgICBjYXNlICd0ZXN0JzogZXgudGVzdHMucHVzaChwYXJzZVRlc3QodmFsdWUsIGZpbGUpKTsgYnJlYWtcbiAgICAgICAgY2FzZSAnZGF0ZWknOiB7XG4gICAgICAgICAgLy8gYGRhdGVpOiBuZXUudHh0IC0+IEhldSB8IMOEcGZlbGA6IERpZXNlIERhdGVpIHNvbGwgZGFzIFByb2dyYW1tIGltIGxldHp0ZW4gVGVzdCBzcGVpY2hlcm4uXG4gICAgICAgICAgY29uc3QgbSA9IC9eKFtcXHcuLV0rKVxccyooPzotPnzihpIpXFxzKiguKikkLy5leGVjKHZhbHVlLnRyaW0oKSlcbiAgICAgICAgICBpZiAoIW0gfHwgIWV4LnRlc3RzLmxlbmd0aCkgdGhyb3cgbmV3IEZvcm1hdEVycm9yKGAke2ZpbGV9OiDDnGJ1bmcg4oCeJHtpZH3igJw6IOKAnmRhdGVpOuKAnCBicmF1Y2h0IHZvcmhlciBlaW5lbiBUZXN0IHVuZCBkaWUgRm9ybSDigJ5uYW1lLnR4dCAtPiBaZWlsZSB8IFplaWxl4oCcLmApXG4gICAgICAgICAgY29uc3QgZXhwZWN0ZWQgPSBleC50ZXN0c1tleC50ZXN0cy5sZW5ndGggLSAxXVxuICAgICAgICAgIGV4cGVjdGVkLmZpbGVzID0gWy4uLihleHBlY3RlZC5maWxlcyA/PyBbXSksIHsgbmFtZTogbVsxXSwgbGluZXM6IG1bMl0udHJpbSgpID09PSAnJyA/IFtdIDogbVsyXS5zcGxpdCgvXFxzKlxcfFxccyovKS5tYXAoKHgpID0+IHgudHJpbSgpKSB9XVxuICAgICAgICAgIGJyZWFrXG4gICAgICAgIH1cbiAgICAgICAgY2FzZSAnZmFocnQnOlxuICAgICAgICAgIC8vIFZpc3VCb3Q6IGBmYWhydDogNCB4IChmb3J3YXJkIDUwLCB0dXJuUmlnaHQgOTApYCDigJMgc28gc29sbCBkZXIgUm9ib3RlciBmYWhyZW4gKG9obmUgQXVzZ2FiZSwgb2huZSBFaW5nYWJlKS5cbiAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgZXgudGVzdHMucHVzaCh7IGlucHV0czogW10sIGV4cGVjdGVkOiBbXSwgZHJpdmU6IGRyaXZlU2lnbmF0dXJlKHBhcnNlRHJpdmVTcGVjKHZhbHVlKSkgfSlcbiAgICAgICAgICB9IGNhdGNoIChlcnIpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBGb3JtYXRFcnJvcihgJHtmaWxlfTogw5xidW5nIOKAniR7aWR94oCcOiAkeyhlcnIgYXMgRXJyb3IpLm1lc3NhZ2V9YClcbiAgICAgICAgICB9XG4gICAgICAgICAgYnJlYWtcbiAgICAgICAgY2FzZSAnd2VsdCc6IHtcbiAgICAgICAgICAvLyBWaXN1Qm90OiBgd2VsdDogd2FuZC1uYWgsIHdhbmQtd2VpdGAg4oCTIGluIGplZGVyIGRpZXNlciBXZWx0ZW4gbXVzcyBkZXIgUm9ib3RlciBvaG5lIEFuc3Rvw59lbiBpbnMgWmllbC5cbiAgICAgICAgICAvLyBgd2VsdDogd2FuZC1uYWggLT4gdHVyblJpZ2h0YCDigJMgaW4gZGllc2VyIFdlbHQgc29sbCBlciBnZW5hdSBzbyBmYWhyZW4gKGbDvHIgVmVyendlaWd1bmdlbiBtaXQgU2Vuc29yZW4pLlxuICAgICAgICAgIGNvbnN0IGFycm93ID0gL14oW1xcdy1dKylcXHMqKD86LT584oaSKVxccyooLispJC8uZXhlYyh2YWx1ZS50cmltKCkpXG4gICAgICAgICAgaWYgKGFycm93KSB7XG4gICAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgICBleC50ZXN0cy5wdXNoKHJvYm90RXhwZWN0YXRpb24oeyBpbnB1dHM6IFtdLCBleHBlY3RlZDogW10sIHdvcmxkOiBhcnJvd1sxXSB9LCBhcnJvd1syXSkpXG4gICAgICAgICAgICB9IGNhdGNoIChlcnIpIHtcbiAgICAgICAgICAgICAgdGhyb3cgbmV3IEZvcm1hdEVycm9yKGAke2ZpbGV9OiDDnGJ1bmcg4oCeJHtpZH3igJw6ICR7KGVyciBhcyBFcnJvcikubWVzc2FnZX1gKVxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgYnJlYWtcbiAgICAgICAgICB9XG4gICAgICAgICAgZm9yIChjb25zdCBuYW1lIG9mIHZhbHVlLnNwbGl0KC9cXHMqLFxccyovKS5maWx0ZXIoQm9vbGVhbikpIHtcbiAgICAgICAgICAgIGlmICghL15bXFx3LV0rJC8udGVzdChuYW1lKSkgdGhyb3cgbmV3IEZvcm1hdEVycm9yKGAke2ZpbGV9OiDDnGJ1bmcg4oCeJHtpZH3igJw6IFdlbHRuYW1lIOKAniR7bmFtZX3igJwgKG51ciBCdWNoc3RhYmVuLCBaaWZmZXJuLCAtKS5gKVxuICAgICAgICAgICAgZXgudGVzdHMucHVzaCh7IGlucHV0czogW10sIGV4cGVjdGVkOiBbXSwgd29ybGQ6IG5hbWUgfSlcbiAgICAgICAgICB9XG4gICAgICAgICAgYnJlYWtcbiAgICAgICAgfVxuICAgICAgICBjYXNlICdiZWZlaGxlJzpcbiAgICAgICAgICAvLyBWaXN1Qm90OiBgYmVmZWhsZTogMyB4IChzZXRMZWQgMjU1IDAgMCwgcGF1c2UgNTAwLCBsZWRPZmYsIHBhdXNlIDUwMClgIOKAkyBnZW5hdSBkaWVzZSBCZWZlaGxlIGbDvHIgTEVEcywgVG9uIHVuZCBCaWxkc2NoaXJtLlxuICAgICAgICAgIHRyeSB7XG4gICAgICAgICAgICBleC50ZXN0cy5wdXNoKHsgaW5wdXRzOiBbXSwgZXhwZWN0ZWQ6IFtdLCBhY3Rpb25zOiBwYXJzZUFjdGlvblNwZWModmFsdWUpIH0pXG4gICAgICAgICAgfSBjYXRjaCAoZXJyKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgRm9ybWF0RXJyb3IoYCR7ZmlsZX06IMOcYnVuZyDigJ4ke2lkfeKAnDogJHsoZXJyIGFzIEVycm9yKS5tZXNzYWdlfWApXG4gICAgICAgICAgfVxuICAgICAgICAgIGJyZWFrXG4gICAgICAgIGNhc2UgJ21lc3N3ZXJ0ZSc6XG4gICAgICAgICAgLy8gVmlzdUJvdDogYG1lc3N3ZXJ0ZTogZ2V0TG91ZG5lc3M9MC84MCwgaXNCdXR0b25BPWZhbHNlIC0+IGZvcndhcmQsIGxlZE9uYCDigJMgbWl0IGRpZXNlbiBTZW5zb3J3ZXJ0ZW5cbiAgICAgICAgICAvLyAobmFjaGVpbmFuZGVyLCBkdXJjaCAvIGdldHJlbm50KSBzb2xsIGRlciBSb2JvdGVyIHNvIGZhaHJlbiBiencuIGxldWNodGVuIChgbGVkT25gLCBgbGVkT2ZmYCwgYHRvbmVgLCBgbm9Ub25lYCwgYG5vbmVgKS5cbiAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgZXgudGVzdHMucHVzaChwYXJzZVNlbnNvclRlc3QodmFsdWUpKVxuICAgICAgICAgIH0gY2F0Y2ggKGVycikge1xuICAgICAgICAgICAgdGhyb3cgbmV3IEZvcm1hdEVycm9yKGAke2ZpbGV9OiDDnGJ1bmcg4oCeJHtpZH3igJw6ICR7KGVyciBhcyBFcnJvcikubWVzc2FnZX1gKVxuICAgICAgICAgIH1cbiAgICAgICAgICBicmVha1xuICAgICAgICBjYXNlICdzY2hsZWlmZW50aWVmZSc6XG4gICAgICAgICAgZXgubG9vcERlcHRoID0gTnVtYmVyKHZhbHVlKVxuICAgICAgICAgIGlmICghTnVtYmVyLmlzSW50ZWdlcihleC5sb29wRGVwdGgpIHx8IGV4Lmxvb3BEZXB0aCA8IDEpIHRocm93IG5ldyBGb3JtYXRFcnJvcihgJHtmaWxlfTogw5xidW5nIOKAniR7aWR94oCcOiDigJ5zY2hsZWlmZW50aWVmZTrigJwgYnJhdWNodCBlaW5lIFphaGwgYWIgMS5gKVxuICAgICAgICAgIGJyZWFrXG4gICAgICAgIGNhc2UgJ2JyYXVjaHQnOiBleC5yZXF1aXJlcy5wdXNoKC4uLnZhbHVlLnNwbGl0KC9cXHMqLFxccyovKS5maWx0ZXIoQm9vbGVhbikpOyBicmVha1xuICAgICAgICBjYXNlICd0aXBwJzogZXguaGludHMucHVzaCh2YWx1ZSk7IGxhc3QgPSAnaGludCc7IGJyZWFrXG4gICAgICAgIGNhc2UgJ2zDtnN1bmcnOlxuICAgICAgICBjYXNlICdsb2VzdW5nJzogZXguc29sdXRpb24gPSB2YWx1ZTsgYnJlYWtcbiAgICAgICAgY2FzZSAndW50ZXJwcm9ncmFtbSc6IGV4LnN1YnByb2dyYW1zLnB1c2goLi4udmFsdWUuc3BsaXQoL1xccyosXFxzKi8pLmZpbHRlcihCb29sZWFuKSk7IGJyZWFrXG4gICAgICAgIGNhc2UgJ2NvZGUnOlxuICAgICAgICAgIGlmICh2YWx1ZS50cmltKCkudG9Mb3dlckNhc2UoKSAhPT0gJ2phdmEnKSB0aHJvdyBuZXcgRm9ybWF0RXJyb3IoYCR7ZmlsZX06IMOcYnVuZyDigJ4ke2lkfeKAnDog4oCeY29kZTrigJwga2VubnQgbnVyIOKAnmphdmHigJwuYClcbiAgICAgICAgICBleC5jb2RlID0gJ2phdmEnXG4gICAgICAgICAgYnJlYWtcbiAgICAgIH1cbiAgICB9IGVsc2UgaWYgKGxhc3QgJiYgcmF3LnRyaW0oKSAhPT0gJycpIHtcbiAgICAgIC8vIEZvcnRzZXR6dW5nc3plaWxlbiBmw7xyIEF1ZnRyYWcgdW5kIFRpcHBcbiAgICAgIGlmIChsYXN0ID09PSAndGFzaycpIGV4LnRhc2sgKz0gJ1xcbicgKyByYXcudHJpbSgpXG4gICAgICBlbHNlIGV4LmhpbnRzW2V4LmhpbnRzLmxlbmd0aCAtIDFdICs9ICdcXG4nICsgcmF3LnRyaW0oKVxuICAgIH0gZWxzZSBpZiAocmF3LnRyaW0oKSA9PT0gJycgJiYgbGFzdCA9PT0gJ3Rhc2snKSB7XG4gICAgICBleC50YXNrICs9ICdcXG4nXG4gICAgfVxuICB9XG4gIGlmICghZXgudGl0bGUpIHRocm93IG5ldyBGb3JtYXRFcnJvcihgJHtmaWxlfTogw5xidW5nIOKAniR7aWR94oCcIGhhdCBrZWluZW4gVGl0ZWwuYClcbiAgaWYgKCFleC50YXNrLnRyaW0oKSkgdGhyb3cgbmV3IEZvcm1hdEVycm9yKGAke2ZpbGV9OiDDnGJ1bmcg4oCeJHtpZH3igJwgaGF0IGtlaW5lbiBBdWZ0cmFnLmApXG4gIGV4LnRhc2sgPSBleC50YXNrLnRyaW0oKVxuICByZXR1cm4gZXhcbn1cblxuZnVuY3Rpb24gcGFyc2VRdWl6KGxpbmVzOiBzdHJpbmdbXSwgZmlsZTogc3RyaW5nKTogUXVpelF1ZXN0aW9uW10ge1xuICBjb25zdCBxdWVzdGlvbnM6IFF1aXpRdWVzdGlvbltdID0gW11cbiAgZm9yIChjb25zdCByYXcgb2YgbGluZXMpIHtcbiAgICBjb25zdCBsaW5lID0gcmF3LnRyaW0oKVxuICAgIGlmIChsaW5lLnN0YXJ0c1dpdGgoJz8nKSkge1xuICAgICAgcXVlc3Rpb25zLnB1c2goeyBxdWVzdGlvbjogbGluZS5zbGljZSgxKS50cmltKCksIG9wdGlvbnM6IFtdIH0pXG4gICAgfSBlbHNlIGlmICgvXi0gXFxbWyB4WF1cXF0vLnRlc3QobGluZSkpIHtcbiAgICAgIGNvbnN0IHEgPSBxdWVzdGlvbnMuYXQoLTEpXG4gICAgICBpZiAoIXEpIHRocm93IG5ldyBGb3JtYXRFcnJvcihgJHtmaWxlfTogQW50d29ydCBvaG5lIEZyYWdlIGltIFF1aXouYClcbiAgICAgIHEub3B0aW9ucy5wdXNoKHsgdGV4dDogbGluZS5zbGljZSg1KS50cmltKCksIGNvcnJlY3Q6IGxpbmVbM10udG9Mb3dlckNhc2UoKSA9PT0gJ3gnIH0pXG4gICAgfSBlbHNlIGlmIChsaW5lLnN0YXJ0c1dpdGgoJz0gJykpIHtcbiAgICAgIGNvbnN0IHEgPSBxdWVzdGlvbnMuYXQoLTEpXG4gICAgICBjb25zdCBtID0gL149XFxzKyguKz8pXFxzKy0+XFxzKyguKykkLy5leGVjKGxpbmUpXG4gICAgICBpZiAoIXEgfHwgIW0pIHRocm93IG5ldyBGb3JtYXRFcnJvcihgJHtmaWxlfTogWnVvcmRudW5nIOKAniR7bGluZX3igJwgYnJhdWNodCBkaWUgRm9ybSDigJ49IGxpbmtzIC0+IHJlY2h0c+KAnCBuYWNoIGVpbmVyIEZyYWdlLmApXG4gICAgICA7KHEucGFpcnMgPz89IFtdKS5wdXNoKHsgbGVmdDogbVsxXS50cmltKCksIHJpZ2h0OiBtWzJdLnRyaW0oKSB9KVxuICAgIH0gZWxzZSBpZiAobGluZS5zdGFydHNXaXRoKCfihpInKSkge1xuICAgICAgY29uc3QgcSA9IHF1ZXN0aW9ucy5hdCgtMSlcbiAgICAgIGlmICghcSkgdGhyb3cgbmV3IEZvcm1hdEVycm9yKGAke2ZpbGV9OiDigJ7ihpIgU2Nocml0dOKAnCBvaG5lIEZyYWdlIGltIFF1aXouYClcbiAgICAgIHEucmVmID0gbGluZS5zbGljZSgxKS50cmltKClcbiAgICB9IGVsc2UgaWYgKGxpbmUuc3RhcnRzV2l0aCgnPicpKSB7XG4gICAgICBjb25zdCBxID0gcXVlc3Rpb25zLmF0KC0xKVxuICAgICAgaWYgKHEpIHEuZXhwbGFuYXRpb24gPSAoKHEuZXhwbGFuYXRpb24gPyBxLmV4cGxhbmF0aW9uICsgJyAnIDogJycpICsgbGluZS5zbGljZSgxKS50cmltKCkpLnRyaW0oKVxuICAgIH1cbiAgfVxuICBmb3IgKGNvbnN0IHEgb2YgcXVlc3Rpb25zKSB7XG4gICAgaWYgKHEucGFpcnMpIHtcbiAgICAgIGNvbnN0IHJpZ2h0cyA9IG5ldyBTZXQocS5wYWlycy5tYXAoKHApID0+IHAucmlnaHQpKVxuICAgICAgaWYgKHEub3B0aW9ucy5sZW5ndGggPiAwIHx8IHEucGFpcnMubGVuZ3RoIDwgMiB8fCByaWdodHMuc2l6ZSAhPT0gcS5wYWlycy5sZW5ndGgpIHtcbiAgICAgICAgdGhyb3cgbmV3IEZvcm1hdEVycm9yKGAke2ZpbGV9OiBadW9yZG51bmcg4oCeJHtxLnF1ZXN0aW9ufeKAnCBicmF1Y2h0IG1pbmRlc3RlbnMgendlaSBQYWFyZSBtaXQgdmVyc2NoaWVkZW5lbiByZWNodGVuIFNlaXRlbiB1bmQga2VpbmUgQW50d29ydGVuLmApXG4gICAgICB9XG4gICAgICBjb250aW51ZVxuICAgIH1cbiAgICBpZiAocS5vcHRpb25zLmxlbmd0aCA8IDIgfHwgIXEub3B0aW9ucy5zb21lKChvKSA9PiBvLmNvcnJlY3QpKSB7XG4gICAgICB0aHJvdyBuZXcgRm9ybWF0RXJyb3IoYCR7ZmlsZX06IFF1aXpmcmFnZSDigJ4ke3EucXVlc3Rpb2594oCcIGJyYXVjaHQgbWluZGVzdGVucyB6d2VpIEFudHdvcnRlbiwgZGF2b24gZWluZSByaWNodGlnZS5gKVxuICAgIH1cbiAgfVxuICByZXR1cm4gcXVlc3Rpb25zXG59XG5cbi8qKiBUZXh0IGluIEJsw7Zja2UgemVybGVnZW46IG5vcm1hbGVzIE1hcmtkb3duIHVuZCBgOjo6IGFydCDigKZgIGJpcyBgOjo6YC4gKi9cbmV4cG9ydCBmdW5jdGlvbiBwYXJzZUJsb2Nrcyhib2R5OiBzdHJpbmcsIGZpbGU6IHN0cmluZyk6IEJsb2NrW10ge1xuICBjb25zdCBibG9ja3M6IEJsb2NrW10gPSBbXVxuICBjb25zdCBsaW5lcyA9IGJvZHkuc3BsaXQoJ1xcbicpXG4gIGxldCBtYXJrZG93bjogc3RyaW5nW10gPSBbXVxuICBjb25zdCBmbHVzaCA9ICgpID0+IHtcbiAgICBjb25zdCB0ZXh0ID0gbWFya2Rvd24uam9pbignXFxuJykudHJpbSgpXG4gICAgaWYgKHRleHQpIGJsb2Nrcy5wdXNoKHsga2luZDogJ21hcmtkb3duJywgdGV4dCB9KVxuICAgIG1hcmtkb3duID0gW11cbiAgfVxuICBmb3IgKGxldCBpID0gMDsgaSA8IGxpbmVzLmxlbmd0aDsgaSsrKSB7XG4gICAgY29uc3Qgb3BlbiA9IC9eOjo6XFxzKihbYS16w6TDtsO8w59dW2EtesOkw7bDvMOfMC05XSopXFxzKiguKikkL2kuZXhlYyhsaW5lc1tpXS50cmltKCkpXG4gICAgaWYgKCFvcGVuKSB7XG4gICAgICBtYXJrZG93bi5wdXNoKGxpbmVzW2ldKVxuICAgICAgY29udGludWVcbiAgICB9XG4gICAgZmx1c2goKVxuICAgIGNvbnN0IGlubmVyOiBzdHJpbmdbXSA9IFtdXG4gICAgbGV0IGogPSBpICsgMVxuICAgIHdoaWxlIChqIDwgbGluZXMubGVuZ3RoICYmIGxpbmVzW2pdLnRyaW0oKSAhPT0gJzo6OicpIGlubmVyLnB1c2gobGluZXNbaisrXSlcbiAgICBpZiAoaiA+PSBsaW5lcy5sZW5ndGgpIHRocm93IG5ldyBGb3JtYXRFcnJvcihgJHtmaWxlfTogQmxvY2sg4oCeOjo6ICR7b3BlblsxXX3igJwgd2lyZCBuaWNodCBtaXQg4oCeOjo64oCcIGdlc2NobG9zc2VuLmApXG4gICAgY29uc3Qga2luZCA9IG9wZW5bMV0udG9Mb3dlckNhc2UoKVxuICAgIGNvbnN0IGFyZyA9IG9wZW5bMl0udHJpbSgpXG4gICAgc3dpdGNoIChraW5kKSB7XG4gICAgICBjYXNlICdkaWFncmFtbSc6XG4gICAgICAgIGlmICghYXJnKSB0aHJvdyBuZXcgRm9ybWF0RXJyb3IoYCR7ZmlsZX06IOKAnjo6OiBkaWFncmFtbeKAnCBicmF1Y2h0IGVpbmVuIERhdGVpbmFtZW4uYClcbiAgICAgICAgYmxvY2tzLnB1c2goeyBraW5kOiAnZGlhZ3JhbScsIGZpbGU6IGFyZywgY2FwdGlvbjogaW5uZXIuam9pbignICcpLnRyaW0oKSB9KVxuICAgICAgICBicmVha1xuICAgICAgY2FzZSAnw7xidW5nJzpcbiAgICAgIGNhc2UgJ3VlYnVuZyc6XG4gICAgICAgIGlmICghYXJnKSB0aHJvdyBuZXcgRm9ybWF0RXJyb3IoYCR7ZmlsZX06IOKAnjo6OiDDvGJ1bmfigJwgYnJhdWNodCBlaW5lIEtlbm51bmcuYClcbiAgICAgICAgYmxvY2tzLnB1c2goeyBraW5kOiAnZXhlcmNpc2UnLCBleGVyY2lzZTogcGFyc2VFeGVyY2lzZShhcmcsIGlubmVyLCBmaWxlKSB9KVxuICAgICAgICBicmVha1xuICAgICAgY2FzZSAnY2hlY2tsaXN0ZSc6XG4gICAgICAgIGJsb2Nrcy5wdXNoKHsga2luZDogJ2NoZWNrbGlzdCcsIGl0ZW1zOiBpbm5lci5tYXAoKGwpID0+IGwudHJpbSgpKS5maWx0ZXIoKGwpID0+IGwuc3RhcnRzV2l0aCgnLSAnKSkubWFwKChsKSA9PiBjaGVja2xpc3RJdGVtKGwuc2xpY2UoMikudHJpbSgpKSkgfSlcbiAgICAgICAgYnJlYWtcbiAgICAgIGNhc2UgJ2tvbXBldGVuemVuJzpcbiAgICAgICAgYmxvY2tzLnB1c2goeyBraW5kOiAnY29tcGV0ZW5jZXMnLCBpdGVtczogaW5uZXIubWFwKChsKSA9PiBsLnRyaW0oKSkuZmlsdGVyKChsKSA9PiBsLnN0YXJ0c1dpdGgoJy0gJykpLm1hcCgobCkgPT4gbC5zbGljZSgyKS50cmltKCkpIH0pXG4gICAgICAgIGJyZWFrXG4gICAgICBjYXNlICdxdWl6JzpcbiAgICAgICAgYmxvY2tzLnB1c2goeyBraW5kOiAncXVpeicsIHF1ZXN0aW9uczogcGFyc2VRdWl6KGlubmVyLCBmaWxlKSB9KVxuICAgICAgICBicmVha1xuICAgICAgY2FzZSAnYmlsZCc6XG4gICAgICAgIGlmICghYXJnKSB0aHJvdyBuZXcgRm9ybWF0RXJyb3IoYCR7ZmlsZX06IOKAnjo6OiBiaWxk4oCcIGJyYXVjaHQgZWluZW4gRGF0ZWluYW1lbi5gKVxuICAgICAgICBibG9ja3MucHVzaCh7IGtpbmQ6ICdpbWFnZXMnLCBmaWxlczogYXJnLnNwbGl0KC9cXHMrLyksIGNhcHRpb246IGlubmVyLmpvaW4oJyAnKS50cmltKCkgfSlcbiAgICAgICAgYnJlYWtcbiAgICAgIGNhc2UgJ2dyYWZpayc6XG4gICAgICAgIGlmICghYXJnKSB0aHJvdyBuZXcgRm9ybWF0RXJyb3IoYCR7ZmlsZX06IOKAnjo6OiBncmFmaWvigJwgYnJhdWNodCBlaW5lbiBEYXRlaW5hbWVuLmApXG4gICAgICAgIHtcbiAgICAgICAgICBjb25zdCBbZ3JhcGhpYywgbGFiZWxlZF0gPSBhcmcuc3BsaXQoL1xccysvKVxuICAgICAgICAgIGJsb2Nrcy5wdXNoKHsga2luZDogJ2dyYXBoaWMnLCBmaWxlOiBncmFwaGljLCAuLi4obGFiZWxlZCA/IHsgbGFiZWxlZCB9IDoge30pLCBjYXB0aW9uOiBpbm5lci5qb2luKCcgJykudHJpbSgpIH0pXG4gICAgICAgIH1cbiAgICAgICAgYnJlYWtcbiAgICAgIGNhc2UgJ2FuZ2ViZXJ3aXNzZW4nOlxuICAgICAgICBibG9ja3MucHVzaCh7IGtpbmQ6ICdicmFnJywgdGV4dDogaW5uZXIuam9pbignXFxuJykudHJpbSgpIH0pXG4gICAgICAgIGJyZWFrXG4gICAgICBjYXNlICdzcGllbCc6XG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgaWYgKGlzUm91bmRHYW1lS2luZChhcmcpKSBibG9ja3MucHVzaCh7IGtpbmQ6ICdyb3VuZEdhbWUnLCBnYW1lOiBwYXJzZVJvdW5kR2FtZShhcmcsIGlubmVyLCBmaWxlKSB9KVxuICAgICAgICAgIGVsc2UgaWYgKGFyZyA9PT0gJ3ByaW56ZXNzaW4nKSBibG9ja3MucHVzaCh7IGtpbmQ6ICdyZXNjdWVHYW1lJywgZ2FtZTogcGFyc2VSZXNjdWVHYW1lKGlubmVyLCBmaWxlKSB9KVxuICAgICAgICAgIGVsc2UgaWYgKGFyZykgdGhyb3cgbmV3IEZvcm1hdEVycm9yKGAke2ZpbGV9OiBVbmJla2FubnRlcyBTcGllbCDigJ4ke2FyZ33igJwgKHp1aG9lcmVyLCB2ZXJ0cmFnLCBsYXlvdXQsIGJvbWJlLCBmcmFnZSwgcmVpaGVuZm9sZ2Ugb2RlciBwcmluemVzc2luKS5gKVxuICAgICAgICAgIGVsc2UgYmxvY2tzLnB1c2goeyBraW5kOiAnZ2FtZScsIGdhbWU6IHBhcnNlQm9vbEdhbWUoaW5uZXIsIGZpbGUpIH0pXG4gICAgICAgIH0gY2F0Y2ggKGVycikge1xuICAgICAgICAgIHRocm93IG5ldyBGb3JtYXRFcnJvcigoZXJyIGFzIEVycm9yKS5tZXNzYWdlKVxuICAgICAgICB9XG4gICAgICAgIGJyZWFrXG4gICAgICBjYXNlICdsw7xja2VudGV4dCc6XG4gICAgICBjYXNlICdsdWVja2VudGV4dCc6XG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgYmxvY2tzLnB1c2goeyBraW5kOiAnY2xvemUnLCBjbG96ZTogcGFyc2VDbG96ZShpbm5lciwgZmlsZSkgfSlcbiAgICAgICAgfSBjYXRjaCAoZXJyKSB7XG4gICAgICAgICAgdGhyb3cgbmV3IEZvcm1hdEVycm9yKChlcnIgYXMgRXJyb3IpLm1lc3NhZ2UpXG4gICAgICAgIH1cbiAgICAgICAgYnJlYWtcbiAgICAgIGNhc2UgJ3BhcCc6XG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgYmxvY2tzLnB1c2goeyBraW5kOiAncGFwJywgcGFwOiBwYXJzZVBhcChpbm5lciwgZmlsZSkgfSlcbiAgICAgICAgfSBjYXRjaCAoZXJyKSB7XG4gICAgICAgICAgdGhyb3cgbmV3IEZvcm1hdEVycm9yKChlcnIgYXMgRXJyb3IpLm1lc3NhZ2UpXG4gICAgICAgIH1cbiAgICAgICAgYnJlYWtcbiAgICAgIGNhc2UgJ3Byb2Zpd2lzc2VuJzpcbiAgICAgICAgYmxvY2tzLnB1c2goeyBraW5kOiAnYnJhZycsIHRleHQ6IGlubmVyLmpvaW4oJ1xcbicpLnRyaW0oKSwgcHJvOiB0cnVlIH0pXG4gICAgICAgIGJyZWFrXG4gICAgICBjYXNlICdsdWR3aWcnOlxuICAgICAgICBibG9ja3MucHVzaCh7IGtpbmQ6ICdicmFnJywgdGV4dDogaW5uZXIuam9pbignXFxuJykudHJpbSgpLCB0aXA6IHRydWUgfSlcbiAgICAgICAgYnJlYWtcbiAgICAgIGNhc2UgJ2NhZXNhcic6IHtcbiAgICAgICAgY29uc3Qga2V5ID0gYXJnID8gTnVtYmVyKGFyZykgOiAzXG4gICAgICAgIGlmICghTnVtYmVyLmlzSW50ZWdlcihrZXkpIHx8IGtleSA8IDAgfHwga2V5ID4gMjUpIHRocm93IG5ldyBGb3JtYXRFcnJvcihgJHtmaWxlfTog4oCeOjo6IGNhZXNhcuKAnCBicmF1Y2h0IGVpbmVuIFNjaGzDvHNzZWwgdm9uIDAgYmlzIDI1LmApXG4gICAgICAgIGJsb2Nrcy5wdXNoKHsga2luZDogJ2NhZXNhcicsIGtleSwgdGV4dDogaW5uZXIuam9pbignICcpLnRyaW0oKSB9KVxuICAgICAgICBicmVha1xuICAgICAgfVxuICAgICAgY2FzZSAnbWJvdDInOiB7XG4gICAgICAgIC8vIGBmb2t1czogY3liZXJwaSwgc2NyZWVuYCwgYGFuc2ljaHQ6IHVudGVuYCwgYGRyZWhlbjogamFgXG4gICAgICAgIGNvbnN0IGJsb2NrOiBFeHRyYWN0PEJsb2NrLCB7IGtpbmQ6ICdyb2JvdE1vZGVsJyB9PiA9IHsga2luZDogJ3JvYm90TW9kZWwnLCBmb2N1czogW10gfVxuICAgICAgICBmb3IgKGNvbnN0IGxpbmUgb2YgaW5uZXIuZmlsdGVyKChsKSA9PiBsLnRyaW0oKSkpIHtcbiAgICAgICAgICBjb25zdCBtID0gL15cXHMqKGZva3VzfGZvY3VzfGFuc2ljaHR8dmlld3xkcmVoZW58c3Bpbik6XFxzKiguKikkL2kuZXhlYyhsaW5lKVxuICAgICAgICAgIGlmICghbSkgdGhyb3cgbmV3IEZvcm1hdEVycm9yKGAke2ZpbGV9OiDigJ46OjogbWJvdDLigJwga2VubnQgbnVyIFplaWxlbiDigJ5mb2t1czrigJwsIOKAnmFuc2ljaHQ64oCcIHVuZCDigJ5kcmVoZW464oCcLmApXG4gICAgICAgICAgY29uc3Qga2V5ID0gbVsxXS50b0xvd2VyQ2FzZSgpXG4gICAgICAgICAgaWYgKGtleSA9PT0gJ2Zva3VzJyB8fCBrZXkgPT09ICdmb2N1cycpIGJsb2NrLmZvY3VzID0gcm9ib3RQYXJ0cyhtWzJdLCBmaWxlKVxuICAgICAgICAgIGVsc2UgaWYgKGtleSA9PT0gJ2Fuc2ljaHQnIHx8IGtleSA9PT0gJ3ZpZXcnKSBibG9jay52aWV3ID0gbVsyXS50cmltKCkudG9Mb3dlckNhc2UoKVxuICAgICAgICAgIGVsc2UgYmxvY2suc3BpbiA9IC9eKGphfHllc3x0cnVlfHNpbSkkL2kudGVzdChtWzJdLnRyaW0oKSlcbiAgICAgICAgfVxuICAgICAgICBibG9ja3MucHVzaChibG9jaylcbiAgICAgICAgYnJlYWtcbiAgICAgIH1cbiAgICAgIGNhc2UgJ21ib3QycXVpeic6IHtcbiAgICAgICAgLy8gYC0gdWx0cmFzb25pYzogV28gaXN0IGRlciAqKlVsdHJhc2NoYWxsc2Vuc29yKio/YCB1bmQgYGZlcnRpZzogU3VwZXIhYFxuICAgICAgICBjb25zdCBibG9jazogRXh0cmFjdDxCbG9jaywgeyBraW5kOiAncm9ib3RRdWl6JyB9PiA9IHsga2luZDogJ3JvYm90UXVpeicsIHRhc2tzOiBbXSB9XG4gICAgICAgIGZvciAoY29uc3QgbGluZSBvZiBpbm5lci5maWx0ZXIoKGwpID0+IGwudHJpbSgpKSkge1xuICAgICAgICAgIGNvbnN0IHRhc2sgPSAvXlxccyotXFxzKihcXHcrKVxccyo6XFxzKiguKykkLy5leGVjKGxpbmUpXG4gICAgICAgICAgY29uc3QgZG9uZSA9IC9eXFxzKihmZXJ0aWd8ZG9uZSk6XFxzKiguKykkL2kuZXhlYyhsaW5lKVxuICAgICAgICAgIGlmICh0YXNrKSBibG9jay50YXNrcy5wdXNoKHsgcGFydDogcm9ib3RQYXJ0cyh0YXNrWzFdLCBmaWxlKVswXSwgcXVlc3Rpb246IHRhc2tbMl0udHJpbSgpIH0pXG4gICAgICAgICAgZWxzZSBpZiAoZG9uZSkgYmxvY2suZG9uZSA9IGRvbmVbMl0udHJpbSgpXG4gICAgICAgICAgZWxzZSB0aHJvdyBuZXcgRm9ybWF0RXJyb3IoYCR7ZmlsZX06IOKAnjo6OiBtYm90MnF1aXrigJwgYnJhdWNodCBaZWlsZW4g4oCeLSB0ZWlsOiBGcmFnZeKAnCB1bmQgb3B0aW9uYWwg4oCeZmVydGlnOiBUZXh04oCcLmApXG4gICAgICAgIH1cbiAgICAgICAgaWYgKCFibG9jay50YXNrcy5sZW5ndGgpIHRocm93IG5ldyBGb3JtYXRFcnJvcihgJHtmaWxlfTog4oCeOjo6IG1ib3QycXVpeuKAnCBoYXQga2VpbmUgRnJhZ2VuLmApXG4gICAgICAgIGJsb2Nrcy5wdXNoKGJsb2NrKVxuICAgICAgICBicmVha1xuICAgICAgfVxuICAgICAgY2FzZSAnZGF0ZWknOiB7XG4gICAgICAgIGlmICghL15bXFx3Li1dK1xcLih0eHR8Y3N2fGpzb24pJC91LnRlc3QoYXJnKSkgdGhyb3cgbmV3IEZvcm1hdEVycm9yKGAke2ZpbGV9OiDigJ46OjogZGF0ZWnigJwgYnJhdWNodCBlaW5lbiBEYXRlaW5hbWVuIHdpZSBicmllZi50eHQsIGxpc3RlLmNzdiBvZGVyIGRhdGVuLmpzb24uYClcbiAgICAgICAgLy8gRGVyIEluaGFsdCBibGVpYnQgZ2VuYXUgc28sIHdpZSBlciBkYXN0ZWh0LCBudXIgb2huZSBMZWVyemVpbGVuIGFtIEFuZmFuZyB1bmQgRW5kZS5cbiAgICAgICAgd2hpbGUgKGlubmVyLmxlbmd0aCAmJiBpbm5lclswXS50cmltKCkgPT09ICcnKSBpbm5lci5zaGlmdCgpXG4gICAgICAgIHdoaWxlIChpbm5lci5sZW5ndGggJiYgaW5uZXJbaW5uZXIubGVuZ3RoIC0gMV0udHJpbSgpID09PSAnJykgaW5uZXIucG9wKClcbiAgICAgICAgYmxvY2tzLnB1c2goeyBraW5kOiAndGV4dEZpbGUnLCBuYW1lOiBhcmcsIGNvbnRlbnQ6IGlubmVyLmpvaW4oJ1xcbicpIH0pXG4gICAgICAgIGJyZWFrXG4gICAgICB9XG4gICAgICBkZWZhdWx0OlxuICAgICAgICB0aHJvdyBuZXcgRm9ybWF0RXJyb3IoYCR7ZmlsZX06IFVuYmVrYW5udGVyIEJsb2NrIOKAnjo6OiAke29wZW5bMV194oCcLmApXG4gICAgfVxuICAgIGkgPSBqXG4gIH1cbiAgZmx1c2goKVxuICByZXR1cm4gYmxvY2tzXG59XG5cbmZ1bmN0aW9uIGNoZWNrbGlzdEl0ZW0obGluZTogc3RyaW5nKTogQ2hlY2tsaXN0SXRlbSB7XG4gIGNvbnN0IG0gPSAvXiguKj8pXFxzK+KGklxccysoLispJC8uZXhlYyhsaW5lKVxuICByZXR1cm4gbSA/IHsgdGV4dDogbVsxXSwgcmVmOiBtWzJdLnRyaW0oKSB9IDogeyB0ZXh0OiBsaW5lIH1cbn1cblxuLyoqIFZlcndlaXNlIGF1cyBDaGVja2xpc3RlbiBhdWYgZGVuIGVya2zDpHJlbmRlbiBTY2hyaXR0IGF1ZmzDtnNlbi4gKi9cbmZ1bmN0aW9uIHJlc29sdmVDaGVja2xpc3RSZWZzKHN0ZXBzOiBTdGVwW10sIGZpbGU6IHN0cmluZykge1xuICBjb25zdCBpbmRleCA9IG5ldyBNYXAoc3RlcHMubWFwKChzLCBpKSA9PiBbcy50aXRsZS50b0xvd2VyQ2FzZSgpLCBpXSkpXG4gIGZvciAoY29uc3QgYmxvY2sgb2Ygc3RlcHMuZmxhdE1hcCgocykgPT4gcy5ibG9ja3MpKSB7XG4gICAgaWYgKGJsb2NrLmtpbmQgIT09ICdjaGVja2xpc3QnKSBjb250aW51ZVxuICAgIGZvciAoY29uc3QgaXRlbSBvZiBibG9jay5pdGVtcykge1xuICAgICAgaWYgKGl0ZW0ucmVmID09PSB1bmRlZmluZWQpIGNvbnRpbnVlXG4gICAgICBpdGVtLnN0ZXAgPSBpbmRleC5nZXQoaXRlbS5yZWYudG9Mb3dlckNhc2UoKSlcbiAgICAgIGlmIChpdGVtLnN0ZXAgPT09IHVuZGVmaW5lZCkgdGhyb3cgbmV3IEZvcm1hdEVycm9yKGAke2ZpbGV9OiBDaGVja2xpc3RlIHZlcndlaXN0IGF1ZiB1bmJla2FubnRlbiBTY2hyaXR0IOKAniR7aXRlbS5yZWZ94oCcLmApXG4gICAgfVxuICB9XG4gIGNvbnN0IGNoZWNrZWQgPSBuZXcgU2V0KHN0ZXBzLmZsYXRNYXAoKHMpID0+IHMuYmxvY2tzKS5mbGF0TWFwKChiKSA9PiAoYi5raW5kID09PSAnY2hlY2tsaXN0JyA/IGIuaXRlbXMubWFwKChpKSA9PiBpLnN0ZXApIDogW10pKSlcbiAgZm9yIChjb25zdCBibG9jayBvZiBzdGVwcy5mbGF0TWFwKChzKSA9PiBzLmJsb2NrcykpIHtcbiAgICBpZiAoYmxvY2sua2luZCAhPT0gJ3F1aXonKSBjb250aW51ZVxuICAgIGZvciAoY29uc3QgcSBvZiBibG9jay5xdWVzdGlvbnMpIHtcbiAgICAgIGlmIChxLnJlZiA9PT0gdW5kZWZpbmVkKSBjb250aW51ZVxuICAgICAgcS5zdGVwID0gaW5kZXguZ2V0KHEucmVmLnRvTG93ZXJDYXNlKCkpXG4gICAgICBpZiAocS5zdGVwID09PSB1bmRlZmluZWQpIHRocm93IG5ldyBGb3JtYXRFcnJvcihgJHtmaWxlfTogUXVpemZyYWdlIOKAniR7cS5xdWVzdGlvbn3igJwgdmVyd2Vpc3QgYXVmIHVuYmVrYW5udGVuIFNjaHJpdHQg4oCeJHtxLnJlZn3igJwuYClcbiAgICAgIGlmICghY2hlY2tlZC5oYXMocS5zdGVwKSkgdGhyb3cgbmV3IEZvcm1hdEVycm9yKGAke2ZpbGV9OiBadSDigJ4ke3EucmVmfeKAnCAoUXVpemZyYWdlIOKAniR7cS5xdWVzdGlvbn3igJwpIGdpYnQgZXMga2VpbmVuIENoZWNrbGlzdGVucHVua3QuYClcbiAgICB9XG4gIH1cbn1cblxuZXhwb3J0IGZ1bmN0aW9uIHBhcnNlTGVzc29uKHNvdXJjZTogc3RyaW5nLCBmaWxlOiBzdHJpbmcpOiBMZXNzb24ge1xuICBjb25zdCB7IG1ldGEsIGJvZHkgfSA9IGZyb250TWF0dGVyKHNvdXJjZSwgZmlsZSlcbiAgY29uc3QgbmFtZSA9IGZpbGUucmVwbGFjZSgvXi4qXFwvLywgJycpLnJlcGxhY2UoL1xcLm1kJC8sICcnKVxuICBjb25zdCBudW1iZXIgPSBOdW1iZXIoL14oXFxkKykvLmV4ZWMobmFtZSk/LlsxXSlcbiAgaWYgKCFOdW1iZXIuaXNGaW5pdGUobnVtYmVyKSkgdGhyb3cgbmV3IEZvcm1hdEVycm9yKGAke2ZpbGV9OiBEYXRlaW5hbWUgbXVzcyBtaXQgZGVyIE51bW1lciBiZWdpbm5lbiAoei4gQi4gMDEt4oCmKS5gKVxuICBjb25zdCBzdGVwczogU3RlcFtdID0gW11cbiAgbGV0IGludHJvOiBzdHJpbmdbXSA9IFtdXG4gIGxldCBjdXJyZW50OiB7IHRpdGxlOiBzdHJpbmc7IGxpbmVzOiBzdHJpbmdbXSB9IHwgdW5kZWZpbmVkXG4gIGNvbnN0IGNsb3NlID0gKCkgPT4ge1xuICAgIGlmIChjdXJyZW50KSBzdGVwcy5wdXNoKHsgdGl0bGU6IGN1cnJlbnQudGl0bGUsIGJsb2NrczogcGFyc2VCbG9ja3MoY3VycmVudC5saW5lcy5qb2luKCdcXG4nKSwgZmlsZSkgfSlcbiAgfVxuICBmb3IgKGNvbnN0IGxpbmUgb2YgYm9keS5zcGxpdCgnXFxuJykpIHtcbiAgICBjb25zdCBoID0gL14jI1xccysoLiopJC8uZXhlYyhsaW5lKVxuICAgIGlmIChoKSB7XG4gICAgICBjbG9zZSgpXG4gICAgICBjdXJyZW50ID0geyB0aXRsZTogaFsxXS50cmltKCksIGxpbmVzOiBbXSB9XG4gICAgfSBlbHNlIGlmIChjdXJyZW50KSB7XG4gICAgICBjdXJyZW50LmxpbmVzLnB1c2gobGluZSlcbiAgICB9IGVsc2Uge1xuICAgICAgaW50cm8ucHVzaChsaW5lKVxuICAgIH1cbiAgfVxuICBjbG9zZSgpXG4gIGlmIChzdGVwcy5sZW5ndGggPT09IDApIHRocm93IG5ldyBGb3JtYXRFcnJvcihgJHtmaWxlfTogS2VpbmUgU2Nocml0dGUgKCMjIMOcYmVyc2NocmlmdCkgZ2VmdW5kZW4uYClcbiAgcmVzb2x2ZUNoZWNrbGlzdFJlZnMoc3RlcHMsIGZpbGUpXG4gIGNvbnN0IHRpdGxlID0gbWV0YS5nZXQoJ3RpdGVsJylcbiAgaWYgKCF0aXRsZSkgdGhyb3cgbmV3IEZvcm1hdEVycm9yKGAke2ZpbGV9OiDigJ50aXRlbDrigJwgZmVobHQuYClcbiAgcmV0dXJuIHtcbiAgICBpZDogbmFtZSxcbiAgICBudW1iZXIsXG4gICAgdGl0bGUsXG4gICAgc2VjdGlvbjogbWV0YS5nZXQoJ2JlcmVpY2gnKSA/PyAnJyxcbiAgICBzdW1tYXJ5OiBtZXRhLmdldCgna3VyeicpID8/IGludHJvLmpvaW4oJyAnKS50cmltKCksXG4gICAgc3RlcHMsXG4gIH1cbn1cblxuZXhwb3J0IGZ1bmN0aW9uIHBhcnNlVGFzayhzb3VyY2U6IHN0cmluZywgZmlsZTogc3RyaW5nKTogVGFzayB7XG4gIGNvbnN0IHsgbWV0YSwgYm9keSB9ID0gZnJvbnRNYXR0ZXIoc291cmNlLCBmaWxlKVxuICBjb25zdCB0aXRsZSA9IG1ldGEuZ2V0KCd0aXRlbCcpXG4gIGlmICghdGl0bGUpIHRocm93IG5ldyBGb3JtYXRFcnJvcihgJHtmaWxlfTog4oCedGl0ZWw64oCcIGZlaGx0LmApXG4gIGNvbnN0IGFmdGVyID0gbWV0YS5nZXQoJ25hY2gnKVxuICByZXR1cm4ge1xuICAgIGlkOiBmaWxlLnJlcGxhY2UoL14uKlxcLy8sICcnKS5yZXBsYWNlKC9cXC5tZCQvLCAnJyksXG4gICAgdGl0bGUsXG4gICAgYWZ0ZXI6IGFmdGVyID8gTnVtYmVyKGFmdGVyKSA6IHVuZGVmaW5lZCxcbiAgICBsZXZlbDogTnVtYmVyKG1ldGEuZ2V0KCdzdHVmZScpID8/ICcxJykgfHwgMSxcbiAgICBibG9ja3M6IHBhcnNlQmxvY2tzKGJvZHksIGZpbGUpLFxuICB9XG59XG5cbi8qKiBgY3liZXJwaSwgc2NyZWVuYCDihpIgZ2VwcsO8ZnRlIFRlaWxuYW1lbiBkZXMgbUJvdDItTW9kZWxscy4gKi9cbmZ1bmN0aW9uIHJvYm90UGFydHMobGlzdDogc3RyaW5nLCBmaWxlOiBzdHJpbmcpOiBNQm90UGFydFtdIHtcbiAgY29uc3QgbmFtZXMgPSBsaXN0LnNwbGl0KC9cXHMqLFxccyovKS5tYXAoKHgpID0+IHgudHJpbSgpKS5maWx0ZXIoQm9vbGVhbilcbiAgZm9yIChjb25zdCBuIG9mIG5hbWVzKSBpZiAoIWlzTUJvdFBhcnQobikpIHRocm93IG5ldyBGb3JtYXRFcnJvcihgJHtmaWxlfTogVW5iZWthbm50ZXMgVGVpbCDigJ4ke2594oCcLiBCZWthbm50OiAke01CT1RfUEFSVFMuam9pbignLCAnKX0uYClcbiAgcmV0dXJuIG5hbWVzIGFzIE1Cb3RQYXJ0W11cbn1cbiJdLCJmaWxlIjoiL3dlYi9zcmMvbGVhcm4vbGVzc29uRm9ybWF0LnRzIn0= + +//# vitestCache=W3siZmlsZSI6IjEiLCJpZCI6IjEiLCJ1cmwiOiIyIiwiaW1wb3J0cyI6IjMiLCJtYXBwaW5ncyI6ZmFsc2UsImRlcHMiOiI0IiwiZHluYW1pY0RlcHMiOiI1Iiwic3RhdGljTW9ja3MiOm51bGx9LCIvaG9tZS91c2VyL3Zpc3VzdHJ1Y3Qtc3dpZnR1aS93ZWIvc3JjL2xlYXJuL2xlc3NvbkZvcm1hdC50cyIsIi93ZWIvc3JjL2xlYXJuL2xlc3NvbkZvcm1hdC50cyIseyJ1cmxzIjoiNiIsImlkcyI6IjcifSxbIjgiLCI5IiwiMTAiLCIxMSIsIjEyIiwiMTMiXSxbXSxbIjgiLCI5IiwiMTAiLCIxMSIsIjEyIiwiMTMiXSx7fSwiL3dlYi9zcmMvY29yZS9tYm90LnRzIiwiL3dlYi9zcmMvbGVhcm4vYm9vbEdhbWUudHMiLCIvd2ViL3NyYy9sZWFybi9yb3VuZEdhbWUudHMiLCIvd2ViL3NyYy9sZWFybi9yZXNjdWVHYW1lLnRzIiwiL3dlYi9zcmMvbGVhcm4vY2xvemUudHMiLCIvd2ViL3NyYy9sZWFybi9wYXAudHMiXQ== \ No newline at end of file diff --git a/node_modules/.vitest-cache/e482c53abeaa5899f7e393b26fde791e2b456b18 b/node_modules/.vitest-cache/e482c53abeaa5899f7e393b26fde791e2b456b18 new file mode 100644 index 00000000..cfff90bf --- /dev/null +++ b/node_modules/.vitest-cache/e482c53abeaa5899f7e393b26fde791e2b456b18 @@ -0,0 +1,382 @@ +__vite_ssr_exportName__("RUN", () => { try { return RUN } catch {} }); +__vite_ssr_exportName__("ASK", () => { try { return ASK } catch {} }); +__vite_ssr_exportName__("frame", () => { try { return frame } catch {} }); +__vite_ssr_exportName__("pythonFrame", () => { try { return pythonFrame } catch {} }); +__vite_ssr_exportName__("readAnswers", () => { try { return readAnswers } catch {} }); +__vite_ssr_exportName__("readFrames", () => { try { return readFrames } catch {} }); +__vite_ssr_exportName__("UPLOAD_PATH", () => { try { return UPLOAD_PATH } catch {} }); +__vite_ssr_exportName__("UPLOAD_PREPARE", () => { try { return UPLOAD_PREPARE } catch {} }); +__vite_ssr_exportName__("fileChecksum", () => { try { return fileChecksum } catch {} }); +__vite_ssr_exportName__("uploadFrames", () => { try { return uploadFrames } catch {} }); +__vite_ssr_exportName__("canConnectMBot", () => { try { return canConnectMBot } catch {} }); +__vite_ssr_exportName__("pyLines", () => { try { return pyLines } catch {} }); +__vite_ssr_exportName__("showLabel", () => { try { return showLabel } catch {} }); +__vite_ssr_exportName__("HELLO", () => { try { return HELLO } catch {} }); +__vite_ssr_exportName__("MBotLink", () => { try { return MBotLink } catch {} }); +__vite_ssr_exportName__("mbotLink", () => { try { return mbotLink } catch {} }); +const HEAD = 243; +const FOOT = 244; +const SCRIPT = 40; +const RUN = 4; +const ASK = 1; +/** Rahmen um einen Inhalt legen. */ +function frame(body) { + const len = body.length; + const head = HEAD + (len & 255) + (len >> 8) & 255; + const sum = body.reduce((a, b) => a + b, 0) & 255; + return Uint8Array.from([ + HEAD, + head, + len & 255, + len >> 8, + ...body, + sum, + FOOT + ]); +}; +/** Python-Zeile als Rahmen mit Modus und Nummer. */ +function pythonFrame(code, mode, idx) { + const text = Array.from(new TextEncoder().encode(code)); + return frame([ + SCRIPT, + mode, + idx & 255, + idx >> 8 & 255, + text.length & 255, + text.length >> 8, + ...text + ]); +}; +/** +* Sucht vollständige Rahmen in `rx` und gibt die Antworten auf Python-Zeilen zurück; verbrauchte Bytes werden entfernt. +* Textausgaben des CyberPi außerhalb von Rahmen (z. B. nach dem Neustart) werden übersprungen. +*/ +function readAnswers(rx) { + return readFrames(rx).flatMap((body) => scriptAnswer(body) ?? []); +}; +/** Inhalt einer Antwort auf eine Python-Zeile, sonst `undefined`. */ +function scriptAnswer(body) { + if (body[0] !== SCRIPT || body.length < 6) return undefined; + const text = new TextDecoder().decode(Uint8Array.from(body.slice(6))); + const m = /"ret"\s*:\s*([^}]*)\}/.exec(text); + return m ? { + idx: body[2] | body[3] << 8, + value: pythonValue(m[1].trim()) + } : undefined; +} +/** Alle vollständigen Rahmen aus `rx` (nur der Inhalt); verbrauchte Bytes werden entfernt. */ +function readFrames(rx) { + const bodies = []; + for (;;) { + const start = rx.indexOf(HEAD); + if (start < 0) { + rx.length = 0; + break; + }; + rx.splice(0, start); + if (rx.length < 4) break; + const len = rx[2] | rx[3] << 8; + // Kein Rahmen, nur ein zufälliges F3 im Text: weitersuchen + if (rx[1] !== (HEAD + rx[2] + rx[3] & 255) || len > 4096) { + rx.splice(0, 1); + continue; + }; + if (rx.length < len + 6) break; + bodies.push(rx.slice(4, 4 + len)); + rx.splice(0, len + 6); + }; + return bodies; +}; +function pythonValue(text) { + if (text === "True") return true; + if (text === "False") return false; + // Text, z. B. ein Farbname: "red" oder 'red' + const quoted = /^["'](.*)["']$/.exec(text); + if (quoted) return quoted[1]; + const n = Number(text); + return text !== "" && Number.isFinite(n) ? n : null; +} +/** +* Programm fest auf dem CyberPi speichern, wie „Hochladen“ in mBlock (Ablauf aus github.com/weare2plus3/cyberpi-uploader, MIT): +* Upload-Modus (`0D 00 00`), REPL aus, Dateikopf mit Größe, XOR-Prüfsumme und Pfad, dann Blöcke zu 80 Byte. +* Die Datei landet in einem Zwischenplatz, den die Firmware beim nächsten Neustart übernimmt. +*/ +const UPLOAD_PATH = "/flash/_xx_main.py"; +const UPLOAD_MODE = [ + 13, + 0, + 0 +]; +const FILE_SERVICE = 94; +const BLOCK = 80; +const UPLOAD_PREPARE = ["try:\n import config\nexcept:\n pass", "try:\n config.write_config(\"repl_enable\", False)\nexcept:\n pass"]; +const le = (value, bytes) => Array.from({ length: bytes }, (_, i) => value >>> 8 * i & 255); +/** XOR der 32-Bit-Wörter (little endian, mit Nullen aufgefüllt), wie mBlock. */ +function fileChecksum(data) { + let x = 0; + for (let i = 0; i < data.length; i += 4) x = (x ^ ((data[i] ?? 0) | (data[i + 1] ?? 0) << 8 | (data[i + 2] ?? 0) << 16 | (data[i + 3] ?? 0) << 24)) >>> 0; + return le(x, 4); +}; +const fileFrame = (cmd, payload) => frame([ + 1, + 0, + FILE_SERVICE, + cmd, + ...le(payload.length, 2), + ...payload +]); +/** Python-Datei in Rahmen: Kopf, dann Blöcke zu 80 Byte und ein letzter Block mit 4 Byte (wie mBlock; mit Zeilenumbrüchen aufgefüllt). */ +function uploadFrames(source, path = UPLOAD_PATH) { + const raw = new TextEncoder().encode(source); + const pad = (4 - raw.length % BLOCK + BLOCK) % BLOCK; + const data = new Uint8Array(raw.length + pad).fill(10); + data.set(raw); + const frames = [fileFrame(1, [ + 0, + ...le(data.length, 4), + ...fileChecksum(data), + ...Array.from(new TextEncoder().encode(path)) + ])]; + const end = data.length - 4; + for (let off = 0; off < end; off += BLOCK) frames.push(fileFrame(2, [...le(off, 4), ...data.subarray(off, Math.min(off + BLOCK, end))])); + frames.push(fileFrame(2, [...le(end, 4), ...data.subarray(end)])); + return frames; +}; +const isModeEcho = (body) => body.length === 3 && body[0] === 13; +const isFileAck = (body) => body.length === 7 || body.some((b, i) => b === FILE_SERVICE && body[i + 1] === 240); +const serial = () => typeof navigator === "undefined" ? undefined : navigator.serial; +/** Kann dieser Browser einen mBot2 über USB ansprechen? */ +const canConnectMBot = () => serial() !== undefined; +/** Mehrere Python-Anweisungen als eine Zeile (der CyberPi nimmt nur eine). JSON-Strings sind auch gültige Python-Strings. */ +const pyLines = (...lines) => `exec(${JSON.stringify(lines.join("; "))})`; +/** +* Bildschirm leeren und Text in der Mitte zeigen. Ohne Pinselfarbe: `display.set_brush` wirkt am CyberPi +* unzuverlässig (Texte kamen rot, lila, grün oder blau statt in der gewählten Farbe, auch mit Pausen). +* Die Schrift hat dann die Farbe, die der CyberPi gerade hat (einfarbig, nicht immer weiß; Holger: in Ordnung). +*/ +const showLabel = (text, size = 24) => pyLines("cyberpi.display.clear()", `cyberpi.display.show_label(${JSON.stringify(text)}, ${size}, 'center')`); +/** +* Logo nach dem Verbinden (und nach „mBot2 testen“ → Text): „VisuBot“ groß, einfarbig. +* Grafik (screen.set_pixel, Sprite) zeigt über USB nichts, Farben gehen nicht zuverlässig. Am echten mBot2 getestet (Oktober 2026). +*/ +const HELLO = showLabel("VisuBot", 32); +class MBotLink { + port; + writer; + reader; + loop; + rx = []; + idx = 1; + frameWaiters = []; + waiting = new Map(); + queue = Promise.resolve(); + listeners = new Set(); + error; + /** Port ist offen, der CyberPi startet noch neu. */ + connecting = false; + /** `fn` bei Verbinden, Trennen und Fehlern rufen; gibt eine Abmeldung zurück. */ + listen(fn) { + this.listeners.add(fn); + return () => this.listeners.delete(fn); + } + changed() { + for (const fn of this.listeners) fn(); + } + get connected() { + return this.writer !== undefined && !this.connecting; + } + /** Fragt nach dem USB-Anschluss, öffnet ihn und wartet den Neustart des CyberPi ab. */ + async connect() { + const s = serial(); + if (!s) throw new Error("Web Serial"); + const port = await s.requestPort(); + await port.open({ baudRate: 115200 }); + this.port = port; + this.writer = port.writable.getWriter(); + this.error = undefined; + this.connecting = true; + this.changed(); + this.loop = this.readLoop(); + // Seite schließen oder neu laden: Anschluss freigeben + window.addEventListener("pagehide", () => void this.disconnect(), { once: true }); + // Das Öffnen setzt den CyberPi zurück + await new Promise((r) => setTimeout(r, 3e3)); + if (!this.writer) return; + // Textausgaben vom Neustart verwerfen + this.rx.length = 0; + this.connecting = false; + this.changed(); + await this.run(HELLO); + } + /** + * Sauber trennen wie beim Auswerfen: Motoren anhalten, LEDs aus, Abschied auf dem Bildschirm, + * dann Leser und Schreiber freigeben und den Anschluss schließen. So lässt er sich ohne Neustart wieder verbinden. + */ + async disconnect(error) { + if (!this.port) { + this.error = error; + return this.changed(); + }; + if (!error && this.writer && !this.connecting) { + for (const code of [ + "mbot2.EM_stop('ALL')", + "cyberpi.led.off()", + showLabel("Bis bald!") + ]) await this.send(code, RUN, 2e3).catch(() => undefined); + }; + const port = this.port; + const writer = this.writer; + const reader = this.reader; + const loop = this.loop; + this.port = this.writer = this.reader = this.loop = undefined; + this.error = error; + this.connecting = false; + for (const w of this.waiting.values()) w.reject(new Error(error ?? "getrennt")); + this.waiting.clear(); + try { + await reader?.cancel(); + await loop; + await writer?.close(); + } catch {}; + try { + writer?.releaseLock(); + await port.close(); + } catch (e) { + console.warn("[mBot2] Schließen", e.message); + }; + this.changed(); + } + /** Python-Zeile ausführen; kehrt zurück, wenn der Roboter fertig ist (Fahren dauert). */ + run(code) { + return this.send(code, RUN, 3e4).then(() => undefined); + } + /** Wert eines Python-Ausdrucks, z. B. eines Sensors. */ + ask(code) { + return this.send(code, ASK, 3e3); + } + /** + * Programm auf den CyberPi übertragen (verbindet vorher, wenn nötig). Danach startet der CyberPi neu und + * das Programm bleibt gespeichert, auch ohne Kabel. `progress` bekommt erledigte und alle Schritte. + */ + async upload(source, progress = () => {}) { + if (!this.port) await this.connect(); + if (!this.writer) throw new Error(this.error ?? "nicht verbunden"); + const files = uploadFrames(source); + const total = 6 + files.length + 3; + let done = 0; + const step = () => progress(++done, total); + const prepare = async () => { + await this.sendFrame(frame(UPLOAD_MODE), isModeEcho); + step(); + for (const code of UPLOAD_PREPARE) { + await this.send(code, RUN, 3e3); + step(); + } + }; + await prepare(); + await prepare(); + for (const f of files) { + await this.sendFrame(f, isFileAck); + step(); + }; + done = total - 3; + await prepare(); + await this.restart(); + } + /** Rahmen schicken und auf die passende Antwort warten (bis zu drei Versuche). */ + sendFrame(data, match) { + const next = this.queue.then(async () => { + for (let attempt = 0; attempt < 3; attempt++) { + if (!this.writer) throw new Error("nicht verbunden"); + let resolve = () => {}; + const answered = new Promise((r) => resolve = r); + const waiter = { + match, + resolve + }; + this.frameWaiters.push(waiter); + await this.writer.write(data); + const ok = await Promise.race([answered.then(() => true), new Promise((r) => setTimeout(() => r(false), 3e3))]); + this.frameWaiters = this.frameWaiters.filter((w) => w !== waiter); + if (ok) return; + }; + throw new Error("keine Antwort"); + }); + this.queue = next.catch(() => undefined); + return next; + } + /** Anschluss schließen und wieder öffnen: das setzt den CyberPi zurück, er übernimmt das neue Programm. */ + async restart() { + const port = this.port; + await this.disconnect("restart"); + this.error = undefined; + await new Promise((r) => setTimeout(r, 300)); + await port.open({ baudRate: 115200 }); + await new Promise((r) => setTimeout(r, 500)); + await port.close(); + this.changed(); + } + send(code, mode, timeoutMs) { + // Immer nur eine Zeile unterwegs: der CyberPi arbeitet sie nacheinander ab. + const next = this.queue.then(() => new Promise((resolve, reject) => { + if (!this.writer) return reject(new Error("nicht verbunden")); + const idx = this.idx; + this.idx = this.idx % 65535 + 1; + const timer = setTimeout(() => { + this.waiting.delete(idx); + reject(new Error("keine Antwort")); + }, timeoutMs); + this.waiting.set(idx, { + resolve: (v) => (clearTimeout(timer), resolve(v)), + reject: (e) => (clearTimeout(timer), reject(e)) + }); + this.writer.write(pythonFrame(code, mode, idx)).catch((e) => { + this.waiting.delete(idx); + reject(e); + }); + })); + this.queue = next.catch(() => undefined); + return next; + } + async readLoop() { + while (this.port?.readable) { + const reader = this.port.readable.getReader(); + this.reader = reader; + try { + for (;;) { + const { value, done } = await reader.read(); + if (done) break; + this.rx.push(...value); + for (const body of readFrames(this.rx)) { + const f = this.frameWaiters.findIndex((w) => w.match(body)); + if (f >= 0) this.frameWaiters.splice(f, 1)[0].resolve(); + const a = scriptAnswer(body); + if (!a) continue; + const w = this.waiting.get(a.idx); + this.waiting.delete(a.idx); + w?.resolve(a.value); + } + } + } catch (e) { + // Störungen auf der Leitung (z. B. beim Neustart des CyberPi) sind harmlos: mit neuem Leser weiter + const harmless = [ + "BufferOverrunError", + "FramingError", + "BreakError", + "ParityError" + ].includes(e.name); + console.warn("[mBot2] Lesefehler", e.name, e.message); + if (!harmless && this.port) void this.disconnect(e.message); + } finally { + reader.releaseLock(); + }; + if (!this.writer) break; + } + } +}; +/** Eine Verbindung für die ganze Seite (bleibt beim Neuaufbau der Oberfläche erhalten). */ +const mbotLink = new MBotLink(); +//# sourceMappingSource=vite-generated +//# sourceMappingURL=data:application/json;base64,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QUssYUFBYSxPQUFPLEdBQUcsQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLFFBQVE7TUFDdEQsTUFBTSxJQUFJLGFBQWEsSUFBSTtNQUMzQixJQUFJLENBQUMsR0FBRztNQUNSLE1BQU0sSUFBSSxLQUFLLFFBQVEsSUFBSSxFQUFFLEdBQUc7TUFDaEMsS0FBSyxRQUFRLE9BQU8sRUFBRSxHQUFHO01BQ3pCLEdBQUcsUUFBUSxFQUFFLEtBQUs7S0FDcEI7SUFDRjtHQUNGLFNBQVMsR0FBRzs7SUFFVixNQUFNLFdBQVc7S0FBQztLQUFzQjtLQUFnQjtLQUFjO0lBQWEsQ0FBQyxDQUFDLFNBQVUsRUFBWSxJQUFJO0lBQy9HLFFBQVEsS0FBSyxzQkFBdUIsRUFBWSxNQUFPLEVBQVksT0FBTztJQUMxRSxJQUFJLENBQUMsWUFBWSxLQUFLLE1BQU0sS0FBSyxLQUFLLFdBQVksRUFBWSxPQUFPO0dBQ3ZFLFVBQVU7SUFDUixPQUFPLFlBQVk7R0FDckI7R0FDQSxJQUFJLENBQUMsS0FBSyxRQUFRO0VBQ3BCO0NBQ0Y7QUFDRjs7QUFHTyxNQUFNLFdBQVcsSUFBSSxTQUFTIiwibmFtZXMiOltdLCJpZ25vcmVMaXN0IjpbXSwic291cmNlcyI6WyJtYm90TGluay50cyJdLCJzb3VyY2VzQ29udGVudCI6WyIvKipcbiAqIFZlcmJpbmR1bmcgenVtIGVjaHRlbiBtQm90MiDDvGJlciBVU0IgKFdlYiBTZXJpYWwsIG51ciBDaHJvbWUvRWRnZSkuIERpZSBNYWtlYmxvY2stRmlybXdhcmUgZGVzIEN5YmVyUGlcbiAqIGbDvGhydCBQeXRob24tWmVpbGVuIGF1cywgZGllIGluIGVpbmVuIFJhaG1lbiB2ZXJwYWNrdCBzaW5kOlxuICogYEYzLCBLb3Bmc3VtbWUsIEzDpG5nZSAoMiBCeXRlKSwgMjgsIE1vZHVzLCBOdW1tZXIgKDIgQnl0ZSksIFRleHRsw6RuZ2UgKDIgQnl0ZSksIFRleHQsIFN1bW1lLCBGNGAuXG4gKiBNb2R1cyA0IGbDvGhydCBudXIgYXVzIChGYWhyYmVmZWhsZSBhbnR3b3J0ZW4gZXJzdCwgd2VubiBzaWUgZmVydGlnIHNpbmQpLCBNb2R1cyAxIGxpZWZlcnQgZGVuIFdlcnQgenVyw7xjay5cbiAqIERpZSBBbnR3b3J0IHRyw6RndCBkaWVzZWxiZSBOdW1tZXIgdW5kIGVudGjDpGx0IGB7XCJyZXRcIjrigKZ9YC4gR2V0ZXN0ZXQgbWl0IEhvbGdlcnMgbUJvdDIgKE9rdG9iZXIgMjAyNikuXG4gKi9cblxuaW1wb3J0IHR5cGUgeyBNQm90U2Vuc29yVmFsdWUgfSBmcm9tICcuL21ib3QnXG5cbmNvbnN0IEhFQUQgPSAweGYzXG5jb25zdCBGT09UID0gMHhmNFxuY29uc3QgU0NSSVBUID0gMHgyOFxuZXhwb3J0IGNvbnN0IFJVTiA9IDRcbmV4cG9ydCBjb25zdCBBU0sgPSAxXG5cbi8qKiBSYWhtZW4gdW0gZWluZW4gSW5oYWx0IGxlZ2VuLiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGZyYW1lKGJvZHk6IG51bWJlcltdKTogVWludDhBcnJheSB7XG4gIGNvbnN0IGxlbiA9IGJvZHkubGVuZ3RoXG4gIGNvbnN0IGhlYWQgPSAoSEVBRCArIChsZW4gJiAweGZmKSArIChsZW4gPj4gOCkpICYgMHhmZlxuICBjb25zdCBzdW0gPSBib2R5LnJlZHVjZSgoYSwgYikgPT4gYSArIGIsIDApICYgMHhmZlxuICByZXR1cm4gVWludDhBcnJheS5mcm9tKFtIRUFELCBoZWFkLCBsZW4gJiAweGZmLCBsZW4gPj4gOCwgLi4uYm9keSwgc3VtLCBGT09UXSlcbn1cblxuLyoqIFB5dGhvbi1aZWlsZSBhbHMgUmFobWVuIG1pdCBNb2R1cyB1bmQgTnVtbWVyLiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHB5dGhvbkZyYW1lKGNvZGU6IHN0cmluZywgbW9kZTogbnVtYmVyLCBpZHg6IG51bWJlcik6IFVpbnQ4QXJyYXkge1xuICBjb25zdCB0ZXh0ID0gQXJyYXkuZnJvbShuZXcgVGV4dEVuY29kZXIoKS5lbmNvZGUoY29kZSkpXG4gIHJldHVybiBmcmFtZShbU0NSSVBULCBtb2RlLCBpZHggJiAweGZmLCAoaWR4ID4+IDgpICYgMHhmZiwgdGV4dC5sZW5ndGggJiAweGZmLCB0ZXh0Lmxlbmd0aCA+PiA4LCAuLi50ZXh0XSlcbn1cblxuZXhwb3J0IGludGVyZmFjZSBTY3JpcHRBbnN3ZXIge1xuICBpZHg6IG51bWJlclxuICAvKiogV2VydCBhdXMgYHtcInJldFwiOuKApn1gOiBaYWhsLCBXYWhyaGVpdHN3ZXJ0LCBUZXh0IG9kZXIgYG51bGxgIChQeXRob24gYE5vbmVgKS4gKi9cbiAgdmFsdWU6IE1Cb3RTZW5zb3JWYWx1ZSB8IG51bGxcbn1cblxuLyoqXG4gKiBTdWNodCB2b2xsc3TDpG5kaWdlIFJhaG1lbiBpbiBgcnhgIHVuZCBnaWJ0IGRpZSBBbnR3b3J0ZW4gYXVmIFB5dGhvbi1aZWlsZW4genVyw7xjazsgdmVyYnJhdWNodGUgQnl0ZXMgd2VyZGVuIGVudGZlcm50LlxuICogVGV4dGF1c2dhYmVuIGRlcyBDeWJlclBpIGF1w59lcmhhbGIgdm9uIFJhaG1lbiAoei4gQi4gbmFjaCBkZW0gTmV1c3RhcnQpIHdlcmRlbiDDvGJlcnNwcnVuZ2VuLlxuICovXG5leHBvcnQgZnVuY3Rpb24gcmVhZEFuc3dlcnMocng6IG51bWJlcltdKTogU2NyaXB0QW5zd2VyW10ge1xuICByZXR1cm4gcmVhZEZyYW1lcyhyeCkuZmxhdE1hcCgoYm9keSkgPT4gc2NyaXB0QW5zd2VyKGJvZHkpID8/IFtdKVxufVxuXG4vKiogSW5oYWx0IGVpbmVyIEFudHdvcnQgYXVmIGVpbmUgUHl0aG9uLVplaWxlLCBzb25zdCBgdW5kZWZpbmVkYC4gKi9cbmZ1bmN0aW9uIHNjcmlwdEFuc3dlcihib2R5OiBudW1iZXJbXSk6IFNjcmlwdEFuc3dlciB8IHVuZGVmaW5lZCB7XG4gIGlmIChib2R5WzBdICE9PSBTQ1JJUFQgfHwgYm9keS5sZW5ndGggPCA2KSByZXR1cm4gdW5kZWZpbmVkXG4gIGNvbnN0IHRleHQgPSBuZXcgVGV4dERlY29kZXIoKS5kZWNvZGUoVWludDhBcnJheS5mcm9tKGJvZHkuc2xpY2UoNikpKVxuICBjb25zdCBtID0gL1wicmV0XCJcXHMqOlxccyooW159XSopXFx9Ly5leGVjKHRleHQpXG4gIHJldHVybiBtID8geyBpZHg6IGJvZHlbMl0gfCAoYm9keVszXSA8PCA4KSwgdmFsdWU6IHB5dGhvblZhbHVlKG1bMV0udHJpbSgpKSB9IDogdW5kZWZpbmVkXG59XG5cbi8qKiBBbGxlIHZvbGxzdMOkbmRpZ2VuIFJhaG1lbiBhdXMgYHJ4YCAobnVyIGRlciBJbmhhbHQpOyB2ZXJicmF1Y2h0ZSBCeXRlcyB3ZXJkZW4gZW50ZmVybnQuICovXG5leHBvcnQgZnVuY3Rpb24gcmVhZEZyYW1lcyhyeDogbnVtYmVyW10pOiBudW1iZXJbXVtdIHtcbiAgY29uc3QgYm9kaWVzOiBudW1iZXJbXVtdID0gW11cbiAgZm9yICg7Oykge1xuICAgIGNvbnN0IHN0YXJ0ID0gcnguaW5kZXhPZihIRUFEKVxuICAgIGlmIChzdGFydCA8IDApIHtcbiAgICAgIHJ4Lmxlbmd0aCA9IDBcbiAgICAgIGJyZWFrXG4gICAgfVxuICAgIHJ4LnNwbGljZSgwLCBzdGFydClcbiAgICBpZiAocngubGVuZ3RoIDwgNCkgYnJlYWtcbiAgICBjb25zdCBsZW4gPSByeFsyXSB8IChyeFszXSA8PCA4KVxuICAgIC8vIEtlaW4gUmFobWVuLCBudXIgZWluIHp1ZsOkbGxpZ2VzIEYzIGltIFRleHQ6IHdlaXRlcnN1Y2hlblxuICAgIGlmIChyeFsxXSAhPT0gKChIRUFEICsgcnhbMl0gKyByeFszXSkgJiAweGZmKSB8fCBsZW4gPiA0MDk2KSB7XG4gICAgICByeC5zcGxpY2UoMCwgMSlcbiAgICAgIGNvbnRpbnVlXG4gICAgfVxuICAgIGlmIChyeC5sZW5ndGggPCBsZW4gKyA2KSBicmVha1xuICAgIGJvZGllcy5wdXNoKHJ4LnNsaWNlKDQsIDQgKyBsZW4pKVxuICAgIHJ4LnNwbGljZSgwLCBsZW4gKyA2KVxuICB9XG4gIHJldHVybiBib2RpZXNcbn1cblxuZnVuY3Rpb24gcHl0aG9uVmFsdWUodGV4dDogc3RyaW5nKTogTUJvdFNlbnNvclZhbHVlIHwgbnVsbCB7XG4gIGlmICh0ZXh0ID09PSAnVHJ1ZScpIHJldHVybiB0cnVlXG4gIGlmICh0ZXh0ID09PSAnRmFsc2UnKSByZXR1cm4gZmFsc2VcbiAgLy8gVGV4dCwgei4gQi4gZWluIEZhcmJuYW1lOiBcInJlZFwiIG9kZXIgJ3JlZCdcbiAgY29uc3QgcXVvdGVkID0gL15bXCInXSguKilbXCInXSQvLmV4ZWModGV4dClcbiAgaWYgKHF1b3RlZCkgcmV0dXJuIHF1b3RlZFsxXVxuICBjb25zdCBuID0gTnVtYmVyKHRleHQpXG4gIHJldHVybiB0ZXh0ICE9PSAnJyAmJiBOdW1iZXIuaXNGaW5pdGUobikgPyBuIDogbnVsbFxufVxuXG4vKipcbiAqIFByb2dyYW1tIGZlc3QgYXVmIGRlbSBDeWJlclBpIHNwZWljaGVybiwgd2llIOKAnkhvY2hsYWRlbuKAnCBpbiBtQmxvY2sgKEFibGF1ZiBhdXMgZ2l0aHViLmNvbS93ZWFyZTJwbHVzMy9jeWJlcnBpLXVwbG9hZGVyLCBNSVQpOlxuICogVXBsb2FkLU1vZHVzIChgMEQgMDAgMDBgKSwgUkVQTCBhdXMsIERhdGVpa29wZiBtaXQgR3LDtsOfZSwgWE9SLVByw7xmc3VtbWUgdW5kIFBmYWQsIGRhbm4gQmzDtmNrZSB6dSA4MCBCeXRlLlxuICogRGllIERhdGVpIGxhbmRldCBpbiBlaW5lbSBad2lzY2hlbnBsYXR6LCBkZW4gZGllIEZpcm13YXJlIGJlaW0gbsOkY2hzdGVuIE5ldXN0YXJ0IMO8YmVybmltbXQuXG4gKi9cbmV4cG9ydCBjb25zdCBVUExPQURfUEFUSCA9ICcvZmxhc2gvX3h4X21haW4ucHknXG5jb25zdCBVUExPQURfTU9ERSA9IFsweDBkLCAweDAwLCAweDAwXVxuY29uc3QgRklMRV9TRVJWSUNFID0gMHg1ZVxuY29uc3QgQkxPQ0sgPSA4MFxuZXhwb3J0IGNvbnN0IFVQTE9BRF9QUkVQQVJFID0gWyd0cnk6XFxuICAgIGltcG9ydCBjb25maWdcXG5leGNlcHQ6XFxuICAgIHBhc3MnLCAndHJ5OlxcbiAgICBjb25maWcud3JpdGVfY29uZmlnKFwicmVwbF9lbmFibGVcIiwgRmFsc2UpXFxuZXhjZXB0OlxcbiAgICBwYXNzJ11cblxuY29uc3QgbGUgPSAodmFsdWU6IG51bWJlciwgYnl0ZXM6IG51bWJlcikgPT4gQXJyYXkuZnJvbSh7IGxlbmd0aDogYnl0ZXMgfSwgKF8sIGkpID0+ICh2YWx1ZSA+Pj4gKDggKiBpKSkgJiAweGZmKVxuXG4vKiogWE9SIGRlciAzMi1CaXQtV8O2cnRlciAobGl0dGxlIGVuZGlhbiwgbWl0IE51bGxlbiBhdWZnZWbDvGxsdCksIHdpZSBtQmxvY2suICovXG5leHBvcnQgZnVuY3Rpb24gZmlsZUNoZWNrc3VtKGRhdGE6IFVpbnQ4QXJyYXkpOiBudW1iZXJbXSB7XG4gIGxldCB4ID0gMFxuICBmb3IgKGxldCBpID0gMDsgaSA8IGRhdGEubGVuZ3RoOyBpICs9IDQpIHggPSAoeCBeICgoZGF0YVtpXSA/PyAwKSB8ICgoZGF0YVtpICsgMV0gPz8gMCkgPDwgOCkgfCAoKGRhdGFbaSArIDJdID8/IDApIDw8IDE2KSB8ICgoZGF0YVtpICsgM10gPz8gMCkgPDwgMjQpKSkgPj4+IDBcbiAgcmV0dXJuIGxlKHgsIDQpXG59XG5cbmNvbnN0IGZpbGVGcmFtZSA9IChjbWQ6IG51bWJlciwgcGF5bG9hZDogbnVtYmVyW10pID0+IGZyYW1lKFsweDAxLCAweDAwLCBGSUxFX1NFUlZJQ0UsIGNtZCwgLi4ubGUocGF5bG9hZC5sZW5ndGgsIDIpLCAuLi5wYXlsb2FkXSlcblxuLyoqIFB5dGhvbi1EYXRlaSBpbiBSYWhtZW46IEtvcGYsIGRhbm4gQmzDtmNrZSB6dSA4MCBCeXRlIHVuZCBlaW4gbGV0enRlciBCbG9jayBtaXQgNCBCeXRlICh3aWUgbUJsb2NrOyBtaXQgWmVpbGVudW1icsO8Y2hlbiBhdWZnZWbDvGxsdCkuICovXG5leHBvcnQgZnVuY3Rpb24gdXBsb2FkRnJhbWVzKHNvdXJjZTogc3RyaW5nLCBwYXRoID0gVVBMT0FEX1BBVEgpOiBVaW50OEFycmF5W10ge1xuICBjb25zdCByYXcgPSBuZXcgVGV4dEVuY29kZXIoKS5lbmNvZGUoc291cmNlKVxuICBjb25zdCBwYWQgPSAoNCAtIChyYXcubGVuZ3RoICUgQkxPQ0spICsgQkxPQ0spICUgQkxPQ0tcbiAgY29uc3QgZGF0YSA9IG5ldyBVaW50OEFycmF5KHJhdy5sZW5ndGggKyBwYWQpLmZpbGwoMHgwYSlcbiAgZGF0YS5zZXQocmF3KVxuICBjb25zdCBmcmFtZXMgPSBbZmlsZUZyYW1lKDB4MDEsIFsweDAwLCAuLi5sZShkYXRhLmxlbmd0aCwgNCksIC4uLmZpbGVDaGVja3N1bShkYXRhKSwgLi4uQXJyYXkuZnJvbShuZXcgVGV4dEVuY29kZXIoKS5lbmNvZGUocGF0aCkpXSldXG4gIGNvbnN0IGVuZCA9IGRhdGEubGVuZ3RoIC0gNFxuICBmb3IgKGxldCBvZmYgPSAwOyBvZmYgPCBlbmQ7IG9mZiArPSBCTE9DSykgZnJhbWVzLnB1c2goZmlsZUZyYW1lKDB4MDIsIFsuLi5sZShvZmYsIDQpLCAuLi5kYXRhLnN1YmFycmF5KG9mZiwgTWF0aC5taW4ob2ZmICsgQkxPQ0ssIGVuZCkpXSkpXG4gIGZyYW1lcy5wdXNoKGZpbGVGcmFtZSgweDAyLCBbLi4ubGUoZW5kLCA0KSwgLi4uZGF0YS5zdWJhcnJheShlbmQpXSkpXG4gIHJldHVybiBmcmFtZXNcbn1cblxuY29uc3QgaXNNb2RlRWNobyA9IChib2R5OiBudW1iZXJbXSkgPT4gYm9keS5sZW5ndGggPT09IDMgJiYgYm9keVswXSA9PT0gMHgwZFxuY29uc3QgaXNGaWxlQWNrID0gKGJvZHk6IG51bWJlcltdKSA9PiBib2R5Lmxlbmd0aCA9PT0gNyB8fCBib2R5LnNvbWUoKGIsIGkpID0+IGIgPT09IEZJTEVfU0VSVklDRSAmJiBib2R5W2kgKyAxXSA9PT0gMHhmMClcblxuLy8gV2ViIFNlcmlhbCBpc3QgbmljaHQgaW4gZGVuIFR5cGVTY3JpcHQtVHlwZW47IG51ciBkYXMgTsO2dGlnc3RlLlxuaW50ZXJmYWNlIFNlcmlhbFBvcnRMaWtlIHtcbiAgb3BlbihvcHRpb25zOiB7IGJhdWRSYXRlOiBudW1iZXIgfSk6IFByb21pc2U8dm9pZD5cbiAgY2xvc2UoKTogUHJvbWlzZTx2b2lkPlxuICByZWFkYWJsZTogUmVhZGFibGVTdHJlYW08VWludDhBcnJheT4gfCBudWxsXG4gIHdyaXRhYmxlOiBXcml0YWJsZVN0cmVhbTxVaW50OEFycmF5PiB8IG51bGxcbn1cbmludGVyZmFjZSBTZXJpYWxMaWtlIHtcbiAgcmVxdWVzdFBvcnQoKTogUHJvbWlzZTxTZXJpYWxQb3J0TGlrZT5cbn1cblxuY29uc3Qgc2VyaWFsID0gKCk6IFNlcmlhbExpa2UgfCB1bmRlZmluZWQgPT4gKHR5cGVvZiBuYXZpZ2F0b3IgPT09ICd1bmRlZmluZWQnID8gdW5kZWZpbmVkIDogKG5hdmlnYXRvciBhcyB1bmtub3duIGFzIHsgc2VyaWFsPzogU2VyaWFsTGlrZSB9KS5zZXJpYWwpXG5cbi8qKiBLYW5uIGRpZXNlciBCcm93c2VyIGVpbmVuIG1Cb3QyIMO8YmVyIFVTQiBhbnNwcmVjaGVuPyAqL1xuZXhwb3J0IGNvbnN0IGNhbkNvbm5lY3RNQm90ID0gKCkgPT4gc2VyaWFsKCkgIT09IHVuZGVmaW5lZFxuXG4vKiogTWVocmVyZSBQeXRob24tQW53ZWlzdW5nZW4gYWxzIGVpbmUgWmVpbGUgKGRlciBDeWJlclBpIG5pbW10IG51ciBlaW5lKS4gSlNPTi1TdHJpbmdzIHNpbmQgYXVjaCBnw7xsdGlnZSBQeXRob24tU3RyaW5ncy4gKi9cbmV4cG9ydCBjb25zdCBweUxpbmVzID0gKC4uLmxpbmVzOiBzdHJpbmdbXSkgPT4gYGV4ZWMoJHtKU09OLnN0cmluZ2lmeShsaW5lcy5qb2luKCc7ICcpKX0pYFxuXG4vKipcbiAqIEJpbGRzY2hpcm0gbGVlcmVuIHVuZCBUZXh0IGluIGRlciBNaXR0ZSB6ZWlnZW4uIE9obmUgUGluc2VsZmFyYmU6IGBkaXNwbGF5LnNldF9icnVzaGAgd2lya3QgYW0gQ3liZXJQaVxuICogdW56dXZlcmzDpHNzaWcgKFRleHRlIGthbWVuIHJvdCwgbGlsYSwgZ3LDvG4gb2RlciBibGF1IHN0YXR0IGluIGRlciBnZXfDpGhsdGVuIEZhcmJlLCBhdWNoIG1pdCBQYXVzZW4pLlxuICogRGllIFNjaHJpZnQgaGF0IGRhbm4gZGllIEZhcmJlLCBkaWUgZGVyIEN5YmVyUGkgZ2VyYWRlIGhhdCAoZWluZmFyYmlnLCBuaWNodCBpbW1lciB3ZWnDnzsgSG9sZ2VyOiBpbiBPcmRudW5nKS5cbiAqL1xuZXhwb3J0IGNvbnN0IHNob3dMYWJlbCA9ICh0ZXh0OiBzdHJpbmcsIHNpemUgPSAyNCkgPT4gcHlMaW5lcygnY3liZXJwaS5kaXNwbGF5LmNsZWFyKCknLCBgY3liZXJwaS5kaXNwbGF5LnNob3dfbGFiZWwoJHtKU09OLnN0cmluZ2lmeSh0ZXh0KX0sICR7c2l6ZX0sICdjZW50ZXInKWApXG5cbi8qKlxuICogTG9nbyBuYWNoIGRlbSBWZXJiaW5kZW4gKHVuZCBuYWNoIOKAnm1Cb3QyIHRlc3RlbuKAnCDihpIgVGV4dCk6IOKAnlZpc3VCb3TigJwgZ3Jvw58sIGVpbmZhcmJpZy5cbiAqIEdyYWZpayAoc2NyZWVuLnNldF9waXhlbCwgU3ByaXRlKSB6ZWlndCDDvGJlciBVU0IgbmljaHRzLCBGYXJiZW4gZ2VoZW4gbmljaHQgenV2ZXJsw6Rzc2lnLiBBbSBlY2h0ZW4gbUJvdDIgZ2V0ZXN0ZXQgKE9rdG9iZXIgMjAyNikuXG4gKi9cbmV4cG9ydCBjb25zdCBIRUxMTyA9IHNob3dMYWJlbCgnVmlzdUJvdCcsIDMyKVxuXG5leHBvcnQgY2xhc3MgTUJvdExpbmsge1xuICBwcml2YXRlIHBvcnQ/OiBTZXJpYWxQb3J0TGlrZVxuICBwcml2YXRlIHdyaXRlcj86IFdyaXRhYmxlU3RyZWFtRGVmYXVsdFdyaXRlcjxVaW50OEFycmF5PlxuICBwcml2YXRlIHJlYWRlcj86IFJlYWRhYmxlU3RyZWFtRGVmYXVsdFJlYWRlcjxVaW50OEFycmF5PlxuICBwcml2YXRlIGxvb3A/OiBQcm9taXNlPHZvaWQ+XG4gIHByaXZhdGUgcng6IG51bWJlcltdID0gW11cbiAgcHJpdmF0ZSBpZHggPSAxXG4gIHByaXZhdGUgZnJhbWVXYWl0ZXJzOiB7IG1hdGNoOiAoYm9keTogbnVtYmVyW10pID0+IGJvb2xlYW47IHJlc29sdmU6ICgpID0+IHZvaWQgfVtdID0gW11cbiAgcHJpdmF0ZSB3YWl0aW5nID0gbmV3IE1hcDxudW1iZXIsIHsgcmVzb2x2ZTogKHY6IE1Cb3RTZW5zb3JWYWx1ZSB8IG51bGwpID0+IHZvaWQ7IHJlamVjdDogKGU6IEVycm9yKSA9PiB2b2lkIH0+KClcbiAgcHJpdmF0ZSBxdWV1ZTogUHJvbWlzZTx1bmtub3duPiA9IFByb21pc2UucmVzb2x2ZSgpXG4gIHByaXZhdGUgbGlzdGVuZXJzID0gbmV3IFNldDwoKSA9PiB2b2lkPigpXG4gIGVycm9yPzogc3RyaW5nXG4gIC8qKiBQb3J0IGlzdCBvZmZlbiwgZGVyIEN5YmVyUGkgc3RhcnRldCBub2NoIG5ldS4gKi9cbiAgY29ubmVjdGluZyA9IGZhbHNlXG5cbiAgLyoqIGBmbmAgYmVpIFZlcmJpbmRlbiwgVHJlbm5lbiB1bmQgRmVobGVybiBydWZlbjsgZ2lidCBlaW5lIEFibWVsZHVuZyB6dXLDvGNrLiAqL1xuICBsaXN0ZW4oZm46ICgpID0+IHZvaWQpOiAoKSA9PiB2b2lkIHtcbiAgICB0aGlzLmxpc3RlbmVycy5hZGQoZm4pXG4gICAgcmV0dXJuICgpID0+IHRoaXMubGlzdGVuZXJzLmRlbGV0ZShmbilcbiAgfVxuXG4gIHByaXZhdGUgY2hhbmdlZCgpIHtcbiAgICBmb3IgKGNvbnN0IGZuIG9mIHRoaXMubGlzdGVuZXJzKSBmbigpXG4gIH1cblxuICBnZXQgY29ubmVjdGVkKCkge1xuICAgIHJldHVybiB0aGlzLndyaXRlciAhPT0gdW5kZWZpbmVkICYmICF0aGlzLmNvbm5lY3RpbmdcbiAgfVxuXG4gIC8qKiBGcmFndCBuYWNoIGRlbSBVU0ItQW5zY2hsdXNzLCDDtmZmbmV0IGlobiB1bmQgd2FydGV0IGRlbiBOZXVzdGFydCBkZXMgQ3liZXJQaSBhYi4gKi9cbiAgYXN5bmMgY29ubmVjdCgpIHtcbiAgICBjb25zdCBzID0gc2VyaWFsKClcbiAgICBpZiAoIXMpIHRocm93IG5ldyBFcnJvcignV2ViIFNlcmlhbCcpXG4gICAgY29uc3QgcG9ydCA9IGF3YWl0IHMucmVxdWVzdFBvcnQoKVxuICAgIGF3YWl0IHBvcnQub3Blbih7IGJhdWRSYXRlOiAxMTUyMDAgfSlcbiAgICB0aGlzLnBvcnQgPSBwb3J0XG4gICAgdGhpcy53cml0ZXIgPSBwb3J0LndyaXRhYmxlIS5nZXRXcml0ZXIoKVxuICAgIHRoaXMuZXJyb3IgPSB1bmRlZmluZWRcbiAgICB0aGlzLmNvbm5lY3RpbmcgPSB0cnVlXG4gICAgdGhpcy5jaGFuZ2VkKClcbiAgICB0aGlzLmxvb3AgPSB0aGlzLnJlYWRMb29wKClcbiAgICAvLyBTZWl0ZSBzY2hsaWXDn2VuIG9kZXIgbmV1IGxhZGVuOiBBbnNjaGx1c3MgZnJlaWdlYmVuXG4gICAgd2luZG93LmFkZEV2ZW50TGlzdGVuZXIoJ3BhZ2VoaWRlJywgKCkgPT4gdm9pZCB0aGlzLmRpc2Nvbm5lY3QoKSwgeyBvbmNlOiB0cnVlIH0pXG4gICAgLy8gRGFzIMOWZmZuZW4gc2V0enQgZGVuIEN5YmVyUGkgenVyw7xja1xuICAgIGF3YWl0IG5ldyBQcm9taXNlKChyKSA9PiBzZXRUaW1lb3V0KHIsIDMwMDApKVxuICAgIGlmICghdGhpcy53cml0ZXIpIHJldHVyblxuICAgIC8vIFRleHRhdXNnYWJlbiB2b20gTmV1c3RhcnQgdmVyd2VyZmVuXG4gICAgdGhpcy5yeC5sZW5ndGggPSAwXG4gICAgdGhpcy5jb25uZWN0aW5nID0gZmFsc2VcbiAgICB0aGlzLmNoYW5nZWQoKVxuICAgIGF3YWl0IHRoaXMucnVuKEhFTExPKVxuICB9XG5cbiAgLyoqXG4gICAqIFNhdWJlciB0cmVubmVuIHdpZSBiZWltIEF1c3dlcmZlbjogTW90b3JlbiBhbmhhbHRlbiwgTEVEcyBhdXMsIEFic2NoaWVkIGF1ZiBkZW0gQmlsZHNjaGlybSxcbiAgICogZGFubiBMZXNlciB1bmQgU2NocmVpYmVyIGZyZWlnZWJlbiB1bmQgZGVuIEFuc2NobHVzcyBzY2hsaWXDn2VuLiBTbyBsw6Rzc3QgZXIgc2ljaCBvaG5lIE5ldXN0YXJ0IHdpZWRlciB2ZXJiaW5kZW4uXG4gICAqL1xuICBhc3luYyBkaXNjb25uZWN0KGVycm9yPzogc3RyaW5nKSB7XG4gICAgaWYgKCF0aGlzLnBvcnQpIHtcbiAgICAgIHRoaXMuZXJyb3IgPSBlcnJvclxuICAgICAgcmV0dXJuIHRoaXMuY2hhbmdlZCgpXG4gICAgfVxuICAgIGlmICghZXJyb3IgJiYgdGhpcy53cml0ZXIgJiYgIXRoaXMuY29ubmVjdGluZykge1xuICAgICAgZm9yIChjb25zdCBjb2RlIG9mIFtcIm1ib3QyLkVNX3N0b3AoJ0FMTCcpXCIsICdjeWJlcnBpLmxlZC5vZmYoKScsIHNob3dMYWJlbCgnQmlzIGJhbGQhJyldKVxuICAgICAgICBhd2FpdCB0aGlzLnNlbmQoY29kZSwgUlVOLCAyMDAwKS5jYXRjaCgoKSA9PiB1bmRlZmluZWQpXG4gICAgfVxuICAgIGNvbnN0IHBvcnQgPSB0aGlzLnBvcnRcbiAgICBjb25zdCB3cml0ZXIgPSB0aGlzLndyaXRlclxuICAgIGNvbnN0IHJlYWRlciA9IHRoaXMucmVhZGVyXG4gICAgY29uc3QgbG9vcCA9IHRoaXMubG9vcFxuICAgIHRoaXMucG9ydCA9IHRoaXMud3JpdGVyID0gdGhpcy5yZWFkZXIgPSB0aGlzLmxvb3AgPSB1bmRlZmluZWRcbiAgICB0aGlzLmVycm9yID0gZXJyb3JcbiAgICB0aGlzLmNvbm5lY3RpbmcgPSBmYWxzZVxuICAgIGZvciAoY29uc3QgdyBvZiB0aGlzLndhaXRpbmcudmFsdWVzKCkpIHcucmVqZWN0KG5ldyBFcnJvcihlcnJvciA/PyAnZ2V0cmVubnQnKSlcbiAgICB0aGlzLndhaXRpbmcuY2xlYXIoKVxuICAgIHRyeSB7XG4gICAgICBhd2FpdCByZWFkZXI/LmNhbmNlbCgpXG4gICAgICBhd2FpdCBsb29wXG4gICAgICBhd2FpdCB3cml0ZXI/LmNsb3NlKClcbiAgICB9IGNhdGNoIHtcbiAgICAgIC8qIExlaXR1bmcgc2Nob24gd2VnICovXG4gICAgfVxuICAgIHRyeSB7XG4gICAgICB3cml0ZXI/LnJlbGVhc2VMb2NrKClcbiAgICAgIGF3YWl0IHBvcnQuY2xvc2UoKVxuICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgIGNvbnNvbGUud2FybignW21Cb3QyXSBTY2hsaWXDn2VuJywgKGUgYXMgRXJyb3IpLm1lc3NhZ2UpXG4gICAgfVxuICAgIHRoaXMuY2hhbmdlZCgpXG4gIH1cblxuICAvKiogUHl0aG9uLVplaWxlIGF1c2bDvGhyZW47IGtlaHJ0IHp1csO8Y2ssIHdlbm4gZGVyIFJvYm90ZXIgZmVydGlnIGlzdCAoRmFocmVuIGRhdWVydCkuICovXG4gIHJ1bihjb2RlOiBzdHJpbmcpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICByZXR1cm4gdGhpcy5zZW5kKGNvZGUsIFJVTiwgMzAwMDApLnRoZW4oKCkgPT4gdW5kZWZpbmVkKVxuICB9XG5cbiAgLyoqIFdlcnQgZWluZXMgUHl0aG9uLUF1c2RydWNrcywgei4gQi4gZWluZXMgU2Vuc29ycy4gKi9cbiAgYXNrKGNvZGU6IHN0cmluZyk6IFByb21pc2U8TUJvdFNlbnNvclZhbHVlIHwgbnVsbD4ge1xuICAgIHJldHVybiB0aGlzLnNlbmQoY29kZSwgQVNLLCAzMDAwKVxuICB9XG5cbiAgLyoqXG4gICAqIFByb2dyYW1tIGF1ZiBkZW4gQ3liZXJQaSDDvGJlcnRyYWdlbiAodmVyYmluZGV0IHZvcmhlciwgd2VubiBuw7Z0aWcpLiBEYW5hY2ggc3RhcnRldCBkZXIgQ3liZXJQaSBuZXUgdW5kXG4gICAqIGRhcyBQcm9ncmFtbSBibGVpYnQgZ2VzcGVpY2hlcnQsIGF1Y2ggb2huZSBLYWJlbC4gYHByb2dyZXNzYCBiZWtvbW10IGVybGVkaWd0ZSB1bmQgYWxsZSBTY2hyaXR0ZS5cbiAgICovXG4gIGFzeW5jIHVwbG9hZChzb3VyY2U6IHN0cmluZywgcHJvZ3Jlc3M6IChkb25lOiBudW1iZXIsIHRvdGFsOiBudW1iZXIpID0+IHZvaWQgPSAoKSA9PiB7fSkge1xuICAgIGlmICghdGhpcy5wb3J0KSBhd2FpdCB0aGlzLmNvbm5lY3QoKVxuICAgIGlmICghdGhpcy53cml0ZXIpIHRocm93IG5ldyBFcnJvcih0aGlzLmVycm9yID8/ICduaWNodCB2ZXJidW5kZW4nKVxuICAgIGNvbnN0IGZpbGVzID0gdXBsb2FkRnJhbWVzKHNvdXJjZSlcbiAgICBjb25zdCB0b3RhbCA9IDYgKyBmaWxlcy5sZW5ndGggKyAzXG4gICAgbGV0IGRvbmUgPSAwXG4gICAgY29uc3Qgc3RlcCA9ICgpID0+IHByb2dyZXNzKCsrZG9uZSwgdG90YWwpXG4gICAgY29uc3QgcHJlcGFyZSA9IGFzeW5jICgpID0+IHtcbiAgICAgIGF3YWl0IHRoaXMuc2VuZEZyYW1lKGZyYW1lKFVQTE9BRF9NT0RFKSwgaXNNb2RlRWNobylcbiAgICAgIHN0ZXAoKVxuICAgICAgZm9yIChjb25zdCBjb2RlIG9mIFVQTE9BRF9QUkVQQVJFKSB7XG4gICAgICAgIGF3YWl0IHRoaXMuc2VuZChjb2RlLCBSVU4sIDMwMDApXG4gICAgICAgIHN0ZXAoKVxuICAgICAgfVxuICAgIH1cbiAgICBhd2FpdCBwcmVwYXJlKClcbiAgICBhd2FpdCBwcmVwYXJlKClcbiAgICBmb3IgKGNvbnN0IGYgb2YgZmlsZXMpIHtcbiAgICAgIGF3YWl0IHRoaXMuc2VuZEZyYW1lKGYsIGlzRmlsZUFjaylcbiAgICAgIHN0ZXAoKVxuICAgIH1cbiAgICBkb25lID0gdG90YWwgLSAzXG4gICAgYXdhaXQgcHJlcGFyZSgpXG4gICAgYXdhaXQgdGhpcy5yZXN0YXJ0KClcbiAgfVxuXG4gIC8qKiBSYWhtZW4gc2NoaWNrZW4gdW5kIGF1ZiBkaWUgcGFzc2VuZGUgQW50d29ydCB3YXJ0ZW4gKGJpcyB6dSBkcmVpIFZlcnN1Y2hlKS4gKi9cbiAgcHJpdmF0ZSBzZW5kRnJhbWUoZGF0YTogVWludDhBcnJheSwgbWF0Y2g6IChib2R5OiBudW1iZXJbXSkgPT4gYm9vbGVhbik6IFByb21pc2U8dm9pZD4ge1xuICAgIGNvbnN0IG5leHQgPSB0aGlzLnF1ZXVlLnRoZW4oYXN5bmMgKCkgPT4ge1xuICAgICAgZm9yIChsZXQgYXR0ZW1wdCA9IDA7IGF0dGVtcHQgPCAzOyBhdHRlbXB0KyspIHtcbiAgICAgICAgaWYgKCF0aGlzLndyaXRlcikgdGhyb3cgbmV3IEVycm9yKCduaWNodCB2ZXJidW5kZW4nKVxuICAgICAgICBsZXQgcmVzb2x2ZSA9ICgpID0+IHt9XG4gICAgICAgIGNvbnN0IGFuc3dlcmVkID0gbmV3IFByb21pc2U8dm9pZD4oKHIpID0+IChyZXNvbHZlID0gcikpXG4gICAgICAgIGNvbnN0IHdhaXRlciA9IHsgbWF0Y2gsIHJlc29sdmUgfVxuICAgICAgICB0aGlzLmZyYW1lV2FpdGVycy5wdXNoKHdhaXRlcilcbiAgICAgICAgYXdhaXQgdGhpcy53cml0ZXIud3JpdGUoZGF0YSlcbiAgICAgICAgY29uc3Qgb2sgPSBhd2FpdCBQcm9taXNlLnJhY2UoW2Fuc3dlcmVkLnRoZW4oKCkgPT4gdHJ1ZSksIG5ldyBQcm9taXNlPGJvb2xlYW4+KChyKSA9PiBzZXRUaW1lb3V0KCgpID0+IHIoZmFsc2UpLCAzMDAwKSldKVxuICAgICAgICB0aGlzLmZyYW1lV2FpdGVycyA9IHRoaXMuZnJhbWVXYWl0ZXJzLmZpbHRlcigodykgPT4gdyAhPT0gd2FpdGVyKVxuICAgICAgICBpZiAob2spIHJldHVyblxuICAgICAgfVxuICAgICAgdGhyb3cgbmV3IEVycm9yKCdrZWluZSBBbnR3b3J0JylcbiAgICB9KVxuICAgIHRoaXMucXVldWUgPSBuZXh0LmNhdGNoKCgpID0+IHVuZGVmaW5lZClcbiAgICByZXR1cm4gbmV4dFxuICB9XG5cbiAgLyoqIEFuc2NobHVzcyBzY2hsaWXDn2VuIHVuZCB3aWVkZXIgw7ZmZm5lbjogZGFzIHNldHp0IGRlbiBDeWJlclBpIHp1csO8Y2ssIGVyIMO8YmVybmltbXQgZGFzIG5ldWUgUHJvZ3JhbW0uICovXG4gIHByaXZhdGUgYXN5bmMgcmVzdGFydCgpIHtcbiAgICBjb25zdCBwb3J0ID0gdGhpcy5wb3J0IVxuICAgIGF3YWl0IHRoaXMuZGlzY29ubmVjdCgncmVzdGFydCcpXG4gICAgdGhpcy5lcnJvciA9IHVuZGVmaW5lZFxuICAgIGF3YWl0IG5ldyBQcm9taXNlKChyKSA9PiBzZXRUaW1lb3V0KHIsIDMwMCkpXG4gICAgYXdhaXQgcG9ydC5vcGVuKHsgYmF1ZFJhdGU6IDExNTIwMCB9KVxuICAgIGF3YWl0IG5ldyBQcm9taXNlKChyKSA9PiBzZXRUaW1lb3V0KHIsIDUwMCkpXG4gICAgYXdhaXQgcG9ydC5jbG9zZSgpXG4gICAgdGhpcy5jaGFuZ2VkKClcbiAgfVxuXG4gIHByaXZhdGUgc2VuZChjb2RlOiBzdHJpbmcsIG1vZGU6IG51bWJlciwgdGltZW91dE1zOiBudW1iZXIpOiBQcm9taXNlPE1Cb3RTZW5zb3JWYWx1ZSB8IG51bGw+IHtcbiAgICAvLyBJbW1lciBudXIgZWluZSBaZWlsZSB1bnRlcndlZ3M6IGRlciBDeWJlclBpIGFyYmVpdGV0IHNpZSBuYWNoZWluYW5kZXIgYWIuXG4gICAgY29uc3QgbmV4dCA9IHRoaXMucXVldWUudGhlbihcbiAgICAgICgpID0+XG4gICAgICAgIG5ldyBQcm9taXNlPE1Cb3RTZW5zb3JWYWx1ZSB8IG51bGw+KChyZXNvbHZlLCByZWplY3QpID0+IHtcbiAgICAgICAgICBpZiAoIXRoaXMud3JpdGVyKSByZXR1cm4gcmVqZWN0KG5ldyBFcnJvcignbmljaHQgdmVyYnVuZGVuJykpXG4gICAgICAgICAgY29uc3QgaWR4ID0gdGhpcy5pZHhcbiAgICAgICAgICB0aGlzLmlkeCA9ICh0aGlzLmlkeCAlIDB4ZmZmZikgKyAxXG4gICAgICAgICAgY29uc3QgdGltZXIgPSBzZXRUaW1lb3V0KCgpID0+IHtcbiAgICAgICAgICAgIHRoaXMud2FpdGluZy5kZWxldGUoaWR4KVxuICAgICAgICAgICAgcmVqZWN0KG5ldyBFcnJvcigna2VpbmUgQW50d29ydCcpKVxuICAgICAgICAgIH0sIHRpbWVvdXRNcylcbiAgICAgICAgICB0aGlzLndhaXRpbmcuc2V0KGlkeCwge1xuICAgICAgICAgICAgcmVzb2x2ZTogKHYpID0+IChjbGVhclRpbWVvdXQodGltZXIpLCByZXNvbHZlKHYpKSxcbiAgICAgICAgICAgIHJlamVjdDogKGUpID0+IChjbGVhclRpbWVvdXQodGltZXIpLCByZWplY3QoZSkpLFxuICAgICAgICAgIH0pXG4gICAgICAgICAgdGhpcy53cml0ZXIud3JpdGUocHl0aG9uRnJhbWUoY29kZSwgbW9kZSwgaWR4KSkuY2F0Y2goKGU6IEVycm9yKSA9PiB7XG4gICAgICAgICAgICB0aGlzLndhaXRpbmcuZGVsZXRlKGlkeClcbiAgICAgICAgICAgIHJlamVjdChlKVxuICAgICAgICAgIH0pXG4gICAgICAgIH0pLFxuICAgIClcbiAgICB0aGlzLnF1ZXVlID0gbmV4dC5jYXRjaCgoKSA9PiB1bmRlZmluZWQpXG4gICAgcmV0dXJuIG5leHRcbiAgfVxuXG4gIHByaXZhdGUgYXN5bmMgcmVhZExvb3AoKSB7XG4gICAgd2hpbGUgKHRoaXMucG9ydD8ucmVhZGFibGUpIHtcbiAgICAgIGNvbnN0IHJlYWRlciA9IHRoaXMucG9ydC5yZWFkYWJsZS5nZXRSZWFkZXIoKVxuICAgICAgdGhpcy5yZWFkZXIgPSByZWFkZXJcbiAgICAgIHRyeSB7XG4gICAgICAgIGZvciAoOzspIHtcbiAgICAgICAgICBjb25zdCB7IHZhbHVlLCBkb25lIH0gPSBhd2FpdCByZWFkZXIucmVhZCgpXG4gICAgICAgICAgaWYgKGRvbmUpIGJyZWFrXG4gICAgICAgICAgdGhpcy5yeC5wdXNoKC4uLnZhbHVlKVxuICAgICAgICAgIGZvciAoY29uc3QgYm9keSBvZiByZWFkRnJhbWVzKHRoaXMucngpKSB7XG4gICAgICAgICAgICBjb25zdCBmID0gdGhpcy5mcmFtZVdhaXRlcnMuZmluZEluZGV4KCh3KSA9PiB3Lm1hdGNoKGJvZHkpKVxuICAgICAgICAgICAgaWYgKGYgPj0gMCkgdGhpcy5mcmFtZVdhaXRlcnMuc3BsaWNlKGYsIDEpWzBdLnJlc29sdmUoKVxuICAgICAgICAgICAgY29uc3QgYSA9IHNjcmlwdEFuc3dlcihib2R5KVxuICAgICAgICAgICAgaWYgKCFhKSBjb250aW51ZVxuICAgICAgICAgICAgY29uc3QgdyA9IHRoaXMud2FpdGluZy5nZXQoYS5pZHgpXG4gICAgICAgICAgICB0aGlzLndhaXRpbmcuZGVsZXRlKGEuaWR4KVxuICAgICAgICAgICAgdz8ucmVzb2x2ZShhLnZhbHVlKVxuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgfSBjYXRjaCAoZSkge1xuICAgICAgICAvLyBTdMO2cnVuZ2VuIGF1ZiBkZXIgTGVpdHVuZyAoei4gQi4gYmVpbSBOZXVzdGFydCBkZXMgQ3liZXJQaSkgc2luZCBoYXJtbG9zOiBtaXQgbmV1ZW0gTGVzZXIgd2VpdGVyXG4gICAgICAgIGNvbnN0IGhhcm1sZXNzID0gWydCdWZmZXJPdmVycnVuRXJyb3InLCAnRnJhbWluZ0Vycm9yJywgJ0JyZWFrRXJyb3InLCAnUGFyaXR5RXJyb3InXS5pbmNsdWRlcygoZSBhcyBFcnJvcikubmFtZSlcbiAgICAgICAgY29uc29sZS53YXJuKCdbbUJvdDJdIExlc2VmZWhsZXInLCAoZSBhcyBFcnJvcikubmFtZSwgKGUgYXMgRXJyb3IpLm1lc3NhZ2UpXG4gICAgICAgIGlmICghaGFybWxlc3MgJiYgdGhpcy5wb3J0KSB2b2lkIHRoaXMuZGlzY29ubmVjdCgoZSBhcyBFcnJvcikubWVzc2FnZSlcbiAgICAgIH0gZmluYWxseSB7XG4gICAgICAgIHJlYWRlci5yZWxlYXNlTG9jaygpXG4gICAgICB9XG4gICAgICBpZiAoIXRoaXMud3JpdGVyKSBicmVha1xuICAgIH1cbiAgfVxufVxuXG4vKiogRWluZSBWZXJiaW5kdW5nIGbDvHIgZGllIGdhbnplIFNlaXRlIChibGVpYnQgYmVpbSBOZXVhdWZiYXUgZGVyIE9iZXJmbMOkY2hlIGVyaGFsdGVuKS4gKi9cbmV4cG9ydCBjb25zdCBtYm90TGluayA9IG5ldyBNQm90TGluaygpXG4iXSwiZmlsZSI6Ii93ZWIvc3JjL2NvcmUvbWJvdExpbmsudHMifQ== + +//# vitestCache=W3siZmlsZSI6IjEiLCJpZCI6IjEiLCJ1cmwiOiIyIiwiaW1wb3J0cyI6IjMiLCJtYXBwaW5ncyI6ZmFsc2UsImRlcHMiOiI0IiwiZHluYW1pY0RlcHMiOiI1Iiwic3RhdGljTW9ja3MiOm51bGx9LCIvaG9tZS91c2VyL3Zpc3VzdHJ1Y3Qtc3dpZnR1aS93ZWIvc3JjL2NvcmUvbWJvdExpbmsudHMiLCIvd2ViL3NyYy9jb3JlL21ib3RMaW5rLnRzIix7InVybHMiOiI2IiwiaWRzIjoiNyJ9LFtdLFtdLFtdLHt9XQ== \ No newline at end of file diff --git a/node_modules/.vitest-cache/e8414e1454c9436819af0b8d69e3557e442d9777 b/node_modules/.vitest-cache/e8414e1454c9436819af0b8d69e3557e442d9777 new file mode 100644 index 00000000..14ff0247 --- /dev/null +++ b/node_modules/.vitest-cache/e8414e1454c9436819af0b8d69e3557e442d9777 @@ -0,0 +1,200 @@ +__vite_ssr_exportName__("GameFormatError", () => { try { return GameFormatError } catch {} }); +__vite_ssr_exportName__("parseBoolGame", () => { try { return parseBoolGame } catch {} }); +__vite_ssr_exportName__("evaluate", () => { try { return evaluate } catch {} }); +__vite_ssr_exportName__("explain", () => { try { return explain } catch {} }); +__vite_ssr_exportName__("makeRound", () => { try { return makeRound } catch {} }); +__vite_ssr_exportName__("usedValues", () => { try { return usedValues } catch {} }); +class GameFormatError extends Error {}; +/** Zeilen `alter: 8..20`, `schueler: boolean` und `? bedingung`. */ +function parseBoolGame(lines, file) { + const vars = []; + const conditions = []; + for (const raw of lines) { + const line = raw.trim(); + if (!line) continue; + if (line.startsWith("?")) { + const condition = line.slice(1).trim(); + evaluate(condition, sampleValues(vars)); + conditions.push(condition); + continue; + }; + const m = /^([A-Za-z_]\w*)\s*:\s*(?:(-?\d+)\s*\.\.\s*(-?\d+)|(boolean))$/.exec(line); + if (!m) throw new GameFormatError(`${file}: Unbekannte Zeile im Spiel: „${line}“`); + vars.push(m[4] ? { + name: m[1], + kind: "boolean" + } : { + name: m[1], + kind: "int", + min: Number(m[2]), + max: Number(m[3]) + }); + }; + if (!conditions.length) throw new GameFormatError(`${file}: Das Spiel braucht mindestens eine Zeile „? bedingung“.`); + return { + vars, + conditions + }; +}; +function sampleValues(vars) { + return Object.fromEntries(vars.map((v) => [v.name, v.kind === "boolean" ? true : v.min])); +} +function tokenize(text) { + const out = []; + const re = /\s*(?:(\d+)|(true|false)\b|([A-Za-z_]\w*)|(&&|\|\||==|!=|<=|>=|<|>|!|\(|\)))/y; + let pos = 0; + while (pos < text.length) { + if (/^\s*$/.test(text.slice(pos))) break; + re.lastIndex = pos; + const m = re.exec(text); + if (!m) throw new GameFormatError(`Unerwartetes Zeichen in „${text}“ bei „${text.slice(pos)}“`); + pos = re.lastIndex; + if (m[1] !== undefined) out.push({ + kind: "num", + value: Number(m[1]) + }); + else if (m[2] !== undefined) out.push({ + kind: "bool", + value: m[2] === "true" + }); + else if (m[3] !== undefined) out.push({ + kind: "name", + value: m[3] + }); + else out.push({ + kind: "op", + value: m[4] + }); + }; + return out; +} +/** Bedingung mit diesen Werten auswerten (nur ganze Zahlen, Wahrheitswerte, Vergleiche, !, && und ||). */ +function evaluate(text, values) { + const tokens = tokenize(text); + let i = 0; + const peek = () => tokens[i]; + const isOp = (v) => peek()?.kind === "op" && peek().value === v; + const fail = () => { + throw new GameFormatError(`Bedingung nicht lesbar: „${text}“`); + }; + const primary = () => { + const tok = tokens[i++] ?? fail(); + if (tok.kind === "num" || tok.kind === "bool") return tok.value; + if (tok.kind === "name") { + if (!(tok.value in values)) throw new GameFormatError(`Unbekannte Variable „${tok.value}“ in „${text}“`); + return values[tok.value]; + }; + if (tok.value === "(") { + const v = or(); + if (!isOp(")")) fail(); + i++; + return v; + }; + if (tok.value === "!") { + const v = primary(); + if (typeof v !== "boolean") fail(); + return !v; + }; + return fail(); + }; + const comparison = () => { + const left = primary(); + const op = peek(); + if (op?.kind === "op" && [ + "==", + "!=", + "<", + "<=", + ">", + ">=" + ].includes(op.value)) { + i++; + const right = primary(); + switch (op.value) { + case "==": return left === right; + case "!=": return left !== right; + }; + if (typeof left !== "number" || typeof right !== "number") fail(); + const [a, b] = [left, right]; + return op.value === "<" ? a < b : op.value === "<=" ? a <= b : op.value === ">" ? a > b : a >= b; + }; + return left; + }; + const and = () => { + let v = comparison(); + while (isOp("&&")) { + i++; + const r = comparison(); + v = v && r; + }; + return v; + }; + const or = () => { + let v = and(); + while (isOp("||")) { + i++; + const r = and(); + v = v || r; + }; + return v; + }; + const result = or(); + if (i !== tokens.length || typeof result !== "boolean") return fail(); + return result; +}; +// MARK: - Erklären +/** +* Auswertung in Zwischenschritten, z. B. `alter >= 12 && alter < 18` → +* `15 >= 12 && 15 < 18` → `true && true` → `true`. +*/ +function explain(text, values) { + const steps = [text]; + const substituted = text.replace(/\b[A-Za-z_]\w*\b/g, (name) => name in values ? String(values[name]) : name); + if (substituted !== text) steps.push(substituted); + // Jeden Vergleich durch sein Ergebnis ersetzen. + const compared = substituted.replace(/(-?\d+|true|false)\s*(==|!=|<=|>=|<|>)\s*(-?\d+|true|false)/g, (m) => String(evaluate(m, {}))); + if (compared !== steps[steps.length - 1]) steps.push(compared); + const result = String(evaluate(text, values)); + if (result !== steps[steps.length - 1]) steps.push(result); + return steps; +}; +// MARK: - Runden +/** Zahlen, mit denen in der Bedingung verglichen wird: dort und knapp daneben sind die spannenden Fälle. */ +function edgeValues(condition, name) { + const out = []; + const re = new RegExp(`\\b${name}\\s*(?:==|!=|<=|>=|<|>)\\s*(-?\\d+)|(-?\\d+)\\s*(?:==|!=|<=|>=|<|>)\\s*${name}\\b`, "g"); + for (const m of condition.matchAll(re)) { + const c = Number(m[1] ?? m[2]); + out.push(c - 1, c, c + 1); + }; + return out; +} +/** Runde `index` von `count`: je später, desto schwerer die Bedingung. */ +function makeRound(game, index, count, random = Math.random) { + const n = game.conditions.length; + const base = Math.floor(index * n / count); + const pick = Math.min(n - 1, base + (random() < .5 ? 0 : 1)); + const condition = game.conditions[pick]; + const values = {}; + for (const v of game.vars) { + if (v.kind === "boolean") { + values[v.name] = random() < .5; + continue; + }; + const edges = edgeValues(condition, v.name).filter((x) => x >= v.min && x <= v.max); + values[v.name] = edges.length && random() < .6 ? edges[Math.floor(random() * edges.length)] : v.min + Math.floor(random() * (v.max - v.min + 1)); + }; + return { + condition, + values, + answer: evaluate(condition, values) + }; +}; +/** Nur die Variablen, die in der Bedingung vorkommen. */ +function usedValues(round) { + return Object.entries(round.values).filter(([name]) => new RegExp(`\\b${name}\\b`).test(round.condition)); +} +//# sourceMappingSource=vite-generated +//# sourceMappingURL=data:application/json;base64,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LEtBQUssTUFBTyxRQUFRLElBQUssS0FBSztDQUMzQyxNQUFNLE9BQU8sS0FBSyxJQUFJLElBQUksR0FBRyxRQUFRLE9BQU8sSUFBSSxLQUFNLElBQUksRUFBRTtDQUM1RCxNQUFNLFlBQVksS0FBSyxXQUFXO0NBQ2xDLE1BQU0sU0FBaUIsQ0FBQztDQUN4QixLQUFLLE1BQU0sS0FBSyxLQUFLLE1BQU07RUFDekIsSUFBSSxFQUFFLFNBQVMsV0FBVztHQUN4QixPQUFPLEVBQUUsUUFBUSxPQUFPLElBQUk7R0FDNUI7RUFDRjtFQUNBLE1BQU0sUUFBUSxXQUFXLFdBQVcsRUFBRSxJQUFJLENBQUMsQ0FBQyxRQUFRLE1BQU0sS0FBSyxFQUFFLE9BQU8sS0FBSyxFQUFFLEdBQUc7RUFDbEYsT0FBTyxFQUFFLFFBQVEsTUFBTSxVQUFVLE9BQU8sSUFBSSxLQUFNLE1BQU0sS0FBSyxNQUFNLE9BQU8sSUFBSSxNQUFNLE1BQU0sS0FBSyxFQUFFLE1BQU0sS0FBSyxNQUFNLE9BQU8sS0FBSyxFQUFFLE1BQU0sRUFBRSxNQUFNLEVBQUU7Q0FDbEo7Q0FDQSxPQUFPO0VBQUU7RUFBVztFQUFRLFFBQVEsU0FBUyxXQUFXLE1BQU07Q0FBRTtBQUNsRTs7QUFHTyxTQUFTLFdBQVcsT0FBNEM7Q0FDckUsT0FBTyxPQUFPLFFBQVEsTUFBTSxNQUFNLENBQUMsQ0FBQyxRQUFRLENBQUMsVUFBVSxJQUFJLE9BQU8sTUFBTSxLQUFLLElBQUksQ0FBQyxDQUFDLEtBQUssTUFBTSxTQUFTLENBQUM7QUFDMUciLCJuYW1lcyI6W10sImlnbm9yZUxpc3QiOltdLCJzb3VyY2VzIjpbImJvb2xHYW1lLnRzIl0sInNvdXJjZXNDb250ZW50IjpbIi8qKlxuICogU3BpZWwg4oCeV2FociBvZGVyIGZhbHNjaD/igJwgKEJsb2NrIGA6Ojogc3BpZWxgIGltIExlcm5iZXJlaWNoKTogV2VydGUgdW5kIGVpbmUgQmVkaW5ndW5nIHplaWdlbixcbiAqIGRpZSBBbnR3b3J0IHByw7xmZW4gdW5kIGRpZSBBdXN3ZXJ0dW5nIFNjaHJpdHQgZsO8ciBTY2hyaXR0IGVya2zDpHJlbi5cbiAqL1xuXG5leHBvcnQgdHlwZSBHYW1lVmFyID0geyBuYW1lOiBzdHJpbmc7IGtpbmQ6ICdpbnQnOyBtaW46IG51bWJlcjsgbWF4OiBudW1iZXIgfSB8IHsgbmFtZTogc3RyaW5nOyBraW5kOiAnYm9vbGVhbicgfVxuXG5leHBvcnQgaW50ZXJmYWNlIEJvb2xHYW1lIHtcbiAgdmFyczogR2FtZVZhcltdXG4gIC8qKiBCZWRpbmd1bmdlbiB2b20gbGVpY2h0ZW4genVtIHNjaHdlcmVuLiAqL1xuICBjb25kaXRpb25zOiBzdHJpbmdbXVxufVxuXG5leHBvcnQgdHlwZSBWYWx1ZXMgPSBSZWNvcmQ8c3RyaW5nLCBudW1iZXIgfCBib29sZWFuPlxuXG5leHBvcnQgY2xhc3MgR2FtZUZvcm1hdEVycm9yIGV4dGVuZHMgRXJyb3Ige31cblxuLyoqIFplaWxlbiBgYWx0ZXI6IDguLjIwYCwgYHNjaHVlbGVyOiBib29sZWFuYCB1bmQgYD8gYmVkaW5ndW5nYC4gKi9cbmV4cG9ydCBmdW5jdGlvbiBwYXJzZUJvb2xHYW1lKGxpbmVzOiBzdHJpbmdbXSwgZmlsZTogc3RyaW5nKTogQm9vbEdhbWUge1xuICBjb25zdCB2YXJzOiBHYW1lVmFyW10gPSBbXVxuICBjb25zdCBjb25kaXRpb25zOiBzdHJpbmdbXSA9IFtdXG4gIGZvciAoY29uc3QgcmF3IG9mIGxpbmVzKSB7XG4gICAgY29uc3QgbGluZSA9IHJhdy50cmltKClcbiAgICBpZiAoIWxpbmUpIGNvbnRpbnVlXG4gICAgaWYgKGxpbmUuc3RhcnRzV2l0aCgnPycpKSB7XG4gICAgICBjb25zdCBjb25kaXRpb24gPSBsaW5lLnNsaWNlKDEpLnRyaW0oKVxuICAgICAgZXZhbHVhdGUoY29uZGl0aW9uLCBzYW1wbGVWYWx1ZXModmFycykpIC8vIEZlaGxlciBmcsO8aCBtZWxkZW5cbiAgICAgIGNvbmRpdGlvbnMucHVzaChjb25kaXRpb24pXG4gICAgICBjb250aW51ZVxuICAgIH1cbiAgICBjb25zdCBtID0gL14oW0EtWmEtel9dXFx3KilcXHMqOlxccyooPzooLT9cXGQrKVxccypcXC5cXC5cXHMqKC0/XFxkKyl8KGJvb2xlYW4pKSQvLmV4ZWMobGluZSlcbiAgICBpZiAoIW0pIHRocm93IG5ldyBHYW1lRm9ybWF0RXJyb3IoYCR7ZmlsZX06IFVuYmVrYW5udGUgWmVpbGUgaW0gU3BpZWw6IOKAniR7bGluZX3igJxgKVxuICAgIHZhcnMucHVzaChtWzRdID8geyBuYW1lOiBtWzFdLCBraW5kOiAnYm9vbGVhbicgfSA6IHsgbmFtZTogbVsxXSwga2luZDogJ2ludCcsIG1pbjogTnVtYmVyKG1bMl0pLCBtYXg6IE51bWJlcihtWzNdKSB9KVxuICB9XG4gIGlmICghY29uZGl0aW9ucy5sZW5ndGgpIHRocm93IG5ldyBHYW1lRm9ybWF0RXJyb3IoYCR7ZmlsZX06IERhcyBTcGllbCBicmF1Y2h0IG1pbmRlc3RlbnMgZWluZSBaZWlsZSDigJ4/IGJlZGluZ3VuZ+KAnC5gKVxuICByZXR1cm4geyB2YXJzLCBjb25kaXRpb25zIH1cbn1cblxuZnVuY3Rpb24gc2FtcGxlVmFsdWVzKHZhcnM6IEdhbWVWYXJbXSk6IFZhbHVlcyB7XG4gIHJldHVybiBPYmplY3QuZnJvbUVudHJpZXModmFycy5tYXAoKHYpID0+IFt2Lm5hbWUsIHYua2luZCA9PT0gJ2Jvb2xlYW4nID8gdHJ1ZSA6IHYubWluXSkpXG59XG5cbi8vIE1BUks6IC0gQXVzd2VydGVuXG5cbnR5cGUgVG9rZW4gPSB7IGtpbmQ6ICdudW0nOyB2YWx1ZTogbnVtYmVyIH0gfCB7IGtpbmQ6ICdib29sJzsgdmFsdWU6IGJvb2xlYW4gfSB8IHsga2luZDogJ25hbWUnOyB2YWx1ZTogc3RyaW5nIH0gfCB7IGtpbmQ6ICdvcCc7IHZhbHVlOiBzdHJpbmcgfVxuXG5mdW5jdGlvbiB0b2tlbml6ZSh0ZXh0OiBzdHJpbmcpOiBUb2tlbltdIHtcbiAgY29uc3Qgb3V0OiBUb2tlbltdID0gW11cbiAgY29uc3QgcmUgPSAvXFxzKig/OihcXGQrKXwodHJ1ZXxmYWxzZSlcXGJ8KFtBLVphLXpfXVxcdyopfCgmJnxcXHxcXHx8PT18IT18PD18Pj18PHw+fCF8XFwofFxcKSkpL3lcbiAgbGV0IHBvcyA9IDBcbiAgd2hpbGUgKHBvcyA8IHRleHQubGVuZ3RoKSB7XG4gICAgaWYgKC9eXFxzKiQvLnRlc3QodGV4dC5zbGljZShwb3MpKSkgYnJlYWtcbiAgICByZS5sYXN0SW5kZXggPSBwb3NcbiAgICBjb25zdCBtID0gcmUuZXhlYyh0ZXh0KVxuICAgIGlmICghbSkgdGhyb3cgbmV3IEdhbWVGb3JtYXRFcnJvcihgVW5lcndhcnRldGVzIFplaWNoZW4gaW4g4oCeJHt0ZXh0feKAnCBiZWkg4oCeJHt0ZXh0LnNsaWNlKHBvcyl94oCcYClcbiAgICBwb3MgPSByZS5sYXN0SW5kZXhcbiAgICBpZiAobVsxXSAhPT0gdW5kZWZpbmVkKSBvdXQucHVzaCh7IGtpbmQ6ICdudW0nLCB2YWx1ZTogTnVtYmVyKG1bMV0pIH0pXG4gICAgZWxzZSBpZiAobVsyXSAhPT0gdW5kZWZpbmVkKSBvdXQucHVzaCh7IGtpbmQ6ICdib29sJywgdmFsdWU6IG1bMl0gPT09ICd0cnVlJyB9KVxuICAgIGVsc2UgaWYgKG1bM10gIT09IHVuZGVmaW5lZCkgb3V0LnB1c2goeyBraW5kOiAnbmFtZScsIHZhbHVlOiBtWzNdIH0pXG4gICAgZWxzZSBvdXQucHVzaCh7IGtpbmQ6ICdvcCcsIHZhbHVlOiBtWzRdIH0pXG4gIH1cbiAgcmV0dXJuIG91dFxufVxuXG4vKiogQmVkaW5ndW5nIG1pdCBkaWVzZW4gV2VydGVuIGF1c3dlcnRlbiAobnVyIGdhbnplIFphaGxlbiwgV2FocmhlaXRzd2VydGUsIFZlcmdsZWljaGUsICEsICYmIHVuZCB8fCkuICovXG5leHBvcnQgZnVuY3Rpb24gZXZhbHVhdGUodGV4dDogc3RyaW5nLCB2YWx1ZXM6IFZhbHVlcyk6IGJvb2xlYW4ge1xuICBjb25zdCB0b2tlbnMgPSB0b2tlbml6ZSh0ZXh0KVxuICBsZXQgaSA9IDBcbiAgY29uc3QgcGVlayA9ICgpID0+IHRva2Vuc1tpXVxuICBjb25zdCBpc09wID0gKHY6IHN0cmluZykgPT4gcGVlaygpPy5raW5kID09PSAnb3AnICYmIHBlZWsoKSEudmFsdWUgPT09IHZcbiAgY29uc3QgZmFpbCA9ICgpOiBuZXZlciA9PiB7XG4gICAgdGhyb3cgbmV3IEdhbWVGb3JtYXRFcnJvcihgQmVkaW5ndW5nIG5pY2h0IGxlc2Jhcjog4oCeJHt0ZXh0feKAnGApXG4gIH1cblxuICBjb25zdCBwcmltYXJ5ID0gKCk6IG51bWJlciB8IGJvb2xlYW4gPT4ge1xuICAgIGNvbnN0IHRvayA9IHRva2Vuc1tpKytdID8/IGZhaWwoKVxuICAgIGlmICh0b2sua2luZCA9PT0gJ251bScgfHwgdG9rLmtpbmQgPT09ICdib29sJykgcmV0dXJuIHRvay52YWx1ZVxuICAgIGlmICh0b2sua2luZCA9PT0gJ25hbWUnKSB7XG4gICAgICBpZiAoISh0b2sudmFsdWUgaW4gdmFsdWVzKSkgdGhyb3cgbmV3IEdhbWVGb3JtYXRFcnJvcihgVW5iZWthbm50ZSBWYXJpYWJsZSDigJ4ke3Rvay52YWx1ZX3igJwgaW4g4oCeJHt0ZXh0feKAnGApXG4gICAgICByZXR1cm4gdmFsdWVzW3Rvay52YWx1ZV1cbiAgICB9XG4gICAgaWYgKHRvay52YWx1ZSA9PT0gJygnKSB7XG4gICAgICBjb25zdCB2ID0gb3IoKVxuICAgICAgaWYgKCFpc09wKCcpJykpIGZhaWwoKVxuICAgICAgaSsrXG4gICAgICByZXR1cm4gdlxuICAgIH1cbiAgICBpZiAodG9rLnZhbHVlID09PSAnIScpIHtcbiAgICAgIGNvbnN0IHYgPSBwcmltYXJ5KClcbiAgICAgIGlmICh0eXBlb2YgdiAhPT0gJ2Jvb2xlYW4nKSBmYWlsKClcbiAgICAgIHJldHVybiAhdlxuICAgIH1cbiAgICByZXR1cm4gZmFpbCgpXG4gIH1cbiAgY29uc3QgY29tcGFyaXNvbiA9ICgpOiBudW1iZXIgfCBib29sZWFuID0+IHtcbiAgICBjb25zdCBsZWZ0ID0gcHJpbWFyeSgpXG4gICAgY29uc3Qgb3AgPSBwZWVrKClcbiAgICBpZiAob3A/LmtpbmQgPT09ICdvcCcgJiYgWyc9PScsICchPScsICc8JywgJzw9JywgJz4nLCAnPj0nXS5pbmNsdWRlcyhvcC52YWx1ZSkpIHtcbiAgICAgIGkrK1xuICAgICAgY29uc3QgcmlnaHQgPSBwcmltYXJ5KClcbiAgICAgIHN3aXRjaCAob3AudmFsdWUpIHtcbiAgICAgICAgY2FzZSAnPT0nOlxuICAgICAgICAgIHJldHVybiBsZWZ0ID09PSByaWdodFxuICAgICAgICBjYXNlICchPSc6XG4gICAgICAgICAgcmV0dXJuIGxlZnQgIT09IHJpZ2h0XG4gICAgICB9XG4gICAgICBpZiAodHlwZW9mIGxlZnQgIT09ICdudW1iZXInIHx8IHR5cGVvZiByaWdodCAhPT0gJ251bWJlcicpIGZhaWwoKVxuICAgICAgY29uc3QgW2EsIGJdID0gW2xlZnQgYXMgbnVtYmVyLCByaWdodCBhcyBudW1iZXJdXG4gICAgICByZXR1cm4gb3AudmFsdWUgPT09ICc8JyA/IGEgPCBiIDogb3AudmFsdWUgPT09ICc8PScgPyBhIDw9IGIgOiBvcC52YWx1ZSA9PT0gJz4nID8gYSA+IGIgOiBhID49IGJcbiAgICB9XG4gICAgcmV0dXJuIGxlZnRcbiAgfVxuICBjb25zdCBhbmQgPSAoKTogbnVtYmVyIHwgYm9vbGVhbiA9PiB7XG4gICAgbGV0IHYgPSBjb21wYXJpc29uKClcbiAgICB3aGlsZSAoaXNPcCgnJiYnKSkge1xuICAgICAgaSsrXG4gICAgICBjb25zdCByID0gY29tcGFyaXNvbigpXG4gICAgICB2ID0gKHYgYXMgYm9vbGVhbikgJiYgKHIgYXMgYm9vbGVhbilcbiAgICB9XG4gICAgcmV0dXJuIHZcbiAgfVxuICBjb25zdCBvciA9ICgpOiBudW1iZXIgfCBib29sZWFuID0+IHtcbiAgICBsZXQgdiA9IGFuZCgpXG4gICAgd2hpbGUgKGlzT3AoJ3x8JykpIHtcbiAgICAgIGkrK1xuICAgICAgY29uc3QgciA9IGFuZCgpXG4gICAgICB2ID0gKHYgYXMgYm9vbGVhbikgfHwgKHIgYXMgYm9vbGVhbilcbiAgICB9XG4gICAgcmV0dXJuIHZcbiAgfVxuICBjb25zdCByZXN1bHQgPSBvcigpXG4gIGlmIChpICE9PSB0b2tlbnMubGVuZ3RoIHx8IHR5cGVvZiByZXN1bHQgIT09ICdib29sZWFuJykgcmV0dXJuIGZhaWwoKVxuICByZXR1cm4gcmVzdWx0XG59XG5cbi8vIE1BUks6IC0gRXJrbMOkcmVuXG5cbi8qKlxuICogQXVzd2VydHVuZyBpbiBad2lzY2hlbnNjaHJpdHRlbiwgei4gQi4gYGFsdGVyID49IDEyICYmIGFsdGVyIDwgMThgIOKGklxuICogYDE1ID49IDEyICYmIDE1IDwgMThgIOKGkiBgdHJ1ZSAmJiB0cnVlYCDihpIgYHRydWVgLlxuICovXG5leHBvcnQgZnVuY3Rpb24gZXhwbGFpbih0ZXh0OiBzdHJpbmcsIHZhbHVlczogVmFsdWVzKTogc3RyaW5nW10ge1xuICBjb25zdCBzdGVwcyA9IFt0ZXh0XVxuICBjb25zdCBzdWJzdGl0dXRlZCA9IHRleHQucmVwbGFjZSgvXFxiW0EtWmEtel9dXFx3KlxcYi9nLCAobmFtZSkgPT4gKG5hbWUgaW4gdmFsdWVzID8gU3RyaW5nKHZhbHVlc1tuYW1lXSkgOiBuYW1lKSlcbiAgaWYgKHN1YnN0aXR1dGVkICE9PSB0ZXh0KSBzdGVwcy5wdXNoKHN1YnN0aXR1dGVkKVxuICAvLyBKZWRlbiBWZXJnbGVpY2ggZHVyY2ggc2VpbiBFcmdlYm5pcyBlcnNldHplbi5cbiAgY29uc3QgY29tcGFyZWQgPSBzdWJzdGl0dXRlZC5yZXBsYWNlKC8oLT9cXGQrfHRydWV8ZmFsc2UpXFxzKig9PXwhPXw8PXw+PXw8fD4pXFxzKigtP1xcZCt8dHJ1ZXxmYWxzZSkvZywgKG0pID0+IFN0cmluZyhldmFsdWF0ZShtLCB7fSkpKVxuICBpZiAoY29tcGFyZWQgIT09IHN0ZXBzW3N0ZXBzLmxlbmd0aCAtIDFdKSBzdGVwcy5wdXNoKGNvbXBhcmVkKVxuICBjb25zdCByZXN1bHQgPSBTdHJpbmcoZXZhbHVhdGUodGV4dCwgdmFsdWVzKSlcbiAgaWYgKHJlc3VsdCAhPT0gc3RlcHNbc3RlcHMubGVuZ3RoIC0gMV0pIHN0ZXBzLnB1c2gocmVzdWx0KVxuICByZXR1cm4gc3RlcHNcbn1cblxuLy8gTUFSSzogLSBSdW5kZW5cblxuLyoqIFphaGxlbiwgbWl0IGRlbmVuIGluIGRlciBCZWRpbmd1bmcgdmVyZ2xpY2hlbiB3aXJkOiBkb3J0IHVuZCBrbmFwcCBkYW5lYmVuIHNpbmQgZGllIHNwYW5uZW5kZW4gRsOkbGxlLiAqL1xuZnVuY3Rpb24gZWRnZVZhbHVlcyhjb25kaXRpb246IHN0cmluZywgbmFtZTogc3RyaW5nKTogbnVtYmVyW10ge1xuICBjb25zdCBvdXQ6IG51bWJlcltdID0gW11cbiAgY29uc3QgcmUgPSBuZXcgUmVnRXhwKGBcXFxcYiR7bmFtZX1cXFxccyooPzo9PXwhPXw8PXw+PXw8fD4pXFxcXHMqKC0/XFxcXGQrKXwoLT9cXFxcZCspXFxcXHMqKD86PT18IT18PD18Pj18PHw+KVxcXFxzKiR7bmFtZX1cXFxcYmAsICdnJylcbiAgZm9yIChjb25zdCBtIG9mIGNvbmRpdGlvbi5tYXRjaEFsbChyZSkpIHtcbiAgICBjb25zdCBjID0gTnVtYmVyKG1bMV0gPz8gbVsyXSlcbiAgICBvdXQucHVzaChjIC0gMSwgYywgYyArIDEpXG4gIH1cbiAgcmV0dXJuIG91dFxufVxuXG5leHBvcnQgaW50ZXJmYWNlIFJvdW5kIHtcbiAgY29uZGl0aW9uOiBzdHJpbmdcbiAgdmFsdWVzOiBWYWx1ZXNcbiAgYW5zd2VyOiBib29sZWFuXG59XG5cbi8qKiBSdW5kZSBgaW5kZXhgIHZvbiBgY291bnRgOiBqZSBzcMOkdGVyLCBkZXN0byBzY2h3ZXJlciBkaWUgQmVkaW5ndW5nLiAqL1xuZXhwb3J0IGZ1bmN0aW9uIG1ha2VSb3VuZChnYW1lOiBCb29sR2FtZSwgaW5kZXg6IG51bWJlciwgY291bnQ6IG51bWJlciwgcmFuZG9tOiAoKSA9PiBudW1iZXIgPSBNYXRoLnJhbmRvbSk6IFJvdW5kIHtcbiAgY29uc3QgbiA9IGdhbWUuY29uZGl0aW9ucy5sZW5ndGhcbiAgY29uc3QgYmFzZSA9IE1hdGguZmxvb3IoKGluZGV4ICogbikgLyBjb3VudClcbiAgY29uc3QgcGljayA9IE1hdGgubWluKG4gLSAxLCBiYXNlICsgKHJhbmRvbSgpIDwgMC41ID8gMCA6IDEpKVxuICBjb25zdCBjb25kaXRpb24gPSBnYW1lLmNvbmRpdGlvbnNbcGlja11cbiAgY29uc3QgdmFsdWVzOiBWYWx1ZXMgPSB7fVxuICBmb3IgKGNvbnN0IHYgb2YgZ2FtZS52YXJzKSB7XG4gICAgaWYgKHYua2luZCA9PT0gJ2Jvb2xlYW4nKSB7XG4gICAgICB2YWx1ZXNbdi5uYW1lXSA9IHJhbmRvbSgpIDwgMC41XG4gICAgICBjb250aW51ZVxuICAgIH1cbiAgICBjb25zdCBlZGdlcyA9IGVkZ2VWYWx1ZXMoY29uZGl0aW9uLCB2Lm5hbWUpLmZpbHRlcigoeCkgPT4geCA+PSB2Lm1pbiAmJiB4IDw9IHYubWF4KVxuICAgIHZhbHVlc1t2Lm5hbWVdID0gZWRnZXMubGVuZ3RoICYmIHJhbmRvbSgpIDwgMC42ID8gZWRnZXNbTWF0aC5mbG9vcihyYW5kb20oKSAqIGVkZ2VzLmxlbmd0aCldIDogdi5taW4gKyBNYXRoLmZsb29yKHJhbmRvbSgpICogKHYubWF4IC0gdi5taW4gKyAxKSlcbiAgfVxuICByZXR1cm4geyBjb25kaXRpb24sIHZhbHVlcywgYW5zd2VyOiBldmFsdWF0ZShjb25kaXRpb24sIHZhbHVlcykgfVxufVxuXG4vKiogTnVyIGRpZSBWYXJpYWJsZW4sIGRpZSBpbiBkZXIgQmVkaW5ndW5nIHZvcmtvbW1lbi4gKi9cbmV4cG9ydCBmdW5jdGlvbiB1c2VkVmFsdWVzKHJvdW5kOiBSb3VuZCk6IFtzdHJpbmcsIG51bWJlciB8IGJvb2xlYW5dW10ge1xuICByZXR1cm4gT2JqZWN0LmVudHJpZXMocm91bmQudmFsdWVzKS5maWx0ZXIoKFtuYW1lXSkgPT4gbmV3IFJlZ0V4cChgXFxcXGIke25hbWV9XFxcXGJgKS50ZXN0KHJvdW5kLmNvbmRpdGlvbikpXG59XG4iXSwiZmlsZSI6Ii93ZWIvc3JjL2xlYXJuL2Jvb2xHYW1lLnRzIn0= + +//# vitestCache=W3siZmlsZSI6IjEiLCJpZCI6IjEiLCJ1cmwiOiIyIiwiaW1wb3J0cyI6IjMiLCJtYXBwaW5ncyI6ZmFsc2UsImRlcHMiOiI0IiwiZHluYW1pY0RlcHMiOiI1Iiwic3RhdGljTW9ja3MiOm51bGx9LCIvaG9tZS91c2VyL3Zpc3VzdHJ1Y3Qtc3dpZnR1aS93ZWIvc3JjL2xlYXJuL2Jvb2xHYW1lLnRzIiwiL3dlYi9zcmMvbGVhcm4vYm9vbEdhbWUudHMiLHsidXJscyI6IjYiLCJpZHMiOiI3In0sW10sW10sW10se31d \ No newline at end of file diff --git a/node_modules/.vitest-cache/ead0aad5e88b12ac47bd410f9cc055bc1ed9a667 b/node_modules/.vitest-cache/ead0aad5e88b12ac47bd410f9cc055bc1ed9a667 new file mode 100644 index 00000000..8d536e21 --- /dev/null +++ b/node_modules/.vitest-cache/ead0aad5e88b12ac47bd410f9cc055bc1ed9a667 @@ -0,0 +1,83 @@ +__vite_ssr_exportName__("parseCloze", () => { try { return parseCloze } catch {} }); +__vite_ssr_exportName__("clozeGaps", () => { try { return clozeGaps } catch {} }); +__vite_ssr_exportName__("clozeAnswerRight", () => { try { return clozeAnswerRight } catch {} }); +const gapPattern = /\[\[(.+?)\]\]/g; +function parseCloze(inner, file) { + const cloze = { + title: "", + task: "", + blocks: [] + }; + const codes = []; + let inCode = false; + for (const raw of inner) { + if (/^\s*```/.test(raw)) { + if (!inCode) codes.push([]); + inCode = !inCode; + continue; + }; + if (inCode) { + codes[codes.length - 1].push(raw.replace(/\s+$/, "")); + continue; + }; + const line = raw.trim(); + if (!line) continue; + const m = /^([a-zäöü]+):\s*(.*)$/i.exec(line); + if (!m) throw new Error(`${file}: Unbekannte Zeile im Lückentext: „${line}“.`); + const value = m[2].trim(); + switch (m[1].toLowerCase()) { + case "titel": + cloze.title = value; + break; + case "auftrag": + cloze.task = value; + break; + case "erklärung": + case "erklaerung": + cloze.explanation = value; + break; + default: throw new Error(`${file}: Unbekannter Schlüssel „${m[1]}“ im Lückentext.`); + } + }; + if (inCode) throw new Error(`${file}: Der Codeblock im Lückentext wird nicht mit \`\`\` geschlossen.`); + if (!cloze.title) throw new Error(`${file}: Ein Lückentext braucht einen Titel.`); + if (!codes.some((c) => c.some((l) => l.trim()))) throw new Error(`${file}: Lückentext „${cloze.title}“ braucht einen Codeblock.`); + cloze.blocks = codes.map((code) => { + // Gemeinsame Einrückung entfernen, damit der Code links beginnt. + const indent = Math.min(...code.filter((l) => l.trim()).map((l) => /^ */.exec(l)[0].length)); + return code.map((l) => splitGaps(l.slice(indent), file, cloze.title)); + }); + if (!clozeGaps(cloze).length) { + throw new Error(`${file}: Lückentext „${cloze.title}“ braucht mindestens eine Lücke [[…]].`); + }; + return cloze; +}; +function splitGaps(line, file, title) { + const parts = []; + let at = 0; + for (const m of line.matchAll(gapPattern)) { + if (m.index > at) parts.push(line.slice(at, m.index)); + const answers = m[1].split(/\s+\|\s+/).map((a) => a.trim()).filter(Boolean); + if (!answers.length) throw new Error(`${file}: Leere Lücke im Lückentext „${title}“.`); + parts.push({ answers }); + at = m.index + m[0].length; + }; + if (at < line.length) parts.push(line.slice(at)); + if (parts.some((p) => typeof p === "string" && (p.includes("[[") || p.includes("]]")))) { + throw new Error(`${file}: Unvollständige Lücke im Lückentext „${title}“: „${line}“.`); + }; + return parts; +} +/** Alle Lücken in Reihenfolge. */ +function clozeGaps(cloze) { + return cloze.blocks.flat().flatMap((l) => l.flatMap((p) => typeof p === "string" ? [] : [p.answers])); +}; +/** Leerzeichen zählen nicht: `i = i + 1` und `i=i+1` sind gleich. Groß/klein zählt (wie in Java). */ +function clozeAnswerRight(answers, input) { + const norm = (s) => s.replace(/\s+/g, ""); + return norm(input) !== "" && answers.some((a) => norm(a) === norm(input)); +} +//# sourceMappingSource=vite-generated +//# sourceMappingURL=data:application/json;base64,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QUssTUFBTSxFQUFFLENBQUM7Q0FDL0MsSUFBSSxNQUFNLE1BQU0sTUFBTSxPQUFPLE1BQU0sYUFBYSxFQUFFLFNBQVMsSUFBSSxLQUFLLEVBQUUsU0FBUyxJQUFJLEVBQUUsR0FBRztFQUN0RixNQUFNLElBQUksTUFBTSxHQUFHLEtBQUssd0NBQXdDLE1BQU0sTUFBTSxLQUFLLEdBQUc7Q0FDdEY7Q0FDQSxPQUFPO0FBQ1Q7O0FBR08sU0FBUyxVQUFVLE9BQTBCO0NBQ2xELE9BQU8sTUFBTSxPQUFPLEtBQUssQ0FBQyxDQUFDLFNBQVMsTUFBTSxFQUFFLFNBQVMsTUFBTyxPQUFPLE1BQU0sV0FBVyxDQUFDLElBQUksQ0FBQyxFQUFFLE9BQU8sQ0FBRSxDQUFDO0FBQ3hHOztBQUdPLFNBQVMsaUJBQWlCLFNBQW1CLE9BQXdCO0NBQzFFLE1BQU0sUUFBUSxNQUFjLEVBQUUsUUFBUSxRQUFRLEVBQUU7Q0FDaEQsT0FBTyxLQUFLLEtBQUssTUFBTSxNQUFNLFFBQVEsTUFBTSxNQUFNLEtBQUssQ0FBQyxNQUFNLEtBQUssS0FBSyxDQUFDO0FBQzFFIiwibmFtZXMiOltdLCJpZ25vcmVMaXN0IjpbXSwic291cmNlcyI6WyJjbG96ZS50cyJdLCJzb3VyY2VzQ29udGVudCI6WyIvKipcbiAqIEzDvGNrZW50ZXh0OiBmZXJ0aWdlciBDb2RlLCBpbiBkZW0gZWluemVsbmUgV8O2cnRlciBmZWhsZW4uXG4gKlxuICogICAgIDo6OiBsw7xja2VudGV4dFxuICogICAgIHRpdGVsOiBMw7xja2VudGV4dDogWsOkaGxzY2hsZWlmZVxuICogICAgIGF1ZnRyYWc6IEVyZ8OkbnplIGRpZSBmZWhsZW5kZW4gV8O2cnRlci5cbiAqICAgICBgYGBqYXZhXG4gKiAgICAgZm9yIChbW2ludF1dIGkgPSAxOyBpIFtbPD1dXSAxMDsgW1tpKysgfCBpICs9IDEgfCBpID0gaSArIDFdXSkge1xuICogICAgIGBgYFxuICogICAgIGVya2zDpHJ1bmc6IFdpcmQgZ2V6ZWlndCwgd2VubiBhbGxlIEzDvGNrZW4gc3RpbW1lbi5cbiAqICAgICA6OjpcbiAqXG4gKiBNZWhyZXJlIENvZGVibMO2Y2tlIHN0ZWhlbiB1bnRlcmVpbmFuZGVyLCB6LiBCLiBlaW5lIE1ldGhvZGUgdW5kIGRhcyBIYXVwdHByb2dyYW1tLlxuICogYFtbYV1dYCBpc3QgZWluZSBMw7xja2UuIFdlaXRlcmUgcmljaHRpZ2UgQW50d29ydGVuIHN0ZWhlbiBtaXQgYCB8IGAgKExlZXJ6ZWljaGVuIGRhdm9yIHVuZCBkYW5hY2gpXG4gKiBkYWhpbnRlciwgZGFtaXQgYHx8YCB1bmQgYHxgIHNlbGJzdCBhbHMgQW50d29ydCBnZWhlbjogYFtbaSsrIHwgaSArPSAxXV1gLlxuICovXG5leHBvcnQgaW50ZXJmYWNlIENsb3plIHtcbiAgdGl0bGU6IHN0cmluZ1xuICB0YXNrOiBzdHJpbmdcbiAgLyoqIENvZGVibMO2Y2tlICh6LiBCLiBNZXRob2RlIHVuZCBIYXVwdHByb2dyYW1tIHdpZSBpbiBlaWdlbmVuIFJlaXRlcm4pLCBkYXJpbiBaZWlsZW4gYXVzIFRleHQgdW5kIEzDvGNrZW4uICovXG4gIGJsb2NrczogQ2xvemVQYXJ0W11bXVtdXG4gIGV4cGxhbmF0aW9uPzogc3RyaW5nXG59XG5cbmV4cG9ydCB0eXBlIENsb3plUGFydCA9IHN0cmluZyB8IHsgYW5zd2Vyczogc3RyaW5nW10gfVxuXG5jb25zdCBnYXBQYXR0ZXJuID0gL1xcW1xcWyguKz8pXFxdXFxdL2dcblxuZXhwb3J0IGZ1bmN0aW9uIHBhcnNlQ2xvemUoaW5uZXI6IHN0cmluZ1tdLCBmaWxlOiBzdHJpbmcpOiBDbG96ZSB7XG4gIGNvbnN0IGNsb3plOiBDbG96ZSA9IHsgdGl0bGU6ICcnLCB0YXNrOiAnJywgYmxvY2tzOiBbXSB9XG4gIGNvbnN0IGNvZGVzOiBzdHJpbmdbXVtdID0gW11cbiAgbGV0IGluQ29kZSA9IGZhbHNlXG4gIGZvciAoY29uc3QgcmF3IG9mIGlubmVyKSB7XG4gICAgaWYgKC9eXFxzKmBgYC8udGVzdChyYXcpKSB7XG4gICAgICBpZiAoIWluQ29kZSkgY29kZXMucHVzaChbXSlcbiAgICAgIGluQ29kZSA9ICFpbkNvZGVcbiAgICAgIGNvbnRpbnVlXG4gICAgfVxuICAgIGlmIChpbkNvZGUpIHtcbiAgICAgIGNvZGVzW2NvZGVzLmxlbmd0aCAtIDFdLnB1c2gocmF3LnJlcGxhY2UoL1xccyskLywgJycpKVxuICAgICAgY29udGludWVcbiAgICB9XG4gICAgY29uc3QgbGluZSA9IHJhdy50cmltKClcbiAgICBpZiAoIWxpbmUpIGNvbnRpbnVlXG4gICAgY29uc3QgbSA9IC9eKFthLXrDpMO2w7xdKyk6XFxzKiguKikkL2kuZXhlYyhsaW5lKVxuICAgIGlmICghbSkgdGhyb3cgbmV3IEVycm9yKGAke2ZpbGV9OiBVbmJla2FubnRlIFplaWxlIGltIEzDvGNrZW50ZXh0OiDigJ4ke2xpbmV94oCcLmApXG4gICAgY29uc3QgdmFsdWUgPSBtWzJdLnRyaW0oKVxuICAgIHN3aXRjaCAobVsxXS50b0xvd2VyQ2FzZSgpKSB7XG4gICAgICBjYXNlICd0aXRlbCc6IGNsb3plLnRpdGxlID0gdmFsdWU7IGJyZWFrXG4gICAgICBjYXNlICdhdWZ0cmFnJzogY2xvemUudGFzayA9IHZhbHVlOyBicmVha1xuICAgICAgY2FzZSAnZXJrbMOkcnVuZyc6XG4gICAgICBjYXNlICdlcmtsYWVydW5nJzogY2xvemUuZXhwbGFuYXRpb24gPSB2YWx1ZTsgYnJlYWtcbiAgICAgIGRlZmF1bHQ6IHRocm93IG5ldyBFcnJvcihgJHtmaWxlfTogVW5iZWthbm50ZXIgU2NobMO8c3NlbCDigJ4ke21bMV194oCcIGltIEzDvGNrZW50ZXh0LmApXG4gICAgfVxuICB9XG4gIGlmIChpbkNvZGUpIHRocm93IG5ldyBFcnJvcihgJHtmaWxlfTogRGVyIENvZGVibG9jayBpbSBMw7xja2VudGV4dCB3aXJkIG5pY2h0IG1pdCBcXGBcXGBcXGAgZ2VzY2hsb3NzZW4uYClcbiAgaWYgKCFjbG96ZS50aXRsZSkgdGhyb3cgbmV3IEVycm9yKGAke2ZpbGV9OiBFaW4gTMO8Y2tlbnRleHQgYnJhdWNodCBlaW5lbiBUaXRlbC5gKVxuICBpZiAoIWNvZGVzLnNvbWUoKGMpID0+IGMuc29tZSgobCkgPT4gbC50cmltKCkpKSkgdGhyb3cgbmV3IEVycm9yKGAke2ZpbGV9OiBMw7xja2VudGV4dCDigJ4ke2Nsb3plLnRpdGxlfeKAnCBicmF1Y2h0IGVpbmVuIENvZGVibG9jay5gKVxuICBjbG96ZS5ibG9ja3MgPSBjb2Rlcy5tYXAoKGNvZGUpID0+IHtcbiAgICAvLyBHZW1laW5zYW1lIEVpbnLDvGNrdW5nIGVudGZlcm5lbiwgZGFtaXQgZGVyIENvZGUgbGlua3MgYmVnaW5udC5cbiAgICBjb25zdCBpbmRlbnQgPSBNYXRoLm1pbiguLi5jb2RlLmZpbHRlcigobCkgPT4gbC50cmltKCkpLm1hcCgobCkgPT4gL14gKi8uZXhlYyhsKSFbMF0ubGVuZ3RoKSlcbiAgICByZXR1cm4gY29kZS5tYXAoKGwpID0+IHNwbGl0R2FwcyhsLnNsaWNlKGluZGVudCksIGZpbGUsIGNsb3plLnRpdGxlKSlcbiAgfSlcbiAgaWYgKCFjbG96ZUdhcHMoY2xvemUpLmxlbmd0aCkge1xuICAgIHRocm93IG5ldyBFcnJvcihgJHtmaWxlfTogTMO8Y2tlbnRleHQg4oCeJHtjbG96ZS50aXRsZX3igJwgYnJhdWNodCBtaW5kZXN0ZW5zIGVpbmUgTMO8Y2tlIFtb4oCmXV0uYClcbiAgfVxuICByZXR1cm4gY2xvemVcbn1cblxuZnVuY3Rpb24gc3BsaXRHYXBzKGxpbmU6IHN0cmluZywgZmlsZTogc3RyaW5nLCB0aXRsZTogc3RyaW5nKTogQ2xvemVQYXJ0W10ge1xuICBjb25zdCBwYXJ0czogQ2xvemVQYXJ0W10gPSBbXVxuICBsZXQgYXQgPSAwXG4gIGZvciAoY29uc3QgbSBvZiBsaW5lLm1hdGNoQWxsKGdhcFBhdHRlcm4pKSB7XG4gICAgaWYgKG0uaW5kZXghID4gYXQpIHBhcnRzLnB1c2gobGluZS5zbGljZShhdCwgbS5pbmRleCkpXG4gICAgY29uc3QgYW5zd2VycyA9IG1bMV0uc3BsaXQoL1xccytcXHxcXHMrLykubWFwKChhKSA9PiBhLnRyaW0oKSkuZmlsdGVyKEJvb2xlYW4pXG4gICAgaWYgKCFhbnN3ZXJzLmxlbmd0aCkgdGhyb3cgbmV3IEVycm9yKGAke2ZpbGV9OiBMZWVyZSBMw7xja2UgaW0gTMO8Y2tlbnRleHQg4oCeJHt0aXRsZX3igJwuYClcbiAgICBwYXJ0cy5wdXNoKHsgYW5zd2VycyB9KVxuICAgIGF0ID0gbS5pbmRleCEgKyBtWzBdLmxlbmd0aFxuICB9XG4gIGlmIChhdCA8IGxpbmUubGVuZ3RoKSBwYXJ0cy5wdXNoKGxpbmUuc2xpY2UoYXQpKVxuICBpZiAocGFydHMuc29tZSgocCkgPT4gdHlwZW9mIHAgPT09ICdzdHJpbmcnICYmIChwLmluY2x1ZGVzKCdbWycpIHx8IHAuaW5jbHVkZXMoJ11dJykpKSkge1xuICAgIHRocm93IG5ldyBFcnJvcihgJHtmaWxlfTogVW52b2xsc3TDpG5kaWdlIEzDvGNrZSBpbSBMw7xja2VudGV4dCDigJ4ke3RpdGxlfeKAnDog4oCeJHtsaW5lfeKAnC5gKVxuICB9XG4gIHJldHVybiBwYXJ0c1xufVxuXG4vKiogQWxsZSBMw7xja2VuIGluIFJlaWhlbmZvbGdlLiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGNsb3plR2FwcyhjbG96ZTogQ2xvemUpOiBzdHJpbmdbXVtdIHtcbiAgcmV0dXJuIGNsb3plLmJsb2Nrcy5mbGF0KCkuZmxhdE1hcCgobCkgPT4gbC5mbGF0TWFwKChwKSA9PiAodHlwZW9mIHAgPT09ICdzdHJpbmcnID8gW10gOiBbcC5hbnN3ZXJzXSkpKVxufVxuXG4vKiogTGVlcnplaWNoZW4gesOkaGxlbiBuaWNodDogYGkgPSBpICsgMWAgdW5kIGBpPWkrMWAgc2luZCBnbGVpY2guIEdyb8OfL2tsZWluIHrDpGhsdCAod2llIGluIEphdmEpLiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGNsb3plQW5zd2VyUmlnaHQoYW5zd2Vyczogc3RyaW5nW10sIGlucHV0OiBzdHJpbmcpOiBib29sZWFuIHtcbiAgY29uc3Qgbm9ybSA9IChzOiBzdHJpbmcpID0+IHMucmVwbGFjZSgvXFxzKy9nLCAnJylcbiAgcmV0dXJuIG5vcm0oaW5wdXQpICE9PSAnJyAmJiBhbnN3ZXJzLnNvbWUoKGEpID0+IG5vcm0oYSkgPT09IG5vcm0oaW5wdXQpKVxufVxuIl0sImZpbGUiOiIvd2ViL3NyYy9sZWFybi9jbG96ZS50cyJ9 + +//# vitestCache=W3siZmlsZSI6IjEiLCJpZCI6IjEiLCJ1cmwiOiIyIiwiaW1wb3J0cyI6IjMiLCJtYXBwaW5ncyI6ZmFsc2UsImRlcHMiOiI0IiwiZHluYW1pY0RlcHMiOiI1Iiwic3RhdGljTW9ja3MiOm51bGx9LCIvaG9tZS91c2VyL3Zpc3VzdHJ1Y3Qtc3dpZnR1aS93ZWIvc3JjL2xlYXJuL2Nsb3plLnRzIiwiL3dlYi9zcmMvbGVhcm4vY2xvemUudHMiLHsidXJscyI6IjYiLCJpZHMiOiI3In0sW10sW10sW10se31d \ No newline at end of file diff --git a/web/lessons/README.md b/web/lessons/README.md index 19ab0d8a..91b0e65d 100644 --- a/web/lessons/README.md +++ b/web/lessons/README.md @@ -168,6 +168,15 @@ Ben Shneiderman hatte die Idee 1972. [Mehr dazu](https://visustruct.org/de/angeb ::: ``` +Ein Kasten „Profiwissen mit Ludwig“ sieht genauso aus, ist aber für Profi-Tipps über den Unterricht hinaus, zum Beispiel +Befehle in der Konsole: + +``` +::: profiwissen +`java -version` zeigt, welche Java-Version installiert ist. +::: +``` + Ein Spiel „Wahr oder falsch?“: oben die Variablen (`name: von..bis` für ganze Zahlen, `name: boolean`), darunter mit `?` die Bedingungen vom leichten zum schweren. Zehn Runden; Werte knapp an den Grenzen der Vergleiche kommen öfter vor: diff --git a/web/lessons/de/20-java.md b/web/lessons/de/20-java.md index 2e705e99..1f00dc89 100644 --- a/web/lessons/de/20-java.md +++ b/web/lessons/de/20-java.md @@ -119,12 +119,16 @@ Deine Datei `Einmaleins.java` ist **Quellcode**: Text für Menschen. Der Prozess 2. Die **JVM** (Java Virtual Machine) liest den Bytecode und übersetzt ihn beim Ausführen in **Maschinencode**, also in Befehle für den Prozessor deines Computers. ::: grafik l20-jvm.svg +Einmal kompilieren: Derselbe Bytecode läuft auf jeder JVM. +::: Den Bytecode gibt es nur einmal. Die JVM gibt es dagegen für Windows, macOS, Linux und viele andere Systeme. Deshalb läuft dieselbe `.class`-Datei auf jedem Computer, auf dem eine JVM installiert ist. Das nennt man **plattformunabhängig**. Der Werbespruch dazu heißt **„Write once, run anywhere“**: einmal schreiben, überall ausführen. Zum Vergleich **C++**: Dort übersetzt der Compiler den Quellcode direkt in Maschinencode für genau einen Prozessor und ein Betriebssystem. Das fertige Programm läuft nur dort. Für Windows, macOS und Linux musst du es jeweils neu kompilieren. ::: grafik l20-cpp.svg +C++ wird für jedes System einzeln zu Maschinencode kompiliert. +::: | | C++ | Java | |---|---|---| @@ -145,6 +149,22 @@ Beim Installieren begegnen dir zwei Abkürzungen: Zum Programmieren brauchst du also das JDK. Heute lädt man meist nur noch das JDK herunter, die JRE steckt darin. Für VisuStruct im Browser musst du nichts davon installieren. +::: profiwissen +Mit einem JDK kannst du alles auch selbst in der Konsole machen, also im Terminal oder in der Eingabeaufforderung: + +``` +java -version +javac Einmaleins.java +java Einmaleins +``` + +- `java -version` zeigt, welche Java-Version installiert ist. Kommt eine Fehlermeldung, fehlt Java noch. +- `javac Einmaleins.java` startet den Compiler. Danach liegt `Einmaleins.class` im selben Ordner. +- `java Einmaleins` startet die JVM mit deinem Bytecode. Den Klassennamen schreibst du hier ohne `.class`. + +Klappt `java -version`, aber `javac -version` nicht, ist nur eine JRE installiert. Dann fehlt dir das JDK. +::: + ::: angeberwissen Jede übersetzte Java-Datei (`.class`) beginnt mit denselben vier Bytes, in Hexadezimal geschrieben: `CA FE BA BE`. Daran erkennt der Computer, dass es Java ist. Das „Kaffee-Baby“ hat sich James Gosling ausgedacht, passend zum Kaffee im Namen. ::: diff --git a/web/lessons/en/20-java.md b/web/lessons/en/20-java.md index acc366b4..9a328f86 100644 --- a/web/lessons/en/20-java.md +++ b/web/lessons/en/20-java.md @@ -119,12 +119,16 @@ Your file `TimesTable.java` is **source code**: text for people. The processor i 2. The **JVM** (Java Virtual Machine) reads the bytecode and, while running it, translates it into **machine code**: instructions for the processor in your computer. ::: grafik l20-jvm.svg +Compile once: the same bytecode runs on every JVM. +::: There is only one bytecode. But there is a JVM for Windows, macOS, Linux and many other systems. That is why the same `.class` file runs on every computer that has a JVM installed. This is called **platform independent**. The slogan for it is **“Write once, run anywhere”**. Compare this with **C++**: there the compiler translates the source code directly into machine code for exactly one processor and one operating system. The finished program only runs there. For Windows, macOS and Linux you have to compile it again each time. ::: grafik l20-cpp.svg +C++ is compiled to machine code separately for every system. +::: | | C++ | Java | |---|---|---| @@ -145,6 +149,22 @@ When you install Java you meet two abbreviations: So to program you need the JDK. Today you usually only download the JDK, the JRE is inside it. For VisuStruct in the browser you don't need to install any of this. +::: profiwissen +With a JDK you can do all of this yourself in the console, that is in the terminal or the command prompt: + +``` +java -version +javac TimesTable.java +java TimesTable +``` + +- `java -version` shows which Java version is installed. If you get an error message, Java is still missing. +- `javac TimesTable.java` starts the compiler. Afterwards `TimesTable.class` is in the same folder. +- `java TimesTable` starts the JVM with your bytecode. Here you write the class name without `.class`. + +If `java -version` works but `javac -version` doesn't, only a JRE is installed. Then you are missing the JDK. +::: + ::: angeberwissen Every compiled Java file (`.class`) starts with the same four bytes, written in hexadecimal: `CA FE BA BE`. That is how the computer recognises it as Java. James Gosling came up with this “cafe babe”, to go with the coffee in the name. ::: diff --git a/web/lessons/pt/20-java.md b/web/lessons/pt/20-java.md index 78aa4358..9d39377a 100644 --- a/web/lessons/pt/20-java.md +++ b/web/lessons/pt/20-java.md @@ -119,12 +119,16 @@ O teu ficheiro `Tabuada.java` é **código-fonte**: texto para pessoas. O proces 2. A **JVM** (Java Virtual Machine, máquina virtual Java) lê o bytecode e, ao executá-lo, traduz-o em **código máquina**: instruções para o processador do teu computador. ::: grafik l20-jvm.svg +Compilar uma vez: o mesmo bytecode corre em qualquer JVM. +::: O bytecode existe só uma vez. Já a JVM existe para Windows, macOS, Linux e muitos outros sistemas. Por isso, o mesmo ficheiro `.class` corre em qualquer computador que tenha uma JVM instalada. A isto chama-se **independente da plataforma**. O lema é **“Write once, run anywhere”**: escrever uma vez, executar em qualquer lado. Compara com o **C++**: aí o compilador traduz o código-fonte diretamente em código máquina para um só processador e um só sistema operativo. O programa pronto só corre aí. Para Windows, macOS e Linux tens de o compilar de novo de cada vez. ::: grafik l20-cpp.svg +O C++ é compilado para código máquina em separado para cada sistema. +::: | | C++ | Java | |---|---|---| @@ -145,6 +149,22 @@ Ao instalar o Java, encontras duas siglas: Para programar precisas, portanto, do JDK. Hoje em dia normalmente só se descarrega o JDK, o JRE vem lá dentro. Para usar o VisuStruct no browser não precisas de instalar nada disto. +::: profiwissen +Com um JDK podes fazer tudo isto tu próprio na consola, ou seja, no terminal ou na linha de comandos: + +``` +java -version +javac Tabuada.java +java Tabuada +``` + +- `java -version` mostra que versão do Java está instalada. Se aparecer uma mensagem de erro, ainda falta o Java. +- `javac Tabuada.java` inicia o compilador. Depois, o `Tabuada.class` fica na mesma pasta. +- `java Tabuada` inicia a JVM com o teu bytecode. Aqui escreves o nome da classe sem `.class`. + +Se `java -version` funcionar mas `javac -version` não, só tens um JRE instalado. Nesse caso falta-te o JDK. +::: + ::: angeberwissen Todos os ficheiros Java compilados (`.class`) começam com os mesmos quatro bytes, escritos em hexadecimal: `CA FE BA BE`. É assim que o computador reconhece que é Java. Foi James Gosling que inventou este “cafe babe”, a condizer com o café do nome. ::: diff --git a/web/package-lock.json b/web/package-lock.json index 685fae41..9bcd28c5 100644 --- a/web/package-lock.json +++ b/web/package-lock.json @@ -1,12 +1,12 @@ { "name": "visustruct-web", - "version": "0.14.1", + "version": "0.14.2", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "visustruct-web", - "version": "0.14.1", + "version": "0.14.2", "dependencies": { "@codemirror/autocomplete": "^6.20.4", "@codemirror/commands": "^6.11.1", diff --git a/web/package.json b/web/package.json index 65abe83f..90d13f52 100644 --- a/web/package.json +++ b/web/package.json @@ -1,7 +1,7 @@ { "name": "visustruct-web", "private": true, - "version": "0.14.1", + "version": "0.14.2", "type": "module", "scripts": { "dev": "vite", diff --git a/web/src/i18n/ar.strings b/web/src/i18n/ar.strings index e4c6b393..88bec8b3 100644 --- a/web/src/i18n/ar.strings +++ b/web/src/i18n/ar.strings @@ -135,6 +135,7 @@ "web_files_saved_fmt" = "تم الحفظ: %@"; "web_files_create" = "إنشاء"; "web_learn_ludwig_tip" = "نصيحة لودفيغ"; +"web_learn_pro" = "معرفة المحترفين مع لودفيغ"; "web_game_title" = "لعبة: صحيح أم خطأ؟"; "web_game_intro" = "يعرض لك لودفيغ قيماً وشرطاً. هل الشرط صحيح (true) أم خطأ (false)؟ عشر جولات تزداد صعوبة."; "web_game_start" = "ابدأ اللعبة"; diff --git a/web/src/i18n/da.strings b/web/src/i18n/da.strings index a1e13ff7..160b0ce8 100644 --- a/web/src/i18n/da.strings +++ b/web/src/i18n/da.strings @@ -135,6 +135,7 @@ "web_files_saved_fmt" = "Gemt: %@"; "web_files_create" = "Opret"; "web_learn_ludwig_tip" = "Ludwigs tip"; +"web_learn_pro" = "Profividen med Ludwig"; "web_game_title" = "Spil: Sandt eller falsk?"; "web_game_intro" = "Ludwig viser dig værdier og en betingelse. Er betingelsen sand (true) eller falsk (false)? Ti runder, sværere og sværere."; "web_game_start" = "Start spillet"; diff --git a/web/src/i18n/de.strings b/web/src/i18n/de.strings index 87354a19..edc02522 100644 --- a/web/src/i18n/de.strings +++ b/web/src/i18n/de.strings @@ -221,6 +221,7 @@ "web_files_saved_fmt" = "Gespeichert: %@"; "web_files_create" = "Anlegen"; "web_learn_ludwig_tip" = "Ludwigs Tipp"; +"web_learn_pro" = "Profiwissen mit Ludwig"; "web_game_title" = "Spiel: Wahr oder falsch?"; "web_game_intro" = "Ludwig zeigt dir Werte und eine Bedingung. Ist die Bedingung wahr (true) oder falsch (false)? Zehn Runden, es wird von Runde zu Runde kniffliger."; "web_game_start" = "Spiel starten"; diff --git a/web/src/i18n/el.strings b/web/src/i18n/el.strings index dd9bcf82..1fc02cd0 100644 --- a/web/src/i18n/el.strings +++ b/web/src/i18n/el.strings @@ -135,6 +135,7 @@ "web_files_saved_fmt" = "Αποθηκεύτηκε: %@"; "web_files_create" = "Δημιουργία"; "web_learn_ludwig_tip" = "Η συμβουλή του Ludwig"; +"web_learn_pro" = "Γνώσεις για επαγγελματίες με τον Ludwig"; "web_game_title" = "Παιχνίδι: Αληθές ή ψευδές;"; "web_game_intro" = "Ο Ludwig σου δείχνει τιμές και μια συνθήκη. Είναι αληθής (true) ή ψευδής (false); Δέκα γύροι, όλο και δυσκολότεροι."; "web_game_start" = "Έναρξη παιχνιδιού"; diff --git a/web/src/i18n/en.strings b/web/src/i18n/en.strings index 226917db..adc228b0 100644 --- a/web/src/i18n/en.strings +++ b/web/src/i18n/en.strings @@ -221,6 +221,7 @@ "web_files_saved_fmt" = "Saved: %@"; "web_files_create" = "Create"; "web_learn_ludwig_tip" = "Ludwig’s tip"; +"web_learn_pro" = "Pro knowledge with Ludwig"; "web_game_title" = "Game: True or false?"; "web_game_intro" = "Ludwig shows you values and a condition. Is the condition true or false? Ten rounds, getting trickier each time."; "web_game_start" = "Start game"; diff --git a/web/src/i18n/es.strings b/web/src/i18n/es.strings index 76ebf53e..d441ce41 100644 --- a/web/src/i18n/es.strings +++ b/web/src/i18n/es.strings @@ -135,6 +135,7 @@ "web_files_saved_fmt" = "Guardado: %@"; "web_files_create" = "Crear"; "web_learn_ludwig_tip" = "El consejo de Ludwig"; +"web_learn_pro" = "Saber de profesional con Ludwig"; "web_game_title" = "Juego: ¿Verdadero o falso?"; "web_game_intro" = "Ludwig te muestra valores y una condición. ¿Es verdadera (true) o falsa (false)? Diez rondas, cada vez más difíciles."; "web_game_start" = "Empezar el juego"; diff --git a/web/src/i18n/fr.strings b/web/src/i18n/fr.strings index ecb40127..b65a566a 100644 --- a/web/src/i18n/fr.strings +++ b/web/src/i18n/fr.strings @@ -135,6 +135,7 @@ "web_files_saved_fmt" = "Enregistré : %@"; "web_files_create" = "Créer"; "web_learn_ludwig_tip" = "Le conseil de Ludwig"; +"web_learn_pro" = "Savoir de pro avec Ludwig"; "web_game_title" = "Jeu : Vrai ou faux ?"; "web_game_intro" = "Ludwig te montre des valeurs et une condition. Est-elle vraie (true) ou fausse (false) ? Dix manches, de plus en plus difficiles."; "web_game_start" = "Commencer le jeu"; diff --git a/web/src/i18n/he.strings b/web/src/i18n/he.strings index ac7a7248..d576e62f 100644 --- a/web/src/i18n/he.strings +++ b/web/src/i18n/he.strings @@ -135,6 +135,7 @@ "web_files_saved_fmt" = "נשמר: %@"; "web_files_create" = "יצירה"; "web_learn_ludwig_tip" = "הטיפ של לודוויג"; +"web_learn_pro" = "ידע של מקצוענים עם לודוויג"; "web_game_title" = "משחק: אמת או שקר?"; "web_game_intro" = "לודוויג מראה ערכים ותנאי. האם התנאי אמת (true) או שקר (false)? עשרה סבבים, כל פעם קשה יותר."; "web_game_start" = "התחלת המשחק"; diff --git a/web/src/i18n/it.strings b/web/src/i18n/it.strings index 4b42e666..6f62c346 100644 --- a/web/src/i18n/it.strings +++ b/web/src/i18n/it.strings @@ -135,6 +135,7 @@ "web_files_saved_fmt" = "Salvato: %@"; "web_files_create" = "Crea"; "web_learn_ludwig_tip" = "Il consiglio di Ludwig"; +"web_learn_pro" = "Sapere da professionisti con Ludwig"; "web_game_title" = "Gioco: Vero o falso?"; "web_game_intro" = "Ludwig ti mostra dei valori e una condizione. È vera (true) o falsa (false)? Dieci turni, sempre più difficili."; "web_game_start" = "Inizia il gioco"; diff --git a/web/src/i18n/ja.strings b/web/src/i18n/ja.strings index 0a0ec387..9b672a7f 100644 --- a/web/src/i18n/ja.strings +++ b/web/src/i18n/ja.strings @@ -135,6 +135,7 @@ "web_files_saved_fmt" = "保存しました:%@"; "web_files_create" = "作成"; "web_learn_ludwig_tip" = "ルートヴィヒのヒント"; +"web_learn_pro" = "ルートヴィヒのプロ知識"; "web_game_title" = "ゲーム:真か偽か?"; "web_game_intro" = "ルートヴィヒが値と条件を見せます。条件は真(true)?それとも偽(false)?10ラウンド、だんだん難しくなります。"; "web_game_start" = "ゲームを始める"; diff --git a/web/src/i18n/ko.strings b/web/src/i18n/ko.strings index d0ac8c28..dcfc102f 100644 --- a/web/src/i18n/ko.strings +++ b/web/src/i18n/ko.strings @@ -135,6 +135,7 @@ "web_files_saved_fmt" = "저장됨: %@"; "web_files_create" = "만들기"; "web_learn_ludwig_tip" = "루트비히의 팁"; +"web_learn_pro" = "루트비히의 전문가 지식"; "web_game_title" = "게임: 참일까 거짓일까?"; "web_game_intro" = "루트비히가 값과 조건을 보여 줍니다. 조건이 참(true)일까요, 거짓(false)일까요? 10라운드, 점점 어려워집니다."; "web_game_start" = "게임 시작"; diff --git a/web/src/i18n/nb.strings b/web/src/i18n/nb.strings index da1ba87a..03116d84 100644 --- a/web/src/i18n/nb.strings +++ b/web/src/i18n/nb.strings @@ -135,6 +135,7 @@ "web_files_saved_fmt" = "Lagret: %@"; "web_files_create" = "Lag"; "web_learn_ludwig_tip" = "Ludwigs tips"; +"web_learn_pro" = "Proffkunnskap med Ludwig"; "web_game_title" = "Spill: Sant eller usant?"; "web_game_intro" = "Ludwig viser deg verdier og en betingelse. Er betingelsen sann (true) eller usann (false)? Ti runder, stadig vanskeligere."; "web_game_start" = "Start spillet"; diff --git a/web/src/i18n/nl.strings b/web/src/i18n/nl.strings index 41b30e58..2b144e9d 100644 --- a/web/src/i18n/nl.strings +++ b/web/src/i18n/nl.strings @@ -135,6 +135,7 @@ "web_files_saved_fmt" = "Opgeslagen: %@"; "web_files_create" = "Maken"; "web_learn_ludwig_tip" = "Ludwigs tip"; +"web_learn_pro" = "Profkennis met Ludwig"; "web_game_title" = "Spel: Waar of onwaar?"; "web_game_intro" = "Ludwig laat je waarden en een voorwaarde zien. Is de voorwaarde waar (true) of onwaar (false)? Tien rondes, steeds lastiger."; "web_game_start" = "Spel starten"; diff --git a/web/src/i18n/pl.strings b/web/src/i18n/pl.strings index 54bb5061..24da49f8 100644 --- a/web/src/i18n/pl.strings +++ b/web/src/i18n/pl.strings @@ -135,6 +135,7 @@ "web_files_saved_fmt" = "Zapisano: %@"; "web_files_create" = "Utwórz"; "web_learn_ludwig_tip" = "Wskazówka Ludwiga"; +"web_learn_pro" = "Wiedza dla profesjonalistów z Ludwigiem"; "web_game_title" = "Gra: Prawda czy fałsz?"; "web_game_intro" = "Ludwig pokazuje wartości i warunek. Czy warunek jest prawdziwy (true), czy fałszywy (false)? Dziesięć rund, coraz trudniejszych."; "web_game_start" = "Zacznij grę"; diff --git a/web/src/i18n/pt-PT.strings b/web/src/i18n/pt-PT.strings index bc82d4ce..09da5560 100644 --- a/web/src/i18n/pt-PT.strings +++ b/web/src/i18n/pt-PT.strings @@ -219,6 +219,7 @@ "web_files_saved_fmt" = "Guardado: %@"; "web_files_create" = "Criar"; "web_learn_ludwig_tip" = "Dica do Ludwig"; +"web_learn_pro" = "Saber de profissional com o Ludwig"; "web_game_title" = "Jogo: Verdadeiro ou falso?"; "web_game_intro" = "O Ludwig mostra-te valores e uma condição. A condição é verdadeira (true) ou falsa (false)? Dez rondas, cada vez mais difíceis."; "web_game_start" = "Começar o jogo"; diff --git a/web/src/i18n/ru.strings b/web/src/i18n/ru.strings index 71115318..42a29f40 100644 --- a/web/src/i18n/ru.strings +++ b/web/src/i18n/ru.strings @@ -135,6 +135,7 @@ "web_files_saved_fmt" = "Сохранено: %@"; "web_files_create" = "Создать"; "web_learn_ludwig_tip" = "Совет Людвига"; +"web_learn_pro" = "Профи-знания с Людвигом"; "web_game_title" = "Игра: Истина или ложь?"; "web_game_intro" = "Людвиг показывает значения и условие. Условие истинно (true) или ложно (false)? Десять раундов, всё сложнее."; "web_game_start" = "Начать игру"; diff --git a/web/src/i18n/sv.strings b/web/src/i18n/sv.strings index aa533939..b88de94c 100644 --- a/web/src/i18n/sv.strings +++ b/web/src/i18n/sv.strings @@ -135,6 +135,7 @@ "web_files_saved_fmt" = "Sparat: %@"; "web_files_create" = "Skapa"; "web_learn_ludwig_tip" = "Ludwigs tips"; +"web_learn_pro" = "Proffskunskap med Ludwig"; "web_game_title" = "Spel: Sant eller falskt?"; "web_game_intro" = "Ludwig visar värden och ett villkor. Är villkoret sant (true) eller falskt (false)? Tio rundor, allt svårare."; "web_game_start" = "Starta spelet"; diff --git a/web/src/i18n/tr.strings b/web/src/i18n/tr.strings index 5a79faf8..1ba5eac4 100644 --- a/web/src/i18n/tr.strings +++ b/web/src/i18n/tr.strings @@ -135,6 +135,7 @@ "web_files_saved_fmt" = "Kaydedildi: %@"; "web_files_create" = "Oluştur"; "web_learn_ludwig_tip" = "Ludwig’in ipucu"; +"web_learn_pro" = "Ludwig ile profesyonel bilgi"; "web_game_title" = "Oyun: Doğru mu yanlış mı?"; "web_game_intro" = "Ludwig sana değerler ve bir koşul gösterir. Koşul doğru (true) mu yanlış (false) mı? On tur, giderek zorlaşır."; "web_game_start" = "Oyunu başlat"; diff --git a/web/src/i18n/uk.strings b/web/src/i18n/uk.strings index 8a39b0c1..e402549f 100644 --- a/web/src/i18n/uk.strings +++ b/web/src/i18n/uk.strings @@ -135,6 +135,7 @@ "web_files_saved_fmt" = "Збережено: %@"; "web_files_create" = "Створити"; "web_learn_ludwig_tip" = "Порада Людвіга"; +"web_learn_pro" = "Знання профі з Людвігом"; "web_game_title" = "Гра: Істина чи хиба?"; "web_game_intro" = "Людвіг показує значення й умову. Умова істинна (true) чи хибна (false)? Десять раундів, щоразу складніше."; "web_game_start" = "Почати гру"; diff --git a/web/src/i18n/zh-Hans.strings b/web/src/i18n/zh-Hans.strings index 0223fa3f..37a08dca 100644 --- a/web/src/i18n/zh-Hans.strings +++ b/web/src/i18n/zh-Hans.strings @@ -135,6 +135,7 @@ "web_files_saved_fmt" = "已保存:%@"; "web_files_create" = "新建"; "web_learn_ludwig_tip" = "路德维希的提示"; +"web_learn_pro" = "路德维希的专业知识"; "web_game_title" = "游戏:真还是假?"; "web_game_intro" = "路德维希给你看一些值和一个条件。这个条件是真(true)还是假(false)?共十轮,越来越难。"; "web_game_start" = "开始游戏"; diff --git a/web/src/i18n/zh-Hant.strings b/web/src/i18n/zh-Hant.strings index 9b0a04a8..70e22188 100644 --- a/web/src/i18n/zh-Hant.strings +++ b/web/src/i18n/zh-Hant.strings @@ -135,6 +135,7 @@ "web_files_saved_fmt" = "已儲存:%@"; "web_files_create" = "新增"; "web_learn_ludwig_tip" = "路德維希的提示"; +"web_learn_pro" = "路德維希的專業知識"; "web_game_title" = "遊戲:真還是假?"; "web_game_intro" = "路德維希給你看一些值和一個條件。這個條件是真(true)還是假(false)?共十輪,越來越難。"; "web_game_start" = "開始遊戲"; diff --git a/web/src/learn/lessonFormat.ts b/web/src/learn/lessonFormat.ts index 305f69f9..725e510f 100644 --- a/web/src/learn/lessonFormat.ts +++ b/web/src/learn/lessonFormat.ts @@ -19,7 +19,7 @@ export type Block = /** Kompetenzen am Anfang der Lektion („Diese Kompetenzen erwerbe ich jetzt“). */ | { kind: 'competences'; items: string[] } | { kind: 'quiz'; questions: QuizQuestion[] } - | { kind: 'brag'; text: string; tip?: boolean } + | { kind: 'brag'; text: string; tip?: boolean; pro?: boolean } | { kind: 'images'; files: string[]; caption: string } /** `labeled`: beschriftete Fassung, die ein Klick auf die Grafik ein- und ausblendet. */ | { kind: 'graphic'; file: string; labeled?: string; caption: string } @@ -378,6 +378,9 @@ export function parseBlocks(body: string, file: string): Block[] { throw new FormatError((err as Error).message) } break + case 'profiwissen': + blocks.push({ kind: 'brag', text: inner.join('\n').trim(), pro: true }) + break case 'ludwig': blocks.push({ kind: 'brag', text: inner.join('\n').trim(), tip: true }) break diff --git a/web/src/ui/learnPanel.ts b/web/src/ui/learnPanel.ts index 1e8fe3d4..15e5fc35 100644 --- a/web/src/ui/learnPanel.ts +++ b/web/src/ui/learnPanel.ts @@ -448,7 +448,7 @@ export class LearnPanel { case 'quiz': return this.renderQuiz(block.questions, key, lesson) case 'brag': - return this.renderBrag(block.text, block.tip) + return this.renderBrag(block.text, block.tip, block.pro) case 'images': return this.renderImages(block.files, block.caption) case 'graphic': @@ -474,11 +474,11 @@ export class LearnPanel { } } - /** Ludwig der Geißbock erzählt etwas zum Angeben oder gibt einen Tipp. */ - private renderBrag(text: string, tip = false): HTMLElement { + /** Ludwig der Geißbock erzählt etwas zum Angeben, gibt einen Tipp oder Profiwissen. */ + private renderBrag(text: string, tip = false, pro = false): HTMLElement { const box = h('aside', { class: 'learn-brag' }) box.append(h('img', { src: ludwigURL, alt: '', width: '48', height: '48' })) - const body = h('div', {}, h('p', { class: 'learn-brag-title' }, t(tip ? 'web_learn_ludwig_tip' : 'web_learn_brag'))) + const body = h('div', {}, h('p', { class: 'learn-brag-title' }, t(pro ? 'web_learn_pro' : tip ? 'web_learn_ludwig_tip' : 'web_learn_brag'))) body.append(html('div', { class: 'learn-text' }, markdownToHTML(text))) box.append(body) return box diff --git a/web/test/lessons.test.ts b/web/test/lessons.test.ts index 4dc8cd31..6c0ac270 100644 --- a/web/test/lessons.test.ts +++ b/web/test/lessons.test.ts @@ -51,6 +51,12 @@ describe.each(contentLanguages)('Lernbereich: Inhalte (%s)', (lang) => { } }) + it('jede Grafik-Unterschrift ist kurz (sonst fehlt das schließende „:::“)', () => { + for (const { where, block } of allBlocks()) { + if (block.kind === 'graphic' || block.kind === 'images') expect(block.caption.length, `${where}: ${block.caption.slice(0, 60)}`).toBeLessThan(400) + } + }) + it('keine Schleife in einem Diagramm ist leer (Inhalt gehört in )', () => { const loops = [ElementType.forSchleife, ElementType.whileSchleife, ElementType.doUntilSchleife, ElementType.endlosschleife] const check = (els: VSElement[], where: string) => { diff --git a/website/app/assets/ar-DeE-RHam.js b/website/app/assets/ar-Dqb2o0I-.js similarity index 99% rename from website/app/assets/ar-DeE-RHam.js rename to website/app/assets/ar-Dqb2o0I-.js index 5352e2b8..f77bca6b 100644 --- a/website/app/assets/ar-DeE-RHam.js +++ b/website/app/assets/ar-Dqb2o0I-.js @@ -135,6 +135,7 @@ const e=`/* نصوص موجودة في نسخة الويب فقط. أما بقي "web_files_saved_fmt" = "تم الحفظ: %@"; "web_files_create" = "إنشاء"; "web_learn_ludwig_tip" = "نصيحة لودفيغ"; +"web_learn_pro" = "معرفة المحترفين مع لودفيغ"; "web_game_title" = "لعبة: صحيح أم خطأ؟"; "web_game_intro" = "يعرض لك لودفيغ قيماً وشرطاً. هل الشرط صحيح (true) أم خطأ (false)؟ عشر جولات تزداد صعوبة."; "web_game_start" = "ابدأ اللعبة"; diff --git a/website/app/assets/da-D4INXE4p.js b/website/app/assets/da-ey_ipgDe.js similarity index 99% rename from website/app/assets/da-D4INXE4p.js rename to website/app/assets/da-ey_ipgDe.js index 635f9b95..2713742e 100644 --- a/website/app/assets/da-D4INXE4p.js +++ b/website/app/assets/da-ey_ipgDe.js @@ -135,6 +135,7 @@ const e=`/* Tekster, der kun findes i webversionen. Alt andet kommer fra appens "web_files_saved_fmt" = "Gemt: %@"; "web_files_create" = "Opret"; "web_learn_ludwig_tip" = "Ludwigs tip"; +"web_learn_pro" = "Profividen med Ludwig"; "web_game_title" = "Spil: Sandt eller falsk?"; "web_game_intro" = "Ludwig viser dig værdier og en betingelse. Er betingelsen sand (true) eller falsk (false)? Ti runder, sværere og sværere."; "web_game_start" = "Start spillet"; diff --git a/website/app/assets/de-NQF_CaEx.js b/website/app/assets/de-DMor0Vtb.js similarity index 99% rename from website/app/assets/de-NQF_CaEx.js rename to website/app/assets/de-DMor0Vtb.js index b06ca204..c0b2b718 100644 --- a/website/app/assets/de-NQF_CaEx.js +++ b/website/app/assets/de-DMor0Vtb.js @@ -221,6 +221,7 @@ const e=`/* Texte, die es nur in der Web-Version gibt. Alle anderen kommen aus d "web_files_saved_fmt" = "Gespeichert: %@"; "web_files_create" = "Anlegen"; "web_learn_ludwig_tip" = "Ludwigs Tipp"; +"web_learn_pro" = "Profiwissen mit Ludwig"; "web_game_title" = "Spiel: Wahr oder falsch?"; "web_game_intro" = "Ludwig zeigt dir Werte und eine Bedingung. Ist die Bedingung wahr (true) oder falsch (false)? Zehn Runden, es wird von Runde zu Runde kniffliger."; "web_game_start" = "Spiel starten"; diff --git a/website/app/assets/el-CtIZyj0I.js b/website/app/assets/el-DaQv4rR_.js similarity index 99% rename from website/app/assets/el-CtIZyj0I.js rename to website/app/assets/el-DaQv4rR_.js index 0c996c1b..e0848569 100644 --- a/website/app/assets/el-CtIZyj0I.js +++ b/website/app/assets/el-DaQv4rR_.js @@ -135,6 +135,7 @@ const e=`/* Κείμενα που υπάρχουν μόνο στην έκδοσ "web_files_saved_fmt" = "Αποθηκεύτηκε: %@"; "web_files_create" = "Δημιουργία"; "web_learn_ludwig_tip" = "Η συμβουλή του Ludwig"; +"web_learn_pro" = "Γνώσεις για επαγγελματίες με τον Ludwig"; "web_game_title" = "Παιχνίδι: Αληθές ή ψευδές;"; "web_game_intro" = "Ο Ludwig σου δείχνει τιμές και μια συνθήκη. Είναι αληθής (true) ή ψευδής (false); Δέκα γύροι, όλο και δυσκολότεροι."; "web_game_start" = "Έναρξη παιχνιδιού"; diff --git a/website/app/assets/en-DysVTM-W.js b/website/app/assets/en-CEwI5dlH.js similarity index 99% rename from website/app/assets/en-DysVTM-W.js rename to website/app/assets/en-CEwI5dlH.js index 6cbc0380..bd942593 100644 --- a/website/app/assets/en-DysVTM-W.js +++ b/website/app/assets/en-CEwI5dlH.js @@ -221,6 +221,7 @@ const e=`/* Texts that exist only in the web version. Everything else comes from "web_files_saved_fmt" = "Saved: %@"; "web_files_create" = "Create"; "web_learn_ludwig_tip" = "Ludwig’s tip"; +"web_learn_pro" = "Pro knowledge with Ludwig"; "web_game_title" = "Game: True or false?"; "web_game_intro" = "Ludwig shows you values and a condition. Is the condition true or false? Ten rounds, getting trickier each time."; "web_game_start" = "Start game"; diff --git a/website/app/assets/es-BAduFB3L.js b/website/app/assets/es-BHz7jCrz.js similarity index 99% rename from website/app/assets/es-BAduFB3L.js rename to website/app/assets/es-BHz7jCrz.js index b05a09bc..b6fa5864 100644 --- a/website/app/assets/es-BAduFB3L.js +++ b/website/app/assets/es-BHz7jCrz.js @@ -135,6 +135,7 @@ const e=`/* Textos que solo existen en la versión web. Todo lo demás procede d "web_files_saved_fmt" = "Guardado: %@"; "web_files_create" = "Crear"; "web_learn_ludwig_tip" = "El consejo de Ludwig"; +"web_learn_pro" = "Saber de profesional con Ludwig"; "web_game_title" = "Juego: ¿Verdadero o falso?"; "web_game_intro" = "Ludwig te muestra valores y una condición. ¿Es verdadera (true) o falsa (false)? Diez rondas, cada vez más difíciles."; "web_game_start" = "Empezar el juego"; diff --git a/website/app/assets/flowApp-DkiXDJDe.js b/website/app/assets/flowApp-4s69NVPv.js similarity index 99% rename from website/app/assets/flowApp-DkiXDJDe.js rename to website/app/assets/flowApp-4s69NVPv.js index 068e4136..dd3c5dcc 100644 --- a/website/app/assets/flowApp-DkiXDJDe.js +++ b/website/app/assets/flowApp-4s69NVPv.js @@ -1,4 +1,4 @@ -var dt=Object.defineProperty;var lt=(n,t,e)=>t in n?dt(n,t,{enumerable:!0,configurable:!0,writable:!0,value:e}):n[t]=e;var y=(n,t,e)=>lt(n,typeof t!="symbol"?t+"":t,e);import{t as h,g as ct,i as I,w as ht,n as ut,f as ft,o as G,q as pt,u as gt,v as wt,x as vt,y as mt,l as xt}from"./index-BVzzpk4y.js";const et=["start","anweisung","ein","verzweigung","unterprogramm","ende"],m=20,st={start:"#d1f2d9",ende:"#d1f2d9",anweisung:"#e5f0ff",ein:"#f2e6ff",verzweigung:"#fff4d6",unterprogramm:"#e5f0ff"},H=16,yt=170;function bt(n,t,e){const i=[];for(const s of n.split(` +var dt=Object.defineProperty;var lt=(n,t,e)=>t in n?dt(n,t,{enumerable:!0,configurable:!0,writable:!0,value:e}):n[t]=e;var y=(n,t,e)=>lt(n,typeof t!="symbol"?t+"":t,e);import{t as h,g as ct,i as I,w as ht,n as ut,f as ft,o as G,q as pt,u as gt,v as wt,x as vt,y as mt,l as xt}from"./index-DqKA7YqL.js";const et=["start","anweisung","ein","verzweigung","unterprogramm","ende"],m=20,st={start:"#d1f2d9",ende:"#d1f2d9",anweisung:"#e5f0ff",ein:"#f2e6ff",verzweigung:"#fff4d6",unterprogramm:"#e5f0ff"},H=16,yt=170;function bt(n,t,e){const i=[];for(const s of n.split(` `)){let o="";for(const r of s.split(/\s+/).filter(Boolean)){const a=o?`${o} ${r}`:r;o&&e(a)>t?(i.push(o),o=r):o=a}i.push(o)}return i.length?i:[""]}const q=n=>Math.round(n/m)*m;function C(n,t){const e=bt(n.text,yt,t),i=Math.max(0,...e.map(t)),s=e.length*H;let o,r;if(n.shape==="verzweigung")o=Math.max(140,i*1.7+30),r=Math.max(80,s*1.8+24);else{const a=n.shape==="ein"?44:n.shape==="unterprogramm"?40:n.shape==="anweisung"?24:36;o=Math.max(n.shape==="start"||n.shape==="ende"?100:120,i+a),r=Math.max(40,s+18)}return{x:n.x,y:n.y,w:Math.ceil(o/m)*m,h:Math.ceil(r/m)*m,lines:e}}function V(n){return n==="ende"?[]:n==="verzweigung"?["ja","nein"]:["out"]}const D=n=>n!=="start";function P(n,t,e){var s;if(e==="out")return"bottom";const i=((s=n.yesRight)==null?void 0:s.includes(t.id))??!1;return e==="ja"===i?"right":"bottom"}function F(n,t){return t==="bottom"?[n.x,n.y+n.h/2]:[n.x+n.w/2,n.y]}const _t=n=>[n.x,n.y-n.h/2];function $t(n,t,e,i=0){const[s,o]=F(n,t),[r,a]=_t(e),d=m,u=Math.max(n.x+n.w/2,e.x+e.w/2)+d*(1.5+i);if(t==="bottom"){if(a>=o+d){if(s===r)return[[s,o],[r,a]];const l=o+d;return[[s,o],[s,l],[r,l],[r,a]]}return[[s,o],[s,o+d],[u,o+d],[u,a-d],[r,a-d],[r,a]]}const p=e.x-e.w/2;if(p>=s+d&&Math.abs(e.y-o)=o+d){if(r>=s+d)return[[s,o],[r,o],[r,a]];const l=s+d;return[[s,o],[l,o],[l,a-d],[r,a-d],[r,a]]}const f=Math.max(s+d,u);return[[s,o],[f,o],[f,a-d],[r,a-d],[r,a]]}function nt(n=""){return{title:n,nodes:[],edges:[]}}function it(n,t){const e=new Set([...n.nodes.map(s=>s.id),...n.edges.map(s=>s.id)]);let i=1;for(;e.has(`${t}${i}`);)i++;return`${t}${i}`}function O(n,t,e,i,s){const o=it(n,"n");return{doc:{...n,nodes:[...n.nodes,{id:o,shape:t,x:q(e),y:q(i),text:s}]},id:o}}function J(n,t,e,i){return{...n,nodes:n.nodes.map(s=>s.id===t?{...s,x:Math.max(m*4,q(e)),y:Math.max(m*2,q(i))}:s)}}function Lt(n,t,e){return{...n,nodes:n.nodes.map(i=>i.id===t?{...i,text:e}:i)}}function _(n,t,e,i){const s=n.nodes.find(a=>a.id===t),o=n.nodes.find(a=>a.id===i);if(!s||!o||t===i||!V(s.shape).includes(e)||!D(o.shape))return n;const r=n.edges.filter(a=>!(a.from===t&&a.port===e));return{...n,edges:[...r,{id:it(n,"e"),from:t,port:e,to:i}]}}function Et(n,t){return V(t.shape).find(e=>!n.edges.some(i=>i.from===t.id&&i.port===e))}function kt(n,t){var e;return{...n,nodes:n.nodes.filter(i=>i.id!==t),edges:n.edges.filter(i=>i.from!==t&&i.to!==t),yesRight:(e=n.yesRight)==null?void 0:e.filter(i=>i!==t)}}function St(n,t){return{...n,edges:n.edges.filter(e=>e.id!==t)}}function ot(n,t){const e=new Set(n.yesRight??[]);return e.has(t)?e.delete(t):e.add(t),{...n,yesRight:[...e]}}function b(n){return JSON.stringify({format:"visuflow",version:1,...n},null,2)}function W(n){let t;try{t=JSON.parse(n)}catch{return}if(!t||typeof t!="object")return;const e=t;if(!Array.isArray(e.nodes)||!Array.isArray(e.edges))return;const i=[];for(const o of e.nodes)!o||typeof o.id!="string"||!et.includes(o.shape)||!Number.isFinite(o.x)||!Number.isFinite(o.y)||i.some(r=>r.id===o.id)||i.push({id:o.id,shape:o.shape,x:o.x,y:o.y,text:typeof o.text=="string"?o.text:""});let s={title:typeof e.title=="string"?e.title:"",nodes:i,edges:[]};for(const o of e.edges)!o||typeof o.from!="string"||typeof o.to!="string"||typeof o.port!="string"||(s=_(s,o.from,o.port,o.to));return Array.isArray(e.yesRight)&&(s.yesRight=e.yesRight.filter(o=>typeof o=="string"&&i.some(r=>r.id===o))),s}const z="http://www.w3.org/2000/svg",X="visuflow.doc",Mt=100,Y=14,rt=`${Y}px -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif`,T="#1c1c1e",w=n=>n.replace(/[&<>"]/g,t=>({"&":"&","<":"<",">":">",'"':"""})[t]);function At(n){try{return localStorage.getItem(n)}catch{return null}}function Z(n,t){try{localStorage.setItem(n,t)}catch{}}function It(){const n=xt(),t=n==="pt-PT"?"pt":n==="de"?"de":"en";return`${/\/app\/(index\.html)?$/.test(location.pathname)?"../":"https://visustruct.org/"}${t}/index.html`}function j(n,t,e){const i=URL.createObjectURL(new Blob([t],{type:e})),s=document.createElement("a");s.href=i,s.download=n,s.click(),setTimeout(()=>URL.revokeObjectURL(i),1e3)}function v(n,t={}){const e=document.createElementNS(z,n);for(const[i,s]of Object.entries(t))e.setAttribute(i,String(s));return e}let N;function R(n){return N===void 0&&(N=document.createElement("canvas").getContext("2d")),N?(N.font=rt,N.measureText(n).width):n.length*Y*.55}const Ct=n=>h(`web_visuflow_shape_${n}`),B=n=>h(`web_visuflow_text_${n}`);function at(n,t){const e=t.x-t.w/2,i=t.x+t.w/2,s=t.y-t.h/2,o=t.y+t.h/2;return n==="verzweigung"?v("path",{d:`M${t.x} ${s} L${i} ${t.y} L${t.x} ${o} L${e} ${t.y} Z`}):n==="ein"?v("path",{d:`M${e+14} ${s} L${i} ${s} L${i-14} ${o} L${e} ${o} Z`}):n==="unterprogramm"?v("path",{d:`M${e} ${s} H${i} V${o} H${e} Z M${e+10} ${s} V${o} M${i-10} ${s} V${o}`}):v("rect",{x:e,y:s,width:t.w,height:t.h,rx:n==="anweisung"?2:t.h/2})}function Rt(n){const t=v("text",{"text-anchor":"middle","font-size":Y,fill:T});return n.lines.forEach((e,i)=>{const s=v("tspan",{x:n.x,y:n.y+5+(i-(n.lines.length-1)/2)*H});s.textContent=e,t.append(s)}),t}function Q(n){const t=v("svg",{viewBox:"0 0 64 36",width:64,height:36,"aria-hidden":"true"}),e=at(n,{x:32,y:18,w:n==="verzweigung"?54:56,h:n==="verzweigung"?32:26});return e.setAttribute("fill",st[n]),e.setAttribute("stroke",T),e.setAttribute("stroke-width","1.5"),t.append(e),t.outerHTML}function tt(){let n=nt(h("web_visuflow_example_title"));const t=[],e=(p,f,l,c)=>{const g=O(n,p,f,l,c);n=g.doc,t.push(g.id)};e("start",240,60,B("start")),e("anweisung",240,160,h("web_visuflow_example_water")),e("anweisung",240,260,h("web_visuflow_example_bag")),e("verzweigung",240,380,h("web_visuflow_example_hot")),e("anweisung",480,380,h("web_visuflow_example_wait")),e("anweisung",240,500,h("web_visuflow_example_drink")),e("ende",240,600,B("ende"));const[i,s,o,r,a,d,u]=t;return n=_(n,i,"out",s),n=_(n,s,"out",o),n=_(n,o,"out",r),n=ot(n,r),n=_(n,r,"ja",a),n=_(n,a,"out",r),n=_(n,r,"nein",d),n=_(n,d,"out",u),n}function Tt(){return O(nt(),"start",240,60,B("start")).doc}class Pt{constructor(t){y(this,"shell");y(this,"svg");y(this,"scroller");y(this,"status");y(this,"titleInput");y(this,"doc");y(this,"selection");y(this,"history",[]);y(this,"future",[]);y(this,"editor");y(this,"dragLine");document.documentElement.classList.add("visuflow-theme"),history.replaceState(history.state,"",`${location.pathname}?visuflow${location.hash}`),this.doc=W(At(X)??"")??tt(),this.shell=document.createElement("div"),this.shell.className="shell visuflow",t.replaceWith(this.shell),this.build(),this.render(),window.addEventListener("keydown",e=>this.onKey(e))}build(){const t=(l,c,g,x=c)=>``,e=et.map(l=>``).join("");this.shell.innerHTML=`
    VisuFlow ${w(h("web_visuflow_subtitle"))} @@ -28,7 +28,7 @@ var dt=Object.defineProperty;var lt=(n,t,e)=>t in n?dt(n,t,{enumerable:!0,config ${ht()}
    - ${w(h("web_about_version_fmt").replace("%@","0.14.1"))} + ${w(h("web_about_version_fmt").replace("%@","0.14.2"))}
    diff --git a/website/app/assets/fr-C_mSEvw5.js b/website/app/assets/fr-CEc9fFV7.js similarity index 99% rename from website/app/assets/fr-C_mSEvw5.js rename to website/app/assets/fr-CEc9fFV7.js index 33ead673..f5bc8d68 100644 --- a/website/app/assets/fr-C_mSEvw5.js +++ b/website/app/assets/fr-CEc9fFV7.js @@ -135,6 +135,7 @@ const e=`/* Textes propres à la version web. Tout le reste provient des Localiz "web_files_saved_fmt" = "Enregistré : %@"; "web_files_create" = "Créer"; "web_learn_ludwig_tip" = "Le conseil de Ludwig"; +"web_learn_pro" = "Savoir de pro avec Ludwig"; "web_game_title" = "Jeu : Vrai ou faux ?"; "web_game_intro" = "Ludwig te montre des valeurs et une condition. Est-elle vraie (true) ou fausse (false) ? Dix manches, de plus en plus difficiles."; "web_game_start" = "Commencer le jeu"; diff --git a/website/app/assets/he-BAg3LrWK.js b/website/app/assets/he-B1FDwOEu.js similarity index 99% rename from website/app/assets/he-BAg3LrWK.js rename to website/app/assets/he-B1FDwOEu.js index 2f086eab..e28b73c9 100644 --- a/website/app/assets/he-BAg3LrWK.js +++ b/website/app/assets/he-B1FDwOEu.js @@ -135,6 +135,7 @@ const e=`/* טקסטים שקיימים רק בגרסת הרשת. כל השאר "web_files_saved_fmt" = "נשמר: %@"; "web_files_create" = "יצירה"; "web_learn_ludwig_tip" = "הטיפ של לודוויג"; +"web_learn_pro" = "ידע של מקצוענים עם לודוויג"; "web_game_title" = "משחק: אמת או שקר?"; "web_game_intro" = "לודוויג מראה ערכים ותנאי. האם התנאי אמת (true) או שקר (false)? עשרה סבבים, כל פעם קשה יותר."; "web_game_start" = "התחלת המשחק"; diff --git a/website/app/assets/index-BVzzpk4y.js b/website/app/assets/index-DqKA7YqL.js similarity index 99% rename from website/app/assets/index-BVzzpk4y.js rename to website/app/assets/index-DqKA7YqL.js index e1c29d15..d3e2afad 100644 --- a/website/app/assets/index-BVzzpk4y.js +++ b/website/app/assets/index-DqKA7YqL.js @@ -8,7 +8,7 @@ var m2=Object.defineProperty;var c2=(i,e,t)=>e in i?m2(i,e,{enumerable:!0,config `}if(i.cases)for(const n of i.cases){t+=`${e} `;for(const a of n.elements)t+=go(a,e+" ");t+=`${e} `}return t+=`${e} -`,t}function qd(i){return i.replace(/&/g,"&").replace(/"/g,""").replace(//g,">")}function N2(i){return i.replace(/&/g,"&").replace(//g,">")}function au(i){return String(i.a<<24|i.r<<16|i.g<<8|i.b|0)}function Za(i,e){return Array.from(i.children).filter(t=>t.tagName===e)}function po(i){const e=[];for(const t of Za(i,"strelem")){const n=J2(t);n&&e.push(n)}return e}function J2(i){const e=si(i,"typ");if(e===void 0||S[e]===void 0)return;const t={type:e,zoomX:si(i,"zx")??0,zoomY:si(i,"zy")??0,textLines:Za(i,"text").map(o=>ho((o.textContent??"").trim()))},n=ru(i.getAttribute("textcolor"));n&&(t.textColor=n);const a=ru(i.getAttribute("bgcolor"));a&&(t.backgroundColor=a),t.textLines.length===0&&(t.textLines=[""]);const s=Za(i,"schleifeninhalt")[0];if(s){const o=po(s);o.length>0&&(t.loopBody=o)}const r=Za(i,"fall").map(o=>({name:ho(o.getAttribute("fallname")??""),elements:po(o)}));return r.length>0&&(t.cases=r),t}function su(i,e){const t=i.getAttribute(e);return t===null?void 0:ho(t)}function si(i,e){const t=i.getAttribute(e);if(!(t===null||!/^[+-]?\d+$/.test(t)))return Number(t)}function ru(i){if(i===null||!/^[+-]?\d+$/.test(i))return;const e=Number(i);if(e<-2147483648||e>2147483647)return;const t=e>>>0;return{a:t>>>24&255,r:t>>>16&255,g:t>>>8&255,b:t&255}}const F2="http://www.w3.org/2000/svg",We={diagramLineWidth:2,outerFrameLineWidth:2,selectionLineWidth:3.5,canvasOuterMargin:16,cellTextInsetX:18,cellTextInsetY:15,multiHeaderFirstLineY:14,branchLabelInsetX:10,fallauswahlCaseLabelBand:26,callSideBarInset:14,callTextInsetFromSideBar:20,loopBodyLeadingInset:20};function Ud(i){switch(i){case S.forSchleife:case S.whileSchleife:case S.doUntilSchleife:case S.endlosschleife:return"loop";case S.verzweigung:case S.fallauswahl:return"if";default:return}}function Se(i,e={}){const t=document.createElementNS(F2,i);for(const[n,a]of Object.entries(e))t.setAttribute(n,String(a));return t}class $d{constructor(e,t){y(this,"usesSimulationHighlight",!1);y(this,"fillsSelection",!1);this.metrics=e,this.measure=t}get lineHeight(){return this.metrics.lineHeight}get fontSize(){return this.metrics.fontSize}render(e,t,n,a=We.canvasOuterMargin){const s=Se("svg",{width:t.width,height:t.height,viewBox:`0 0 ${t.width} ${t.height}`,"font-family":Ns,"font-size":this.fontSize,class:"diagram"});s.append(Se("rect",{x:0,y:0,width:t.width,height:t.height,fill:"#fafafa"}));const r=a;s.append(Se("rect",{x:r,y:r,width:e.canvasSize.width-2*r-1,height:e.canvasSize.height-2*r-1,fill:"none",stroke:"black","stroke-width":We.outerFrameLineWidth}));const o=Se("g");for(const l of e.elements)this.drawNode(l,o,n,{},void 0,"method");return s.append(o),s}line(e,t){e.append(Se("polyline",{points:t.map(n=>n.join(",")).join(" "),fill:"none",stroke:"black","stroke-width":We.diagramLineWidth,"stroke-linejoin":"miter"}))}strokeCellBorder(e,t,n){const a=t.x,s=t.y,r=t.x+t.width,o=t.y+t.height;if(!n.top&&!n.left&&!n.bottom&&!n.right){e.append(Se("rect",{x:a,y:s,width:t.width,height:t.height,fill:"none",stroke:"black","stroke-width":We.diagramLineWidth}));return}n.top||this.line(e,[[a,s],[r,s]]),n.right||this.line(e,[[r,s],[r,o]]),n.bottom||this.line(e,[[r,o],[a,o]]),n.left||this.line(e,[[a,o],[a,s]])}textWidth(e){const t=U0(e);return t?this.measure(t.keyword,this.fontSize,"bold")+(t.rest===""?0:this.measure(" "+t.rest,this.fontSize,"medium")):this.measure(e,this.fontSize,"medium")}drawKeywordLine(e,t,n,a){const s=Se("text",{x:n,y:a+eu(this.fontSize,"medium").ascent,"font-weight":500});s.style.whiteSpace="pre";const r=U0(t);if(r){const o=Se("tspan",{"font-weight":700});if(o.textContent=r.keyword,s.append(o),r.rest!==""){const l=Se("tspan",{});l.textContent=" "+r.rest,s.append(l)}}else s.textContent=t;e.append(s)}drawLabel(e,t,n,a,s,r){const o=eu(this.fontSize,s?"bold":"medium"),l=Se("text",{x:n,y:r==="top"?a+o.ascent:a-o.descent,"font-weight":s?700:500});l.style.whiteSpace="pre",l.textContent=t,e.append(l)}roofMetrics(e,t,n,a){const s=t.y+n,r=e.dividerYInset??0,o=12,l=Math.max(e.element.textLines.length,1)*this.lineHeight,u=t.y+We.multiHeaderFirstLineY;if(e.element.type===S.fallauswahl){const c=Math.max(We.fallauswahlCaseLabelBand,this.lineHeight+10),d=s-c,h=Math.min(s+r,d-8),g=Math.max(h,u+l+6);return{apex:{x:a,y:g},maxTextBottom:d-o,roofBottom:s}}const m={x:a,y:s+r};return{apex:m,maxTextBottom:m.y-o,roofBottom:s}}drawNode(e,t,n,a,s,r){var j;const o=e.frame,l=e.element,u=o.x+o.width,m=o.y+o.height,c=l.type===S.verzweigung||l.type===S.fallauswahl,d=c?e.headerBandHeight:0,h=n!==void 0&&fo(e.idPath,n),g=Zl(l),f=Se("g",{"data-path":e.idPath.join(",")});t.append(f);const b=this.usesSimulationHighlight,x=l.backgroundColor,v=x&&x.a>0?`rgba(${x.r}, ${x.g}, ${x.b}, ${x.a/255})`:"white",w=h&&(b||this.fillsSelection)?"rgba(199, 230, 255, 0.55)":v,I=Ud(l.type)??(l.type===S.leerElement?r:"method"),z=Se("rect",{x:o.x,y:o.y,width:o.width,height:o.height,fill:w});w==="white"&&I&&z.setAttribute("class",`ns-scope ns-scope-${I}`),f.append(z),this.strokeCellBorder(f,o,a);const k=We.callSideBarInset;if(l.type===S.aufruf?(this.line(f,[[o.x+k,o.y],[o.x+k,m]]),this.line(f,[[u-k,o.y],[u-k,m]])):l.type===S.aussprung&&this.line(f,[[o.x+k,o.y],[o.x,o.y+o.height/2],[o.x+k,m]]),c&&e.dividerX!==void 0){const D=e.dividerX,O=this.roofMetrics(e,o,d,D),C=Math.max(g.length,1)*this.lineHeight,A=o.y+We.multiHeaderFirstLineY;this.line(f,[[o.x,o.y],[O.apex.x,O.apex.y],[u,o.y]]),l.type===S.fallauswahl&&this.line(f,[[o.x,O.roofBottom],[u,O.roofBottom]]);let B;A+C<=O.maxTextBottom?B=A:B=Math.max(o.y+2,O.maxTextBottom-(Math.max(g.length,1)-1)*this.lineHeight-this.lineHeight),g.forEach((E,U)=>{const ee=this.textWidth(E);let he;if(l.type===S.verzweigung){const Ie=o.x+We.cellTextInsetX,fe=u-ee-We.cellTextInsetX;he=Math.min(Math.max(D-ee/2,Ie),fe)}else he=o.x+o.width/2-ee/2;this.drawKeywordLine(f,E,he,B+U*this.lineHeight)})}else if(l.type!==S.doUntilSchleife)if(l.type===S.anweisung||l.type===S.aufruf||l.type===S.aussprung){const D=We.cellTextInsetX;let O=o.x+D,C=u-D;l.type===S.aufruf?(O=o.x+k+We.callTextInsetFromSideBar,C=u-k-We.callTextInsetFromSideBar):l.type===S.aussprung&&(O=o.x+k+D);const A=Math.max(0,C-O);let B=o.y+o.height/2-Math.max(1,g.length)*this.lineHeight/2;for(const E of g)this.drawKeywordLine(f,E,O+(A-this.textWidth(E))/2,B),B+=this.lineHeight}else{const D=Math.max(1,g.length)*this.lineHeight;let O=s===S.doUntilSchleife?o.y+o.height/2-D/2:o.y+We.cellTextInsetY;for(const C of g)this.drawKeywordLine(f,C,o.x+We.cellTextInsetX,O),O+=this.lineHeight}e.children.forEach((D,O)=>{const C=l.type===S.doUntilSchleife&&O===0?{top:!0,left:!0}:{};this.drawNode(D,t,n,C,l.type,I)});const T=Se("g");if(t.append(T),l.type===S.doUntilSchleife){const D=((j=e.children[0])==null?void 0:j.frame.x)??o.x+(e.loopBodyLeadingInset>0?e.loopBodyLeadingInset:We.loopBodyLeadingInset);this.drawLabel(T,"do",o.x+4,o.y+this.metrics.doUntilDoLabelTopInset,!0,"top");const O=m-e.headerBandHeight;this.line(T,[[D,O],[u,O]]),this.line(T,[[D,o.y],[D,O]]);let C=O+this.metrics.doUntilFooterTopInset;for(const A of g)this.drawKeywordLine(T,A,o.x+We.cellTextInsetX,C),C+=this.lineHeight}if(c&&e.dividerX!==void 0&&e.caseColumnFrames.length>1){const D=this.roofMetrics(e,o,d,e.dividerX),O=D.apex;e.caseColumnFrames.forEach((A,B)=>{if(B>=e.caseColumnFrames.length-1)return;const E=A.x+A.width,U=R2(E,o,O),ee=Number.isFinite(U)?Math.min(Math.max(U,o.y),m):o.y;this.line(T,[[E,m],[E,ee]])});const C=l.cases;if(C&&C.length===e.caseColumnFrames.length){const A=l.type===S.fallauswahl?D.roofBottom-6:o.y+d-8,B=We.branchLabelInsetX;if(l.type===S.verzweigung&&C.length===2){this.drawLabel(T,"true",o.x+B,A,!0,"bottom");const E=e.caseColumnFrames[1],U=this.measure("false",this.fontSize,"bold");this.drawLabel(T,"false",E.x+E.width-B-U,A,!0,"bottom")}else C.forEach((E,U)=>{const ee=e.caseColumnFrames[U],he=["default","true","false"].includes(E.name.toLowerCase()),Ie=this.measure(E.name,this.fontSize,he?"bold":"medium");this.drawLabel(T,E.name,ee.x+ee.width/2-Ie/2,A,he,"bottom")})}}h&&T.append(Se("rect",{x:o.x,y:o.y,width:o.width,height:o.height,class:"selection-frame",fill:"none",stroke:b?"rgba(66, 140, 242, 0.78)":"rgba(0, 122, 255, 0.9)","stroke-width":We.selectionLineWidth}))}}function R2(i,e,t){const n=e.y;if(i<=t.x){const s=t.x-e.x;return Math.abs(s)<.5?t.y:n+(t.y-n)/s*(i-e.x)}const a=e.x+e.width-t.x;return Math.abs(a)<.5?t.y:t.y+(n-t.y)/a*(i-t.x)}function fo(i,e){return i.length===e.length&&i.every((t,n)=>t===e[n])}function G2(i){const e=[],t=n=>{e.push(n),n.children.forEach(t)};return i.forEach(t),e}function Xa(i){var e,t;return{...i,textLines:Zl(i),loopBody:(e=i.loopBody)==null?void 0:e.map(Xa),cases:(t=i.cases)==null?void 0:t.map(n=>({name:n.name,elements:n.elements.map(Xa)}))}}const H2=[{code:"de",name:"Deutsch"},{code:"en",name:"English"},{code:"es",name:"Español"},{code:"fr",name:"Français"},{code:"it",name:"Italiano"},{code:"pl",name:"Polski"},{code:"tr",name:"Türkçe"},{code:"ko",name:"한국어"},{code:"ja",name:"日本語"},{code:"el",name:"Ελληνικά"},{code:"uk",name:"Українська"},{code:"ar",name:"العربية"},{code:"ru",name:"Русский"},{code:"he",name:"עברית"},{code:"nl",name:"Nederlands"},{code:"sv",name:"Svenska"},{code:"da",name:"Dansk"},{code:"nb",name:"Norsk bokmål"},{code:"zh-Hans",name:"中文(简体)"},{code:"zh-Hant",name:"中文(繁體)"},{code:"pt-PT",name:"Português"},{code:"java",name:"Java (Keywords)"}],Yd=["de","en","pt-PT"],Xd=H2.filter(i=>Yd.includes(i.code)),ou=i=>Yd.includes(i),V2=Object.assign({"../../../VisuStruct-iOS/VisuStructXcodeOpen/VisuStruct/ar.lproj/Localizable.strings":()=>K(()=>import("./Localizable-CxCno28C.js"),[],import.meta.url).then(i=>i.default),"../../../VisuStruct-iOS/VisuStructXcodeOpen/VisuStruct/da.lproj/Localizable.strings":()=>K(()=>import("./Localizable-BAutdlBb.js"),[],import.meta.url).then(i=>i.default),"../../../VisuStruct-iOS/VisuStructXcodeOpen/VisuStruct/de.lproj/Localizable.strings":()=>K(()=>import("./Localizable-Dk8F86qS.js"),[],import.meta.url).then(i=>i.default),"../../../VisuStruct-iOS/VisuStructXcodeOpen/VisuStruct/el.lproj/Localizable.strings":()=>K(()=>import("./Localizable-rqA-20hM.js"),[],import.meta.url).then(i=>i.default),"../../../VisuStruct-iOS/VisuStructXcodeOpen/VisuStruct/en.lproj/Localizable.strings":()=>K(()=>import("./Localizable-DBLIUcBd.js"),[],import.meta.url).then(i=>i.default),"../../../VisuStruct-iOS/VisuStructXcodeOpen/VisuStruct/es.lproj/Localizable.strings":()=>K(()=>import("./Localizable-LSTVB2Q5.js"),[],import.meta.url).then(i=>i.default),"../../../VisuStruct-iOS/VisuStructXcodeOpen/VisuStruct/fr.lproj/Localizable.strings":()=>K(()=>import("./Localizable-ByPZS4RL.js"),[],import.meta.url).then(i=>i.default),"../../../VisuStruct-iOS/VisuStructXcodeOpen/VisuStruct/he.lproj/Localizable.strings":()=>K(()=>import("./Localizable-R-16GCrk.js"),[],import.meta.url).then(i=>i.default),"../../../VisuStruct-iOS/VisuStructXcodeOpen/VisuStruct/it.lproj/Localizable.strings":()=>K(()=>import("./Localizable-DXAPah1g.js"),[],import.meta.url).then(i=>i.default),"../../../VisuStruct-iOS/VisuStructXcodeOpen/VisuStruct/ja.lproj/Localizable.strings":()=>K(()=>import("./Localizable-CkJEmEEP.js"),[],import.meta.url).then(i=>i.default),"../../../VisuStruct-iOS/VisuStructXcodeOpen/VisuStruct/ko.lproj/Localizable.strings":()=>K(()=>import("./Localizable-BudCXCER.js"),[],import.meta.url).then(i=>i.default),"../../../VisuStruct-iOS/VisuStructXcodeOpen/VisuStruct/nb.lproj/Localizable.strings":()=>K(()=>import("./Localizable-DSvkBkp-.js"),[],import.meta.url).then(i=>i.default),"../../../VisuStruct-iOS/VisuStructXcodeOpen/VisuStruct/nl.lproj/Localizable.strings":()=>K(()=>import("./Localizable-BJ55WGVD.js"),[],import.meta.url).then(i=>i.default),"../../../VisuStruct-iOS/VisuStructXcodeOpen/VisuStruct/pl.lproj/Localizable.strings":()=>K(()=>import("./Localizable-BYJK0mdR.js"),[],import.meta.url).then(i=>i.default),"../../../VisuStruct-iOS/VisuStructXcodeOpen/VisuStruct/pt-PT.lproj/Localizable.strings":()=>K(()=>import("./Localizable-CHv0OL9S.js"),[],import.meta.url).then(i=>i.default),"../../../VisuStruct-iOS/VisuStructXcodeOpen/VisuStruct/ru.lproj/Localizable.strings":()=>K(()=>import("./Localizable-1QZ0wfvJ.js"),[],import.meta.url).then(i=>i.default),"../../../VisuStruct-iOS/VisuStructXcodeOpen/VisuStruct/sv.lproj/Localizable.strings":()=>K(()=>import("./Localizable-M33nNbEe.js"),[],import.meta.url).then(i=>i.default),"../../../VisuStruct-iOS/VisuStructXcodeOpen/VisuStruct/tr.lproj/Localizable.strings":()=>K(()=>import("./Localizable-BM86Igqt.js"),[],import.meta.url).then(i=>i.default),"../../../VisuStruct-iOS/VisuStructXcodeOpen/VisuStruct/uk.lproj/Localizable.strings":()=>K(()=>import("./Localizable-UGog_aku.js"),[],import.meta.url).then(i=>i.default),"../../../VisuStruct-iOS/VisuStructXcodeOpen/VisuStruct/zh-Hans.lproj/Localizable.strings":()=>K(()=>import("./Localizable-CaVEL1es.js"),[],import.meta.url).then(i=>i.default),"../../../VisuStruct-iOS/VisuStructXcodeOpen/VisuStruct/zh-Hant.lproj/Localizable.strings":()=>K(()=>import("./Localizable-DqIDp_hh.js"),[],import.meta.url).then(i=>i.default)}),Kd=Object.assign({"../../../VisuStruct-iOS/VisuStructXcodeOpen/VisuStruct/Java.strings":()=>K(()=>import("./Java-Bpx1Vwvg.js"),[],import.meta.url).then(i=>i.default)}),Q2=Object.assign({"../i18n/ar.strings":()=>K(()=>import("./ar-DeE-RHam.js"),[],import.meta.url).then(i=>i.default),"../i18n/da.strings":()=>K(()=>import("./da-D4INXE4p.js"),[],import.meta.url).then(i=>i.default),"../i18n/de.strings":()=>K(()=>import("./de-NQF_CaEx.js"),[],import.meta.url).then(i=>i.default),"../i18n/el.strings":()=>K(()=>import("./el-CtIZyj0I.js"),[],import.meta.url).then(i=>i.default),"../i18n/en.strings":()=>K(()=>import("./en-DysVTM-W.js"),[],import.meta.url).then(i=>i.default),"../i18n/es.strings":()=>K(()=>import("./es-BAduFB3L.js"),[],import.meta.url).then(i=>i.default),"../i18n/fr.strings":()=>K(()=>import("./fr-C_mSEvw5.js"),[],import.meta.url).then(i=>i.default),"../i18n/he.strings":()=>K(()=>import("./he-BAg3LrWK.js"),[],import.meta.url).then(i=>i.default),"../i18n/it.strings":()=>K(()=>import("./it-ClGS2uQV.js"),[],import.meta.url).then(i=>i.default),"../i18n/ja.strings":()=>K(()=>import("./ja-JQ8MwNFB.js"),[],import.meta.url).then(i=>i.default),"../i18n/ko.strings":()=>K(()=>import("./ko-tfdKG8Fb.js"),[],import.meta.url).then(i=>i.default),"../i18n/nb.strings":()=>K(()=>import("./nb-BpibUAkX.js"),[],import.meta.url).then(i=>i.default),"../i18n/nl.strings":()=>K(()=>import("./nl-HArZjiga.js"),[],import.meta.url).then(i=>i.default),"../i18n/pl.strings":()=>K(()=>import("./pl-C3HmQqUD.js"),[],import.meta.url).then(i=>i.default),"../i18n/pt-PT.strings":()=>K(()=>import("./pt-PT-2W9Vff48.js"),[],import.meta.url).then(i=>i.default),"../i18n/ru.strings":()=>K(()=>import("./ru-B4vTuE57.js"),[],import.meta.url).then(i=>i.default),"../i18n/sv.strings":()=>K(()=>import("./sv-Dau75zUV.js"),[],import.meta.url).then(i=>i.default),"../i18n/tr.strings":()=>K(()=>import("./tr-DrZsTe-O.js"),[],import.meta.url).then(i=>i.default),"../i18n/uk.strings":()=>K(()=>import("./uk-DQrOpK2W.js"),[],import.meta.url).then(i=>i.default),"../i18n/zh-Hans.strings":()=>K(()=>import("./zh-Hans-CeIYjS3N.js"),[],import.meta.url).then(i=>i.default),"../i18n/zh-Hant.strings":()=>K(()=>import("./zh-Hant-7-ScZHAu.js"),[],import.meta.url).then(i=>i.default)});function Ba(i,e){var t;return(t=Object.entries(i).find(([n])=>n.endsWith(e)))==null?void 0:t[1]}function eh(i){const e=new Map,t=i.replace(/\/\*[\s\S]*?\*\//g,"").replace(/^\s*\/\/.*$/gm,""),n=/"((?:[^"\\]|\\.)*)"\s*=\s*"((?:[^"\\]|\\.)*)"\s*;/g,a=s=>s.replace(/\\(u[0-9a-fA-F]{4}|.)/g,(r,o)=>o==="n"?` +`,t}function qd(i){return i.replace(/&/g,"&").replace(/"/g,""").replace(//g,">")}function N2(i){return i.replace(/&/g,"&").replace(//g,">")}function au(i){return String(i.a<<24|i.r<<16|i.g<<8|i.b|0)}function Za(i,e){return Array.from(i.children).filter(t=>t.tagName===e)}function po(i){const e=[];for(const t of Za(i,"strelem")){const n=J2(t);n&&e.push(n)}return e}function J2(i){const e=si(i,"typ");if(e===void 0||S[e]===void 0)return;const t={type:e,zoomX:si(i,"zx")??0,zoomY:si(i,"zy")??0,textLines:Za(i,"text").map(o=>ho((o.textContent??"").trim()))},n=ru(i.getAttribute("textcolor"));n&&(t.textColor=n);const a=ru(i.getAttribute("bgcolor"));a&&(t.backgroundColor=a),t.textLines.length===0&&(t.textLines=[""]);const s=Za(i,"schleifeninhalt")[0];if(s){const o=po(s);o.length>0&&(t.loopBody=o)}const r=Za(i,"fall").map(o=>({name:ho(o.getAttribute("fallname")??""),elements:po(o)}));return r.length>0&&(t.cases=r),t}function su(i,e){const t=i.getAttribute(e);return t===null?void 0:ho(t)}function si(i,e){const t=i.getAttribute(e);if(!(t===null||!/^[+-]?\d+$/.test(t)))return Number(t)}function ru(i){if(i===null||!/^[+-]?\d+$/.test(i))return;const e=Number(i);if(e<-2147483648||e>2147483647)return;const t=e>>>0;return{a:t>>>24&255,r:t>>>16&255,g:t>>>8&255,b:t&255}}const F2="http://www.w3.org/2000/svg",We={diagramLineWidth:2,outerFrameLineWidth:2,selectionLineWidth:3.5,canvasOuterMargin:16,cellTextInsetX:18,cellTextInsetY:15,multiHeaderFirstLineY:14,branchLabelInsetX:10,fallauswahlCaseLabelBand:26,callSideBarInset:14,callTextInsetFromSideBar:20,loopBodyLeadingInset:20};function Ud(i){switch(i){case S.forSchleife:case S.whileSchleife:case S.doUntilSchleife:case S.endlosschleife:return"loop";case S.verzweigung:case S.fallauswahl:return"if";default:return}}function Se(i,e={}){const t=document.createElementNS(F2,i);for(const[n,a]of Object.entries(e))t.setAttribute(n,String(a));return t}class $d{constructor(e,t){y(this,"usesSimulationHighlight",!1);y(this,"fillsSelection",!1);this.metrics=e,this.measure=t}get lineHeight(){return this.metrics.lineHeight}get fontSize(){return this.metrics.fontSize}render(e,t,n,a=We.canvasOuterMargin){const s=Se("svg",{width:t.width,height:t.height,viewBox:`0 0 ${t.width} ${t.height}`,"font-family":Ns,"font-size":this.fontSize,class:"diagram"});s.append(Se("rect",{x:0,y:0,width:t.width,height:t.height,fill:"#fafafa"}));const r=a;s.append(Se("rect",{x:r,y:r,width:e.canvasSize.width-2*r-1,height:e.canvasSize.height-2*r-1,fill:"none",stroke:"black","stroke-width":We.outerFrameLineWidth}));const o=Se("g");for(const l of e.elements)this.drawNode(l,o,n,{},void 0,"method");return s.append(o),s}line(e,t){e.append(Se("polyline",{points:t.map(n=>n.join(",")).join(" "),fill:"none",stroke:"black","stroke-width":We.diagramLineWidth,"stroke-linejoin":"miter"}))}strokeCellBorder(e,t,n){const a=t.x,s=t.y,r=t.x+t.width,o=t.y+t.height;if(!n.top&&!n.left&&!n.bottom&&!n.right){e.append(Se("rect",{x:a,y:s,width:t.width,height:t.height,fill:"none",stroke:"black","stroke-width":We.diagramLineWidth}));return}n.top||this.line(e,[[a,s],[r,s]]),n.right||this.line(e,[[r,s],[r,o]]),n.bottom||this.line(e,[[r,o],[a,o]]),n.left||this.line(e,[[a,o],[a,s]])}textWidth(e){const t=U0(e);return t?this.measure(t.keyword,this.fontSize,"bold")+(t.rest===""?0:this.measure(" "+t.rest,this.fontSize,"medium")):this.measure(e,this.fontSize,"medium")}drawKeywordLine(e,t,n,a){const s=Se("text",{x:n,y:a+eu(this.fontSize,"medium").ascent,"font-weight":500});s.style.whiteSpace="pre";const r=U0(t);if(r){const o=Se("tspan",{"font-weight":700});if(o.textContent=r.keyword,s.append(o),r.rest!==""){const l=Se("tspan",{});l.textContent=" "+r.rest,s.append(l)}}else s.textContent=t;e.append(s)}drawLabel(e,t,n,a,s,r){const o=eu(this.fontSize,s?"bold":"medium"),l=Se("text",{x:n,y:r==="top"?a+o.ascent:a-o.descent,"font-weight":s?700:500});l.style.whiteSpace="pre",l.textContent=t,e.append(l)}roofMetrics(e,t,n,a){const s=t.y+n,r=e.dividerYInset??0,o=12,l=Math.max(e.element.textLines.length,1)*this.lineHeight,u=t.y+We.multiHeaderFirstLineY;if(e.element.type===S.fallauswahl){const c=Math.max(We.fallauswahlCaseLabelBand,this.lineHeight+10),d=s-c,h=Math.min(s+r,d-8),g=Math.max(h,u+l+6);return{apex:{x:a,y:g},maxTextBottom:d-o,roofBottom:s}}const m={x:a,y:s+r};return{apex:m,maxTextBottom:m.y-o,roofBottom:s}}drawNode(e,t,n,a,s,r){var j;const o=e.frame,l=e.element,u=o.x+o.width,m=o.y+o.height,c=l.type===S.verzweigung||l.type===S.fallauswahl,d=c?e.headerBandHeight:0,h=n!==void 0&&fo(e.idPath,n),g=Zl(l),f=Se("g",{"data-path":e.idPath.join(",")});t.append(f);const b=this.usesSimulationHighlight,x=l.backgroundColor,v=x&&x.a>0?`rgba(${x.r}, ${x.g}, ${x.b}, ${x.a/255})`:"white",w=h&&(b||this.fillsSelection)?"rgba(199, 230, 255, 0.55)":v,I=Ud(l.type)??(l.type===S.leerElement?r:"method"),z=Se("rect",{x:o.x,y:o.y,width:o.width,height:o.height,fill:w});w==="white"&&I&&z.setAttribute("class",`ns-scope ns-scope-${I}`),f.append(z),this.strokeCellBorder(f,o,a);const k=We.callSideBarInset;if(l.type===S.aufruf?(this.line(f,[[o.x+k,o.y],[o.x+k,m]]),this.line(f,[[u-k,o.y],[u-k,m]])):l.type===S.aussprung&&this.line(f,[[o.x+k,o.y],[o.x,o.y+o.height/2],[o.x+k,m]]),c&&e.dividerX!==void 0){const D=e.dividerX,O=this.roofMetrics(e,o,d,D),C=Math.max(g.length,1)*this.lineHeight,A=o.y+We.multiHeaderFirstLineY;this.line(f,[[o.x,o.y],[O.apex.x,O.apex.y],[u,o.y]]),l.type===S.fallauswahl&&this.line(f,[[o.x,O.roofBottom],[u,O.roofBottom]]);let B;A+C<=O.maxTextBottom?B=A:B=Math.max(o.y+2,O.maxTextBottom-(Math.max(g.length,1)-1)*this.lineHeight-this.lineHeight),g.forEach((E,U)=>{const ee=this.textWidth(E);let he;if(l.type===S.verzweigung){const Ie=o.x+We.cellTextInsetX,fe=u-ee-We.cellTextInsetX;he=Math.min(Math.max(D-ee/2,Ie),fe)}else he=o.x+o.width/2-ee/2;this.drawKeywordLine(f,E,he,B+U*this.lineHeight)})}else if(l.type!==S.doUntilSchleife)if(l.type===S.anweisung||l.type===S.aufruf||l.type===S.aussprung){const D=We.cellTextInsetX;let O=o.x+D,C=u-D;l.type===S.aufruf?(O=o.x+k+We.callTextInsetFromSideBar,C=u-k-We.callTextInsetFromSideBar):l.type===S.aussprung&&(O=o.x+k+D);const A=Math.max(0,C-O);let B=o.y+o.height/2-Math.max(1,g.length)*this.lineHeight/2;for(const E of g)this.drawKeywordLine(f,E,O+(A-this.textWidth(E))/2,B),B+=this.lineHeight}else{const D=Math.max(1,g.length)*this.lineHeight;let O=s===S.doUntilSchleife?o.y+o.height/2-D/2:o.y+We.cellTextInsetY;for(const C of g)this.drawKeywordLine(f,C,o.x+We.cellTextInsetX,O),O+=this.lineHeight}e.children.forEach((D,O)=>{const C=l.type===S.doUntilSchleife&&O===0?{top:!0,left:!0}:{};this.drawNode(D,t,n,C,l.type,I)});const T=Se("g");if(t.append(T),l.type===S.doUntilSchleife){const D=((j=e.children[0])==null?void 0:j.frame.x)??o.x+(e.loopBodyLeadingInset>0?e.loopBodyLeadingInset:We.loopBodyLeadingInset);this.drawLabel(T,"do",o.x+4,o.y+this.metrics.doUntilDoLabelTopInset,!0,"top");const O=m-e.headerBandHeight;this.line(T,[[D,O],[u,O]]),this.line(T,[[D,o.y],[D,O]]);let C=O+this.metrics.doUntilFooterTopInset;for(const A of g)this.drawKeywordLine(T,A,o.x+We.cellTextInsetX,C),C+=this.lineHeight}if(c&&e.dividerX!==void 0&&e.caseColumnFrames.length>1){const D=this.roofMetrics(e,o,d,e.dividerX),O=D.apex;e.caseColumnFrames.forEach((A,B)=>{if(B>=e.caseColumnFrames.length-1)return;const E=A.x+A.width,U=R2(E,o,O),ee=Number.isFinite(U)?Math.min(Math.max(U,o.y),m):o.y;this.line(T,[[E,m],[E,ee]])});const C=l.cases;if(C&&C.length===e.caseColumnFrames.length){const A=l.type===S.fallauswahl?D.roofBottom-6:o.y+d-8,B=We.branchLabelInsetX;if(l.type===S.verzweigung&&C.length===2){this.drawLabel(T,"true",o.x+B,A,!0,"bottom");const E=e.caseColumnFrames[1],U=this.measure("false",this.fontSize,"bold");this.drawLabel(T,"false",E.x+E.width-B-U,A,!0,"bottom")}else C.forEach((E,U)=>{const ee=e.caseColumnFrames[U],he=["default","true","false"].includes(E.name.toLowerCase()),Ie=this.measure(E.name,this.fontSize,he?"bold":"medium");this.drawLabel(T,E.name,ee.x+ee.width/2-Ie/2,A,he,"bottom")})}}h&&T.append(Se("rect",{x:o.x,y:o.y,width:o.width,height:o.height,class:"selection-frame",fill:"none",stroke:b?"rgba(66, 140, 242, 0.78)":"rgba(0, 122, 255, 0.9)","stroke-width":We.selectionLineWidth}))}}function R2(i,e,t){const n=e.y;if(i<=t.x){const s=t.x-e.x;return Math.abs(s)<.5?t.y:n+(t.y-n)/s*(i-e.x)}const a=e.x+e.width-t.x;return Math.abs(a)<.5?t.y:t.y+(n-t.y)/a*(i-t.x)}function fo(i,e){return i.length===e.length&&i.every((t,n)=>t===e[n])}function G2(i){const e=[],t=n=>{e.push(n),n.children.forEach(t)};return i.forEach(t),e}function Xa(i){var e,t;return{...i,textLines:Zl(i),loopBody:(e=i.loopBody)==null?void 0:e.map(Xa),cases:(t=i.cases)==null?void 0:t.map(n=>({name:n.name,elements:n.elements.map(Xa)}))}}const H2=[{code:"de",name:"Deutsch"},{code:"en",name:"English"},{code:"es",name:"Español"},{code:"fr",name:"Français"},{code:"it",name:"Italiano"},{code:"pl",name:"Polski"},{code:"tr",name:"Türkçe"},{code:"ko",name:"한국어"},{code:"ja",name:"日本語"},{code:"el",name:"Ελληνικά"},{code:"uk",name:"Українська"},{code:"ar",name:"العربية"},{code:"ru",name:"Русский"},{code:"he",name:"עברית"},{code:"nl",name:"Nederlands"},{code:"sv",name:"Svenska"},{code:"da",name:"Dansk"},{code:"nb",name:"Norsk bokmål"},{code:"zh-Hans",name:"中文(简体)"},{code:"zh-Hant",name:"中文(繁體)"},{code:"pt-PT",name:"Português"},{code:"java",name:"Java (Keywords)"}],Yd=["de","en","pt-PT"],Xd=H2.filter(i=>Yd.includes(i.code)),ou=i=>Yd.includes(i),V2=Object.assign({"../../../VisuStruct-iOS/VisuStructXcodeOpen/VisuStruct/ar.lproj/Localizable.strings":()=>K(()=>import("./Localizable-CxCno28C.js"),[],import.meta.url).then(i=>i.default),"../../../VisuStruct-iOS/VisuStructXcodeOpen/VisuStruct/da.lproj/Localizable.strings":()=>K(()=>import("./Localizable-BAutdlBb.js"),[],import.meta.url).then(i=>i.default),"../../../VisuStruct-iOS/VisuStructXcodeOpen/VisuStruct/de.lproj/Localizable.strings":()=>K(()=>import("./Localizable-Dk8F86qS.js"),[],import.meta.url).then(i=>i.default),"../../../VisuStruct-iOS/VisuStructXcodeOpen/VisuStruct/el.lproj/Localizable.strings":()=>K(()=>import("./Localizable-rqA-20hM.js"),[],import.meta.url).then(i=>i.default),"../../../VisuStruct-iOS/VisuStructXcodeOpen/VisuStruct/en.lproj/Localizable.strings":()=>K(()=>import("./Localizable-DBLIUcBd.js"),[],import.meta.url).then(i=>i.default),"../../../VisuStruct-iOS/VisuStructXcodeOpen/VisuStruct/es.lproj/Localizable.strings":()=>K(()=>import("./Localizable-LSTVB2Q5.js"),[],import.meta.url).then(i=>i.default),"../../../VisuStruct-iOS/VisuStructXcodeOpen/VisuStruct/fr.lproj/Localizable.strings":()=>K(()=>import("./Localizable-ByPZS4RL.js"),[],import.meta.url).then(i=>i.default),"../../../VisuStruct-iOS/VisuStructXcodeOpen/VisuStruct/he.lproj/Localizable.strings":()=>K(()=>import("./Localizable-R-16GCrk.js"),[],import.meta.url).then(i=>i.default),"../../../VisuStruct-iOS/VisuStructXcodeOpen/VisuStruct/it.lproj/Localizable.strings":()=>K(()=>import("./Localizable-DXAPah1g.js"),[],import.meta.url).then(i=>i.default),"../../../VisuStruct-iOS/VisuStructXcodeOpen/VisuStruct/ja.lproj/Localizable.strings":()=>K(()=>import("./Localizable-CkJEmEEP.js"),[],import.meta.url).then(i=>i.default),"../../../VisuStruct-iOS/VisuStructXcodeOpen/VisuStruct/ko.lproj/Localizable.strings":()=>K(()=>import("./Localizable-BudCXCER.js"),[],import.meta.url).then(i=>i.default),"../../../VisuStruct-iOS/VisuStructXcodeOpen/VisuStruct/nb.lproj/Localizable.strings":()=>K(()=>import("./Localizable-DSvkBkp-.js"),[],import.meta.url).then(i=>i.default),"../../../VisuStruct-iOS/VisuStructXcodeOpen/VisuStruct/nl.lproj/Localizable.strings":()=>K(()=>import("./Localizable-BJ55WGVD.js"),[],import.meta.url).then(i=>i.default),"../../../VisuStruct-iOS/VisuStructXcodeOpen/VisuStruct/pl.lproj/Localizable.strings":()=>K(()=>import("./Localizable-BYJK0mdR.js"),[],import.meta.url).then(i=>i.default),"../../../VisuStruct-iOS/VisuStructXcodeOpen/VisuStruct/pt-PT.lproj/Localizable.strings":()=>K(()=>import("./Localizable-CHv0OL9S.js"),[],import.meta.url).then(i=>i.default),"../../../VisuStruct-iOS/VisuStructXcodeOpen/VisuStruct/ru.lproj/Localizable.strings":()=>K(()=>import("./Localizable-1QZ0wfvJ.js"),[],import.meta.url).then(i=>i.default),"../../../VisuStruct-iOS/VisuStructXcodeOpen/VisuStruct/sv.lproj/Localizable.strings":()=>K(()=>import("./Localizable-M33nNbEe.js"),[],import.meta.url).then(i=>i.default),"../../../VisuStruct-iOS/VisuStructXcodeOpen/VisuStruct/tr.lproj/Localizable.strings":()=>K(()=>import("./Localizable-BM86Igqt.js"),[],import.meta.url).then(i=>i.default),"../../../VisuStruct-iOS/VisuStructXcodeOpen/VisuStruct/uk.lproj/Localizable.strings":()=>K(()=>import("./Localizable-UGog_aku.js"),[],import.meta.url).then(i=>i.default),"../../../VisuStruct-iOS/VisuStructXcodeOpen/VisuStruct/zh-Hans.lproj/Localizable.strings":()=>K(()=>import("./Localizable-CaVEL1es.js"),[],import.meta.url).then(i=>i.default),"../../../VisuStruct-iOS/VisuStructXcodeOpen/VisuStruct/zh-Hant.lproj/Localizable.strings":()=>K(()=>import("./Localizable-DqIDp_hh.js"),[],import.meta.url).then(i=>i.default)}),Kd=Object.assign({"../../../VisuStruct-iOS/VisuStructXcodeOpen/VisuStruct/Java.strings":()=>K(()=>import("./Java-Bpx1Vwvg.js"),[],import.meta.url).then(i=>i.default)}),Q2=Object.assign({"../i18n/ar.strings":()=>K(()=>import("./ar-Dqb2o0I-.js"),[],import.meta.url).then(i=>i.default),"../i18n/da.strings":()=>K(()=>import("./da-ey_ipgDe.js"),[],import.meta.url).then(i=>i.default),"../i18n/de.strings":()=>K(()=>import("./de-DMor0Vtb.js"),[],import.meta.url).then(i=>i.default),"../i18n/el.strings":()=>K(()=>import("./el-DaQv4rR_.js"),[],import.meta.url).then(i=>i.default),"../i18n/en.strings":()=>K(()=>import("./en-CEwI5dlH.js"),[],import.meta.url).then(i=>i.default),"../i18n/es.strings":()=>K(()=>import("./es-BHz7jCrz.js"),[],import.meta.url).then(i=>i.default),"../i18n/fr.strings":()=>K(()=>import("./fr-CEc9fFV7.js"),[],import.meta.url).then(i=>i.default),"../i18n/he.strings":()=>K(()=>import("./he-B1FDwOEu.js"),[],import.meta.url).then(i=>i.default),"../i18n/it.strings":()=>K(()=>import("./it-Bsr1AlWk.js"),[],import.meta.url).then(i=>i.default),"../i18n/ja.strings":()=>K(()=>import("./ja-L0a84IMq.js"),[],import.meta.url).then(i=>i.default),"../i18n/ko.strings":()=>K(()=>import("./ko-U6EDne8i.js"),[],import.meta.url).then(i=>i.default),"../i18n/nb.strings":()=>K(()=>import("./nb-C9pwk403.js"),[],import.meta.url).then(i=>i.default),"../i18n/nl.strings":()=>K(()=>import("./nl-D1JTb8Xr.js"),[],import.meta.url).then(i=>i.default),"../i18n/pl.strings":()=>K(()=>import("./pl-DchXCt_R.js"),[],import.meta.url).then(i=>i.default),"../i18n/pt-PT.strings":()=>K(()=>import("./pt-PT-Dq8KVIrs.js"),[],import.meta.url).then(i=>i.default),"../i18n/ru.strings":()=>K(()=>import("./ru-DGHs_3oc.js"),[],import.meta.url).then(i=>i.default),"../i18n/sv.strings":()=>K(()=>import("./sv-zO9ikvt0.js"),[],import.meta.url).then(i=>i.default),"../i18n/tr.strings":()=>K(()=>import("./tr-zv5TxQHQ.js"),[],import.meta.url).then(i=>i.default),"../i18n/uk.strings":()=>K(()=>import("./uk-D5KOtCBD.js"),[],import.meta.url).then(i=>i.default),"../i18n/zh-Hans.strings":()=>K(()=>import("./zh-Hans-C3na1U20.js"),[],import.meta.url).then(i=>i.default),"../i18n/zh-Hant.strings":()=>K(()=>import("./zh-Hant-BLjr78US.js"),[],import.meta.url).then(i=>i.default)});function Ba(i,e){var t;return(t=Object.entries(i).find(([n])=>n.endsWith(e)))==null?void 0:t[1]}function eh(i){const e=new Map,t=i.replace(/\/\*[\s\S]*?\*\//g,"").replace(/^\s*\/\/.*$/gm,""),n=/"((?:[^"\\]|\\.)*)"\s*=\s*"((?:[^"\\]|\\.)*)"\s*;/g,a=s=>s.replace(/\\(u[0-9a-fA-F]{4}|.)/g,(r,o)=>o==="n"?` `:o==="t"?" ":o.startsWith("u")&&o.length===5?String.fromCharCode(parseInt(o.slice(1),16)):o);for(const s of t.matchAll(n))e.set(a(s[1]),a(s[2]));return e}async function bo(i){const e=i==="java"?Ba(Kd,"/Java.strings"):Ba(V2,`/${i}.lproj/Localizable.strings`),t=Ba(Q2,`/${i}.strings`),n=new Map;for(const a of[e,t])if(a)for(const[s,r]of eh(await a()))n.set(s,r);return n}let th="en",nh=new Map,Xn=new Map;const Ka="appLanguageCode",Jl="visustruct.keywords";let xo=new Map,Fl=!1;const q2=i=>i.startsWith("element_")||i.startsWith("canvas_stub_");function U2(){try{const i=new URLSearchParams(location.search).get("lang")==="java"||localStorage.getItem(Ka)==="java";return i&&(localStorage.setItem(Ka,"en"),localStorage.setItem(Jl,"1")),i}catch{return!1}}function $2(){try{return localStorage.getItem(Jl)==="1"}catch{return!1}}async function ih(i,e=!0){if(i&&xo.size===0){Xn.size===0&&(Xn=await bo("en"));const t=Ba(Kd,"/Java.strings");if(t)for(const[n,a]of eh(await t()))q2(n)&&a!==Xn.get(n)&&xo.set(n,a)}if(Fl=i,e)try{localStorage.setItem(Jl,i?"1":"0")}catch{}}function Y2(){return Fl}function X2(){if(U2())return"en";const i=new URLSearchParams(location.search).get("lang");if(i&&ou(i))return i;try{const e=localStorage.getItem(Ka);if(e&&ou(e))return e}catch{}for(const e of navigator.languages??[navigator.language]){const t=e.toLowerCase();if(t.startsWith("pt"))return"pt-PT";const n=Xd.find(a=>a.code===t.split("-")[0]);if(n)return n.code}return"en"}async function ah(i,e=!0){if(Xn.size===0&&(Xn=await bo("en")),nh=i==="en"?Xn:await bo(i),th=i,e)try{localStorage.setItem(Ka,i)}catch{}const t=document.documentElement;t.lang=i==="java"?"en":i,t.dir=i==="ar"||i==="he"?"rtl":"ltr"}function s1(){return th}function p(i,...e){const t=(Fl?xo.get(i):void 0)??nh.get(i)??Xn.get(i)??i;if(e.length===0)return t;let n=0;return t.replace(/%(?:(\d+)\$)?[@d]/g,(a,s)=>String(e[s?Number(s)-1:n++]??""))}const es=243,K2=244,sh=40,pr=4,e3=1;function Rl(i){const e=i.length,t=es+(e&255)+(e>>8)&255,n=i.reduce((a,s)=>a+s,0)&255;return Uint8Array.from([es,t,e&255,e>>8,...i,n,K2])}function t3(i,e,t){const n=Array.from(new TextEncoder().encode(i));return Rl([sh,e,t&255,t>>8&255,n.length&255,n.length>>8,...n])}function n3(i){if(i[0]!==sh||i.length<6)return;const e=new TextDecoder().decode(Uint8Array.from(i.slice(6))),t=/"ret"\s*:\s*([^}]*)\}/.exec(e);return t?{idx:i[2]|i[3]<<8,value:a3(t[1].trim())}:void 0}function i3(i){const e=[];for(;;){const t=i.indexOf(es);if(t<0){i.length=0;break}if(i.splice(0,t),i.length<4)break;const n=i[2]|i[3]<<8;if(i[1]!==(es+i[2]+i[3]&255)||n>4096){i.splice(0,1);continue}if(i.length")){const s=t.at(-1);s&&(s.explanation=((s.explanation?s.explanation+" ":"")+a.slice(1).trim()).trim())}}for(const n of t){if(n.pairs){const a=new Set(n.pairs.map(s=>s.right));if(n.options.length>0||n.pairs.length<2||a.size!==n.pairs.length)throw new ne(`${e}: Zuordnung „${n.question}“ braucht mindestens zwei Paare mit verschiedenen rechten Seiten und keine Antworten.`);continue}if(n.options.length<2||!n.options.some(a=>a.correct))throw new ne(`${e}: Quizfrage „${n.question}“ braucht mindestens zwei Antworten, davon eine richtige.`)}return t}function Xh(i,e){const t=[],n=i.split(` `);let a=[];const s=()=>{const r=a.join(` `).trim();r&&t.push({kind:"markdown",text:r}),a=[]};for(let r=0;r=n.length)throw new ne(`${e}: Block „::: ${o[1]}“ wird nicht mit „:::“ geschlossen.`);const m=o[1].toLowerCase(),c=o[2].trim();switch(m){case"diagramm":if(!c)throw new ne(`${e}: „::: diagramm“ braucht einen Dateinamen.`);t.push({kind:"diagram",file:c,caption:l.join(" ").trim()});break;case"übung":case"uebung":if(!c)throw new ne(`${e}: „::: übung“ braucht eine Kennung.`);t.push({kind:"exercise",exercise:jM(c,l,e)});break;case"checkliste":t.push({kind:"checklist",items:l.map(d=>d.trim()).filter(d=>d.startsWith("- ")).map(d=>PM(d.slice(2).trim()))});break;case"kompetenzen":t.push({kind:"competences",items:l.map(d=>d.trim()).filter(d=>d.startsWith("- ")).map(d=>d.slice(2).trim())});break;case"quiz":t.push({kind:"quiz",questions:AM(l,e)});break;case"bild":if(!c)throw new ne(`${e}: „::: bild“ braucht einen Dateinamen.`);t.push({kind:"images",files:c.split(/\s+/),caption:l.join(" ").trim()});break;case"grafik":if(!c)throw new ne(`${e}: „::: grafik“ braucht einen Dateinamen.`);{const[d,h]=c.split(/\s+/);t.push({kind:"graphic",file:d,...h?{labeled:h}:{},caption:l.join(" ").trim()})}break;case"angeberwissen":t.push({kind:"brag",text:l.join(` -`).trim()});break;case"spiel":try{if(rM(c))t.push({kind:"roundGame",game:oM(c,l,e)});else if(c==="prinzessin")t.push({kind:"rescueGame",game:dM(l,e)});else{if(c)throw new ne(`${e}: Unbekanntes Spiel „${c}“ (zuhoerer, vertrag, layout, bombe, frage, reihenfolge oder prinzessin).`);t.push({kind:"game",game:rx(l,e)})}}catch(d){throw new ne(d.message)}break;case"lückentext":case"lueckentext":try{t.push({kind:"cloze",cloze:gM(l,e)})}catch(d){throw new ne(d.message)}break;case"pap":try{t.push({kind:"pap",pap:xM(l,e)})}catch(d){throw new ne(d.message)}break;case"ludwig":t.push({kind:"brag",text:l.join(` +`).trim()});break;case"spiel":try{if(rM(c))t.push({kind:"roundGame",game:oM(c,l,e)});else if(c==="prinzessin")t.push({kind:"rescueGame",game:dM(l,e)});else{if(c)throw new ne(`${e}: Unbekanntes Spiel „${c}“ (zuhoerer, vertrag, layout, bombe, frage, reihenfolge oder prinzessin).`);t.push({kind:"game",game:rx(l,e)})}}catch(d){throw new ne(d.message)}break;case"lückentext":case"lueckentext":try{t.push({kind:"cloze",cloze:gM(l,e)})}catch(d){throw new ne(d.message)}break;case"pap":try{t.push({kind:"pap",pap:xM(l,e)})}catch(d){throw new ne(d.message)}break;case"profiwissen":t.push({kind:"brag",text:l.join(` +`).trim(),pro:!0});break;case"ludwig":t.push({kind:"brag",text:l.join(` `).trim(),tip:!0});break;case"caesar":{const d=c?Number(c):3;if(!Number.isInteger(d)||d<0||d>25)throw new ne(`${e}: „::: caesar“ braucht einen Schlüssel von 0 bis 25.`);t.push({kind:"caesar",key:d,text:l.join(" ").trim()});break}case"mbot2":{const d={kind:"robotModel",focus:[]};for(const h of l.filter(g=>g.trim())){const g=/^\s*(fokus|focus|ansicht|view|drehen|spin):\s*(.*)$/i.exec(h);if(!g)throw new ne(`${e}: „::: mbot2“ kennt nur Zeilen „fokus:“, „ansicht:“ und „drehen:“.`);const f=g[1].toLowerCase();f==="fokus"||f==="focus"?d.focus=Fu(g[2],e):f==="ansicht"||f==="view"?d.view=g[2].trim().toLowerCase():d.spin=/^(ja|yes|true|sim)$/i.test(g[2].trim())}t.push(d);break}case"mbot2quiz":{const d={kind:"robotQuiz",tasks:[]};for(const h of l.filter(g=>g.trim())){const g=/^\s*-\s*(\w+)\s*:\s*(.+)$/.exec(h),f=/^\s*(fertig|done):\s*(.+)$/i.exec(h);if(g)d.tasks.push({part:Fu(g[1],e)[0],question:g[2].trim()});else if(f)d.done=f[2].trim();else throw new ne(`${e}: „::: mbot2quiz“ braucht Zeilen „- teil: Frage“ und optional „fertig: Text“.`)}if(!d.tasks.length)throw new ne(`${e}: „::: mbot2quiz“ hat keine Fragen.`);t.push(d);break}case"datei":{if(!/^[\w.-]+\.(txt|csv|json)$/u.test(c))throw new ne(`${e}: „::: datei“ braucht einen Dateinamen wie brief.txt, liste.csv oder daten.json.`);for(;l.length&&l[0].trim()==="";)l.shift();for(;l.length&&l[l.length-1].trim()==="";)l.pop();t.push({kind:"textFile",name:c,content:l.join(` `)});break}default:throw new ne(`${e}: Unbekannter Block „::: ${o[1]}“.`)}r=u}return s(),t}function PM(i){const e=/^(.*?)\s+→\s+(.+)$/.exec(i);return e?{text:e[1],ref:e[2].trim()}:{text:i}}function CM(i,e){const t=new Map(i.map((a,s)=>[a.title.toLowerCase(),s]));for(const a of i.flatMap(s=>s.blocks))if(a.kind==="checklist"){for(const s of a.items)if(s.ref!==void 0&&(s.step=t.get(s.ref.toLowerCase()),s.step===void 0))throw new ne(`${e}: Checkliste verweist auf unbekannten Schritt „${s.ref}“.`)}const n=new Set(i.flatMap(a=>a.blocks).flatMap(a=>a.kind==="checklist"?a.items.map(s=>s.step):[]));for(const a of i.flatMap(s=>s.blocks))if(a.kind==="quiz"){for(const s of a.questions)if(s.ref!==void 0){if(s.step=t.get(s.ref.toLowerCase()),s.step===void 0)throw new ne(`${e}: Quizfrage „${s.question}“ verweist auf unbekannten Schritt „${s.ref}“.`);if(!n.has(s.step))throw new ne(`${e}: Zu „${s.ref}“ (Quizfrage „${s.question}“) gibt es keinen Checklistenpunkt.`)}}}function OM(i,e){var c;const{meta:t,body:n}=$h(i,e),a=e.replace(/^.*\//,"").replace(/\.md$/,""),s=Number((c=/^(\d+)/.exec(a))==null?void 0:c[1]);if(!Number.isFinite(s))throw new ne(`${e}: Dateiname muss mit der Nummer beginnen (z. B. 01-…).`);const r=[];let o=[],l;const u=()=>{l&&r.push({title:l.title,blocks:Xh(l.lines.join(` `),e)})};for(const d of n.split(` @@ -64224,7 +64285,7 @@ ${l}`)}Na=aM(((o=e.find(([l])=>l==="begriffe.md"))==null?void 0:o[1])??"")}const

    ${Me(p("simulation_trace"))}

    ${Me(p("simulation_variables"))}

    ${Me(p("simulation_output"))}

    - `;const e=a=>this.element.querySelector(a);this.buttons={play:e("[data-sim=play]"),pause:e("[data-sim=pause]"),step:e("[data-sim=step]"),stop:e("[data-sim=stop]")},this.buttons.play.addEventListener("click",()=>this.play()),this.buttons.pause.addEventListener("click",()=>this.pause()),this.buttons.step.addEventListener("click",()=>this.step()),this.buttons.stop.addEventListener("click",()=>this.reset()),this.editButton=e(".sim-edit"),this.editButton.addEventListener("click",()=>this.onEdit());const t=e("[data-sim=highlight]");t.value=this.highlightMode,t.addEventListener("change",()=>{this.highlightMode=t.value,Ku(Xu,this.highlightMode)});const n=e("[data-sim=delay]");n.value=this.delay,n.addEventListener("change",()=>{this.delay=n.value,Ku(Ir,this.delay)}),this.inputSection=e(".sim-input > div"),this.trace=e(".sim-trace"),this.variables=e(".sim-vars"),this.output=e(".sim-output"),this.notice=e(".sim-notice")}collectOutput(){const e=this.engine.state.outputLines;for(;this.printedr.localeCompare(o));if(n.length===0)this.variables.innerHTML=`

    ${Me(p("simulation_variables_placeholder"))}

    `;else{const r=document.createElement("table");for(const o of n){const l=r.insertRow();l.insertCell().textContent=o;const u=e.variables.get(o),m=l.insertCell();u.kind==="grid"?m.append(sg(u)):m.textContent=_e(u)}this.variables.replaceChildren(r)}e.outputLines.length===0&&e.files.size===0?this.output.innerHTML=`

    ${Me(p("simulation_output_placeholder"))}

    `:(this.output.replaceChildren(...e.outputLines.map(r=>{const o=document.createElement("div");return o.textContent=r,o}),...ag(e.files)),this.output.scrollTop=this.output.scrollHeight)}updateInput(){const e=this.engine.state.inputRequest,t=this.inputSection;if(t.parentElement.classList.toggle("active",!!e),!e){t.innerHTML=`

    ${Me(p("simulation_input_placeholder"))}

    `;return}let n=t.querySelector("form");if(!n){n=document.createElement("form"),n.innerHTML=`

    `;const l=n.querySelector("input");n.addEventListener("submit",u=>{u.preventDefault(),this.submitInput(l)}),t.replaceChildren(n),requestAnimationFrame(()=>l.focus())}const a=this.engine.state.outputLines;n.querySelector(".sim-prompt").textContent=e.prompt||(a[a.length-1]??"");const s=n.querySelector("input");s.inputMode=e.valueType==="string"||e.valueType==="boolean"?"text":"decimal";const r=this.engine.state.inputErrorNotice,o=n.querySelector(".sim-input-error");o.textContent=r?t1(r):"",o.hidden=!r}}function sg(i){const e=document.createElement("table");e.className="sim-grid";for(const t of i.value){const n=e.insertRow();for(const a of t){const s=n.insertCell();s.textContent=String(a),a===!0&&(s.className="sim-grid-true")}}return e}const x1=Array.from("ABCDEFGHIJKLMNOPQRSTUVWXYZ"),Gn=360/x1.length,UM="http://www.w3.org/2000/svg";function Fe(i,e={},...t){const n=document.createElement(i);for(const[a,s]of Object.entries(e))n.setAttribute(a,s);return n.append(...t),n}function xt(i,e={},t){const n=document.createElementNS(UM,i);for(const[a,s]of Object.entries(e))n.setAttribute(a,String(s));return t!==void 0&&(n.textContent=t),n}function $M(i,e){const t=(e%26+26)%26;return Array.from(i).map(n=>{const a=n.charCodeAt(0);return a>=65&&a<=90?String.fromCharCode((a-65+t)%26+65):a>=97&&a<=122?String.fromCharCode((a-97+t)%26+97):n}).join("")}function em(i,e){const t=xt("g",{class:e}),n=x1.map((a,s)=>{const r=xt("g",{transform:`rotate(${s*Gn})`});return r.append(xt("text",{x:0,y:-i,"text-anchor":"middle","dominant-baseline":"central"},a)),t.append(r),r});return{group:t,cells:n}}function YM(i,e){let t=i,n=!1,a=-t*Gn;const s=Fe("section",{class:"learn-game learn-caesar"});s.append(Fe("div",{class:"learn-game-head"},Fe("strong",{},p("web_learn_caesar_title")))),s.append(Fe("p",{class:"learn-game-status"},p("web_learn_caesar_hint")));const r=xt("svg",{viewBox:"-200 -200 400 400",class:"learn-caesar-disc",role:"img"});r.append(xt("circle",{r:196,class:"outer-disc"})),r.append(xt("path",{d:XM(196,92,Gn/2),class:"window"}));const o=em(168,"outer-letters");r.append(o.group);for(let A=0;A{o.cells.forEach((B,E)=>B.classList.toggle("marked",E===A)),u.cells.forEach((B,E)=>B.classList.toggle("marked",A!==void 0&&E===(A+t)%26))},T=()=>{m.textContent=String(t),l.setAttribute("transform",`rotate(${a})`),r.setAttribute("aria-label",p("web_learn_caesar_key_fmt",t)),x.textContent=p(n?"web_learn_caesar_secret":"web_learn_caesar_plain"),w.textContent=p(n?"web_learn_caesar_plain":"web_learn_caesar_secret"),f.classList.toggle("active",!n),b.classList.toggle("active",n),I.textContent=$M(v.value,n?-t:t)||" ";const A=Array.from(v.value.toUpperCase()).reverse().find(E=>x1.includes(E));if(A===void 0)return k();const B=x1.indexOf(A);k(n?(B-t+26)%26:B)},j=A=>{t=(A%26+26)%26,a=-t*Gn,T()};c.addEventListener("click",()=>j(t-1)),d.addEventListener("click",()=>j(t+1)),f.addEventListener("click",()=>{var A;n&&(v.value=((A=I.textContent)==null?void 0:A.trim())??""),n=!1,T()}),b.addEventListener("click",()=>{var A;n||(v.value=((A=I.textContent)==null?void 0:A.trim())??""),n=!0,T()}),v.addEventListener("input",T),o.cells.forEach((A,B)=>A.addEventListener("click",()=>k(B)));let D;const O=A=>{const B=r.getBoundingClientRect();return Math.atan2(A.clientY-(B.top+B.height/2),A.clientX-(B.left+B.width/2))*180/Math.PI};l.addEventListener("pointerdown",A=>{const B=A;D=O(B)-a,l.classList.add("dragging"),r.setPointerCapture(B.pointerId),B.preventDefault()}),r.addEventListener("pointermove",A=>{if(D===void 0)return;a=O(A)-D,l.setAttribute("transform",`rotate(${a})`);const B=Math.round(-a/Gn);if((B%26+26)%26!==t){t=(B%26+26)%26;const E=a;T(),a=E,l.setAttribute("transform",`rotate(${a})`)}});const C=()=>{D!==void 0&&(D=void 0,l.classList.remove("dragging"),j(t))};return r.addEventListener("pointerup",C),r.addEventListener("pointercancel",C),T(),s}function XM(i,e,t){const n=(a,s)=>{const r=(s-90)*Math.PI/180;return`${(a*Math.cos(r)).toFixed(2)} ${(a*Math.sin(r)).toFixed(2)}`};return`M ${n(i,-t)} A ${i} ${i} 0 0 1 ${n(i,t)} L ${n(e,t)} A ${e} ${e} 0 0 0 ${n(e,-t)} Z`}const l0=i=>p(`web_visubot_part_${i}`),rg=new WeakMap;function og(i,e,t,n){const a=document.createElement("div");a.className="visubot-model";const s=document.createElement("div");s.className="visubot-stage";const r=document.createElement("div");r.className="visubot-part-label",r.hidden=!0,s.append(r);const o=(c,d,h)=>{r.hidden=!1,r.textContent=l0(c),r.style.left=`${Math.min(d+12,s.clientWidth-140)}px`,r.style.top=`${h+12}px`},l=document.createElement("p");l.className="visubot-model-hint hint",l.textContent=p("web_visubot_tap_part"),l.hidden=!!n,a.append(s,l);const u=K(async()=>{const{Robot3D:c}=await import("./robot3d-B1TGngW1.js");return{Robot3D:c}},[],import.meta.url).then(({Robot3D:c})=>{const d=new c(s);d.showcase(),d.highlight(i),i.includes("leds")&&d.setLed([40,90,255]),d.focusOn([],e==="unten"||e==="bottom"?"":e,!1,1),d.focusOn(i,e,t);let h;return s.addEventListener("pointerdown",g=>h={x:g.clientX,y:g.clientY}),s.addEventListener("pointerup",g=>{if(!h||Math.hypot(g.clientX-h.x,g.clientY-h.y)>5)return;const f=d.partAt(g.clientX,g.clientY);if(!f)return;if(n)return n(f);d.highlight(f);const b=s.getBoundingClientRect();o(f,g.clientX-b.left,g.clientY-b.top)}),s.addEventListener("pointermove",g=>{if(g.pointerType!=="mouse"||n)return;const f=d.partAt(g.clientX,g.clientY);if(r.hidden=!f,!f)return;const b=s.getBoundingClientRect();o(f,g.clientX-b.left,g.clientY-b.top)}),s.addEventListener("pointerleave",()=>r.hidden=!0),d}).catch(c=>{console.error(c),s.textContent=p("web_visubot_no_3d")}),m={box:a,ready:u,focus:i,view:e};return rg.set(a,m),m}function KM(i,e,t=!1){return og(i,e,t).box}function eZ(i){const e=i.querySelector(".visubot-model"),t=e&&rg.get(e);for(const n of i.querySelectorAll("[data-robot-part]")){const a=(n.dataset.robotPart??"").split(",").filter(Boolean);if(n.title=a.map(l0).join(", "),!t)continue;const s=()=>void t.ready.then(o=>o==null?void 0:o.highlight(a)),r=()=>void t.ready.then(o=>o==null?void 0:o.highlight(t.focus));n.addEventListener("mouseenter",s),n.addEventListener("focus",s),n.addEventListener("mouseleave",r),n.addEventListener("blur",r),n.addEventListener("click",()=>{t.ready.then(o=>{o==null||o.highlight(a),o==null||o.focusOn(a,t.view)}),t.box.scrollIntoView({block:"nearest",behavior:"smooth"})})}}function tZ(i,e){let t=0;const n=document.createElement("div");n.className="visubot-quiz-question";const a=document.createElement("p");a.className="visubot-quiz-feedback",a.setAttribute("aria-live","polite");const s=()=>{n.innerHTML=Tn(`**${t+1}/${i.length}** ${i[t].question}`)},r=og([],void 0,!1,l=>{if(!(t>=i.length)){if(r.ready.then(u=>u==null?void 0:u.highlight(l)),l!==i[t].part){a.className="visubot-quiz-feedback wrong",a.textContent=p("web_visubot_quiz_wrong_fmt",l0(l));return}t++,a.className="visubot-quiz-feedback right",t{u.forEach(v=>{window.clearTimeout(v),window.clearInterval(v)}),u=[]},c=()=>{a.textContent=`${p("web_game_round_fmt",o+1,r)} · ${p("web_game_score_fmt",l)}`},d=()=>{const v=$("button",{class:"primary"},o+1{o++,o{const v=i.rounds[o],w=i.seconds,I=$("div",{class:"learn-bomb-fuse"},$("span",{})),z=$("span",{class:"learn-bomb-time"}),k=$("div",{class:"learn-bomb","aria-live":"polite"},$("span",{class:"learn-bomb-icon","aria-hidden":"true"},"💣"),z,I),T=$("div",{class:"learn-game-feedback",role:"status"}),j=v.code.split(` + `;const e=a=>this.element.querySelector(a);this.buttons={play:e("[data-sim=play]"),pause:e("[data-sim=pause]"),step:e("[data-sim=step]"),stop:e("[data-sim=stop]")},this.buttons.play.addEventListener("click",()=>this.play()),this.buttons.pause.addEventListener("click",()=>this.pause()),this.buttons.step.addEventListener("click",()=>this.step()),this.buttons.stop.addEventListener("click",()=>this.reset()),this.editButton=e(".sim-edit"),this.editButton.addEventListener("click",()=>this.onEdit());const t=e("[data-sim=highlight]");t.value=this.highlightMode,t.addEventListener("change",()=>{this.highlightMode=t.value,Ku(Xu,this.highlightMode)});const n=e("[data-sim=delay]");n.value=this.delay,n.addEventListener("change",()=>{this.delay=n.value,Ku(Ir,this.delay)}),this.inputSection=e(".sim-input > div"),this.trace=e(".sim-trace"),this.variables=e(".sim-vars"),this.output=e(".sim-output"),this.notice=e(".sim-notice")}collectOutput(){const e=this.engine.state.outputLines;for(;this.printedr.localeCompare(o));if(n.length===0)this.variables.innerHTML=`

    ${Me(p("simulation_variables_placeholder"))}

    `;else{const r=document.createElement("table");for(const o of n){const l=r.insertRow();l.insertCell().textContent=o;const u=e.variables.get(o),m=l.insertCell();u.kind==="grid"?m.append(sg(u)):m.textContent=_e(u)}this.variables.replaceChildren(r)}e.outputLines.length===0&&e.files.size===0?this.output.innerHTML=`

    ${Me(p("simulation_output_placeholder"))}

    `:(this.output.replaceChildren(...e.outputLines.map(r=>{const o=document.createElement("div");return o.textContent=r,o}),...ag(e.files)),this.output.scrollTop=this.output.scrollHeight)}updateInput(){const e=this.engine.state.inputRequest,t=this.inputSection;if(t.parentElement.classList.toggle("active",!!e),!e){t.innerHTML=`

    ${Me(p("simulation_input_placeholder"))}

    `;return}let n=t.querySelector("form");if(!n){n=document.createElement("form"),n.innerHTML=`

    `;const l=n.querySelector("input");n.addEventListener("submit",u=>{u.preventDefault(),this.submitInput(l)}),t.replaceChildren(n),requestAnimationFrame(()=>l.focus())}const a=this.engine.state.outputLines;n.querySelector(".sim-prompt").textContent=e.prompt||(a[a.length-1]??"");const s=n.querySelector("input");s.inputMode=e.valueType==="string"||e.valueType==="boolean"?"text":"decimal";const r=this.engine.state.inputErrorNotice,o=n.querySelector(".sim-input-error");o.textContent=r?t1(r):"",o.hidden=!r}}function sg(i){const e=document.createElement("table");e.className="sim-grid";for(const t of i.value){const n=e.insertRow();for(const a of t){const s=n.insertCell();s.textContent=String(a),a===!0&&(s.className="sim-grid-true")}}return e}const x1=Array.from("ABCDEFGHIJKLMNOPQRSTUVWXYZ"),Gn=360/x1.length,UM="http://www.w3.org/2000/svg";function Fe(i,e={},...t){const n=document.createElement(i);for(const[a,s]of Object.entries(e))n.setAttribute(a,s);return n.append(...t),n}function xt(i,e={},t){const n=document.createElementNS(UM,i);for(const[a,s]of Object.entries(e))n.setAttribute(a,String(s));return t!==void 0&&(n.textContent=t),n}function $M(i,e){const t=(e%26+26)%26;return Array.from(i).map(n=>{const a=n.charCodeAt(0);return a>=65&&a<=90?String.fromCharCode((a-65+t)%26+65):a>=97&&a<=122?String.fromCharCode((a-97+t)%26+97):n}).join("")}function em(i,e){const t=xt("g",{class:e}),n=x1.map((a,s)=>{const r=xt("g",{transform:`rotate(${s*Gn})`});return r.append(xt("text",{x:0,y:-i,"text-anchor":"middle","dominant-baseline":"central"},a)),t.append(r),r});return{group:t,cells:n}}function YM(i,e){let t=i,n=!1,a=-t*Gn;const s=Fe("section",{class:"learn-game learn-caesar"});s.append(Fe("div",{class:"learn-game-head"},Fe("strong",{},p("web_learn_caesar_title")))),s.append(Fe("p",{class:"learn-game-status"},p("web_learn_caesar_hint")));const r=xt("svg",{viewBox:"-200 -200 400 400",class:"learn-caesar-disc",role:"img"});r.append(xt("circle",{r:196,class:"outer-disc"})),r.append(xt("path",{d:XM(196,92,Gn/2),class:"window"}));const o=em(168,"outer-letters");r.append(o.group);for(let A=0;A{o.cells.forEach((B,E)=>B.classList.toggle("marked",E===A)),u.cells.forEach((B,E)=>B.classList.toggle("marked",A!==void 0&&E===(A+t)%26))},T=()=>{m.textContent=String(t),l.setAttribute("transform",`rotate(${a})`),r.setAttribute("aria-label",p("web_learn_caesar_key_fmt",t)),x.textContent=p(n?"web_learn_caesar_secret":"web_learn_caesar_plain"),w.textContent=p(n?"web_learn_caesar_plain":"web_learn_caesar_secret"),f.classList.toggle("active",!n),b.classList.toggle("active",n),I.textContent=$M(v.value,n?-t:t)||" ";const A=Array.from(v.value.toUpperCase()).reverse().find(E=>x1.includes(E));if(A===void 0)return k();const B=x1.indexOf(A);k(n?(B-t+26)%26:B)},j=A=>{t=(A%26+26)%26,a=-t*Gn,T()};c.addEventListener("click",()=>j(t-1)),d.addEventListener("click",()=>j(t+1)),f.addEventListener("click",()=>{var A;n&&(v.value=((A=I.textContent)==null?void 0:A.trim())??""),n=!1,T()}),b.addEventListener("click",()=>{var A;n||(v.value=((A=I.textContent)==null?void 0:A.trim())??""),n=!0,T()}),v.addEventListener("input",T),o.cells.forEach((A,B)=>A.addEventListener("click",()=>k(B)));let D;const O=A=>{const B=r.getBoundingClientRect();return Math.atan2(A.clientY-(B.top+B.height/2),A.clientX-(B.left+B.width/2))*180/Math.PI};l.addEventListener("pointerdown",A=>{const B=A;D=O(B)-a,l.classList.add("dragging"),r.setPointerCapture(B.pointerId),B.preventDefault()}),r.addEventListener("pointermove",A=>{if(D===void 0)return;a=O(A)-D,l.setAttribute("transform",`rotate(${a})`);const B=Math.round(-a/Gn);if((B%26+26)%26!==t){t=(B%26+26)%26;const E=a;T(),a=E,l.setAttribute("transform",`rotate(${a})`)}});const C=()=>{D!==void 0&&(D=void 0,l.classList.remove("dragging"),j(t))};return r.addEventListener("pointerup",C),r.addEventListener("pointercancel",C),T(),s}function XM(i,e,t){const n=(a,s)=>{const r=(s-90)*Math.PI/180;return`${(a*Math.cos(r)).toFixed(2)} ${(a*Math.sin(r)).toFixed(2)}`};return`M ${n(i,-t)} A ${i} ${i} 0 0 1 ${n(i,t)} L ${n(e,t)} A ${e} ${e} 0 0 0 ${n(e,-t)} Z`}const l0=i=>p(`web_visubot_part_${i}`),rg=new WeakMap;function og(i,e,t,n){const a=document.createElement("div");a.className="visubot-model";const s=document.createElement("div");s.className="visubot-stage";const r=document.createElement("div");r.className="visubot-part-label",r.hidden=!0,s.append(r);const o=(c,d,h)=>{r.hidden=!1,r.textContent=l0(c),r.style.left=`${Math.min(d+12,s.clientWidth-140)}px`,r.style.top=`${h+12}px`},l=document.createElement("p");l.className="visubot-model-hint hint",l.textContent=p("web_visubot_tap_part"),l.hidden=!!n,a.append(s,l);const u=K(async()=>{const{Robot3D:c}=await import("./robot3d-I0g91EHr.js");return{Robot3D:c}},[],import.meta.url).then(({Robot3D:c})=>{const d=new c(s);d.showcase(),d.highlight(i),i.includes("leds")&&d.setLed([40,90,255]),d.focusOn([],e==="unten"||e==="bottom"?"":e,!1,1),d.focusOn(i,e,t);let h;return s.addEventListener("pointerdown",g=>h={x:g.clientX,y:g.clientY}),s.addEventListener("pointerup",g=>{if(!h||Math.hypot(g.clientX-h.x,g.clientY-h.y)>5)return;const f=d.partAt(g.clientX,g.clientY);if(!f)return;if(n)return n(f);d.highlight(f);const b=s.getBoundingClientRect();o(f,g.clientX-b.left,g.clientY-b.top)}),s.addEventListener("pointermove",g=>{if(g.pointerType!=="mouse"||n)return;const f=d.partAt(g.clientX,g.clientY);if(r.hidden=!f,!f)return;const b=s.getBoundingClientRect();o(f,g.clientX-b.left,g.clientY-b.top)}),s.addEventListener("pointerleave",()=>r.hidden=!0),d}).catch(c=>{console.error(c),s.textContent=p("web_visubot_no_3d")}),m={box:a,ready:u,focus:i,view:e};return rg.set(a,m),m}function KM(i,e,t=!1){return og(i,e,t).box}function eZ(i){const e=i.querySelector(".visubot-model"),t=e&&rg.get(e);for(const n of i.querySelectorAll("[data-robot-part]")){const a=(n.dataset.robotPart??"").split(",").filter(Boolean);if(n.title=a.map(l0).join(", "),!t)continue;const s=()=>void t.ready.then(o=>o==null?void 0:o.highlight(a)),r=()=>void t.ready.then(o=>o==null?void 0:o.highlight(t.focus));n.addEventListener("mouseenter",s),n.addEventListener("focus",s),n.addEventListener("mouseleave",r),n.addEventListener("blur",r),n.addEventListener("click",()=>{t.ready.then(o=>{o==null||o.highlight(a),o==null||o.focusOn(a,t.view)}),t.box.scrollIntoView({block:"nearest",behavior:"smooth"})})}}function tZ(i,e){let t=0;const n=document.createElement("div");n.className="visubot-quiz-question";const a=document.createElement("p");a.className="visubot-quiz-feedback",a.setAttribute("aria-live","polite");const s=()=>{n.innerHTML=Tn(`**${t+1}/${i.length}** ${i[t].question}`)},r=og([],void 0,!1,l=>{if(!(t>=i.length)){if(r.ready.then(u=>u==null?void 0:u.highlight(l)),l!==i[t].part){a.className="visubot-quiz-feedback wrong",a.textContent=p("web_visubot_quiz_wrong_fmt",l0(l));return}t++,a.className="visubot-quiz-feedback right",t{u.forEach(v=>{window.clearTimeout(v),window.clearInterval(v)}),u=[]},c=()=>{a.textContent=`${p("web_game_round_fmt",o+1,r)} · ${p("web_game_score_fmt",l)}`},d=()=>{const v=$("button",{class:"primary"},o+1{o++,o{const v=i.rounds[o],w=i.seconds,I=$("div",{class:"learn-bomb-fuse"},$("span",{})),z=$("span",{class:"learn-bomb-time"}),k=$("div",{class:"learn-bomb","aria-live":"polite"},$("span",{class:"learn-bomb-icon","aria-hidden":"true"},"💣"),z,I),T=$("div",{class:"learn-game-feedback",role:"status"}),j=v.code.split(` `).map((E,U)=>{const ee=$("button",{class:"ln",type:"button"},E||" ");return ee.disabled=!E.trim(),ee.addEventListener("click",()=>A(U+1===v.wrongLine?"right":"wrong",ee)),ee}),D=$("div",{class:"learn-game-code learn-bomb-code mono",dir:"ltr"},...j),O=Date.now(),C=()=>{if(!t.isConnected&&Date.now()-O>1e3)return m();const E=Math.max(0,w-(Date.now()-O)/1e3);z.textContent=p("web_game_time_fmt",Math.ceil(E)),I.firstChild.style.width=`${E/w*100}%`,k.classList.toggle("hurry",E<=5),E<=0&&A("time")},A=(E,U)=>{m(),j.forEach((Ie,fe)=>{Ie.disabled=!0,fe+1===v.wrongLine&&Ie.classList.add("right")}),U&&E==="wrong"&&U.classList.add("wrong");const ee=E==="right";ee&&l++,c(),k.classList.add(ee?"defused":"boom"),k.firstChild.textContent=ee?"✂️":"💥",T.className=`learn-game-feedback ${ee?"right":"wrong"}`;const he=d();T.replaceChildren($("p",{},p(ee?"web_game_defused":E==="time"?"web_game_boom_time":"web_game_boom_wrong")),Fn("div",{class:"learn-game-explain"},v.explanation),$("p",{class:"learn-bomb-fix"},`${p("web_game_fix")} `,$("code",{},v.fix.trim())),he),he.focus({preventScroll:!0})};s.replaceChildren(k,Fn("p",{class:"learn-game-question"},v.question),D,T),C();const B=window.setInterval(C,200);u.push(B)},g=()=>{const v=i.rounds[o],w=[];v.code.trim()&&w.push(nm(v.code).element),w.push(Fn("p",{class:"learn-game-question"},v.question),$("p",{class:"learn-order-hint"},p("web_game_order_hint")));const I=$("div",{class:"learn-game-options learn-order"}),z=$("div",{class:"learn-game-feedback",role:"status"});let k=0;const T=iZ(v.options.length).map(D=>{const O=$("span",{class:"learn-order-badge","aria-hidden":"true"}),C=$("span",{});C.innerHTML=Ce(v.options[D].text);const A=$("button",{},O,C);return A.addEventListener("click",()=>{if(D!==k)return A.classList.add("wrong"),j(!1);A.classList.add("right"),O.textContent=String(++k),A.disabled=!0,k===v.options.length&&j(!0)}),I.append(A),{k:D,b:A,badge:O}}),j=D=>{for(const{k:C,b:A,badge:B}of[...T].sort((E,U)=>E.k-U.k))A.disabled=!0,B.textContent=String(C+1),I.append(A);D&&l++,c(),z.className=`learn-game-feedback ${D?"right":"wrong"}`;const O=d();z.replaceChildren($("p",{},p(D?"web_game_right":"web_game_wrong_short")),Fn("div",{class:"learn-game-explain"},v.explanation),O),O.focus({preventScroll:!0})};s.replaceChildren(...w,I,z)},f=()=>{if(m(),i.kind==="bombe"||i.kind==="reihenfolge"){c(),i.kind==="bombe"?h():g();return}const v=i.rounds[o];c();const w=nm(v.code),I=[];let z;i.kind==="zuhoerer"?(z=aZ(Gh(v.code),w),I.push($("div",{class:"learn-swing-row"},w.element,z.element)),v.clicks.length&&I.push($("p",{class:"learn-swing-clicks"},`${p("web_game_clicks")} `,...v.clicks.flatMap((O,C)=>[...C?[" → "]:[],$("code",{},O)])))):v.code.trim()&&I.push(w.element),I.push(Fn("p",{class:"learn-game-question"},v.question));const k=$("div",{class:`learn-game-options ${i.kind==="layout"?"pictures":""}`}),T=$("div",{class:"learn-game-feedback",role:"status"}),j=v.options.map(O=>{const C=$("button",{});return i.kind==="layout"?C.append(rZ(O.text)):O.text.includes(` `)?C.append(sZ(O.text)):C.innerHTML=Ce(O.text),C.addEventListener("click",()=>D(O.right,C)),k.append(C),C}),D=(O,C)=>{j.forEach((B,E)=>{B.disabled=!0,v.options[E].right&&B.classList.add("right")}),O||C.classList.add("wrong"),O&&l++,c(),T.className=`learn-game-feedback ${O?"right":"wrong"}`;const A=d();T.replaceChildren($("p",{},p(O?"web_game_right":"web_game_wrong_short")),Fn("div",{class:"learn-game-explain"},v.explanation)),T.append(A),z&&(u=z.replay(v.clicks,()=>A.before($("p",{class:"learn-swing-try"},p("web_game_try"))))),A.focus({preventScroll:!0})};s.replaceChildren(...I,k,T)},b=()=>{m(),a.textContent="";const v=$("button",{class:"primary"},p("web_game_again"));v.addEventListener("click",()=>{o=l=0,f()}),s.replaceChildren($("p",{class:"learn-game-result"},p("web_game_done_fmt",l,r)),$("p",{},p(l===r?"web_game_perfect":l>=r*.7?"web_game_good":"web_game_practice_short")),v)},x=$("button",{class:"primary"},p("web_game_start"));return x.addEventListener("click",f),s.append(Fn("p",{},i.intro),x),t}function iZ(i){const e=[...Array(i).keys()];for(;e.every((t,n)=>t===n);)for(let t=i-1;t>0;t--){const n=Math.floor(Math.random()*(t+1));[e[t],e[n]]=[e[n],e[t]]}return e}function nm(i){const e=i.split(` `).map(n=>$("div",{class:"ln"},n||" "));return{element:$("pre",{class:"learn-game-code mono",dir:"ltr"},...e),highlight(n,a){e.forEach((s,r)=>s.classList.toggle("hit",n!==void 0&&r>=n&&r<=(a??n)))}}}function aZ(i,e){const t=Hh(i),n=$("div",{class:"learn-swing-window",dir:"ltr"});n.append($("div",{class:"learn-swing-title"},i.title||" "));const a=$("div",{class:"learn-swing-body"}),s=new Map;for(const c of i.labels){const d=$("div",{class:"learn-swing-label"},t.texts[c.name]);s.set(c.name,d),a.append(d)}const r=i.buttons.map(c=>{const d=$("button",{class:"learn-swing-button",disabled:""},t.texts[c.name]);return s.set(c.name,d),a.append(d),d}),o=$("p",{class:"learn-swing-event",role:"status"}),l=$("pre",{class:"learn-swing-console mono",hidden:""});n.append(a,o,l);const u=c=>{var h,g;const d=s.get(c.button);d.classList.add("pressed"),window.setTimeout(()=>d.classList.remove("pressed"),350),e.highlight((h=c.listener)==null?void 0:h.from,(g=c.listener)==null?void 0:g.to),o.textContent=c.listener?p("web_game_event_fmt",d.textContent??""):p("web_game_nobody"),o.className=`learn-swing-event ${c.listener?"heard":"nobody"}`;for(const[f,b]of Object.entries(c.texts)){const x=s.get(f);x&&x.textContent!==b&&(x.textContent=b,x.classList.remove("changed"),x.offsetWidth,x.classList.add("changed"))}c.console.length&&(l.hidden=!1,l.textContent+=c.console.map(f=>`${f} @@ -64236,10 +64297,10 @@ ${l}`)}Na=aM(((o=e.find(([l])=>l==="begriffe.md"))==null?void 0:o[1])??"")}const ## ${p("web_learn_terms")} -${a}`));this.body.append(s),this.foldReference(s)}}foldReference(e){const t="visustruct.reference.open";let n=[];try{n=JSON.parse(localStorage.getItem(t)??"[]")}catch{}for(const a of[...e.querySelectorAll("h2")]){const s=a.textContent??"",r=_("details",{class:"reference-group"});r.open=n.includes(s);const o=_("summary",{},s);for(a.replaceWith(r),r.append(o);r.nextSibling&&r.nextSibling.nodeName!=="H2";)r.append(r.nextSibling);r.addEventListener("toggle",()=>{n=r.open?[...new Set([...n,s])]:n.filter(l=>l!==s);try{localStorage.setItem(t,JSON.stringify(n))}catch{}})}}showReference(){this.tab="reference",this.persist(),this.render()}persist(){be.setView({tab:this.tab,lesson:this.lessonId,task:this.taskId})}openLesson(e){this.tab="lessons",this.lessonId=e,this.returnTo=void 0,this.persist(),this.render(),this.body.scrollTop=0}renderLessonList(){this.body.append(_("p",{class:"hint"},p("web_learn_intro")));for(const e of IZ()){this.body.append(_("h3",{class:"learn-section"},e.name));const t=_("ol",{class:"learn-list"});for(const n of e.lessons){const a=be.lesson(n.id),s=a.done?"✓":a.step>0?p("web_learn_step_of_fmt",a.step+1,n.steps.length):"",r=_("button",{class:"learn-item"+(a.done?" done":""),"data-lesson":n.id},_("span",{class:"learn-num"},String(n.number)),_("span",{class:"learn-item-text"},_("strong",{},n.robot?`🤖 ${n.title}`:n.title),_("small",{},n.summary)),_("span",{class:"learn-status"},s));r.addEventListener("click",()=>this.openLesson(n.id)),t.append(_("li",{},r))}this.body.append(t)}this.body.append(this.renderTeacherBox())}renderLesson(e){var u;const t=be.lesson(e.id),n=Math.min(t.step,e.steps.length-1),a=e.steps[n],s=_("button",{class:"learn-back"},`← ${p("web_learn_all_lessons")}`);s.addEventListener("click",()=>this.openLesson(void 0));const r=_("nav",{class:"learn-progress","aria-label":p("web_learn_step_of_fmt",n+1,e.steps.length)});r.append(...e.steps.map((m,c)=>{const d=p("web_learn_step_fmt",c+1,m.title),h=cthis.goToStep(e,c)),g})),this.body.append(_("div",{class:"learn-lesson-head"},_("div",{class:"learn-head-row"},s,this.stepNav(e,n,t.done,"learn-nav learn-nav-top")),_("p",{class:"learn-kicker"},`${p("web_learn_lesson_fmt",e.number)} · ${e.section}${e.robot?" · 🤖 VisuBot":""}`),_("h2",{class:"learn-title"},_("span",{class:"learn-num","aria-hidden":"true"},String(e.number)),e.title),r,_("h3",{class:"learn-step-title"},`${n+1}. ${a.title}`)));const o=((u=this.returnTo)==null?void 0:u.lesson)===e.id&&this.returnTo.step!==n?this.returnTo:void 0,l=()=>{const m=_("button",{class:"learn-return"},`↩ ${p("web_learn_back_to_checklist")}`);return m.addEventListener("click",()=>{this.returnTo=void 0,this.goToStep(e,o.step),this.body.scrollTop=o.scroll}),m};o&&this.body.append(l()),a.blocks.forEach((m,c)=>this.body.append(this.renderBlock(m,`${n}-${c}`,e))),lm(this.body),eZ(this.body),this.openNeededColumns(a.blocks),rm(this.body,Na),this.body.append(this.stepNav(e,n,t.done,"learn-nav")),o&&this.body.append(l())}stepNav(e,t,n,a){const s=_("div",{class:a}),r=_("button",{},`← ${p("web_learn_back")}`);if(r.disabled=t===0,r.addEventListener("click",()=>this.goToStep(e,t-1)),s.append(r),tthis.goToStep(e,t+1)),s.append(o)}else{const o=_("button",{class:"primary"},n?`✓ ${p("web_learn_done")}`:p("web_learn_finish"));o.addEventListener("click",()=>{be.updateLesson(e.id,{done:!0});const l=Ct.find(u=>u.number===e.number+1);this.openLesson(l==null?void 0:l.id)}),s.append(o)}return s}goToStep(e,t){be.updateLesson(e.id,{step:t}),this.render(),this.body.scrollTop=0}openNeededColumns(e){const t=e.flatMap(n=>n.kind==="exercise"?[n.exercise]:[]);yZ(this.body)?(this.host.showEditor(),xZ(this.body)&&this.host.reveal(["palette"])):vZ(this.body)?this.host.showFiles():t.some(n=>n.code!=="java")?this.host.showEditor():(t.length>0||this.body.querySelector(".lesson-code[data-lang=java]"))&&this.host.showJava(),wZ(this.body)&&this.host.showLiveCode()}renderTaskList(){this.body.append(_("p",{class:"hint"},p("web_learn_tasks_intro")));const e=_("ul",{class:"learn-list"});for(const t of An){const n=this.taskExercises(t),a=n.length>0&&n.every(o=>be.exercise(o.id).done),s=Ct.find(o=>o.number===t.after),r=_("button",{class:"learn-item"+(a?" done":""),"data-task":t.id},_("span",{class:"learn-num","aria-label":p("web_learn_level_fmt",t.level)},"★".repeat(t.level)),_("span",{class:"learn-item-text"},_("strong",{},t.title),_("small",{},s?p("web_learn_after_fmt",s.number,s.title):"")),_("span",{class:"learn-status"},a?"✓":""));r.addEventListener("click",()=>{this.taskId=t.id,this.persist(),this.render(),this.body.scrollTop=0}),e.append(_("li",{},r))}this.body.append(e,this.renderTeacherBox())}renderTeacherBox(){const e=_("details",{class:"learn-teacher"},_("summary",{},p("web_learn_teacher")));if($u()){e.setAttribute("open","");const s=_("button",{},p("web_learn_teacher_off"));return s.addEventListener("click",()=>{VM(),this.render()}),e.append(_("p",{},p("web_learn_teacher_on")),s),e}const t=_("input",{type:"password",autocomplete:"off","aria-label":p("web_learn_teacher_code"),placeholder:p("web_learn_teacher_code")}),n=_("p",{class:"learn-result",role:"status"}),a=_("form",{class:"group"},t,_("button",{type:"submit"},p("web_learn_teacher_unlock")));return a.addEventListener("submit",async s=>{s.preventDefault(),await HM(t.value)?this.render():(n.className="learn-result info",n.textContent=p("web_learn_teacher_wrong"))}),e.append(_("p",{class:"hint"},p("web_learn_teacher_intro")),a,n),e}taskExercises(e){return e.blocks.flatMap(t=>t.kind==="exercise"?[t.exercise]:[])}renderTask(e){const t=_("button",{class:"learn-back"},`← ${p("web_learn_all_tasks")}`);t.addEventListener("click",()=>{this.taskId=void 0,this.persist(),this.render()});const n=Ct.find(a=>a.number===e.after);if(this.body.append(t,_("h2",{class:"learn-title"},e.title)),n){const a=_("button",{class:"link-button"},p("web_learn_after_fmt",n.number,n.title));a.addEventListener("click",()=>this.openLesson(n.id)),this.body.append(_("p",{class:"learn-kicker"},a))}e.blocks.forEach((a,s)=>this.body.append(this.renderBlock(a,`task-${s}`))),lm(this.body),this.openNeededColumns(e.blocks),rm(this.body,Na)}renderBlock(e,t,n){switch(e.kind){case"markdown":return this.withOpenButtons(tt("div",{class:"learn-text"},Tn(e.text)));case"diagram":return this.renderDiagram(e.file,e.caption);case"exercise":return this.renderExercise(e.exercise);case"competences":return this.renderCompetences(e.items);case"checklist":return this.renderChecklist(e.items,t,n);case"quiz":return this.renderQuiz(e.questions,t,n);case"brag":return this.renderBrag(e.text,e.tip);case"images":return this.renderImages(e.files,e.caption);case"graphic":return this.renderGraphic(e.file,e.caption,e.labeled);case"game":return this.renderGame(e.game);case"roundGame":return nZ(e.game,ra);case"rescueGame":return oZ(e.game,ra);case"caesar":return YM(e.key,e.text);case"cloze":return uZ(e.cloze);case"pap":return pZ(e.pap);case"textFile":return ig(e.name,e.content);case"robotModel":return KM(e.focus,e.view,e.spin);case"robotQuiz":return tZ(e.tasks,e.done)}}renderBrag(e,t=!1){const n=_("aside",{class:"learn-brag"});n.append(_("img",{src:ra,alt:"",width:"48",height:"48"}));const a=_("div",{},_("p",{class:"learn-brag-title"},p(t?"web_learn_ludwig_tip":"web_learn_brag")));return a.append(tt("div",{class:"learn-text"},Tn(e))),n.append(a),n}renderGame(e){const n=_("section",{class:"learn-game"}),a=_("div",{class:"learn-game-head"});a.append(_("img",{src:ra,alt:"",width:"40",height:"40"}),_("strong",{},p("web_game_title")));const s=_("p",{class:"learn-game-status"}),r=_("div",{class:"learn-game-stage"});n.append(a,s,r);let o=0,l=0;const u=()=>{const d=cx(e,o,10);s.textContent=`${p("web_game_round_fmt",o+1,10)} · ${p("web_game_score_fmt",l)}`;const h=_("div",{class:"learn-game-values mono"});for(const[w,I]of dx(d))h.append(_("code",{},`${w} = ${I}`));const g=_("div",{class:"group learn-game-answers"}),f=_("button",{class:"learn-game-true"},`✓ ${p("web_game_true")}`),b=_("button",{class:"learn-game-false"},`✗ ${p("web_game_false")}`);g.append(f,b);const x=_("div",{class:"learn-game-feedback",role:"status"}),v=w=>{f.disabled=b.disabled=!0;const I=w===d.answer;I&&l++,s.textContent=`${p("web_game_round_fmt",o+1,10)} · ${p("web_game_score_fmt",l)}`,x.className=`learn-game-feedback ${I?"right":"wrong"}`;const z=_("div",{class:"learn-game-steps mono"});ux(d.condition,d.values).forEach((T,j)=>z.append(_("div",{},`${j?"→ ":""}${T}`)));const k=_("button",{class:"primary"},o+1<10?p("web_game_next"):p("web_game_finish"));k.addEventListener("click",()=>{o++,o<10?u():m()}),x.replaceChildren(_("p",{},p(I?"web_game_right":"web_game_wrong")),z,k),k.focus()};f.addEventListener("click",()=>v(!0)),b.addEventListener("click",()=>v(!1)),r.replaceChildren(h,_("div",{class:"learn-game-condition mono"},d.condition),g,x)},m=()=>{s.textContent="";const d=_("button",{class:"primary"},p("web_game_again"));d.addEventListener("click",()=>{o=l=0,u()}),r.replaceChildren(_("p",{class:"learn-game-result"},p("web_game_done_fmt",l,10)),_("p",{},p(l===10?"web_game_perfect":l>=10*.7?"web_game_good":"web_game_practice")),d)},c=_("button",{class:"primary"},p("web_game_start"));return c.addEventListener("click",u),r.append(_("p",{},p("web_game_intro")),c),n}renderImages(e,t){const n=_("figure",{class:"learn-figure"}),a=_("div",{class:"learn-images"});for(const s of e){const r=zr(s);r&&a.append(_("img",{src:r,alt:"",loading:"lazy"}))}return n.append(a),t&&n.append(tt("figcaption",{},Ce(t))),n}renderGraphic(e,t,n){const a=_("figure",{class:"learn-figure"}),s=zr(e),r=n?zr(n):void 0;if(s&&r){const o=_("img",{class:"learn-graphic",src:s,alt:"",loading:"lazy"}),l=_("button",{class:"learn-graphic-toggle",type:"button",title:p("web_learn_graphic_labels"),"aria-pressed":"false"},o);l.addEventListener("click",()=>{const u=l.getAttribute("aria-pressed")!=="true";l.setAttribute("aria-pressed",String(u)),o.src=u?r:s}),a.append(l,_("p",{class:"learn-graphic-hint"},p("web_learn_graphic_labels")))}else s&&a.append(_("img",{class:"learn-graphic",src:s,alt:"",loading:"lazy"}));return t&&a.append(tt("figcaption",{},Ce(t))),a}withOpenButtons(e){for(const t of e.querySelectorAll("pre.lesson-code[data-open=editor]")){const n=t.textContent??"",a=_("button",{class:"learn-open-code"},p("web_learn_open_in_editor"));a.addEventListener("click",()=>this.host.openJavaCode(n)),t.after(a)}return e}renderDiagram(e,t){const n=ti(e),a=_("figure",{class:"learn-figure"});if(!n)return a;const s=this.host.preview(n);s&&a.append(_("div",{class:"learn-preview",dir:"ltr"},s)),t&&a.append(tt("figcaption",{},Ce(t)));const r=_("button",{},p("web_learn_open_in_editor"));return r.addEventListener("click",()=>this.host.openDiagram(n,e)),a.append(r),a}renderExercise(e){const t=_("section",{class:"learn-exercise","data-exercise":e.id}),n=()=>be.exercise(e.id),a=_("span",{class:"learn-badge"},`✓ ${p("web_learn_solved")}`);a.hidden=!n().done;const s=e.code==="java"?p("web_learn_solve_in_code",p("web_live_title")):p("web_learn_solve_in_editor",p("web_editor_title"));t.append(_("h4",{},`${p("web_learn_exercise")}: ${e.title}`,a),_("p",{class:"learn-where"},s),tt("div",{class:"learn-text"},Tn(e.task)));const r=_("div",{class:"learn-result",role:"status"}),o=_("div",{class:"learn-hints"}),l=_("div",{class:"group"}),u=_("button",{class:"primary"},p("web_learn_open_exercise"));u.addEventListener("click",()=>{const d=n().xml;let h=um(e);if(d)try{h=Nl(d)}catch{}this.host.openExercise(e,h)});const m=_("button",{},p("web_learn_check"));if(m.addEventListener("click",()=>{const d=this.host.exerciseDocument(e.id);if(!d){r.className="learn-result info",r.textContent=p("web_learn_open_first");return}if(d.elements.every(Bl)){r.className="learn-result info",r.textContent=p("web_learn_empty");return}this.host.stopSimulation();const h=ax(d,e.tests,this.host.subprogramsFor(e.id),Ja),g=sx(d),f=e.requires.map(v=>v==="forZaehlSchleife"?"forSchleife":v).filter(v=>v in S&&!g.has(S[v])),b=e.loopDepth!==void 0&&Do(d.elements)v.passed)&&f.length===0&&!b;this.showResult(r,h,f,x,b),x&&(be.updateExercise(e.id,{done:!0}),a.hidden=!1)}),l.append(u,m),e.hints.length>0){const d=_("button",{},p("web_learn_hint"));d.addEventListener("click",()=>{const h=o.children.length;if(h>=e.hints.length)return;const g=e.hints.length>1?`**${p("web_learn_hint_fmt",h+1,e.hints.length)}:** `:"";o.append(tt("aside",{class:"lesson-note"},Tn(g+e.hints[h]))),d.textContent=p("web_learn_hint_more"),d.toggleAttribute("disabled",h+1>=e.hints.length)}),l.append(d)}const c=_("button",{class:"danger-text"},p("web_learn_reset"));if(c.addEventListener("click",()=>{if(c.dataset.confirm!=="1"){c.dataset.confirm="1",c.textContent=p("web_learn_reset_confirm"),setTimeout(()=>{c.dataset.confirm="",c.textContent=p("web_learn_reset")},4e3);return}be.resetExercise(e.id),this.host.resetExercise(e.id,um(e)),a.hidden=!0,r.replaceChildren(),r.className="learn-result",c.dataset.confirm="",c.textContent=p("web_learn_reset")}),l.append(c),t.append(l,o,r),$u()&&e.solution){const d=ti(e.solution);if(d){const h=_("details",{class:"learn-solution"},_("summary",{},p("web_learn_solution")));h.addEventListener("toggle",()=>{if(!h.open||h.querySelector(".learn-preview"))return;const g=this.host.preview(d);g&&h.append(_("div",{class:"learn-preview",dir:"ltr"},g));const f=_("button",{},p("web_learn_open_in_editor"));f.addEventListener("click",()=>{this.host.openDiagram(d,e.solution);for(const b of e.subprograms){const x=ti(b);x&&this.host.openDiagram(x,b)}});for(const b of e.subprograms){const x=ti(b),v=x&&this.host.preview(x);v&&h.append(_("div",{class:"learn-preview",dir:"ltr"},v))}h.append(f)}),t.append(h)}}return t}showResult(e,t,n,a,s){var o,l,u,m,c;e.className="learn-result "+(a?"ok":"fail"),e.replaceChildren(_("p",{class:"learn-result-head"},a?`🎉 ${p("web_learn_passed")}`:p("web_learn_failed")));for(const d of n)e.append(_("p",{},`✗ ${p("web_learn_missing_fmt",kZ(S[d]))}`));s&&e.append(_("p",{},`✗ ${p("web_visubot_depth_fmt",s)}`));const r=_("ul",{class:"learn-tests",dir:"auto"});for(const d of t){const h=d.test.world?t.filter(x=>x.test.world).indexOf(d)+1:0,g=d.test.world?`🗺 ${p("web_visubot_world_fmt",h)}`:d.test.actions?`🤖 ${p("web_visubot_actions")}`:d.test.sensors?`🎛 ${Object.entries(d.test.sensors).map(([x,v])=>`mbot.${x}() = ${v.join(" → ")}`).join(", ")}`:d.test.drive?`🤖 ${p("web_visubot_drive")}`:d.test.inputs.length?p("web_learn_input_fmt",d.test.inputs.join(", ")):p("web_learn_no_input"),f=[`${d.passed?"✓":"✗"} ${g}`],b=_("div",{class:"learn-test-detail"});if(d.test.drive&&b.append(_("span",{},`${p("web_learn_expected")}: `,_("code",{},X1(d.test.drive)||"–")),_("span",{},`${p("web_learn_actual")}: `,_("code",{},X1(d.result.drive??[])||"–"))),d.test.actions&&b.append(_("span",{},`${p("web_learn_expected")}: `,_("code",{},X1(d.test.actions)||"–")),_("span",{},`${p("web_learn_actual")}: `,_("code",{},X1(d.result.actions??[])||"–"))),d.test.led!==void 0){const x=v=>p(v?"web_visubot_led_on":"web_visubot_led_off");b.append(_("span",{},`💡 ${p("web_learn_expected")}: ${x(d.test.led)} · ${p("web_learn_actual")}: ${x(d.result.led)}`))}if(d.test.tone!==void 0){const x=v=>p(v?"web_visubot_tone_yes":"web_visubot_tone_no");b.append(_("span",{},`🔊 ${p("web_learn_expected")}: ${x(d.test.tone)} · ${p("web_learn_actual")}: ${x(d.result.tone)}`))}d.test.screen!==void 0&&b.append(_("span",{},`📺 ${p("web_learn_expected")}: `,_("code",{},d.test.screen),` · ${p("web_learn_actual")}: `,_("code",{},d.result.screen??"–"))),d.test.world&&(((l=(o=Ja(d.test.world))==null?void 0:o.goals)!=null&&l.length||(m=(u=Ja(d.test.world))==null?void 0:u.targets)!=null&&m.length)&&b.append(_("span",{},d.result.atGoal?`✓ ${p("web_visubot_goal_reached")}`:`✗ ${p("web_visubot_goal_missed")}`)),d.result.bumps&&b.append(_("span",{class:"learn-error"},`⚠︎ ${p("web_visubot_bumps")}: ${d.result.bumps}`))),(!d.test.drive&&!d.test.world&&!d.test.sensors&&!d.test.actions||d.result.outputs.length)&&b.append(_("span",{},`${p("web_learn_expected")}: `,_("code",{},d.test.expected.join(" | ")||"–")),_("span",{},`${p("web_learn_actual")}: `,_("code",{},d.result.outputs.join(" | ")||"–")));for(const x of d.test.files??[])b.append(_("span",{},`📄 ${x.name}, ${p("web_learn_expected")}: `,_("code",{},x.lines.join(" | ")||"–")),_("span",{},`📄 ${x.name}, ${p("web_learn_actual")}: `,_("code",{},Fh((c=d.result.files)==null?void 0:c.get(x.name)).join(" | ")||"–")));d.result.error&&b.append(_("span",{class:"learn-error"},t1(d.result.error))),d.result.missingInput&&b.append(_("span",{class:"learn-error"},p("web_learn_missing_input"))),d.result.tooManySteps&&b.append(_("span",{class:"learn-error"},p("web_learn_too_many_steps"))),!d.passed&&d.result.unusedInputs&&b.append(_("span",{class:"learn-error"},p("web_learn_unused_input"))),r.append(_("li",{class:d.passed?"ok":"fail"},...f,b))}e.append(r)}renderCompetences(e){const t=_("aside",{class:"learn-competences"},_("p",{class:"learn-competences-title"},p("web_learn_competences_intro"))),n=_("ul",{});for(const a of e)n.append(tt("li",{},Ce(a)));return t.append(n),t}renderChecklist(e,t,n){const a=[{value:"umbrella",icon:"☂️",label:p("web_learn_rating_umbrella")},{value:"cloud",icon:"⛅",label:p("web_learn_rating_cloud")},{value:"sun",icon:"☀️",label:p("web_learn_rating_sun")}],s=_("div",{class:"learn-checklist-wrap"}),r=_("p",{class:"learn-rating-legend"});for(const l of a)r.append(_("span",{},`${l.icon} ${l.label}`));const o=_("ul",{class:"learn-checklist"});return s.append(r,o),e.forEach((l,u)=>{var v;const m=`${t}-${u}`,c=n?(v=be.lesson(n.id).checks)==null?void 0:v[m]:void 0;let d=c===!0?"sun":c||void 0;const h=tt("span",{class:"learn-check-text"},Ce(l.text)),g=_("span",{class:"learn-rating",role:"group","aria-label":h.textContent??""}),f=a.map(w=>{const I=_("button",{class:"learn-rating-button",title:w.label,"aria-label":w.label},w.icon);return I.addEventListener("click",()=>{if(d=d===w.value?void 0:w.value,b(),!n)return;const z={...be.lesson(n.id).checks??{}};d?z[m]=d:delete z[m],be.updateLesson(n.id,{checks:Object.keys(z).length?z:void 0})}),I}),b=()=>{f.forEach((w,I)=>w.setAttribute("aria-pressed",String(a[I].value===d))),x.dataset.rating=d??""};g.append(...f);const x=_("li",{},h,g);if(n&&l.step!==void 0){const w=l.step,I=p("web_learn_step_fmt",w+1,n.steps[w].title),z=_("button",{class:"link-button learn-check-link",title:I,"aria-label":`${p("web_learn_review")}: ${I}`},p("web_learn_review"));z.addEventListener("click",()=>{this.returnTo={lesson:n.id,step:be.lesson(n.id).step,scroll:this.body.scrollTop},this.goToStep(n,w)}),x.append(z)}b(),o.append(x)}),s}renderQuiz(e,t,n){const a=_("div",{class:"learn-quiz"}),s=_("p",{class:"learn-score",role:"status"}),r=()=>n?be.lesson(n.id).quiz??{}:{},o=_("div",{class:"learn-review"}),l=()=>{const u=r(),m=(f,b)=>f.pairs?f.pairs.every((x,v)=>u[`${t}-${b}-${v}`]!==void 0):u[`${t}-${b}`]!==void 0,c=(f,b)=>{var x;return!!(f.pairs?f.pairs.every((v,w)=>mm(f)[u[`${t}-${b}-${w}`]]===f.pairs[w].right):(x=f.options[u[`${t}-${b}`]])!=null&&x.correct)},d=e.filter(m).length,h=e.filter(c).length,g=d===e.length;s.textContent=g?p("web_learn_score_fmt",h,e.length):"",o.replaceChildren(),g&&n&&this.fillChecklistReview(o,n,e,f=>c(e[f],f))};return e.forEach((u,m)=>{const c=`${t}-${m}`,d=_("fieldset",{},tt("legend",{},Ce(u.question))),h=tt("p",{class:"learn-explanation"},Ce(u.explanation??""));if(u.pairs){d.append(this.renderMatch(u,c,r,n,h,l),h),a.append(d);return}const g=f=>{d.querySelectorAll("button").forEach((b,x)=>{b.classList.toggle("right",f!==void 0&&u.options[x].correct),b.classList.toggle("wrong",f===x&&!u.options[x].correct),b.setAttribute("aria-pressed",String(f===x))}),h.hidden=f===void 0||!u.explanation};u.options.forEach((f,b)=>{const x=tt("button",{class:"learn-option"},Ce(f.text));x.addEventListener("click",()=>{n&&be.updateLesson(n.id,{quiz:{...r(),[c]:b}}),g(b),l()}),d.append(x)}),d.append(h),g(r()[c]),a.append(d)}),a.append(s,o),l(),a}fillChecklistReview(e,t,n,a){const s={sun:"☀️",cloud:"⛅",umbrella:"☂️"},r=be.lesson(t.id).checks??{},o=[];let l=0;t.steps.forEach((u,m)=>u.blocks.forEach((c,d)=>{c.kind==="checklist"&&c.items.forEach((h,g)=>{const f=r[`${m}-${d}-${g}`],b=f===!0?"sun":f||void 0,x=h.step===void 0?[]:n.map((k,T)=>k.step===h.step?T:-1).filter(k=>k>=0),v=x.filter(k=>!a(k));let w="";b==="sun"&&v.length?w=p("web_learn_review_overrated_fmt",v.map(k=>k+1).join(", ")):b&&b!=="sun"&&x.length&&!v.length&&(w=p("web_learn_review_underrated")),w&&l++;const I=_("li",{class:w?"learn-review-deviation":""}),z=tt("span",{class:"learn-check-text"},Ce(h.text));if(w&&z.append(_("br",{}),_("em",{},w)),I.append(z,_("span",{class:"learn-review-icon","aria-label":p(b?`web_learn_rating_${b}`:"web_learn_review_unrated")},b?s[b]:"–")),w&&b==="sun"&&h.step!==void 0){const k=h.step,T=_("button",{class:"link-button learn-check-link"},p("web_learn_review"));T.addEventListener("click",()=>{this.returnTo={lesson:t.id,step:be.lesson(t.id).step,scroll:this.body.scrollTop},this.goToStep(t,k)}),I.append(T)}o.push(I)})})),o.length&&e.append(_("p",{class:"learn-review-title"},`📋 ${p("web_learn_review_title")}`),_("p",{},p(l?"web_learn_review_hint":"web_learn_review_match")),_("ul",{class:"learn-checklist"},...o))}renderMatch(e,t,n,a,s,r){const o=e.pairs,l=mm(e),u=_("div",{class:"learn-match"});let m={};const c=()=>a?n():m,d=b=>a?be.updateLesson(a.id,{quiz:b}):m=b,h=b=>c()[`${t}-${b}`],g=o.map(b=>{const x=_("select",{class:"learn-match-select"});x.append(_("option",{value:""},"–")),l.forEach((w,I)=>x.append(_("option",{value:String(I)},w)));const v=tt("label",{class:"learn-match-left"},Ce(b.left));return v.append(x),u.append(v),x}),f=()=>{const b=o.every((x,v)=>h(v)!==void 0);g.forEach((x,v)=>{const w=h(v);x.value=w===void 0?"":String(w),x.classList.toggle("right",b&&l[w]===o[v].right),x.classList.toggle("wrong",b&&l[w]!==o[v].right)}),s.hidden=!b||!e.explanation};return g.forEach((b,x)=>b.addEventListener("change",()=>{const v={...c()};b.value===""?delete v[`${t}-${x}`]:v[`${t}-${x}`]=Number(b.value),d(v),f(),r()})),f(),u}}function mm(i){return(i.pairs??[]).map(e=>e.right).sort((e,t)=>e.localeCompare(t,"de"))}const _Z=""+new URL("visubot-CyGFOI9V.webp",import.meta.url).href,Us="visustruct.visubot";function $s(){try{return localStorage.getItem(Us)}catch{return null}}function ui(){const i=$s();return i==="1"||i==="kurs"?"on":"off"}const dg=()=>$s()==="2";function hg(){try{localStorage.setItem(Us,"2")}catch{}}const gg=()=>$s()==="3";function pg(){try{localStorage.setItem(Us,"3")}catch{}}const jZ=()=>$s()!==null;function Sr(i){try{localStorage.setItem(Us,i==="on"?"1":"0")}catch{}}const AZ=`VisuBot`,Hn=()=>ui()!=="off",cm=i=>i.replace(/[&<>"]/g,e=>({"&":"&","<":"<",">":">",'"':"""})[e]);function Lo(){const i=dg()?"object":gg()?"flow":ui(),e=(n,a)=>``,t={off:"web_visubot_world_visustruct_hint",on:"web_visubot_world_visubot_hint",object:"web_visuobject_world_hint",flow:"web_visuflow_world_hint"}[i];return`
    +${a}`));this.body.append(s),this.foldReference(s)}}foldReference(e){const t="visustruct.reference.open";let n=[];try{n=JSON.parse(localStorage.getItem(t)??"[]")}catch{}for(const a of[...e.querySelectorAll("h2")]){const s=a.textContent??"",r=_("details",{class:"reference-group"});r.open=n.includes(s);const o=_("summary",{},s);for(a.replaceWith(r),r.append(o);r.nextSibling&&r.nextSibling.nodeName!=="H2";)r.append(r.nextSibling);r.addEventListener("toggle",()=>{n=r.open?[...new Set([...n,s])]:n.filter(l=>l!==s);try{localStorage.setItem(t,JSON.stringify(n))}catch{}})}}showReference(){this.tab="reference",this.persist(),this.render()}persist(){be.setView({tab:this.tab,lesson:this.lessonId,task:this.taskId})}openLesson(e){this.tab="lessons",this.lessonId=e,this.returnTo=void 0,this.persist(),this.render(),this.body.scrollTop=0}renderLessonList(){this.body.append(_("p",{class:"hint"},p("web_learn_intro")));for(const e of IZ()){this.body.append(_("h3",{class:"learn-section"},e.name));const t=_("ol",{class:"learn-list"});for(const n of e.lessons){const a=be.lesson(n.id),s=a.done?"✓":a.step>0?p("web_learn_step_of_fmt",a.step+1,n.steps.length):"",r=_("button",{class:"learn-item"+(a.done?" done":""),"data-lesson":n.id},_("span",{class:"learn-num"},String(n.number)),_("span",{class:"learn-item-text"},_("strong",{},n.robot?`🤖 ${n.title}`:n.title),_("small",{},n.summary)),_("span",{class:"learn-status"},s));r.addEventListener("click",()=>this.openLesson(n.id)),t.append(_("li",{},r))}this.body.append(t)}this.body.append(this.renderTeacherBox())}renderLesson(e){var u;const t=be.lesson(e.id),n=Math.min(t.step,e.steps.length-1),a=e.steps[n],s=_("button",{class:"learn-back"},`← ${p("web_learn_all_lessons")}`);s.addEventListener("click",()=>this.openLesson(void 0));const r=_("nav",{class:"learn-progress","aria-label":p("web_learn_step_of_fmt",n+1,e.steps.length)});r.append(...e.steps.map((m,c)=>{const d=p("web_learn_step_fmt",c+1,m.title),h=cthis.goToStep(e,c)),g})),this.body.append(_("div",{class:"learn-lesson-head"},_("div",{class:"learn-head-row"},s,this.stepNav(e,n,t.done,"learn-nav learn-nav-top")),_("p",{class:"learn-kicker"},`${p("web_learn_lesson_fmt",e.number)} · ${e.section}${e.robot?" · 🤖 VisuBot":""}`),_("h2",{class:"learn-title"},_("span",{class:"learn-num","aria-hidden":"true"},String(e.number)),e.title),r,_("h3",{class:"learn-step-title"},`${n+1}. ${a.title}`)));const o=((u=this.returnTo)==null?void 0:u.lesson)===e.id&&this.returnTo.step!==n?this.returnTo:void 0,l=()=>{const m=_("button",{class:"learn-return"},`↩ ${p("web_learn_back_to_checklist")}`);return m.addEventListener("click",()=>{this.returnTo=void 0,this.goToStep(e,o.step),this.body.scrollTop=o.scroll}),m};o&&this.body.append(l()),a.blocks.forEach((m,c)=>this.body.append(this.renderBlock(m,`${n}-${c}`,e))),lm(this.body),eZ(this.body),this.openNeededColumns(a.blocks),rm(this.body,Na),this.body.append(this.stepNav(e,n,t.done,"learn-nav")),o&&this.body.append(l())}stepNav(e,t,n,a){const s=_("div",{class:a}),r=_("button",{},`← ${p("web_learn_back")}`);if(r.disabled=t===0,r.addEventListener("click",()=>this.goToStep(e,t-1)),s.append(r),tthis.goToStep(e,t+1)),s.append(o)}else{const o=_("button",{class:"primary"},n?`✓ ${p("web_learn_done")}`:p("web_learn_finish"));o.addEventListener("click",()=>{be.updateLesson(e.id,{done:!0});const l=Ct.find(u=>u.number===e.number+1);this.openLesson(l==null?void 0:l.id)}),s.append(o)}return s}goToStep(e,t){be.updateLesson(e.id,{step:t}),this.render(),this.body.scrollTop=0}openNeededColumns(e){const t=e.flatMap(n=>n.kind==="exercise"?[n.exercise]:[]);yZ(this.body)?(this.host.showEditor(),xZ(this.body)&&this.host.reveal(["palette"])):vZ(this.body)?this.host.showFiles():t.some(n=>n.code!=="java")?this.host.showEditor():(t.length>0||this.body.querySelector(".lesson-code[data-lang=java]"))&&this.host.showJava(),wZ(this.body)&&this.host.showLiveCode()}renderTaskList(){this.body.append(_("p",{class:"hint"},p("web_learn_tasks_intro")));const e=_("ul",{class:"learn-list"});for(const t of An){const n=this.taskExercises(t),a=n.length>0&&n.every(o=>be.exercise(o.id).done),s=Ct.find(o=>o.number===t.after),r=_("button",{class:"learn-item"+(a?" done":""),"data-task":t.id},_("span",{class:"learn-num","aria-label":p("web_learn_level_fmt",t.level)},"★".repeat(t.level)),_("span",{class:"learn-item-text"},_("strong",{},t.title),_("small",{},s?p("web_learn_after_fmt",s.number,s.title):"")),_("span",{class:"learn-status"},a?"✓":""));r.addEventListener("click",()=>{this.taskId=t.id,this.persist(),this.render(),this.body.scrollTop=0}),e.append(_("li",{},r))}this.body.append(e,this.renderTeacherBox())}renderTeacherBox(){const e=_("details",{class:"learn-teacher"},_("summary",{},p("web_learn_teacher")));if($u()){e.setAttribute("open","");const s=_("button",{},p("web_learn_teacher_off"));return s.addEventListener("click",()=>{VM(),this.render()}),e.append(_("p",{},p("web_learn_teacher_on")),s),e}const t=_("input",{type:"password",autocomplete:"off","aria-label":p("web_learn_teacher_code"),placeholder:p("web_learn_teacher_code")}),n=_("p",{class:"learn-result",role:"status"}),a=_("form",{class:"group"},t,_("button",{type:"submit"},p("web_learn_teacher_unlock")));return a.addEventListener("submit",async s=>{s.preventDefault(),await HM(t.value)?this.render():(n.className="learn-result info",n.textContent=p("web_learn_teacher_wrong"))}),e.append(_("p",{class:"hint"},p("web_learn_teacher_intro")),a,n),e}taskExercises(e){return e.blocks.flatMap(t=>t.kind==="exercise"?[t.exercise]:[])}renderTask(e){const t=_("button",{class:"learn-back"},`← ${p("web_learn_all_tasks")}`);t.addEventListener("click",()=>{this.taskId=void 0,this.persist(),this.render()});const n=Ct.find(a=>a.number===e.after);if(this.body.append(t,_("h2",{class:"learn-title"},e.title)),n){const a=_("button",{class:"link-button"},p("web_learn_after_fmt",n.number,n.title));a.addEventListener("click",()=>this.openLesson(n.id)),this.body.append(_("p",{class:"learn-kicker"},a))}e.blocks.forEach((a,s)=>this.body.append(this.renderBlock(a,`task-${s}`))),lm(this.body),this.openNeededColumns(e.blocks),rm(this.body,Na)}renderBlock(e,t,n){switch(e.kind){case"markdown":return this.withOpenButtons(tt("div",{class:"learn-text"},Tn(e.text)));case"diagram":return this.renderDiagram(e.file,e.caption);case"exercise":return this.renderExercise(e.exercise);case"competences":return this.renderCompetences(e.items);case"checklist":return this.renderChecklist(e.items,t,n);case"quiz":return this.renderQuiz(e.questions,t,n);case"brag":return this.renderBrag(e.text,e.tip,e.pro);case"images":return this.renderImages(e.files,e.caption);case"graphic":return this.renderGraphic(e.file,e.caption,e.labeled);case"game":return this.renderGame(e.game);case"roundGame":return nZ(e.game,ra);case"rescueGame":return oZ(e.game,ra);case"caesar":return YM(e.key,e.text);case"cloze":return uZ(e.cloze);case"pap":return pZ(e.pap);case"textFile":return ig(e.name,e.content);case"robotModel":return KM(e.focus,e.view,e.spin);case"robotQuiz":return tZ(e.tasks,e.done)}}renderBrag(e,t=!1,n=!1){const a=_("aside",{class:"learn-brag"});a.append(_("img",{src:ra,alt:"",width:"48",height:"48"}));const s=_("div",{},_("p",{class:"learn-brag-title"},p(n?"web_learn_pro":t?"web_learn_ludwig_tip":"web_learn_brag")));return s.append(tt("div",{class:"learn-text"},Tn(e))),a.append(s),a}renderGame(e){const n=_("section",{class:"learn-game"}),a=_("div",{class:"learn-game-head"});a.append(_("img",{src:ra,alt:"",width:"40",height:"40"}),_("strong",{},p("web_game_title")));const s=_("p",{class:"learn-game-status"}),r=_("div",{class:"learn-game-stage"});n.append(a,s,r);let o=0,l=0;const u=()=>{const d=cx(e,o,10);s.textContent=`${p("web_game_round_fmt",o+1,10)} · ${p("web_game_score_fmt",l)}`;const h=_("div",{class:"learn-game-values mono"});for(const[w,I]of dx(d))h.append(_("code",{},`${w} = ${I}`));const g=_("div",{class:"group learn-game-answers"}),f=_("button",{class:"learn-game-true"},`✓ ${p("web_game_true")}`),b=_("button",{class:"learn-game-false"},`✗ ${p("web_game_false")}`);g.append(f,b);const x=_("div",{class:"learn-game-feedback",role:"status"}),v=w=>{f.disabled=b.disabled=!0;const I=w===d.answer;I&&l++,s.textContent=`${p("web_game_round_fmt",o+1,10)} · ${p("web_game_score_fmt",l)}`,x.className=`learn-game-feedback ${I?"right":"wrong"}`;const z=_("div",{class:"learn-game-steps mono"});ux(d.condition,d.values).forEach((T,j)=>z.append(_("div",{},`${j?"→ ":""}${T}`)));const k=_("button",{class:"primary"},o+1<10?p("web_game_next"):p("web_game_finish"));k.addEventListener("click",()=>{o++,o<10?u():m()}),x.replaceChildren(_("p",{},p(I?"web_game_right":"web_game_wrong")),z,k),k.focus()};f.addEventListener("click",()=>v(!0)),b.addEventListener("click",()=>v(!1)),r.replaceChildren(h,_("div",{class:"learn-game-condition mono"},d.condition),g,x)},m=()=>{s.textContent="";const d=_("button",{class:"primary"},p("web_game_again"));d.addEventListener("click",()=>{o=l=0,u()}),r.replaceChildren(_("p",{class:"learn-game-result"},p("web_game_done_fmt",l,10)),_("p",{},p(l===10?"web_game_perfect":l>=10*.7?"web_game_good":"web_game_practice")),d)},c=_("button",{class:"primary"},p("web_game_start"));return c.addEventListener("click",u),r.append(_("p",{},p("web_game_intro")),c),n}renderImages(e,t){const n=_("figure",{class:"learn-figure"}),a=_("div",{class:"learn-images"});for(const s of e){const r=zr(s);r&&a.append(_("img",{src:r,alt:"",loading:"lazy"}))}return n.append(a),t&&n.append(tt("figcaption",{},Ce(t))),n}renderGraphic(e,t,n){const a=_("figure",{class:"learn-figure"}),s=zr(e),r=n?zr(n):void 0;if(s&&r){const o=_("img",{class:"learn-graphic",src:s,alt:"",loading:"lazy"}),l=_("button",{class:"learn-graphic-toggle",type:"button",title:p("web_learn_graphic_labels"),"aria-pressed":"false"},o);l.addEventListener("click",()=>{const u=l.getAttribute("aria-pressed")!=="true";l.setAttribute("aria-pressed",String(u)),o.src=u?r:s}),a.append(l,_("p",{class:"learn-graphic-hint"},p("web_learn_graphic_labels")))}else s&&a.append(_("img",{class:"learn-graphic",src:s,alt:"",loading:"lazy"}));return t&&a.append(tt("figcaption",{},Ce(t))),a}withOpenButtons(e){for(const t of e.querySelectorAll("pre.lesson-code[data-open=editor]")){const n=t.textContent??"",a=_("button",{class:"learn-open-code"},p("web_learn_open_in_editor"));a.addEventListener("click",()=>this.host.openJavaCode(n)),t.after(a)}return e}renderDiagram(e,t){const n=ti(e),a=_("figure",{class:"learn-figure"});if(!n)return a;const s=this.host.preview(n);s&&a.append(_("div",{class:"learn-preview",dir:"ltr"},s)),t&&a.append(tt("figcaption",{},Ce(t)));const r=_("button",{},p("web_learn_open_in_editor"));return r.addEventListener("click",()=>this.host.openDiagram(n,e)),a.append(r),a}renderExercise(e){const t=_("section",{class:"learn-exercise","data-exercise":e.id}),n=()=>be.exercise(e.id),a=_("span",{class:"learn-badge"},`✓ ${p("web_learn_solved")}`);a.hidden=!n().done;const s=e.code==="java"?p("web_learn_solve_in_code",p("web_live_title")):p("web_learn_solve_in_editor",p("web_editor_title"));t.append(_("h4",{},`${p("web_learn_exercise")}: ${e.title}`,a),_("p",{class:"learn-where"},s),tt("div",{class:"learn-text"},Tn(e.task)));const r=_("div",{class:"learn-result",role:"status"}),o=_("div",{class:"learn-hints"}),l=_("div",{class:"group"}),u=_("button",{class:"primary"},p("web_learn_open_exercise"));u.addEventListener("click",()=>{const d=n().xml;let h=um(e);if(d)try{h=Nl(d)}catch{}this.host.openExercise(e,h)});const m=_("button",{},p("web_learn_check"));if(m.addEventListener("click",()=>{const d=this.host.exerciseDocument(e.id);if(!d){r.className="learn-result info",r.textContent=p("web_learn_open_first");return}if(d.elements.every(Bl)){r.className="learn-result info",r.textContent=p("web_learn_empty");return}this.host.stopSimulation();const h=ax(d,e.tests,this.host.subprogramsFor(e.id),Ja),g=sx(d),f=e.requires.map(v=>v==="forZaehlSchleife"?"forSchleife":v).filter(v=>v in S&&!g.has(S[v])),b=e.loopDepth!==void 0&&Do(d.elements)v.passed)&&f.length===0&&!b;this.showResult(r,h,f,x,b),x&&(be.updateExercise(e.id,{done:!0}),a.hidden=!1)}),l.append(u,m),e.hints.length>0){const d=_("button",{},p("web_learn_hint"));d.addEventListener("click",()=>{const h=o.children.length;if(h>=e.hints.length)return;const g=e.hints.length>1?`**${p("web_learn_hint_fmt",h+1,e.hints.length)}:** `:"";o.append(tt("aside",{class:"lesson-note"},Tn(g+e.hints[h]))),d.textContent=p("web_learn_hint_more"),d.toggleAttribute("disabled",h+1>=e.hints.length)}),l.append(d)}const c=_("button",{class:"danger-text"},p("web_learn_reset"));if(c.addEventListener("click",()=>{if(c.dataset.confirm!=="1"){c.dataset.confirm="1",c.textContent=p("web_learn_reset_confirm"),setTimeout(()=>{c.dataset.confirm="",c.textContent=p("web_learn_reset")},4e3);return}be.resetExercise(e.id),this.host.resetExercise(e.id,um(e)),a.hidden=!0,r.replaceChildren(),r.className="learn-result",c.dataset.confirm="",c.textContent=p("web_learn_reset")}),l.append(c),t.append(l,o,r),$u()&&e.solution){const d=ti(e.solution);if(d){const h=_("details",{class:"learn-solution"},_("summary",{},p("web_learn_solution")));h.addEventListener("toggle",()=>{if(!h.open||h.querySelector(".learn-preview"))return;const g=this.host.preview(d);g&&h.append(_("div",{class:"learn-preview",dir:"ltr"},g));const f=_("button",{},p("web_learn_open_in_editor"));f.addEventListener("click",()=>{this.host.openDiagram(d,e.solution);for(const b of e.subprograms){const x=ti(b);x&&this.host.openDiagram(x,b)}});for(const b of e.subprograms){const x=ti(b),v=x&&this.host.preview(x);v&&h.append(_("div",{class:"learn-preview",dir:"ltr"},v))}h.append(f)}),t.append(h)}}return t}showResult(e,t,n,a,s){var o,l,u,m,c;e.className="learn-result "+(a?"ok":"fail"),e.replaceChildren(_("p",{class:"learn-result-head"},a?`🎉 ${p("web_learn_passed")}`:p("web_learn_failed")));for(const d of n)e.append(_("p",{},`✗ ${p("web_learn_missing_fmt",kZ(S[d]))}`));s&&e.append(_("p",{},`✗ ${p("web_visubot_depth_fmt",s)}`));const r=_("ul",{class:"learn-tests",dir:"auto"});for(const d of t){const h=d.test.world?t.filter(x=>x.test.world).indexOf(d)+1:0,g=d.test.world?`🗺 ${p("web_visubot_world_fmt",h)}`:d.test.actions?`🤖 ${p("web_visubot_actions")}`:d.test.sensors?`🎛 ${Object.entries(d.test.sensors).map(([x,v])=>`mbot.${x}() = ${v.join(" → ")}`).join(", ")}`:d.test.drive?`🤖 ${p("web_visubot_drive")}`:d.test.inputs.length?p("web_learn_input_fmt",d.test.inputs.join(", ")):p("web_learn_no_input"),f=[`${d.passed?"✓":"✗"} ${g}`],b=_("div",{class:"learn-test-detail"});if(d.test.drive&&b.append(_("span",{},`${p("web_learn_expected")}: `,_("code",{},X1(d.test.drive)||"–")),_("span",{},`${p("web_learn_actual")}: `,_("code",{},X1(d.result.drive??[])||"–"))),d.test.actions&&b.append(_("span",{},`${p("web_learn_expected")}: `,_("code",{},X1(d.test.actions)||"–")),_("span",{},`${p("web_learn_actual")}: `,_("code",{},X1(d.result.actions??[])||"–"))),d.test.led!==void 0){const x=v=>p(v?"web_visubot_led_on":"web_visubot_led_off");b.append(_("span",{},`💡 ${p("web_learn_expected")}: ${x(d.test.led)} · ${p("web_learn_actual")}: ${x(d.result.led)}`))}if(d.test.tone!==void 0){const x=v=>p(v?"web_visubot_tone_yes":"web_visubot_tone_no");b.append(_("span",{},`🔊 ${p("web_learn_expected")}: ${x(d.test.tone)} · ${p("web_learn_actual")}: ${x(d.result.tone)}`))}d.test.screen!==void 0&&b.append(_("span",{},`📺 ${p("web_learn_expected")}: `,_("code",{},d.test.screen),` · ${p("web_learn_actual")}: `,_("code",{},d.result.screen??"–"))),d.test.world&&(((l=(o=Ja(d.test.world))==null?void 0:o.goals)!=null&&l.length||(m=(u=Ja(d.test.world))==null?void 0:u.targets)!=null&&m.length)&&b.append(_("span",{},d.result.atGoal?`✓ ${p("web_visubot_goal_reached")}`:`✗ ${p("web_visubot_goal_missed")}`)),d.result.bumps&&b.append(_("span",{class:"learn-error"},`⚠︎ ${p("web_visubot_bumps")}: ${d.result.bumps}`))),(!d.test.drive&&!d.test.world&&!d.test.sensors&&!d.test.actions||d.result.outputs.length)&&b.append(_("span",{},`${p("web_learn_expected")}: `,_("code",{},d.test.expected.join(" | ")||"–")),_("span",{},`${p("web_learn_actual")}: `,_("code",{},d.result.outputs.join(" | ")||"–")));for(const x of d.test.files??[])b.append(_("span",{},`📄 ${x.name}, ${p("web_learn_expected")}: `,_("code",{},x.lines.join(" | ")||"–")),_("span",{},`📄 ${x.name}, ${p("web_learn_actual")}: `,_("code",{},Fh((c=d.result.files)==null?void 0:c.get(x.name)).join(" | ")||"–")));d.result.error&&b.append(_("span",{class:"learn-error"},t1(d.result.error))),d.result.missingInput&&b.append(_("span",{class:"learn-error"},p("web_learn_missing_input"))),d.result.tooManySteps&&b.append(_("span",{class:"learn-error"},p("web_learn_too_many_steps"))),!d.passed&&d.result.unusedInputs&&b.append(_("span",{class:"learn-error"},p("web_learn_unused_input"))),r.append(_("li",{class:d.passed?"ok":"fail"},...f,b))}e.append(r)}renderCompetences(e){const t=_("aside",{class:"learn-competences"},_("p",{class:"learn-competences-title"},p("web_learn_competences_intro"))),n=_("ul",{});for(const a of e)n.append(tt("li",{},Ce(a)));return t.append(n),t}renderChecklist(e,t,n){const a=[{value:"umbrella",icon:"☂️",label:p("web_learn_rating_umbrella")},{value:"cloud",icon:"⛅",label:p("web_learn_rating_cloud")},{value:"sun",icon:"☀️",label:p("web_learn_rating_sun")}],s=_("div",{class:"learn-checklist-wrap"}),r=_("p",{class:"learn-rating-legend"});for(const l of a)r.append(_("span",{},`${l.icon} ${l.label}`));const o=_("ul",{class:"learn-checklist"});return s.append(r,o),e.forEach((l,u)=>{var v;const m=`${t}-${u}`,c=n?(v=be.lesson(n.id).checks)==null?void 0:v[m]:void 0;let d=c===!0?"sun":c||void 0;const h=tt("span",{class:"learn-check-text"},Ce(l.text)),g=_("span",{class:"learn-rating",role:"group","aria-label":h.textContent??""}),f=a.map(w=>{const I=_("button",{class:"learn-rating-button",title:w.label,"aria-label":w.label},w.icon);return I.addEventListener("click",()=>{if(d=d===w.value?void 0:w.value,b(),!n)return;const z={...be.lesson(n.id).checks??{}};d?z[m]=d:delete z[m],be.updateLesson(n.id,{checks:Object.keys(z).length?z:void 0})}),I}),b=()=>{f.forEach((w,I)=>w.setAttribute("aria-pressed",String(a[I].value===d))),x.dataset.rating=d??""};g.append(...f);const x=_("li",{},h,g);if(n&&l.step!==void 0){const w=l.step,I=p("web_learn_step_fmt",w+1,n.steps[w].title),z=_("button",{class:"link-button learn-check-link",title:I,"aria-label":`${p("web_learn_review")}: ${I}`},p("web_learn_review"));z.addEventListener("click",()=>{this.returnTo={lesson:n.id,step:be.lesson(n.id).step,scroll:this.body.scrollTop},this.goToStep(n,w)}),x.append(z)}b(),o.append(x)}),s}renderQuiz(e,t,n){const a=_("div",{class:"learn-quiz"}),s=_("p",{class:"learn-score",role:"status"}),r=()=>n?be.lesson(n.id).quiz??{}:{},o=_("div",{class:"learn-review"}),l=()=>{const u=r(),m=(f,b)=>f.pairs?f.pairs.every((x,v)=>u[`${t}-${b}-${v}`]!==void 0):u[`${t}-${b}`]!==void 0,c=(f,b)=>{var x;return!!(f.pairs?f.pairs.every((v,w)=>mm(f)[u[`${t}-${b}-${w}`]]===f.pairs[w].right):(x=f.options[u[`${t}-${b}`]])!=null&&x.correct)},d=e.filter(m).length,h=e.filter(c).length,g=d===e.length;s.textContent=g?p("web_learn_score_fmt",h,e.length):"",o.replaceChildren(),g&&n&&this.fillChecklistReview(o,n,e,f=>c(e[f],f))};return e.forEach((u,m)=>{const c=`${t}-${m}`,d=_("fieldset",{},tt("legend",{},Ce(u.question))),h=tt("p",{class:"learn-explanation"},Ce(u.explanation??""));if(u.pairs){d.append(this.renderMatch(u,c,r,n,h,l),h),a.append(d);return}const g=f=>{d.querySelectorAll("button").forEach((b,x)=>{b.classList.toggle("right",f!==void 0&&u.options[x].correct),b.classList.toggle("wrong",f===x&&!u.options[x].correct),b.setAttribute("aria-pressed",String(f===x))}),h.hidden=f===void 0||!u.explanation};u.options.forEach((f,b)=>{const x=tt("button",{class:"learn-option"},Ce(f.text));x.addEventListener("click",()=>{n&&be.updateLesson(n.id,{quiz:{...r(),[c]:b}}),g(b),l()}),d.append(x)}),d.append(h),g(r()[c]),a.append(d)}),a.append(s,o),l(),a}fillChecklistReview(e,t,n,a){const s={sun:"☀️",cloud:"⛅",umbrella:"☂️"},r=be.lesson(t.id).checks??{},o=[];let l=0;t.steps.forEach((u,m)=>u.blocks.forEach((c,d)=>{c.kind==="checklist"&&c.items.forEach((h,g)=>{const f=r[`${m}-${d}-${g}`],b=f===!0?"sun":f||void 0,x=h.step===void 0?[]:n.map((k,T)=>k.step===h.step?T:-1).filter(k=>k>=0),v=x.filter(k=>!a(k));let w="";b==="sun"&&v.length?w=p("web_learn_review_overrated_fmt",v.map(k=>k+1).join(", ")):b&&b!=="sun"&&x.length&&!v.length&&(w=p("web_learn_review_underrated")),w&&l++;const I=_("li",{class:w?"learn-review-deviation":""}),z=tt("span",{class:"learn-check-text"},Ce(h.text));if(w&&z.append(_("br",{}),_("em",{},w)),I.append(z,_("span",{class:"learn-review-icon","aria-label":p(b?`web_learn_rating_${b}`:"web_learn_review_unrated")},b?s[b]:"–")),w&&b==="sun"&&h.step!==void 0){const k=h.step,T=_("button",{class:"link-button learn-check-link"},p("web_learn_review"));T.addEventListener("click",()=>{this.returnTo={lesson:t.id,step:be.lesson(t.id).step,scroll:this.body.scrollTop},this.goToStep(t,k)}),I.append(T)}o.push(I)})})),o.length&&e.append(_("p",{class:"learn-review-title"},`📋 ${p("web_learn_review_title")}`),_("p",{},p(l?"web_learn_review_hint":"web_learn_review_match")),_("ul",{class:"learn-checklist"},...o))}renderMatch(e,t,n,a,s,r){const o=e.pairs,l=mm(e),u=_("div",{class:"learn-match"});let m={};const c=()=>a?n():m,d=b=>a?be.updateLesson(a.id,{quiz:b}):m=b,h=b=>c()[`${t}-${b}`],g=o.map(b=>{const x=_("select",{class:"learn-match-select"});x.append(_("option",{value:""},"–")),l.forEach((w,I)=>x.append(_("option",{value:String(I)},w)));const v=tt("label",{class:"learn-match-left"},Ce(b.left));return v.append(x),u.append(v),x}),f=()=>{const b=o.every((x,v)=>h(v)!==void 0);g.forEach((x,v)=>{const w=h(v);x.value=w===void 0?"":String(w),x.classList.toggle("right",b&&l[w]===o[v].right),x.classList.toggle("wrong",b&&l[w]!==o[v].right)}),s.hidden=!b||!e.explanation};return g.forEach((b,x)=>b.addEventListener("change",()=>{const v={...c()};b.value===""?delete v[`${t}-${x}`]:v[`${t}-${x}`]=Number(b.value),d(v),f(),r()})),f(),u}}function mm(i){return(i.pairs??[]).map(e=>e.right).sort((e,t)=>e.localeCompare(t,"de"))}const _Z=""+new URL("visubot-CyGFOI9V.webp",import.meta.url).href,Us="visustruct.visubot";function $s(){try{return localStorage.getItem(Us)}catch{return null}}function ui(){const i=$s();return i==="1"||i==="kurs"?"on":"off"}const dg=()=>$s()==="2";function hg(){try{localStorage.setItem(Us,"2")}catch{}}const gg=()=>$s()==="3";function pg(){try{localStorage.setItem(Us,"3")}catch{}}const jZ=()=>$s()!==null;function Sr(i){try{localStorage.setItem(Us,i==="on"?"1":"0")}catch{}}const AZ=`VisuBot`,Hn=()=>ui()!=="off",cm=i=>i.replace(/[&<>"]/g,e=>({"&":"&","<":"<",">":">",'"':"""})[e]);function Lo(){const i=dg()?"object":gg()?"flow":ui(),e=(n,a)=>``,t={off:"web_visubot_world_visustruct_hint",on:"web_visubot_world_visubot_hint",object:"web_visuobject_world_hint",flow:"web_visuflow_world_hint"}[i];return`
    ${e("off","VisuStruct")}${e("on","🤖 VisuBot")}${e("object","VisuObject")}${e("flow","VisuFlow")}
    - ${cm(p(t))}`}class PZ{constructor(e=Ii){y(this,"element");y(this,"world");y(this,"view");y(this,"loading");y(this,"status");y(this,"stage");y(this,"picker");y(this,"applied",0);y(this,"sent",0);y(this,"liveStatus");y(this,"viewport");y(this,"stopListening");y(this,"realSensors");y(this,"controls",{getBrightness:50,getLoudness:0,getPitch:0,getRoll:0});y(this,"pressTimers",new Map);y(this,"check");y(this,"checking",!1);y(this,"onWorldChange");this.world=new ds(e),this.element=document.createElement("section"),this.element.className="visubot",this.element.innerHTML=`

    ${p("web_visubot_world")}

    ${p("web_visubot_world_in_preview")}

    ${CZ()}${OZ()}`,this.stage=this.element.querySelector(".visubot-stage"),this.picker=this.element.querySelector(".visubot-worlds"),this.status=this.element.querySelector(".visubot-status"),this.liveStatus=this.element.querySelector(".visubot-live"),this.viewport=this.element.querySelector(".visubot-viewport"),this.stopListening=ge.listen(()=>this.updateLive()),this.setupControls(),this.check=this.element.querySelector(".visubot-check"),this.setupCheck(),this.updateLive(),this.updateStatus()}show(){this.loading??(this.loading=K(async()=>{const{Robot3D:e}=await import("./robot3d-B1TGngW1.js");return{Robot3D:e}},[],import.meta.url).then(({Robot3D:e})=>{this.view=new e(this.stage),this.view.setWorld(this.world.setup),this.view.place(this.world.pose,this.world.trail),this.view.setLeds(this.world.leds)}).catch(()=>{this.stage.textContent=p("web_visubot_no_3d")}))}restoreViewport(){this.viewport.parentElement!==this.element&&this.liveStatus.after(this.viewport)}setWorlds(e){this.picker.replaceChildren(),this.picker.hidden=e.length<2,e.forEach((t,n)=>{const a=document.createElement("button");a.textContent=p("web_visubot_world_fmt",n+1),a.addEventListener("click",()=>this.useWorld(t,a)),this.picker.append(a)}),this.useWorld(e[0]??Ii,this.picker.firstElementChild)}useWorld(e,t){var n,a,s,r,o;for(const l of this.picker.children)l.classList.toggle("active",l===t);e!==this.world.setup&&(this.world=new ds(e),this.applied=0,this.sent=0,(n=this.view)==null||n.setWorld(e),(a=this.view)==null||a.place(this.world.pose,this.world.trail),(s=this.view)==null||s.setLed(void 0),(r=this.view)==null||r.setScreen(void 0),this.updateStatus(),(o=this.onWorldChange)==null||o.call(this))}reset(){var e,t,n;this.world.reset(),this.applied=0,this.sent=0,this.realSensors=void 0,(e=this.view)==null||e.place(this.world.pose,this.world.trail),(t=this.view)==null||t.setLed(void 0),(n=this.view)==null||n.setScreen(void 0),this.updateStatus()}prepare(e){e.robotSensors={...this.controls,...this.world.sensors()}}setupControls(){for(const e of this.element.querySelectorAll(".visubot-controls input[type=range]")){const t=e.parentElement.querySelector("output"),n=()=>{this.controls[e.name]=Number(e.value),t.textContent=e.value};e.addEventListener("input",n),n()}for(const e of this.element.querySelectorAll(".visubot-controls button[name]"))e.addEventListener("click",()=>{const t=e.name;this.controls[t]=!0,e.classList.add("pressed"),window.clearTimeout(this.pressTimers.get(t)),this.pressTimers.set(t,window.setTimeout(()=>{this.controls[t]=!1,e.classList.remove("pressed")},1e3))})}setupCheck(){for(const e of this.check.querySelectorAll("button[data-py]"))e.addEventListener("click",()=>{const{after:t,wait:n}=e.dataset;ge.run(e.dataset.py).then(()=>t?new Promise(a=>setTimeout(a,Number(n))).then(()=>ge.run(t)):void 0).catch(a=>this.liveFailed(a))});this.check.addEventListener("toggle",()=>void this.readCheck())}async readCheck(){if(!this.checking){this.checking=!0;try{for(;this.check.open&&ge.connected;){for(const e of this.check.querySelectorAll("[data-sensor]")){if(!this.check.open||!ge.connected)break;const t=e.dataset.sensor,n=await ge.ask(jt[t].python).catch(()=>{});n!==void 0&&(e.textContent=typeof jt[t].simulated=="boolean"?n===!0||typeof n=="number"&&n!==0?"✓":"–":String(typeof n=="number"?Math.round(n*10)/10:n))}await new Promise(e=>setTimeout(e,200))}}finally{this.checking=!1}}}get live(){return ge.connected}async prepareLive(e,t=[]){const n={};for(const a of new Set(["getDistance","getLine",...t])){const s=await ge.ask(jt[a].python);typeof jt[a].simulated=="boolean"?n[a]=s===!0||typeof s=="number"&&s!==0:typeof jt[a].simulated=="string"?n[a]=typeof s=="string"?s:String(jt[a].simulated):n[a]=typeof s=="number"?a==="getDistance"?Math.round(s):s:0}this.realSensors=n,e.robotSensors={...this.controls,...this.world.sensors(),...n}}async drive(e){for(;this.sentsetTimeout(n,t.args[0]))}}liveFailed(e){ge.disconnect(e instanceof Error?e.message:String(e))}updateLive(){this.liveStatus.textContent=bg(),this.liveStatus.classList.toggle("connected",ge.connected),this.check.hidden=!ge.connected,ge.connected||(this.check.open=!1),this.updateStatus()}follow(e,t){var a,s,r,o;for(;this.appliedl!==0);this.world.tick(s0),n&&((o=this.view)==null||o.moveTo(this.world.pose,this.world.trail,t)),this.updateStatus()}dispose(){var e;this.stopListening();for(const t of this.pressTimers.values())window.clearTimeout(t);(e=this.view)==null||e.dispose(),this.view=void 0,this.loading=void 0}updateStatus(){const e=this.world.lineState().toString(2).padStart(4,"0"),t=[`${p("web_visubot_distance")}: ${this.world.distance()} cm`,`${p("web_visubot_line")}: ${e}`];this.world.bumps>0&&t.push(`⚠︎ ${p("web_visubot_bumps")}: ${this.world.bumps}`),this.world.screen!==void 0&&t.push(`📺 ${this.world.screen}`),this.realSensors&&ge.connected&&t.push(`🤖 ${p("web_visubot_distance")}: ${this.realSensors.getDistance} cm · ${p("web_visubot_line")}: ${Number(this.realSensors.getLine).toString(2).padStart(4,"0")}`),this.status.textContent=t.join(" · ")}}let H1;function fg(i,e){try{H1??(H1=new AudioContext);const t=H1.createOscillator(),n=H1.createGain();t.type="square",t.frequency.value=Math.max(20,Math.min(2e4,i)),n.gain.value=.05,t.connect(n).connect(H1.destination);const a=H1.currentTime+Math.min(Math.max(e,0),5e3)/1e3;t.start(),t.stop(a)}catch{}}function CZ(){const i=(t,n,a,s,r)=>``,e=(t,n,a)=>``;return`
    🎛 ${p("web_visubot_controls")} + ${cm(p(t))}`}class PZ{constructor(e=Ii){y(this,"element");y(this,"world");y(this,"view");y(this,"loading");y(this,"status");y(this,"stage");y(this,"picker");y(this,"applied",0);y(this,"sent",0);y(this,"liveStatus");y(this,"viewport");y(this,"stopListening");y(this,"realSensors");y(this,"controls",{getBrightness:50,getLoudness:0,getPitch:0,getRoll:0});y(this,"pressTimers",new Map);y(this,"check");y(this,"checking",!1);y(this,"onWorldChange");this.world=new ds(e),this.element=document.createElement("section"),this.element.className="visubot",this.element.innerHTML=`

    ${p("web_visubot_world")}

    ${p("web_visubot_world_in_preview")}

    ${CZ()}${OZ()}`,this.stage=this.element.querySelector(".visubot-stage"),this.picker=this.element.querySelector(".visubot-worlds"),this.status=this.element.querySelector(".visubot-status"),this.liveStatus=this.element.querySelector(".visubot-live"),this.viewport=this.element.querySelector(".visubot-viewport"),this.stopListening=ge.listen(()=>this.updateLive()),this.setupControls(),this.check=this.element.querySelector(".visubot-check"),this.setupCheck(),this.updateLive(),this.updateStatus()}show(){this.loading??(this.loading=K(async()=>{const{Robot3D:e}=await import("./robot3d-I0g91EHr.js");return{Robot3D:e}},[],import.meta.url).then(({Robot3D:e})=>{this.view=new e(this.stage),this.view.setWorld(this.world.setup),this.view.place(this.world.pose,this.world.trail),this.view.setLeds(this.world.leds)}).catch(()=>{this.stage.textContent=p("web_visubot_no_3d")}))}restoreViewport(){this.viewport.parentElement!==this.element&&this.liveStatus.after(this.viewport)}setWorlds(e){this.picker.replaceChildren(),this.picker.hidden=e.length<2,e.forEach((t,n)=>{const a=document.createElement("button");a.textContent=p("web_visubot_world_fmt",n+1),a.addEventListener("click",()=>this.useWorld(t,a)),this.picker.append(a)}),this.useWorld(e[0]??Ii,this.picker.firstElementChild)}useWorld(e,t){var n,a,s,r,o;for(const l of this.picker.children)l.classList.toggle("active",l===t);e!==this.world.setup&&(this.world=new ds(e),this.applied=0,this.sent=0,(n=this.view)==null||n.setWorld(e),(a=this.view)==null||a.place(this.world.pose,this.world.trail),(s=this.view)==null||s.setLed(void 0),(r=this.view)==null||r.setScreen(void 0),this.updateStatus(),(o=this.onWorldChange)==null||o.call(this))}reset(){var e,t,n;this.world.reset(),this.applied=0,this.sent=0,this.realSensors=void 0,(e=this.view)==null||e.place(this.world.pose,this.world.trail),(t=this.view)==null||t.setLed(void 0),(n=this.view)==null||n.setScreen(void 0),this.updateStatus()}prepare(e){e.robotSensors={...this.controls,...this.world.sensors()}}setupControls(){for(const e of this.element.querySelectorAll(".visubot-controls input[type=range]")){const t=e.parentElement.querySelector("output"),n=()=>{this.controls[e.name]=Number(e.value),t.textContent=e.value};e.addEventListener("input",n),n()}for(const e of this.element.querySelectorAll(".visubot-controls button[name]"))e.addEventListener("click",()=>{const t=e.name;this.controls[t]=!0,e.classList.add("pressed"),window.clearTimeout(this.pressTimers.get(t)),this.pressTimers.set(t,window.setTimeout(()=>{this.controls[t]=!1,e.classList.remove("pressed")},1e3))})}setupCheck(){for(const e of this.check.querySelectorAll("button[data-py]"))e.addEventListener("click",()=>{const{after:t,wait:n}=e.dataset;ge.run(e.dataset.py).then(()=>t?new Promise(a=>setTimeout(a,Number(n))).then(()=>ge.run(t)):void 0).catch(a=>this.liveFailed(a))});this.check.addEventListener("toggle",()=>void this.readCheck())}async readCheck(){if(!this.checking){this.checking=!0;try{for(;this.check.open&&ge.connected;){for(const e of this.check.querySelectorAll("[data-sensor]")){if(!this.check.open||!ge.connected)break;const t=e.dataset.sensor,n=await ge.ask(jt[t].python).catch(()=>{});n!==void 0&&(e.textContent=typeof jt[t].simulated=="boolean"?n===!0||typeof n=="number"&&n!==0?"✓":"–":String(typeof n=="number"?Math.round(n*10)/10:n))}await new Promise(e=>setTimeout(e,200))}}finally{this.checking=!1}}}get live(){return ge.connected}async prepareLive(e,t=[]){const n={};for(const a of new Set(["getDistance","getLine",...t])){const s=await ge.ask(jt[a].python);typeof jt[a].simulated=="boolean"?n[a]=s===!0||typeof s=="number"&&s!==0:typeof jt[a].simulated=="string"?n[a]=typeof s=="string"?s:String(jt[a].simulated):n[a]=typeof s=="number"?a==="getDistance"?Math.round(s):s:0}this.realSensors=n,e.robotSensors={...this.controls,...this.world.sensors(),...n}}async drive(e){for(;this.sentsetTimeout(n,t.args[0]))}}liveFailed(e){ge.disconnect(e instanceof Error?e.message:String(e))}updateLive(){this.liveStatus.textContent=bg(),this.liveStatus.classList.toggle("connected",ge.connected),this.check.hidden=!ge.connected,ge.connected||(this.check.open=!1),this.updateStatus()}follow(e,t){var a,s,r,o;for(;this.appliedl!==0);this.world.tick(s0),n&&((o=this.view)==null||o.moveTo(this.world.pose,this.world.trail,t)),this.updateStatus()}dispose(){var e;this.stopListening();for(const t of this.pressTimers.values())window.clearTimeout(t);(e=this.view)==null||e.dispose(),this.view=void 0,this.loading=void 0}updateStatus(){const e=this.world.lineState().toString(2).padStart(4,"0"),t=[`${p("web_visubot_distance")}: ${this.world.distance()} cm`,`${p("web_visubot_line")}: ${e}`];this.world.bumps>0&&t.push(`⚠︎ ${p("web_visubot_bumps")}: ${this.world.bumps}`),this.world.screen!==void 0&&t.push(`📺 ${this.world.screen}`),this.realSensors&&ge.connected&&t.push(`🤖 ${p("web_visubot_distance")}: ${this.realSensors.getDistance} cm · ${p("web_visubot_line")}: ${Number(this.realSensors.getLine).toString(2).padStart(4,"0")}`),this.status.textContent=t.join(" · ")}}let H1;function fg(i,e){try{H1??(H1=new AudioContext);const t=H1.createOscillator(),n=H1.createGain();t.type="square",t.frequency.value=Math.max(20,Math.min(2e4,i)),n.gain.value=.05,t.connect(n).connect(H1.destination);const a=H1.currentTime+Math.min(Math.max(e,0),5e3)/1e3;t.start(),t.stop(a)}catch{}}function CZ(){const i=(t,n,a,s,r)=>``,e=(t,n,a)=>``;return`
    🎛 ${p("web_visubot_controls")}

    ${p("web_visubot_controls_hint")}

    ${i("getBrightness","web_visubot_sensor_brightness",0,100,50)} ${i("getLoudness","web_visubot_sensor_loudness",0,100,0)} @@ -64468,7 +64529,7 @@ ${i}

    ${yn(p("web_visubot_preview_hint"))}

    -

    `;const e=t=>this.element.querySelector(t);this.heightBar=e(".robotpreview-height"),this.stage=e(".robotpreview-stage"),this.status=e(".robotpreview-status"),this.picker=e(".visubot-worlds"),this.playButton=e(".robotpreview-play"),this.stackButton=e(".robotpreview-stack"),this.playButton.addEventListener("click",()=>this.playTimer===void 0?this.play():this.stopPlaying(!0)),this.stackButton.addEventListener("click",()=>this.onToggleStacked()),e(".learn-hide").addEventListener("click",()=>this.onHide()),this.rail=document.createElement("button"),this.rail.className="learn-rail robotpreview-rail",this.setStacked(!1),this.relabel()}hostSimulation(e){var t;e!==this.simulation&&((t=this.simulation)==null||t.remove(),this.simulation=e,this.element.classList.toggle("simulation",!!e),e&&(this.pause(),this.status.after(e)),this.relabel())}relabel(){const e=a=>this.element.querySelector(a),t=!!this.simulation;e("h2").textContent=`🤖 ${p(t?"web_visubot_preview_sim_title":"web_visubot_preview_title")}`,e(".hint").textContent=p(t?"web_visubot_preview_sim_hint":"web_visubot_preview_hint"),this.heightBar.title=p("web_visubot_preview_resize");const n=e(".learn-hide");n.title=p("web_visubot_preview_hide"),n.setAttribute("aria-label",p("web_visubot_preview_hide")),this.rail.title=p("web_visubot_preview_show"),this.rail.innerHTML=`${_t}🤖 ${yn(p("web_visubot_preview_title"))}`,this.setStacked(this.stackButton.textContent==="▥"),this.stopPlaying(!1),this.worldsKey=void 0,this.lastKey=void 0}setStacked(e){const t=e?"web_visubot_preview_side":"web_visubot_preview_stack";this.stackButton.innerHTML=e?"▥":"⬓",this.stackButton.className="icon robotpreview-stack",this.stackButton.dataset.tip=p(t),this.stackButton.setAttribute("aria-label",p(t))}show(){this.loading??(this.loading=K(async()=>{const{Robot3D:e}=await import("./robot3d-B1TGngW1.js");return{Robot3D:e}},[],import.meta.url).then(({Robot3D:e})=>{var t;this.view=new e(this.stage),this.view.setWorld(this.setup),this.showFrame((t=this.result)==null?void 0:t.frames.at(-1))}).catch(()=>{this.stage.textContent=p("web_visubot_no_3d")}))}update(e,t,n,a,s){if(this.simulation)return;this.show(),a!==this.worldsKey&&(this.worldsKey=a,this.setWorlds(n)),this.input={doc:e,resolve:t};const r=JSON.stringify(s)+` +

    `;const e=t=>this.element.querySelector(t);this.heightBar=e(".robotpreview-height"),this.stage=e(".robotpreview-stage"),this.status=e(".robotpreview-status"),this.picker=e(".visubot-worlds"),this.playButton=e(".robotpreview-play"),this.stackButton=e(".robotpreview-stack"),this.playButton.addEventListener("click",()=>this.playTimer===void 0?this.play():this.stopPlaying(!0)),this.stackButton.addEventListener("click",()=>this.onToggleStacked()),e(".learn-hide").addEventListener("click",()=>this.onHide()),this.rail=document.createElement("button"),this.rail.className="learn-rail robotpreview-rail",this.setStacked(!1),this.relabel()}hostSimulation(e){var t;e!==this.simulation&&((t=this.simulation)==null||t.remove(),this.simulation=e,this.element.classList.toggle("simulation",!!e),e&&(this.pause(),this.status.after(e)),this.relabel())}relabel(){const e=a=>this.element.querySelector(a),t=!!this.simulation;e("h2").textContent=`🤖 ${p(t?"web_visubot_preview_sim_title":"web_visubot_preview_title")}`,e(".hint").textContent=p(t?"web_visubot_preview_sim_hint":"web_visubot_preview_hint"),this.heightBar.title=p("web_visubot_preview_resize");const n=e(".learn-hide");n.title=p("web_visubot_preview_hide"),n.setAttribute("aria-label",p("web_visubot_preview_hide")),this.rail.title=p("web_visubot_preview_show"),this.rail.innerHTML=`${_t}🤖 ${yn(p("web_visubot_preview_title"))}`,this.setStacked(this.stackButton.textContent==="▥"),this.stopPlaying(!1),this.worldsKey=void 0,this.lastKey=void 0}setStacked(e){const t=e?"web_visubot_preview_side":"web_visubot_preview_stack";this.stackButton.innerHTML=e?"▥":"⬓",this.stackButton.className="icon robotpreview-stack",this.stackButton.dataset.tip=p(t),this.stackButton.setAttribute("aria-label",p(t))}show(){this.loading??(this.loading=K(async()=>{const{Robot3D:e}=await import("./robot3d-I0g91EHr.js");return{Robot3D:e}},[],import.meta.url).then(({Robot3D:e})=>{var t;this.view=new e(this.stage),this.view.setWorld(this.setup),this.showFrame((t=this.result)==null?void 0:t.frames.at(-1))}).catch(()=>{this.stage.textContent=p("web_visubot_no_3d")}))}update(e,t,n,a,s){if(this.simulation)return;this.show(),a!==this.worldsKey&&(this.worldsKey=a,this.setWorlds(n)),this.input={doc:e,resolve:t};const r=JSON.stringify(s)+` `+JSON.stringify(e);r!==this.lastKey&&(this.lastKey=r,window.clearTimeout(this.pending),this.pending=window.setTimeout(()=>this.recompute(),120))}setWorlds(e){this.worlds=e,this.picker.replaceChildren(),this.picker.hidden=e.length<2,e.forEach((t,n)=>{const a=document.createElement("button");a.textContent=p("web_visubot_world_fmt",n+1),a.addEventListener("click",()=>this.useWorld(t)),this.picker.append(a)}),this.useWorld(e[0]??Ii)}useWorld(e){var t;this.worlds.forEach((n,a)=>{var s;return(s=this.picker.children[a])==null?void 0:s.classList.toggle("active",n===e)}),!(e===this.setup&&this.result)&&(this.setup=e,(t=this.view)==null||t.setWorld(e),this.recompute())}recompute(){var e;if(this.pending=void 0,this.stopPlaying(!1),!!this.input){try{this.result=qF(this.input.doc,this.input.resolve,this.setup)}catch{this.result=void 0}this.showFrame((e=this.result)==null?void 0:e.frames.at(-1)),this.updateStatus()}}showFrame(e,t=0){if(!this.view)return;const n=e??{pose:{...this.setup.start},trail:[{x:this.setup.start.x,y:this.setup.start.y}],leds:Array(5).fill(void 0),screen:void 0};t>0?this.view.moveTo(n.pose,n.trail,t):this.view.place(n.pose,n.trail),this.view.setLeds(n.leds),this.view.setScreen(n.screen)}play(){var a;const e=(a=this.result)==null?void 0:a.frames;if(!e||e.length<2||!this.view)return;this.stopPlaying(!1);let t=0;this.showFrame(e[0]),this.playButton.innerHTML=se.stop,this.playButton.dataset.tip=p("web_visubot_preview_stop"),this.playButton.setAttribute("aria-label",p("web_visubot_preview_stop"));const n=()=>{if(t++,t>=e.length){this.stopPlaying(!1);return}const s=e[t];s.tone&&fg(s.tone[0],s.tone[1]),this.showFrame(s,io-30),this.playTimer=window.setTimeout(n,io)};this.playTimer=window.setTimeout(n,io)}stopPlaying(e){var t;this.playTimer!==void 0&&window.clearTimeout(this.playTimer),this.playTimer=void 0,this.playButton.innerHTML=se.play,this.playButton.dataset.tip=p("web_visubot_preview_play"),this.playButton.setAttribute("aria-label",p("web_visubot_preview_play")),e&&this.showFrame((t=this.result)==null?void 0:t.frames.at(-1))}updateStatus(){const e=this.result;if(this.playButton.disabled=!e||e.frames.length<2,!e){this.status.textContent="";return}const t=[p("web_visubot_preview_distance_fmt",e.distance)];e.bumps>0&&t.push(`⚠︎ ${p("web_visubot_bumps")}: ${e.bumps}`),e.stop==="input"?t.push(p("web_visubot_preview_input")):e.stop==="limit"?t.push(p("web_visubot_preview_limit")):e.stop==="error"&&e.notice&&t.push(`⚠︎ ${t1(e.notice)}`),this.status.textContent=t.join(" · ")}pause(){window.clearTimeout(this.pending),this.pending=void 0,this.lastKey=void 0,this.stopPlaying(!1)}}const $F={left:12,top:10},YF=8,Es=8e3,xi=16,ao=12,i2="#fafafa";function a2(i){const e=i.caption.trim();return e===""?p("diagram_title_placeholder"):e}function od(i){let e=i.trim().replace(/\.visustruct$/i,"");if(e==="")return"";for(e=e.replace(/\s/g,"-").replace(/[/:\\*?"<>|]/g,"-");e.includes("--");)e=e.replace(/--/g,"-");return e=e.replace(/^-+|-+$/g,""),e.length>120&&(e=e.slice(0,120).replace(/^-+|-+$/g,"")),e}function ld(i,e){return od(i.caption)||od(e)||"VisuStruct"}function XF(i,e,t){const n=i.split(/\s+/),a=[];let s="";for(const r of n){const o=s?`${s} ${r}`:r;s&&t(o,xi,"bold")>e?(a.push(s),s=r):s=o}if(s&&a.push(s),a.length>2){let r=a.slice(1).join(" ");for(;r.length>1&&t(r+"…",xi,"bold")>e;)r=r.slice(0,-1);return[a[0],r+"…"]}return a}function ud(i,e,t,n=320){const a={...i,elements:i.elements.map(Xa)},s=new Vd(e,t).layout(a,$F),r=Math.min(Es,Math.max(n,s.canvasSize.width)),o=Math.min(Es,Math.max(n,s.canvasSize.height));if(r<=2||o<=2)return;const l=XF(a2(i),r-2*ao,t),u=Math.ceil(xi*1.2),m=Math.min(56,l.length*u+2),c=m+o,d=new $d(e,t).render(s,{width:r,height:o},void 0,YF);d.setAttribute("y",String(m)),d.removeAttribute("class");const h=Se("svg",{xmlns:"http://www.w3.org/2000/svg",width:r,height:c,viewBox:`0 0 ${r} ${c}`});h.append(Se("rect",{x:0,y:0,width:r,height:c,fill:i2}));const g=Se("text",{x:ao,y:0,"font-family":Ns,"font-size":xi,"font-weight":600,fill:"black"});return l.forEach((f,b)=>{const x=Se("tspan",{x:ao,y:b*u+xi});x.textContent=f,g.append(x)}),h.append(g,d),{svg:h,width:r,height:c}}function s2(i){return` `+new XMLSerializer().serializeToString(i.svg)}async function md(i,e){const t=Math.max(1,Math.min(e,Es/i.width,Es/i.height)),n=URL.createObjectURL(new Blob([s2(i)],{type:"image/svg+xml"}));try{const a=new Image;a.src=n,await a.decode();const s=document.createElement("canvas");s.width=Math.round(i.width*t),s.height=Math.round(i.height*t);const r=s.getContext("2d");return r.fillStyle=i2,r.fillRect(0,0,s.width,s.height),r.drawImage(a,0,0,s.width,s.height),s}finally{URL.revokeObjectURL(n)}}function KF(i){return new Promise((e,t)=>i.toBlob(n=>n?e(n):t(new Error("PNG konnte nicht erzeugt werden.")),"image/png"))}function eR(i,e){const a=Math.max(1,i),s=Math.max(1,e),r=f=>{const b=f.width-64,x=f.height-64;return{s:Math.min(b/a,x/s)*.98,cw:b,ch:x}},o={width:595,height:842},l={width:842,height:595},u=r(o),m=r(l),[c,d]=m.s>u.s?[l,m]:[o,u],h=a*d.s,g=s*d.s;return{page:c,draw:{x:32+(d.cw-h)/2,y:32+(d.ch-g)/2,width:h,height:g}}}async function tR(i){const e=new Blob([i]).stream().pipeThrough(new CompressionStream("deflate"));return new Uint8Array(await new Response(e).arrayBuffer())}function cd(i){let e="FEFF";for(let t=0;t`}async function nR(i,e,t,n,a){const{page:s,draw:r}=eR(n.width,n.height),o=await tR(i),l=x=>(Math.round(x*100)/100).toString(),u=`q ${l(r.width)} 0 0 ${l(r.height)} ${l(r.x)} ${l(s.height-r.y-r.height)} cm /Im0 Do Q`,m=new TextEncoder,c=[["<< /Type /Catalog /Pages 2 0 R >>"],["<< /Type /Pages /Kids [3 0 R] /Count 1 >>"],[`<< /Type /Page /Parent 2 0 R /MediaBox [0 0 ${s.width} ${s.height}] /Resources << /XObject << /Im0 4 0 R >> >> /Contents 5 0 R >>`],[`<< /Type /XObject /Subtype /Image /Width ${e} /Height ${t} /ColorSpace /DeviceRGB /BitsPerComponent 8 /Filter /FlateDecode /Length ${o.length} >> stream @@ -64683,7 +64744,7 @@ ${c}
    - ${W(p("web_about_version_fmt").replace("%@","0.14.1"))} + ${W(p("web_about_version_fmt").replace("%@","0.14.2"))}
    @@ -64754,7 +64815,7 @@ ${c}

    VisuStruct ${W(p("web_brand_suffix"))}

    -

    ${W(p("web_about_version_fmt").replace("%@","0.14.1"))}

    +

    ${W(p("web_about_version_fmt").replace("%@","0.14.2"))}

    Holger Sebastiao

    ${e("about_web_label","https://www.visustruct.org","www.visustruct.org")} ${e("about_developer_label","https://www.sebastiao.org","www.sebastiao.org")} @@ -64776,4 +64837,4 @@ ${c}

    ${W(p("close_unsaved_title"))}

    ${W(p("web_discard_message_fmt",this.fileName))}

    -
    `,t.addEventListener("click",n=>{const a=n.target.dataset.r;a===void 0&&n.target!==t||(t.remove(),e(a==="1"))}),document.body.append(t),t.querySelector('[data-r="0"]').focus()}):Promise.resolve(!0)}showMessage(e){this.statusLine.textContent=e,this.statusLine.classList.add("message"),setTimeout(()=>{this.statusLine.classList.remove("message"),this.updateStatus()},6e3)}loadXML(e,t,n){let a;try{a=Nl(e)}catch(s){this.showMessage(p("web_err_unreadable_fmt",t,s.message));return}(this.dirty||this.tab.fileName||this.tab.exerciseId)&&this.addTab(),this.doc=a,this.tab.fileName=t.replace(/\.(strk|xml)$/i,".visustruct"),this.fileHandle=n&&/\.visustruct$/i.test(t)?n:void 0,this.resetHistory()}async open(e){const t=window;if(!t.showOpenFilePicker||this.inViewer)return e.click();try{const[n]=await t.showOpenFilePicker({types:pd()}),a=await n.getFile();this.loadXML(await a.text(),a.name,n)}catch{}}async save(){var n,a;if(!this.downloads&&await this.saveToWorkspace())return;const e=new Blob([u1(this.doc)],{type:"application/xml"}),t=window;try{if(this.downloads){const s=this.fileName+".txt";await this.downloads.save({filename:s,data:e}),(n=this.tab).fileName??(n.fileName=this.fileName),this.dirty=!1,this.render(),this.showMessage(p("web_saved_txt_fmt",s));return}if(!this.fileHandle&&t.showSaveFilePicker&&!this.inViewer&&(this.fileHandle=await t.showSaveFilePicker({suggestedName:this.fileName,types:pd()}),this.tab.fileName=this.fileHandle.name),this.fileHandle){const s=await this.fileHandle.createWritable();await s.write(e),await s.close()}else{const s=document.createElement("a");s.href=URL.createObjectURL(e),s.download=this.fileName,s.click(),setTimeout(()=>URL.revokeObjectURL(s.href),1e3)}(a=this.tab).fileName??(a.fileName=this.fileName),this.dirty=!1,this.render()}catch{}}async exportDiagram(e){if(e==="visustruct"){const s=ld(this.doc,un(this.tab));return this.offerDownload(`${s}.visustruct`,new Blob([u1(this.doc)],{type:"application/xml"}))}const t=ud(this.doc,this.metrics,this.measure);if(!t){this.showMessage(p(e==="print"?"err_diagram_too_small_print":"err_diagram_too_small_export"));return}const n=ld(this.doc,un(this.tab)),a=Math.max(2,window.devicePixelRatio||1)*this.zoom;try{switch(e){case"svg":{t.svg.setAttribute("width",String(t.width*this.zoom)),t.svg.setAttribute("height",String(t.height*this.zoom)),await this.offerDownload(`${n}.svg`,new Blob([s2(t)],{type:"image/svg+xml"}));break}case"png":{const s=await md(t,a);await this.offerDownload(`${n}.png`,await KF(s));break}case"pdf":{const s=await md(t,Math.max(a,3)),r=await nR(iR(s),s.width,s.height,t,a2(this.doc));await this.offerDownload(`${n}.pdf`,r);break}case"print":this.printDiagram(t);break}}catch(s){this.showMessage(p("web_export_failed_fmt",s instanceof Error?s.message:String(s)))}}printDiagram(e){const t=document.createElement("div");t.className="print-sheet",e.svg.removeAttribute("width"),e.svg.removeAttribute("height"),t.append(e.svg),document.body.append(t);const n=()=>t.remove();window.addEventListener("afterprint",n,{once:!0});try{window.print()}catch{n(),this.showMessage(`${p("err_print_unavailable")} ${p("web_print_hint")}`);return}setTimeout(n,6e4)}async offerDownload(e,t){try{if(this.downloads){try{await this.downloads.save({filename:e,data:t}),this.showMessage(p("web_saved_fmt",e))}catch{await this.downloads.save({filename:e+".txt",data:t}),this.showMessage(p("web_saved_txt_fmt",e+".txt"))}return}const n=document.createElement("a");n.href=URL.createObjectURL(t),n.download=e,n.click(),setTimeout(()=>URL.revokeObjectURL(n.href),1e3)}catch{this.showMessage(p("err_save_failed_fmt",e))}}setupFileDrop(){window.addEventListener("dragover",e=>{var t;(t=e.dataTransfer)!=null&&t.types.includes("Files")&&(e.preventDefault(),this.root.classList.add("file-drag"))}),window.addEventListener("dragleave",e=>{e.relatedTarget===null&&this.root.classList.remove("file-drag")}),window.addEventListener("drop",async e=>{var n;this.root.classList.remove("file-drag");const t=(n=e.dataTransfer)==null?void 0:n.files[0];t&&(e.preventDefault(),this.loadXML(await t.text(),t.name))})}onKeyDown(e){var a,s;const t=e.metaKey||e.ctrlKey,n=e.target instanceof HTMLTextAreaElement||e.target instanceof HTMLInputElement||((a=e.target)==null?void 0:a.isContentEditable)===!0;if(t&&e.key.toLowerCase()==="s")e.preventDefault(),this.save();else if(t&&e.key.toLowerCase()==="p")e.preventDefault(),this.simulating||this.exportDiagram("print");else if(t&&e.key.toLowerCase()==="o")e.preventDefault(),this.open(this.root.querySelector("input[type=file]"));else{if(n||this.simulating)return;t&&e.key.toLowerCase()==="z"?(e.preventDefault(),e.shiftKey?this.redo():this.undo()):t&&e.key.toLowerCase()==="c"&&!((s=getSelection())!=null&&s.toString())?this.copySelection()&&e.preventDefault():t&&e.key.toLowerCase()==="x"?(e.preventDefault(),this.cutSelection()):t&&e.key.toLowerCase()==="v"?(e.preventDefault(),this.paste()):t&&e.key.toLowerCase()==="y"?(e.preventDefault(),this.redo()):e.key==="Delete"||e.key==="Backspace"?(e.preventDefault(),this.deleteSelection()):e.key==="Escape"&&(this.drag?this.endDrag():(this.selected=void 0,this.render()))}}svgPoint(e,t){if(!this.svg)return;const n=this.svg.getBoundingClientRect(),a=e-n.left,s=t-n.top;if(!(a<0||s<0||a>n.width||s>n.height))return{x:a/this.zoom,y:s/this.zoom}}nodeAt(e,t){for(let n=this.flat.length-1;n>=0;n--){const a=this.flat[n].frame;if(e>=a.x&&e<=a.x+a.width&&t>=a.y&&t<=a.y+a.height)return this.flat[n]}}onCanvasPointerDown(e){if(this.simulating)return;const t=this.svgPoint(e.clientX,e.clientY);if(!t)return;document.activeElement instanceof HTMLElement&&document.activeElement.blur();const n=this.nodeAt(t.x,t.y),a=n&&this.selected&&fo(n.idPath,this.selected);this.selected=n==null?void 0:n.idPath,this.render(),n&&e.pointerType!=="touch"&&!(In(this.doc,n.idPath)&&!a)&&this.beginDrag(e,{kind:"move",path:n.idPath})}beginDrag(e,t){e.button!==0||this.simulating||(e.preventDefault(),this.drag={source:t,pointerId:e.pointerId,startX:e.clientX,startY:e.clientY,active:!1})}onPointerMove(e){const t=this.drag;if(!t||e.pointerId!==t.pointerId)return;if(!t.active){if(Math.hypot(e.clientX-t.startX,e.clientY-t.startY)<5)return;t.active=!0,t.ghost=this.makeGhost(t.source),document.body.append(t.ghost),this.root.classList.add("dragging")}t.ghost.style.transform=`translate(${e.clientX+12}px, ${e.clientY+12}px)`,this.autoScroll(e.clientX,e.clientY);const n=this.svgPoint(e.clientX,e.clientY);t.target=n?this.dropTargetAt(n.x,n.y,t.source):void 0,this.showDropTarget(t.target)}onPointerUp(e){const t=this.drag;!t||e.pointerId!==t.pointerId||(t.active&&t.target?this.applyDrop(t.source,t.target):!t.active&&t.source.kind==="palette"?this.insertNearSelection(t.source.make()):!t.active&&t.source.kind==="sensor"&&this.insertSensor(t.source.text),this.endDrag())}endDrag(){var e,t;(t=(e=this.drag)==null?void 0:e.ghost)==null||t.remove(),this.drag=void 0,this.root.classList.remove("dragging"),this.showDropTarget(void 0)}makeGhost(e){const t=document.createElement("div");if(t.className="drag-ghost",e.kind==="palette"||e.kind==="sensor")t.textContent=e.label;else{const n=Ot(this.doc,e.path);t.textContent=`${so(n.type)}: ${Zl(n)[0]}`}return t}autoScroll(e,t){const n=this.canvasHost.getBoundingClientRect(),a=40,s=12;t>n.bottom-a&&tn.top-a&&(this.canvasHost.scrollTop-=s),e>n.right-a&&en.left-a&&(this.canvasHost.scrollLeft-=s)}dropTargetAt(e,t,n){var l;const a=((l=this.layout)==null?void 0:l.elements)??[],s=this.nodeAt(e,t);if(n.kind==="sensor")return!s||In(this.doc,s.idPath)?void 0:gd.includes(Ot(this.doc,s.idPath).type)?{kind:"condition",path:s.idPath,frame:s.frame}:void 0;if(!s){const u=a[a.length-1];if(!u)return;const m=u.frame.y+u.frame.height;return t>m?n.kind==="move"&&n.path.length===1&&n.path[0]===a.length-1?void 0:{kind:"rootAppend",frame:{x:u.frame.x,y:m,width:u.frame.width,height:0}}:t=n.path.length&&n.path.every((u,m)=>r[m]===u)?void 0:In(this.doc,r)?{kind:"replace",path:r,frame:s.frame}:{kind:t"]/g,e=>({"&":"&","<":"<",">":">",'"':"""})[e])}function Zd(i){if(!i)return[];for(const e of[...Ct.flatMap(t=>t.steps.flatMap(n=>n.blocks)),...An.flatMap(t=>t.blocks)])if(!(e.kind!=="exercise"||e.exercise.id!==i))return e.exercise.tests.flatMap(t=>{const n=t.world?Ja(t.world):void 0;return n?[n]:[]});return[]}let Jt,Ol,Dl;function Bd(i){const e=i.dataset.tip;if(!e)return;Jt??(Jt=Object.assign(document.createElement("div"),{className:"tooltip",role:"tooltip"})),Jt.isConnected||document.body.append(Jt),Jt.textContent=e,Jt.hidden=!1;const t=i.getBoundingClientRect(),n=Jt.offsetWidth,a=Jt.offsetHeight,s=Math.min(Math.max(8,t.left+t.width/2-n/2),window.innerWidth-n-8),r=t.bottom+6+a{if(i.pointerType==="touch")return;const e=i.target.closest("[data-tip]");e!==Dl&&(uo(),e&&(Dl=e,Ol=window.setTimeout(()=>Bd(e),350)))}),document.addEventListener("focusin",i=>{const e=i.target.closest("[data-tip]");uo(),e!=null&&e.matches(":focus-visible")&&Bd(e)});for(const i of["pointerdown","focusout","scroll","keydown"])document.addEventListener(i,uo,!0)}const Ml="visustruct.reloadedAfterError";function u2(){try{const i=Number(sessionStorage.getItem(Ml));if(i&&Date.now()-i<3e4)return!1;sessionStorage.setItem(Ml,String(Date.now()))}catch{return!1}return location.reload(),!0}function SR(i){console.error(i);const e=(navigator.language||"").toLowerCase().startsWith("de"),t=document.createElement("div");t.className="startup-error";const n=document.createElement("h1");n.textContent=e?"VisuStruct konnte nicht starten":"VisuStruct could not start";const a=document.createElement("p");a.textContent=e?"Wahrscheinlich gibt es gerade eine neue Version. Lade die Seite neu. Hilft das nicht, drücke Strg+Umschalt+R (Mac: ⌘⇧R).":"There is probably a new version. Reload the page. If that does not help, press Ctrl+Shift+R (Mac: ⌘⇧R).";const s=document.createElement("button");s.textContent=e?"Neu laden":"Reload",s.addEventListener("click",()=>location.reload());const r=document.createElement("pre");r.textContent=String(i instanceof Error?i.message:i),t.append(n,a,s,r),(document.getElementById("app")??document.body).replaceWith(t)}window.addEventListener("vite:preloadError",i=>{u2()&&i.preventDefault()});const TR=X2();Promise.all([ah(TR,!1),ih($2(),!1)]).then(()=>{l2(),kR();const i=new URLSearchParams(location.search);i.has("visuobject")&&hg(),i.has("visuflow")&&pg();const e=document.getElementById("app"),t=!i.has("visustruct")&&!i.has("visubot");if(dg()&&t)return K(async()=>{const{ObjectApp:n}=await import("./objectApp-ZNEjA-0f.js").then(a=>a.g);return{ObjectApp:n}},[],import.meta.url).then(({ObjectApp:n})=>void new n(e));if(gg()&&t)return K(async()=>{const{FlowApp:n}=await import("./flowApp-DkiXDJDe.js");return{FlowApp:n}},[],import.meta.url).then(({FlowApp:n})=>void new n(e));new wR(e)}).then(()=>{try{sessionStorage.removeItem(Ml)}catch{}}).catch(i=>{/dynamically imported module|Importing a module script failed|error loading dynamically/i.test(String(i))&&u2()||SR(i)});export{qn as C,_F as J,Qb as L,K as _,hF as a,BF as b,Yf as c,OR as d,pg as e,Sr as f,vR as g,la as h,se as i,WZ as j,LZ as k,s1 as l,CR as m,hg as n,od as o,CF as p,s2 as q,hm as r,RZ as s,p as t,md as u,KF as v,Lo as w,nR as x,iR as y}; + `,t.addEventListener("click",n=>{const a=n.target.dataset.r;a===void 0&&n.target!==t||(t.remove(),e(a==="1"))}),document.body.append(t),t.querySelector('[data-r="0"]').focus()}):Promise.resolve(!0)}showMessage(e){this.statusLine.textContent=e,this.statusLine.classList.add("message"),setTimeout(()=>{this.statusLine.classList.remove("message"),this.updateStatus()},6e3)}loadXML(e,t,n){let a;try{a=Nl(e)}catch(s){this.showMessage(p("web_err_unreadable_fmt",t,s.message));return}(this.dirty||this.tab.fileName||this.tab.exerciseId)&&this.addTab(),this.doc=a,this.tab.fileName=t.replace(/\.(strk|xml)$/i,".visustruct"),this.fileHandle=n&&/\.visustruct$/i.test(t)?n:void 0,this.resetHistory()}async open(e){const t=window;if(!t.showOpenFilePicker||this.inViewer)return e.click();try{const[n]=await t.showOpenFilePicker({types:pd()}),a=await n.getFile();this.loadXML(await a.text(),a.name,n)}catch{}}async save(){var n,a;if(!this.downloads&&await this.saveToWorkspace())return;const e=new Blob([u1(this.doc)],{type:"application/xml"}),t=window;try{if(this.downloads){const s=this.fileName+".txt";await this.downloads.save({filename:s,data:e}),(n=this.tab).fileName??(n.fileName=this.fileName),this.dirty=!1,this.render(),this.showMessage(p("web_saved_txt_fmt",s));return}if(!this.fileHandle&&t.showSaveFilePicker&&!this.inViewer&&(this.fileHandle=await t.showSaveFilePicker({suggestedName:this.fileName,types:pd()}),this.tab.fileName=this.fileHandle.name),this.fileHandle){const s=await this.fileHandle.createWritable();await s.write(e),await s.close()}else{const s=document.createElement("a");s.href=URL.createObjectURL(e),s.download=this.fileName,s.click(),setTimeout(()=>URL.revokeObjectURL(s.href),1e3)}(a=this.tab).fileName??(a.fileName=this.fileName),this.dirty=!1,this.render()}catch{}}async exportDiagram(e){if(e==="visustruct"){const s=ld(this.doc,un(this.tab));return this.offerDownload(`${s}.visustruct`,new Blob([u1(this.doc)],{type:"application/xml"}))}const t=ud(this.doc,this.metrics,this.measure);if(!t){this.showMessage(p(e==="print"?"err_diagram_too_small_print":"err_diagram_too_small_export"));return}const n=ld(this.doc,un(this.tab)),a=Math.max(2,window.devicePixelRatio||1)*this.zoom;try{switch(e){case"svg":{t.svg.setAttribute("width",String(t.width*this.zoom)),t.svg.setAttribute("height",String(t.height*this.zoom)),await this.offerDownload(`${n}.svg`,new Blob([s2(t)],{type:"image/svg+xml"}));break}case"png":{const s=await md(t,a);await this.offerDownload(`${n}.png`,await KF(s));break}case"pdf":{const s=await md(t,Math.max(a,3)),r=await nR(iR(s),s.width,s.height,t,a2(this.doc));await this.offerDownload(`${n}.pdf`,r);break}case"print":this.printDiagram(t);break}}catch(s){this.showMessage(p("web_export_failed_fmt",s instanceof Error?s.message:String(s)))}}printDiagram(e){const t=document.createElement("div");t.className="print-sheet",e.svg.removeAttribute("width"),e.svg.removeAttribute("height"),t.append(e.svg),document.body.append(t);const n=()=>t.remove();window.addEventListener("afterprint",n,{once:!0});try{window.print()}catch{n(),this.showMessage(`${p("err_print_unavailable")} ${p("web_print_hint")}`);return}setTimeout(n,6e4)}async offerDownload(e,t){try{if(this.downloads){try{await this.downloads.save({filename:e,data:t}),this.showMessage(p("web_saved_fmt",e))}catch{await this.downloads.save({filename:e+".txt",data:t}),this.showMessage(p("web_saved_txt_fmt",e+".txt"))}return}const n=document.createElement("a");n.href=URL.createObjectURL(t),n.download=e,n.click(),setTimeout(()=>URL.revokeObjectURL(n.href),1e3)}catch{this.showMessage(p("err_save_failed_fmt",e))}}setupFileDrop(){window.addEventListener("dragover",e=>{var t;(t=e.dataTransfer)!=null&&t.types.includes("Files")&&(e.preventDefault(),this.root.classList.add("file-drag"))}),window.addEventListener("dragleave",e=>{e.relatedTarget===null&&this.root.classList.remove("file-drag")}),window.addEventListener("drop",async e=>{var n;this.root.classList.remove("file-drag");const t=(n=e.dataTransfer)==null?void 0:n.files[0];t&&(e.preventDefault(),this.loadXML(await t.text(),t.name))})}onKeyDown(e){var a,s;const t=e.metaKey||e.ctrlKey,n=e.target instanceof HTMLTextAreaElement||e.target instanceof HTMLInputElement||((a=e.target)==null?void 0:a.isContentEditable)===!0;if(t&&e.key.toLowerCase()==="s")e.preventDefault(),this.save();else if(t&&e.key.toLowerCase()==="p")e.preventDefault(),this.simulating||this.exportDiagram("print");else if(t&&e.key.toLowerCase()==="o")e.preventDefault(),this.open(this.root.querySelector("input[type=file]"));else{if(n||this.simulating)return;t&&e.key.toLowerCase()==="z"?(e.preventDefault(),e.shiftKey?this.redo():this.undo()):t&&e.key.toLowerCase()==="c"&&!((s=getSelection())!=null&&s.toString())?this.copySelection()&&e.preventDefault():t&&e.key.toLowerCase()==="x"?(e.preventDefault(),this.cutSelection()):t&&e.key.toLowerCase()==="v"?(e.preventDefault(),this.paste()):t&&e.key.toLowerCase()==="y"?(e.preventDefault(),this.redo()):e.key==="Delete"||e.key==="Backspace"?(e.preventDefault(),this.deleteSelection()):e.key==="Escape"&&(this.drag?this.endDrag():(this.selected=void 0,this.render()))}}svgPoint(e,t){if(!this.svg)return;const n=this.svg.getBoundingClientRect(),a=e-n.left,s=t-n.top;if(!(a<0||s<0||a>n.width||s>n.height))return{x:a/this.zoom,y:s/this.zoom}}nodeAt(e,t){for(let n=this.flat.length-1;n>=0;n--){const a=this.flat[n].frame;if(e>=a.x&&e<=a.x+a.width&&t>=a.y&&t<=a.y+a.height)return this.flat[n]}}onCanvasPointerDown(e){if(this.simulating)return;const t=this.svgPoint(e.clientX,e.clientY);if(!t)return;document.activeElement instanceof HTMLElement&&document.activeElement.blur();const n=this.nodeAt(t.x,t.y),a=n&&this.selected&&fo(n.idPath,this.selected);this.selected=n==null?void 0:n.idPath,this.render(),n&&e.pointerType!=="touch"&&!(In(this.doc,n.idPath)&&!a)&&this.beginDrag(e,{kind:"move",path:n.idPath})}beginDrag(e,t){e.button!==0||this.simulating||(e.preventDefault(),this.drag={source:t,pointerId:e.pointerId,startX:e.clientX,startY:e.clientY,active:!1})}onPointerMove(e){const t=this.drag;if(!t||e.pointerId!==t.pointerId)return;if(!t.active){if(Math.hypot(e.clientX-t.startX,e.clientY-t.startY)<5)return;t.active=!0,t.ghost=this.makeGhost(t.source),document.body.append(t.ghost),this.root.classList.add("dragging")}t.ghost.style.transform=`translate(${e.clientX+12}px, ${e.clientY+12}px)`,this.autoScroll(e.clientX,e.clientY);const n=this.svgPoint(e.clientX,e.clientY);t.target=n?this.dropTargetAt(n.x,n.y,t.source):void 0,this.showDropTarget(t.target)}onPointerUp(e){const t=this.drag;!t||e.pointerId!==t.pointerId||(t.active&&t.target?this.applyDrop(t.source,t.target):!t.active&&t.source.kind==="palette"?this.insertNearSelection(t.source.make()):!t.active&&t.source.kind==="sensor"&&this.insertSensor(t.source.text),this.endDrag())}endDrag(){var e,t;(t=(e=this.drag)==null?void 0:e.ghost)==null||t.remove(),this.drag=void 0,this.root.classList.remove("dragging"),this.showDropTarget(void 0)}makeGhost(e){const t=document.createElement("div");if(t.className="drag-ghost",e.kind==="palette"||e.kind==="sensor")t.textContent=e.label;else{const n=Ot(this.doc,e.path);t.textContent=`${so(n.type)}: ${Zl(n)[0]}`}return t}autoScroll(e,t){const n=this.canvasHost.getBoundingClientRect(),a=40,s=12;t>n.bottom-a&&tn.top-a&&(this.canvasHost.scrollTop-=s),e>n.right-a&&en.left-a&&(this.canvasHost.scrollLeft-=s)}dropTargetAt(e,t,n){var l;const a=((l=this.layout)==null?void 0:l.elements)??[],s=this.nodeAt(e,t);if(n.kind==="sensor")return!s||In(this.doc,s.idPath)?void 0:gd.includes(Ot(this.doc,s.idPath).type)?{kind:"condition",path:s.idPath,frame:s.frame}:void 0;if(!s){const u=a[a.length-1];if(!u)return;const m=u.frame.y+u.frame.height;return t>m?n.kind==="move"&&n.path.length===1&&n.path[0]===a.length-1?void 0:{kind:"rootAppend",frame:{x:u.frame.x,y:m,width:u.frame.width,height:0}}:t=n.path.length&&n.path.every((u,m)=>r[m]===u)?void 0:In(this.doc,r)?{kind:"replace",path:r,frame:s.frame}:{kind:t"]/g,e=>({"&":"&","<":"<",">":">",'"':"""})[e])}function Zd(i){if(!i)return[];for(const e of[...Ct.flatMap(t=>t.steps.flatMap(n=>n.blocks)),...An.flatMap(t=>t.blocks)])if(!(e.kind!=="exercise"||e.exercise.id!==i))return e.exercise.tests.flatMap(t=>{const n=t.world?Ja(t.world):void 0;return n?[n]:[]});return[]}let Jt,Ol,Dl;function Bd(i){const e=i.dataset.tip;if(!e)return;Jt??(Jt=Object.assign(document.createElement("div"),{className:"tooltip",role:"tooltip"})),Jt.isConnected||document.body.append(Jt),Jt.textContent=e,Jt.hidden=!1;const t=i.getBoundingClientRect(),n=Jt.offsetWidth,a=Jt.offsetHeight,s=Math.min(Math.max(8,t.left+t.width/2-n/2),window.innerWidth-n-8),r=t.bottom+6+a{if(i.pointerType==="touch")return;const e=i.target.closest("[data-tip]");e!==Dl&&(uo(),e&&(Dl=e,Ol=window.setTimeout(()=>Bd(e),350)))}),document.addEventListener("focusin",i=>{const e=i.target.closest("[data-tip]");uo(),e!=null&&e.matches(":focus-visible")&&Bd(e)});for(const i of["pointerdown","focusout","scroll","keydown"])document.addEventListener(i,uo,!0)}const Ml="visustruct.reloadedAfterError";function u2(){try{const i=Number(sessionStorage.getItem(Ml));if(i&&Date.now()-i<3e4)return!1;sessionStorage.setItem(Ml,String(Date.now()))}catch{return!1}return location.reload(),!0}function SR(i){console.error(i);const e=(navigator.language||"").toLowerCase().startsWith("de"),t=document.createElement("div");t.className="startup-error";const n=document.createElement("h1");n.textContent=e?"VisuStruct konnte nicht starten":"VisuStruct could not start";const a=document.createElement("p");a.textContent=e?"Wahrscheinlich gibt es gerade eine neue Version. Lade die Seite neu. Hilft das nicht, drücke Strg+Umschalt+R (Mac: ⌘⇧R).":"There is probably a new version. Reload the page. If that does not help, press Ctrl+Shift+R (Mac: ⌘⇧R).";const s=document.createElement("button");s.textContent=e?"Neu laden":"Reload",s.addEventListener("click",()=>location.reload());const r=document.createElement("pre");r.textContent=String(i instanceof Error?i.message:i),t.append(n,a,s,r),(document.getElementById("app")??document.body).replaceWith(t)}window.addEventListener("vite:preloadError",i=>{u2()&&i.preventDefault()});const TR=X2();Promise.all([ah(TR,!1),ih($2(),!1)]).then(()=>{l2(),kR();const i=new URLSearchParams(location.search);i.has("visuobject")&&hg(),i.has("visuflow")&&pg();const e=document.getElementById("app"),t=!i.has("visustruct")&&!i.has("visubot");if(dg()&&t)return K(async()=>{const{ObjectApp:n}=await import("./objectApp-exr4obxz.js").then(a=>a.g);return{ObjectApp:n}},[],import.meta.url).then(({ObjectApp:n})=>void new n(e));if(gg()&&t)return K(async()=>{const{FlowApp:n}=await import("./flowApp-4s69NVPv.js");return{FlowApp:n}},[],import.meta.url).then(({FlowApp:n})=>void new n(e));new wR(e)}).then(()=>{try{sessionStorage.removeItem(Ml)}catch{}}).catch(i=>{/dynamically imported module|Importing a module script failed|error loading dynamically/i.test(String(i))&&u2()||SR(i)});export{qn as C,_F as J,Qb as L,K as _,hF as a,BF as b,Yf as c,OR as d,pg as e,Sr as f,vR as g,la as h,se as i,WZ as j,LZ as k,s1 as l,CR as m,hg as n,od as o,CF as p,s2 as q,hm as r,RZ as s,p as t,md as u,KF as v,Lo as w,nR as x,iR as y}; diff --git a/website/app/assets/it-ClGS2uQV.js b/website/app/assets/it-Bsr1AlWk.js similarity index 99% rename from website/app/assets/it-ClGS2uQV.js rename to website/app/assets/it-Bsr1AlWk.js index 436c5511..86381ac7 100644 --- a/website/app/assets/it-ClGS2uQV.js +++ b/website/app/assets/it-Bsr1AlWk.js @@ -135,6 +135,7 @@ const e=`/* Testi presenti solo nella versione web. Tutto il resto proviene dai "web_files_saved_fmt" = "Salvato: %@"; "web_files_create" = "Crea"; "web_learn_ludwig_tip" = "Il consiglio di Ludwig"; +"web_learn_pro" = "Sapere da professionisti con Ludwig"; "web_game_title" = "Gioco: Vero o falso?"; "web_game_intro" = "Ludwig ti mostra dei valori e una condizione. È vera (true) o falsa (false)? Dieci turni, sempre più difficili."; "web_game_start" = "Inizia il gioco"; diff --git a/website/app/assets/ja-JQ8MwNFB.js b/website/app/assets/ja-L0a84IMq.js similarity index 99% rename from website/app/assets/ja-JQ8MwNFB.js rename to website/app/assets/ja-L0a84IMq.js index 7c5d2739..18948e97 100644 --- a/website/app/assets/ja-JQ8MwNFB.js +++ b/website/app/assets/ja-L0a84IMq.js @@ -135,6 +135,7 @@ const e=`/* Web 版にのみ存在するテキスト。その他はすべてア "web_files_saved_fmt" = "保存しました:%@"; "web_files_create" = "作成"; "web_learn_ludwig_tip" = "ルートヴィヒのヒント"; +"web_learn_pro" = "ルートヴィヒのプロ知識"; "web_game_title" = "ゲーム:真か偽か?"; "web_game_intro" = "ルートヴィヒが値と条件を見せます。条件は真(true)?それとも偽(false)?10ラウンド、だんだん難しくなります。"; "web_game_start" = "ゲームを始める"; diff --git a/website/app/assets/ko-tfdKG8Fb.js b/website/app/assets/ko-U6EDne8i.js similarity index 99% rename from website/app/assets/ko-tfdKG8Fb.js rename to website/app/assets/ko-U6EDne8i.js index 6753303e..e74f6754 100644 --- a/website/app/assets/ko-tfdKG8Fb.js +++ b/website/app/assets/ko-U6EDne8i.js @@ -135,6 +135,7 @@ const e=`/* 웹 버전에만 있는 텍스트입니다. 나머지는 모두 앱 "web_files_saved_fmt" = "저장됨: %@"; "web_files_create" = "만들기"; "web_learn_ludwig_tip" = "루트비히의 팁"; +"web_learn_pro" = "루트비히의 전문가 지식"; "web_game_title" = "게임: 참일까 거짓일까?"; "web_game_intro" = "루트비히가 값과 조건을 보여 줍니다. 조건이 참(true)일까요, 거짓(false)일까요? 10라운드, 점점 어려워집니다."; "web_game_start" = "게임 시작"; diff --git a/website/app/assets/nb-BpibUAkX.js b/website/app/assets/nb-C9pwk403.js similarity index 99% rename from website/app/assets/nb-BpibUAkX.js rename to website/app/assets/nb-C9pwk403.js index 976aa674..965bab35 100644 --- a/website/app/assets/nb-BpibUAkX.js +++ b/website/app/assets/nb-C9pwk403.js @@ -135,6 +135,7 @@ const e=`/* Tekster som bare finnes i nettversjonen. Alt annet kommer fra appens "web_files_saved_fmt" = "Lagret: %@"; "web_files_create" = "Lag"; "web_learn_ludwig_tip" = "Ludwigs tips"; +"web_learn_pro" = "Proffkunnskap med Ludwig"; "web_game_title" = "Spill: Sant eller usant?"; "web_game_intro" = "Ludwig viser deg verdier og en betingelse. Er betingelsen sann (true) eller usann (false)? Ti runder, stadig vanskeligere."; "web_game_start" = "Start spillet"; diff --git a/website/app/assets/nl-HArZjiga.js b/website/app/assets/nl-D1JTb8Xr.js similarity index 99% rename from website/app/assets/nl-HArZjiga.js rename to website/app/assets/nl-D1JTb8Xr.js index f64e189c..fdccda5e 100644 --- a/website/app/assets/nl-HArZjiga.js +++ b/website/app/assets/nl-D1JTb8Xr.js @@ -135,6 +135,7 @@ const e=`/* Teksten die alleen in de webversie bestaan. Al het andere komt uit d "web_files_saved_fmt" = "Opgeslagen: %@"; "web_files_create" = "Maken"; "web_learn_ludwig_tip" = "Ludwigs tip"; +"web_learn_pro" = "Profkennis met Ludwig"; "web_game_title" = "Spel: Waar of onwaar?"; "web_game_intro" = "Ludwig laat je waarden en een voorwaarde zien. Is de voorwaarde waar (true) of onwaar (false)? Tien rondes, steeds lastiger."; "web_game_start" = "Spel starten"; diff --git a/website/app/assets/objectApp-ZNEjA-0f.js b/website/app/assets/objectApp-exr4obxz.js similarity index 99% rename from website/app/assets/objectApp-ZNEjA-0f.js rename to website/app/assets/objectApp-exr4obxz.js index 14f44761..f5d6cf2d 100644 --- a/website/app/assets/objectApp-ZNEjA-0f.js +++ b/website/app/assets/objectApp-exr4obxz.js @@ -1,5 +1,5 @@ -const __vite__mapDeps=(i,m=__vite__mapDeps,d=(m.f||(m.f=["./projectZip-DEvwTDaN.js","./index-BVzzpk4y.js","./index-DVwLXYFw.css"])))=>i.map(i=>d[i]); -var Ns=Object.defineProperty;var Os=(a,e,t)=>e in a?Ns(a,e,{enumerable:!0,configurable:!0,writable:!0,value:t}):a[e]=t;var E=(a,e,t)=>Os(a,typeof e!="symbol"?e+"":e,t);import{t as d,i as ie,s as Ps,m as Is,g as Ds,w as Rs,J as Hs,c as Bs,a as Ws,b as Ye,p as zs,d as Vs,e as Us,f as Js,_ as wt,h as $t,j as Ks,r as _t,k as Xs,l as ct}from"./index-BVzzpk4y.js";function Ys(a){const e=[];let t=0;for(;ti.map(i=>d[i]); +var Ns=Object.defineProperty;var Os=(a,e,t)=>e in a?Ns(a,e,{enumerable:!0,configurable:!0,writable:!0,value:t}):a[e]=t;var E=(a,e,t)=>Os(a,typeof e!="symbol"?e+"":e,t);import{t as d,i as ie,s as Ps,m as Is,g as Ds,w as Rs,J as Hs,c as Bs,a as Ws,b as Ye,p as zs,d as Vs,e as Us,f as Js,_ as wt,h as $t,j as Ks,r as _t,k as Xs,l as ct}from"./index-DqKA7YqL.js";function Ys(a){const e=[];let t=0;for(;te.text===","?", ":e.text).join("")}function ms(a){const e=[[]];let t=0;for(const s of a)s.text==="<"||s.text==="("||s.text==="["||s.text==="{"?t++:(s.text===">"||s.text===")"||s.text==="]"||s.text==="}")&&t--,s.text===","&&t===0?e.push([]):e[e.length-1].push(s);return e.filter(s=>s.length>0)}function ft(a){var t,s;const e=[];for(let i=0;i{const t=ft(e).filter(i=>i.text!=="final"),s=t[t.length-1];return{name:s!=null&&s.word?s.text:"",type:lt(t.slice(0,-1))}})}function kt(a,e,t,s){var x,L;const i=ft(a),n=new Set;let o=0;for(;o"));const r=i.slice(o);if(r.length===0||a.length===0)return[];const c=a[0].from,l=r.findIndex(S=>S.text==="("),h=r.findIndex(S=>S.text==="="),u=l>0&&(h<0||lS.text==="="),y=_<0?g:g.slice(0,_);let w=y.length-1;for(;w>0&&!y[w].word;)w--;if(w<1)return[];const $=lt(y.slice(0,w)),p=m.length>1,v=[];return m.forEach((S,k)=>{var C;const j=S.findIndex(F=>F.text==="="),M=j<0?S:S.slice(0,j),A=k===0?y[w]:M.find(F=>F.word);if(!A)return;const R=M.filter(F=>F.from>A.from&&F.text==="[").length;v.push({kind:"field",name:A.text,type:$+"[]".repeat(R),params:[],visibility:xt(n,f),isStatic:n.has("static"),isAbstract:!1,from:c,to:s,headerFrom:c,headerTo:k===0?((C=M[M.length-1])==null?void 0:C.to)??A.to:A.to,shared:p,nameFrom:A.from,nameTo:A.to})}),v}function Zs(a,e,t){var n;let s=[],i=e;for(;ih.text==="="),c=ye(a,i,"{","}");if(r){s.push(...a.slice(i,c)),i=c;continue}const l=s.map(h=>h.text);l.includes("class")||l.includes("interface")||l.includes("enum")||s.length>0&&t.members.push(...kt(s,t.name,t.kind==="interface",((n=a[c-1])==null?void 0:n.to)??o.to)),s=[],i=c;continue}s.push(o),i++}return t.bodyEnd=a.length>0?a[a.length-1].to:0,i}function oe(a){var n,o,r,c;const e=Ys(a),t=[];let s=[],i=0;for(;iw.text==="class"||w.text==="interface"),f=u>=0?h[u+1]:void 0;if(!(f!=null&&f.word)){i=ye(e,i,"{","}"),s=[];continue}let m=u;for(;m>0&&(fs.has(h[m-1].text)||h[m-1].text==="@");)m--;const g={name:f.text,kind:h[u].text==="interface"?"interface":"class",isAbstract:h.slice(m,u).some(w=>w.text==="abstract"),interfaces:[],members:[],from:((n=s[s.indexOf(h[m])])==null?void 0:n.from)??h[m].from,to:0,headerFrom:((o=s[s.indexOf(h[m])])==null?void 0:o.from)??h[m].from,headerTo:h[h.length-1].to,nameFrom:f.from,nameTo:f.to,bodyEnd:0};let _=u+2;((r=h[_])==null?void 0:r.text)==="<"&&(_=ye(h,_,"<",">"));let y="";for(;_")-1:w.word&&y==="extends"&&g.kind==="class"?g.superclass??(g.superclass=w.text):w.word&&y&&g.interfaces.push(w.text)}i=Zs(e,i+1,g),g.to=((c=e[i-1])==null?void 0:c.to)??a.length,t.push(g),s=[]}return t}function Fe(a){const e=/^([\p{L}_$][\p{L}\p{N}_$]*)(\[\])+$/u.exec(a);if(e)return{name:e[1],many:!0};const t=/^(?:ArrayList|LinkedList|List|Set|HashSet|TreeSet|Collection|Queue|Deque|ArrayDeque|Stack|Vector)<([\p{L}_$][\p{L}\p{N}_$]*)>$/u.exec(a);return t?{name:t[1],many:!0}:{name:a,many:!1}}function Qs(a){const e=new Set(a.map(s=>s.name)),t=[];for(const s of a){s.superclass&&e.has(s.superclass)&&t.push({kind:"extends",from:s.name,to:s.superclass});for(const i of s.interfaces)e.has(i)&&t.push({kind:s.kind==="interface"?"extends":"implements",from:s.name,to:i});for(const i of s.members){if(i.kind!=="field")continue;const n=Fe(i.type);e.has(n.name)&&t.push({kind:"association",from:s.name,to:n.name,role:i.name,multiplicity:n.many?"0..*":"1"})}}return t}function Ge(a){const e=a.params.map(t=>`${t.name}: ${t.type}`).join(", ");return a.kind==="field"?`${a.visibility} ${a.name}: ${a.type}`:a.kind==="constructor"?`${a.visibility} ${a.name}(${e})`:`${a.visibility} ${a.name}(${e}): ${a.type}`}const ei=/^[\p{L}_$][\p{L}\p{N}_$]*$/u;function Ve(a){var c;let e=a.trim().replace(/;$/,"").trim();if(!e)return;let t;/^[+\-#~]/.test(e)&&(t=e[0],e=e.slice(1).trim());let s=!1;const i=e.split(/\s+/);for(;["static","public","private","protected"].includes(i[0]);){const l=i.shift();l==="static"?s=!0:t??(t=l==="public"?"+":l==="private"?"-":"#")}e=i.join(" ");const n=e.indexOf("(");if(n>=0){const l=e.lastIndexOf(")");if(lg.trim()).filter(Boolean).map(g=>{const _=/^([\p{L}_$][\p{L}\p{N}_$]*)\s*:\s*(.+)$/u.exec(g);if(_)return{name:_[1],type:_[2].replace(/\s+/g,"")};const y=/^(.+)\s+([\p{L}_$][\p{L}\p{N}_$]*)$/u.exec(g);return y?{name:y[2],type:y[1].replace(/\s+/g,"")}:{name:g,type:"int"}});return{kind:"method",visibility:t,name:h,type:u==null?void 0:u.replace(/\s+/g,""),params:m,isStatic:s}}const o=/^([\p{L}_$][\p{L}\p{N}_$]*)\s*(?::\s*(.+))?$/u.exec(e);if(o)return{kind:"field",visibility:t,name:o[1],type:(c=o[2])==null?void 0:c.replace(/\s+/g,""),params:[],isStatic:s};const r=/^(.+?)\s+([\p{L}_$][\p{L}\p{N}_$]*)$/u.exec(e);if(r)return{kind:"field",visibility:t,name:r[2],type:r[1].replace(/\s+/g,""),params:[],isStatic:s}}const ti={"+":"public ","-":"private ","#":"protected ","~":""};function si(a){return/^(int|long|short|byte)$/.test(a)?"0":/^(double|float)$/.test(a)?"0.0":a==="boolean"?"false":a==="char"?"' '":"null"}function bs(a,e,t){const s=e.kind==="interface",i=s?"":ti[a.visibility??(a.kind==="field"?"-":"+")],n=a.isStatic?"static ":"";if(a.kind==="field")return`${i}${n}${a.type??"int"} ${a.name}`;const o=a.params.map(r=>`${r.type} ${r.name}`).join(", ");return a.name===e.name?`${i}${a.name}(${o})`:`${i}${n}${t&&!s?"abstract ":""}${a.type??"void"} ${a.name}(${o})`}const Ue=(a,e)=>a.lastIndexOf(` `,e-1)+1;function mt(a,e,t){const s=Ue(a,e),i=a.slice(s,e);let n=t;for(;n
    - ${b(d("web_about_version_fmt").replace("%@","0.14.1"))} + ${b(d("web_about_version_fmt").replace("%@","0.14.2"))}
    @@ -315,7 +315,7 @@ public String toString() { `,"in"),this.consolePane().input.hidden=!0,t.vm.input(e),this.debugRun())}debugError(e){var o;const t=e.pos?String(e.pos.line+1):"",s=((o=e.pos)==null?void 0:o.file.split("/").pop())??"",i=e.detail.replace(/^expected:/,""),n={syntax:"web_visuobject_dbg_err_syntax",symbol:"web_visuobject_dbg_err_symbol",unsupported:"web_visuobject_dbg_err_unsupported",nomain:"web_visuobject_no_main",type:"web_visuobject_dbg_err_type",import:"web_visuobject_dbg_err_import",typename:"web_visuobject_dbg_err_typename"}[e.code];e.pos&&this.showLine(e.pos.file,e.pos.line),this.stopDebug(),this.debugStatus(d(n,s,t,i),!0)}showDebugButtons(){const e=this.dbg,t=(e==null?void 0:e.state)==="paused";for(const s of this.shell.querySelectorAll("[data-dbg]"))s.disabled=!e||(s.dataset.dbg==="pause"?e.state!=="running":!t)}showLine(e,t){this.project.files.some(s=>s.path===e)&&e!==this.active&&this.openFile(e),this.editor.setMarks({placeholders:[],problems:[],current:t},!0)}showDebugState(){const e=this.dbg;if(!e)return;e.frames=e.vm.stack();const t=e.vm.heap(),s=e.frames[e.frame];s&&this.showLine(s.pos.file,s.pos.line);const i=e.values.size===0&&e.vars.size===0,n=new Set,o=new Map;for(const h of t)for(const u of h.fields){const f=`dbg${h.id}.${u.name}`;o.set(f,u.value),!i&&e.values.get(f)!==u.value&&n.add(f)}e.values=o;const r=new Set,c=new Map;e.frames.forEach((h,u)=>{for(const f of h.vars){const m=`${e.frames.length-u}|${h.title}|${f.name}`;c.set(m,f.value),!i&&e.vars.get(m)!==f.value&&r.add(`${h.title}|${f.name}`)}}),e.vars=c;const l={objects:this.liveObjects(t),changed:n,frames:e.frames,frame:e.frame,changedVars:r,onFrame:h=>{e.frame=h,l.frame=h;const u=e.frames[h];u&&this.showLine(u.pos.file,u.pos.line),this.objectDiagram.renderInspector()},move:(h,u)=>e.places.set(h,u)};this.objectDiagram.live=l,this.sequence=e.vm.sequence(),this.diagramMode==="object"&&this.objectDiagram.render(),this.diagramMode==="sequence"&&this.renderSequence()}renderSequence(){var n,o,r;const e=this.shell.querySelector(".vo-seqcanvas"),t=e.querySelector(".vo-seq"),s=e.querySelector(".vo-empty"),i=this.sequence;if(s.hidden=!!i&&i.events.length>0,s.textContent=d(i?"web_visuobject_seq_no_calls":"web_visuobject_seq_empty"),!i||!i.events.length)t.innerHTML="",t.setAttribute("width","0");else{const c=((n=this.dbg)==null?void 0:n.state)==="paused"||((o=this.dbg)==null?void 0:o.state)==="input",{svg:l,width:h,height:u}=Ti(i,c?i.events.length-1:void 0);t.innerHTML=l+(i.truncated?`${b(d("web_visuobject_seq_truncated"))}`:""),t.setAttribute("width",String(h)),t.setAttribute("height",String(u)),c&&((r=t.querySelector(".vo-seq-msg.current"))==null||r.scrollIntoView({block:"nearest",inline:"nearest"}))}this.renderSequenceInspector()}renderSequenceInspector(){if(this.objectDiagram.live)return this.objectDiagram.renderInspector();this.inspector.innerHTML=`

    ${b(d("web_visuobject_seq_hint"))}

    `}liveObjects(e){const t=this.dbg,s=this.project.objects??[],i=c=>40+c.fields.length*20,n=[],o=[],r=[];for(const c of e){const l=`dbg${c.id}`,h=t.places.get(l)??s.find(u=>u.name===c.name&&u.cls===c.cls);if(!h){r.push(c);continue}t.places.set(l,{x:h.x,y:h.y}),n.push({x:h.x,y:h.y,w:260,h:i(c)})}for(const c of r){const l=i(c);let h={x:24,y:24};e:for(let u=24;u<6e3;u+=30)for(let f=24;f<=24+3*320;f+=320)if(n.every(m=>f+260+30<=m.x||m.x+m.w+30<=f||u+l+30<=m.y||m.y+m.h+30<=u)){h={x:f,y:u};break e}t.places.set(`dbg${c.id}`,h),n.push({...h,w:260,h:l})}for(const c of e){const l=`dbg${c.id}`;o.push({id:l,name:c.name,cls:c.cls,...t.places.get(l),values:Object.fromEntries(c.fields.map(h=>[h.name,h.value]))})}return o}stopDebug(e,t=!1){const s=this.dbg;s&&clearTimeout(s.timer),this.dbg=void 0,s&&(this.sequence=s.vm.sequence()),this.objectDiagram.live=void 0,this.consolePane().input.hidden=!0,this.shell.querySelector(".vo-dbg-controls").hidden=!0,this.shell.querySelector("[data-action=stop]").disabled=!0,this.shell.querySelector("[data-action=run]").disabled=!1,t||this.editor.setMarks({placeholders:[],problems:[]},!1),e&&this.debugStatus(d(e),t),this.diagramMode==="object"&&this.objectDiagram.render(),this.diagramMode==="sequence"&&this.renderSequence()}chooseWorld(e){if(e!=="object"){if(e==="flow"){Us(),location.href=`${location.pathname}?visuflow${location.hash}`;return}Js(e),location.href=`${location.pathname}?${e==="on"?"visubot":"visustruct"}${location.hash}`}}get activeFile(){return this.project.files.find(e=>e.path===this.active)}showActive(){const e=this.activeFile;this.editor.setText((e==null?void 0:e.text)??""),this.editor.setBreakpoints(e?this.breakpoints.get(e.path)??[]:[]),this.editor.setReadOnly(!e),e&&!this.openTabs.includes(e.path)&&this.openTabs.push(e.path),this.renderTabs(),J(ot,this.active??"")}renderTabs(){if(this.openTabs=this.openTabs.filter(e=>this.project.files.some(t=>t.path===e)),J(cs,JSON.stringify(this.openTabs)),this.openTabs.length===0){this.tabs.innerHTML=`${b(d("web_visuobject_no_file"))}`;return}this.tabs.innerHTML=this.openTabs.map(e=>{const t=e===this.active,s=this.isDirty(e);return`
    -
    `}).join("")}onTabClick(e){var i;const t=e.target,s=(i=t.closest("[data-tab]"))==null?void 0:i.dataset.tab;if(s){if(t.closest("[data-close]"))return this.closeTab(s);this.treeSelection=`file:${s}`,this.openFile(s)}}closeTab(e){const t=this.openTabs.indexOf(e);t<0||(this.openTabs.splice(t,1),e===this.active?(this.active=this.openTabs[Math.min(t,this.openTabs.length-1)],this.lastTyping=0,this.showActive(),this.refresh()):this.renderTabs())}snapshot(){return JSON.stringify({project:this.project,active:this.active})}remember(){this.history.push(this.snapshot()),this.history.length>kn&&this.history.shift(),this.future=[]}setProject(e,t=this.active){var s;this.remember(),this.lastTyping=0,this.project=e,this.active=e.files.some(i=>i.path===t)?t:(s=e.files[0])==null?void 0:s.path,this.showActive(),this.refresh()}openFile(e){if(e===this.active)return;this.active=e,this.lastTyping=0,this.showActive();const t=D(e);this.currentPackage=t,this.open.set(`pkg:${t}`,!0),this.refresh()}typed(){const e=this.activeFile;if(!e)return;const t=Date.now();t-this.lastTyping>1500&&this.remember(),this.lastTyping=t,this.project=$e(this.project,e.path,this.editor.text),this.saveBreakpoints(),this.dbg&&this.stopDebug("web_visuobject_dbg_code_changed"),this.refresh(),clearTimeout(this.renameTimer),this.renameTimer=window.setTimeout(()=>this.syncFileName(),700)}syncFileName(){var c;const e=this.activeFile;if(!e||this.editing)return;const t=Q(e.path).replace(/\.java$/i,""),s=this.classes.filter(l=>l.path===e.path);if(s.length===0||s.some(l=>l.name===t))return;const i=((c=/\bpublic\s+(?:abstract\s+|final\s+)*(?:class|interface|enum)\s+(\w+)/.exec(e.text))==null?void 0:c[1])??s[0].name;if(!pe.test(i)||s.filter(l=>l.name===i).length!==1)return;const n=le(D(e.path),`${i}.java`);if(this.project.files.some(l=>l.path===n))return;let o=Oe(this.project,e.path,n);const r=this.positions.get(t);r&&!this.positions.has(i)&&this.positions.set(i,r);for(const l of Object.keys(o.uml??{}))l.startsWith(`${t}.`)&&(o={...o,uml:ke(o.uml,l,i+l.slice(t.length))});this.openTabs=this.openTabs.map(l=>l===e.path?n:l),this.treeSelection===`file:${e.path}`&&(this.treeSelection=`file:${n}`),this.isOpen(`file:${e.path}`)&&this.open.set(`file:${n}`,!0),this.project=o,this.active=n,J(ot,n),this.savePositions(),this.refresh()}undo(e){const t=e?this.future:this.history,s=e?this.history:this.future,i=t.pop();if(i===void 0)return;s.push(this.snapshot());const n=JSON.parse(i);this.project=n.project,this.active=n.active,this.lastTyping=0,this.showActive(),this.refresh()}refresh(){J(os,Pe(this.project)),this.renderTabs(),this.classes=Ct(this.project),this.selection&&!this.findClass(this.selection.cls)&&(this.selection=void 0),this.relSelection&&!this.findRelation(this.relSelection)&&!this.findDependency(this.relSelection)&&(this.relSelection=void 0),this.editing||(this.render(),this.renderTree())}ownTypesAt(e){const t=this.activeFile;if(!t)return;const s=this.editor.view.state.doc.toString(),i=X(D(t.path)),n=oe(s).map(l=>({...l,pkg:i})),o=new Set(n.map(l=>l.name)),r=n.find(l=>l.headerFrom<=e&&e<=l.bodyEnd),c=ct()==="de"?"de":ct()==="pt-PT"?"pt":"en";return Ji([...n,...this.classes.filter(l=>l.path!==t.path&&!o.has(l.name))],{cls:r==null?void 0:r.name,pkg:i},c)}findClass(e){return this.classes.find(t=>t.name===e)}caretMoved(){var n,o;const e=this.editor.caret,t=this.classes.find(r=>r.path===this.active&&e>=r.from&&e<=r.to),s=t==null?void 0:t.members.findIndex(r=>e>=r.from&&e<=r.to),i=t?{cls:t.name,member:s!==void 0&&s>=0?s:void 0}:void 0;(i==null?void 0:i.cls)===((n=this.selection)==null?void 0:n.cls)&&(i==null?void 0:i.member)===((o=this.selection)==null?void 0:o.member)||(this.selection=i,this.editing||(this.render(),this.renderTree()))}showInCode(e,t){e.path!==this.active&&(this.active=e.path,this.lastTyping=0,this.showActive());const s=this.editor.view,[i,n]=t?[t.headerFrom,t.headerTo]:[e.nameFrom,e.nameTo],o=Math.min(n,s.state.doc.length);s.dispatch({selection:{anchor:Math.min(i,o),head:o},scrollIntoView:!0})}message(e,t=!1){this.status.textContent=e,this.status.classList.toggle("hint",t)}openFiles(){const e=document.createElement("input");e.type="file",e.multiple=!0,e.accept=".zip,.java,.visuobject,application/zip,text/plain",e.addEventListener("change",()=>void this.readFiles([...e.files??[]])),e.click()}async readFiles(e){var t;if(e.length!==0)try{const s=e.find(r=>/\.zip$/i.test(r.name));if(s){const{projectFromZip:r}=await wt(async()=>{const{projectFromZip:l}=await import("./projectZip-DEvwTDaN.js");return{projectFromZip:l}},__vite__mapDeps([0,1,2]),import.meta.url),c=r(new Uint8Array(await s.arrayBuffer()),s.name.replace(/\.zip$/i,""));await this.newProject(c);return}const i=e.find(r=>/\.visuobject$/i.test(r.name));if(i){const r=qt(await i.text());if(!r)throw new Error("format");await this.newProject(r);return}const n=At(this.project.name,await Promise.all(e.map(async r=>({name:r.name,text:await r.text()}))));let o=this.project;for(const r of n.files)o=et(o,r.path,r.text);this.setProject(o,(t=n.files[0])==null?void 0:t.path)}catch{this.message(d("web_visuobject_open_failed"))}}async save(){this.workspace?await this.writeCurrent():await this.downloadZip()}async downloadZip(){const{projectToZip:e}=await wt(async()=>{const{projectToZip:s}=await import("./projectZip-DEvwTDaN.js");return{projectToZip:s}},__vite__mapDeps([0,1,2]),import.meta.url),t=e(this.project);Sn(`${this.project.name||"Projekt"}.zip`,t.slice().buffer,"application/zip")}isDirty(e){var t;return!this.workspace||this.saved===void 0?!1:e===void 0?this.saved!==Pe(this.project):this.savedFiles.get(e)!==((t=this.project.files.find(s=>s.path===e))==null?void 0:t.text)}markSaved(){this.saved=Pe(this.project),this.savedFiles=new Map(this.project.files.map(e=>[e.path,e.text]))}async restoreWorkspace(){if(!$t())return;const e=await Ks(us);if(e!=null&&e.ready){const t=await _t(e.handle);if(t)return this.useWorkspace(t.root,!0)}this.pendingFolder=e==null?void 0:e.handle,this.renderWorkspace()}async useWorkspace(e,t=!1){var s;this.workspace=e,this.pendingFolder=void 0,J(rt,"0");try{this.projects=await is(e);const i=se(We),n=this.project;if(t&&i&&this.projects.includes(i)){const o={active:this.active,tabs:[...this.openTabs],positions:new Map(this.positions)};await this.loadProject(i),this.positions=o.positions,this.savePositions(),Pe(n)!==this.saved&&(this.project=n),this.openTabs=o.tabs.filter(r=>this.project.files.some(c=>c.path===r)),this.active=this.project.files.some(r=>r.path===o.active)?o.active:(s=this.project.files[0])==null?void 0:s.path,this.showActive(),this.refresh()}else!this.projects.some(o=>o.toLowerCase()===ge(n.name).toLowerCase())&&n.files.length?(this.folder=ge(n.name),await this.writeCurrent(!1)):this.projects.length?await this.loadProject(this.projects.includes(i??"")?i:this.projects[0]):(this.folder=ge(n.name),await this.writeCurrent(!1))}catch(i){this.message(d("web_visuobject_ws_failed",String((i==null?void 0:i.message)??i)))}this.renderWorkspace(),this.refresh()}async loadProject(e){var i;const{project:t,positions:s}=await yn(this.workspace,e);this.folder=e,this.project=t,this.markSaved(),this.message(""),this.history=[],this.future=[],this.lastTyping=0,this.selection=void 0,this.relSelection=void 0,this.treeSelection=void 0,this.currentPackage=void 0,this.positions=new Map(Object.entries(s)),this.savePositions(),this.openTabs=[],this.active=(i=t.files[0])==null?void 0:i.path,J(We,e),this.showActive(),this.refresh()}async writeCurrent(e=!0){const t=this.workspace;if(!t)return!1;const s=ge(this.project.name),i=this.folder,n=new Set(this.classes.map(r=>r.name)),o=Object.fromEntries([...this.positions].filter(([r])=>n.has(r)));if(s!==i&&this.projects.some(r=>r!==i&&r.toLowerCase()===s.toLowerCase()))return this.message(d("web_visuobject_ws_taken",this.project.name)),!1;try{return await _n(t,s,this.project,o),i&&i!==s&&this.projects.includes(i)&&await t.remove(i),this.folder=s,this.projects=await is(t),J(We,s),this.markSaved(),e&&this.message(d("web_visuobject_ws_saved",t.name,s),!0),this.refresh(),!0}catch(r){return this.message(d("web_visuobject_ws_failed",String((r==null?void 0:r.message)??r))),!1}}async switchProject(e){if(!(!this.workspace||e===this.folder)&&!(this.isDirty()&&!await this.writeCurrent(!1)))try{await this.loadProject(e)}catch(t){this.message(d("web_visuobject_ws_failed",String((t==null?void 0:t.message)??t)))}}async newProject(e,t,s=!1){var n,o;if(!this.workspace){this.setProject(e,t??((n=e.files[0])==null?void 0:n.path)),e.files.length===0&&!s&&this.editProjectName();return}if(this.isDirty()&&!await this.writeCurrent(!1))return;const i=ns(ge(e.name),this.projects);this.project={...e,name:i},this.folder=i,this.history=[],this.future=[],this.openTabs=[],this.positions.clear(),this.savePositions(),this.active=e.files.some(r=>r.path===t)?t:(o=e.files[0])==null?void 0:o.path,this.showActive(),this.refresh(),await this.writeCurrent(!1)&&(this.message(d("web_visuobject_ws_created",i),!0),e.files.length===0&&!s&&this.editProjectName())}get currentPlace(){const e=this.currentPackage??(this.active?D(this.active):ce(this.project)[0]??"");return{root:U(e),pkg:X(e)}}async newFromWizard(e){var u;const t=this.currentPlace,s=(f,m)=>{let g=f;for(let _=2;m(g);_++)g=f+_;return g},i=await on(e,{roots:ue(this.project),packagesIn:f=>ce(this.project,f).map(X),classes:this.classes,root:t.root,pkg:t.pkg,suggest:f=>f==="project"?ns(d("web_visuobject_project_name"),this.workspace?[...this.projects,this.folder??""]:[]):f==="folder"?s("test",m=>ue(this.project).includes(m)):f==="package"?s(d("web_visuobject_new_package_name"),m=>ce(this.project).includes(re(t.root,m))):this.uniqueClassName(d(f==="class"?"web_visuobject_new_class_name":"web_visuobject_new_interface_name")),check:(f,m,g,_)=>{if(!m)return d("web_visuobject_new_name_missing");if(f==="project")return this.workspace&&this.projects.some(y=>y!==this.folder&&y.toLowerCase()===ge(m).toLowerCase())?d("web_visuobject_ws_taken",m):void 0;if(f==="folder")return!Je(m)||ue(this.project).includes(m)?d("web_visuobject_bad_folder",m):void 0;if(f==="package")return!Mt(m)||ce(this.project).includes(re(g,m))?d("web_visuobject_bad_package",m):void 0;if(!pe.test(m))return d("web_visuobject_bad_name",m);if(this.findClass(m)||this.project.files.some(y=>y.path===le(re(g,_),`${m}.java`)))return d("web_visuobject_new_exists",m);if(m.charAt(0)!==m.charAt(0).toUpperCase())return d("web_visuobject_new_upper")}});if(!i)return;const{name:n,root:o,pkg:r}=i;if(e==="project")return this.newProject({name:n,files:[],packages:[]},void 0,!0);if(this.message(""),e==="folder")return this.currentPackage=re(n,""),this.treeSelection=`root:${n}`,this.open.set(`root:${n}`,!0),this.setProject(bi(this.project,n));if(e==="package"){const f=re(o,n);return this.currentPackage=f,this.treeSelection=`pkg:${f}`,this.open.set(`root:${o}`,!0),this.setProject(fi(this.project,f))}const c=re(o,r),l=le(c,`${n}.java`);this.currentPackage=c,this.selection={cls:n},this.open.set(`root:${o}`,!0),this.open.set(`pkg:${c}`,!0),this.setProject(et(this.project,l,this.sectioned(sn(i.options),n)),l);const h=this.findClass(n);h&&this.showInCode(h),(u=this.canvas.querySelector(`.uml-class[data-class="${CSS.escape(n)}"]`))==null||u.scrollIntoView({block:"nearest",inline:"nearest"})}editProjectName(){this.treeSelection="project",this.renderTree(),this.startEditing(this.tree.querySelector('[data-node="project"] > .vo-row .vo-label'))}renderWorkspace(){const e=this.wsBox;e.hidden=!$t();const t=this.shell.querySelector("[data-action=save]");if(t.dataset.tip=d(this.workspace?"web_visuobject_save_ws_tip":"web_visuobject_save_tip"),e.hidden)return;const s=(i,n,o="text-button",r)=>``;this.workspace?(e.className="vo-ws",e.innerHTML=`${b(this.workspace.name)} + `}).join("")}onTabClick(e){var i;const t=e.target,s=(i=t.closest("[data-tab]"))==null?void 0:i.dataset.tab;if(s){if(t.closest("[data-close]"))return this.closeTab(s);this.treeSelection=`file:${s}`,this.openFile(s)}}closeTab(e){const t=this.openTabs.indexOf(e);t<0||(this.openTabs.splice(t,1),e===this.active?(this.active=this.openTabs[Math.min(t,this.openTabs.length-1)],this.lastTyping=0,this.showActive(),this.refresh()):this.renderTabs())}snapshot(){return JSON.stringify({project:this.project,active:this.active})}remember(){this.history.push(this.snapshot()),this.history.length>kn&&this.history.shift(),this.future=[]}setProject(e,t=this.active){var s;this.remember(),this.lastTyping=0,this.project=e,this.active=e.files.some(i=>i.path===t)?t:(s=e.files[0])==null?void 0:s.path,this.showActive(),this.refresh()}openFile(e){if(e===this.active)return;this.active=e,this.lastTyping=0,this.showActive();const t=D(e);this.currentPackage=t,this.open.set(`pkg:${t}`,!0),this.refresh()}typed(){const e=this.activeFile;if(!e)return;const t=Date.now();t-this.lastTyping>1500&&this.remember(),this.lastTyping=t,this.project=$e(this.project,e.path,this.editor.text),this.saveBreakpoints(),this.dbg&&this.stopDebug("web_visuobject_dbg_code_changed"),this.refresh(),clearTimeout(this.renameTimer),this.renameTimer=window.setTimeout(()=>this.syncFileName(),700)}syncFileName(){var c;const e=this.activeFile;if(!e||this.editing)return;const t=Q(e.path).replace(/\.java$/i,""),s=this.classes.filter(l=>l.path===e.path);if(s.length===0||s.some(l=>l.name===t))return;const i=((c=/\bpublic\s+(?:abstract\s+|final\s+)*(?:class|interface|enum)\s+(\w+)/.exec(e.text))==null?void 0:c[1])??s[0].name;if(!pe.test(i)||s.filter(l=>l.name===i).length!==1)return;const n=le(D(e.path),`${i}.java`);if(this.project.files.some(l=>l.path===n))return;let o=Oe(this.project,e.path,n);const r=this.positions.get(t);r&&!this.positions.has(i)&&this.positions.set(i,r);for(const l of Object.keys(o.uml??{}))l.startsWith(`${t}.`)&&(o={...o,uml:ke(o.uml,l,i+l.slice(t.length))});this.openTabs=this.openTabs.map(l=>l===e.path?n:l),this.treeSelection===`file:${e.path}`&&(this.treeSelection=`file:${n}`),this.isOpen(`file:${e.path}`)&&this.open.set(`file:${n}`,!0),this.project=o,this.active=n,J(ot,n),this.savePositions(),this.refresh()}undo(e){const t=e?this.future:this.history,s=e?this.history:this.future,i=t.pop();if(i===void 0)return;s.push(this.snapshot());const n=JSON.parse(i);this.project=n.project,this.active=n.active,this.lastTyping=0,this.showActive(),this.refresh()}refresh(){J(os,Pe(this.project)),this.renderTabs(),this.classes=Ct(this.project),this.selection&&!this.findClass(this.selection.cls)&&(this.selection=void 0),this.relSelection&&!this.findRelation(this.relSelection)&&!this.findDependency(this.relSelection)&&(this.relSelection=void 0),this.editing||(this.render(),this.renderTree())}ownTypesAt(e){const t=this.activeFile;if(!t)return;const s=this.editor.view.state.doc.toString(),i=X(D(t.path)),n=oe(s).map(l=>({...l,pkg:i})),o=new Set(n.map(l=>l.name)),r=n.find(l=>l.headerFrom<=e&&e<=l.bodyEnd),c=ct()==="de"?"de":ct()==="pt-PT"?"pt":"en";return Ji([...n,...this.classes.filter(l=>l.path!==t.path&&!o.has(l.name))],{cls:r==null?void 0:r.name,pkg:i},c)}findClass(e){return this.classes.find(t=>t.name===e)}caretMoved(){var n,o;const e=this.editor.caret,t=this.classes.find(r=>r.path===this.active&&e>=r.from&&e<=r.to),s=t==null?void 0:t.members.findIndex(r=>e>=r.from&&e<=r.to),i=t?{cls:t.name,member:s!==void 0&&s>=0?s:void 0}:void 0;(i==null?void 0:i.cls)===((n=this.selection)==null?void 0:n.cls)&&(i==null?void 0:i.member)===((o=this.selection)==null?void 0:o.member)||(this.selection=i,this.editing||(this.render(),this.renderTree()))}showInCode(e,t){e.path!==this.active&&(this.active=e.path,this.lastTyping=0,this.showActive());const s=this.editor.view,[i,n]=t?[t.headerFrom,t.headerTo]:[e.nameFrom,e.nameTo],o=Math.min(n,s.state.doc.length);s.dispatch({selection:{anchor:Math.min(i,o),head:o},scrollIntoView:!0})}message(e,t=!1){this.status.textContent=e,this.status.classList.toggle("hint",t)}openFiles(){const e=document.createElement("input");e.type="file",e.multiple=!0,e.accept=".zip,.java,.visuobject,application/zip,text/plain",e.addEventListener("change",()=>void this.readFiles([...e.files??[]])),e.click()}async readFiles(e){var t;if(e.length!==0)try{const s=e.find(r=>/\.zip$/i.test(r.name));if(s){const{projectFromZip:r}=await wt(async()=>{const{projectFromZip:l}=await import("./projectZip-Dv_LmKlY.js");return{projectFromZip:l}},__vite__mapDeps([0,1,2]),import.meta.url),c=r(new Uint8Array(await s.arrayBuffer()),s.name.replace(/\.zip$/i,""));await this.newProject(c);return}const i=e.find(r=>/\.visuobject$/i.test(r.name));if(i){const r=qt(await i.text());if(!r)throw new Error("format");await this.newProject(r);return}const n=At(this.project.name,await Promise.all(e.map(async r=>({name:r.name,text:await r.text()}))));let o=this.project;for(const r of n.files)o=et(o,r.path,r.text);this.setProject(o,(t=n.files[0])==null?void 0:t.path)}catch{this.message(d("web_visuobject_open_failed"))}}async save(){this.workspace?await this.writeCurrent():await this.downloadZip()}async downloadZip(){const{projectToZip:e}=await wt(async()=>{const{projectToZip:s}=await import("./projectZip-Dv_LmKlY.js");return{projectToZip:s}},__vite__mapDeps([0,1,2]),import.meta.url),t=e(this.project);Sn(`${this.project.name||"Projekt"}.zip`,t.slice().buffer,"application/zip")}isDirty(e){var t;return!this.workspace||this.saved===void 0?!1:e===void 0?this.saved!==Pe(this.project):this.savedFiles.get(e)!==((t=this.project.files.find(s=>s.path===e))==null?void 0:t.text)}markSaved(){this.saved=Pe(this.project),this.savedFiles=new Map(this.project.files.map(e=>[e.path,e.text]))}async restoreWorkspace(){if(!$t())return;const e=await Ks(us);if(e!=null&&e.ready){const t=await _t(e.handle);if(t)return this.useWorkspace(t.root,!0)}this.pendingFolder=e==null?void 0:e.handle,this.renderWorkspace()}async useWorkspace(e,t=!1){var s;this.workspace=e,this.pendingFolder=void 0,J(rt,"0");try{this.projects=await is(e);const i=se(We),n=this.project;if(t&&i&&this.projects.includes(i)){const o={active:this.active,tabs:[...this.openTabs],positions:new Map(this.positions)};await this.loadProject(i),this.positions=o.positions,this.savePositions(),Pe(n)!==this.saved&&(this.project=n),this.openTabs=o.tabs.filter(r=>this.project.files.some(c=>c.path===r)),this.active=this.project.files.some(r=>r.path===o.active)?o.active:(s=this.project.files[0])==null?void 0:s.path,this.showActive(),this.refresh()}else!this.projects.some(o=>o.toLowerCase()===ge(n.name).toLowerCase())&&n.files.length?(this.folder=ge(n.name),await this.writeCurrent(!1)):this.projects.length?await this.loadProject(this.projects.includes(i??"")?i:this.projects[0]):(this.folder=ge(n.name),await this.writeCurrent(!1))}catch(i){this.message(d("web_visuobject_ws_failed",String((i==null?void 0:i.message)??i)))}this.renderWorkspace(),this.refresh()}async loadProject(e){var i;const{project:t,positions:s}=await yn(this.workspace,e);this.folder=e,this.project=t,this.markSaved(),this.message(""),this.history=[],this.future=[],this.lastTyping=0,this.selection=void 0,this.relSelection=void 0,this.treeSelection=void 0,this.currentPackage=void 0,this.positions=new Map(Object.entries(s)),this.savePositions(),this.openTabs=[],this.active=(i=t.files[0])==null?void 0:i.path,J(We,e),this.showActive(),this.refresh()}async writeCurrent(e=!0){const t=this.workspace;if(!t)return!1;const s=ge(this.project.name),i=this.folder,n=new Set(this.classes.map(r=>r.name)),o=Object.fromEntries([...this.positions].filter(([r])=>n.has(r)));if(s!==i&&this.projects.some(r=>r!==i&&r.toLowerCase()===s.toLowerCase()))return this.message(d("web_visuobject_ws_taken",this.project.name)),!1;try{return await _n(t,s,this.project,o),i&&i!==s&&this.projects.includes(i)&&await t.remove(i),this.folder=s,this.projects=await is(t),J(We,s),this.markSaved(),e&&this.message(d("web_visuobject_ws_saved",t.name,s),!0),this.refresh(),!0}catch(r){return this.message(d("web_visuobject_ws_failed",String((r==null?void 0:r.message)??r))),!1}}async switchProject(e){if(!(!this.workspace||e===this.folder)&&!(this.isDirty()&&!await this.writeCurrent(!1)))try{await this.loadProject(e)}catch(t){this.message(d("web_visuobject_ws_failed",String((t==null?void 0:t.message)??t)))}}async newProject(e,t,s=!1){var n,o;if(!this.workspace){this.setProject(e,t??((n=e.files[0])==null?void 0:n.path)),e.files.length===0&&!s&&this.editProjectName();return}if(this.isDirty()&&!await this.writeCurrent(!1))return;const i=ns(ge(e.name),this.projects);this.project={...e,name:i},this.folder=i,this.history=[],this.future=[],this.openTabs=[],this.positions.clear(),this.savePositions(),this.active=e.files.some(r=>r.path===t)?t:(o=e.files[0])==null?void 0:o.path,this.showActive(),this.refresh(),await this.writeCurrent(!1)&&(this.message(d("web_visuobject_ws_created",i),!0),e.files.length===0&&!s&&this.editProjectName())}get currentPlace(){const e=this.currentPackage??(this.active?D(this.active):ce(this.project)[0]??"");return{root:U(e),pkg:X(e)}}async newFromWizard(e){var u;const t=this.currentPlace,s=(f,m)=>{let g=f;for(let _=2;m(g);_++)g=f+_;return g},i=await on(e,{roots:ue(this.project),packagesIn:f=>ce(this.project,f).map(X),classes:this.classes,root:t.root,pkg:t.pkg,suggest:f=>f==="project"?ns(d("web_visuobject_project_name"),this.workspace?[...this.projects,this.folder??""]:[]):f==="folder"?s("test",m=>ue(this.project).includes(m)):f==="package"?s(d("web_visuobject_new_package_name"),m=>ce(this.project).includes(re(t.root,m))):this.uniqueClassName(d(f==="class"?"web_visuobject_new_class_name":"web_visuobject_new_interface_name")),check:(f,m,g,_)=>{if(!m)return d("web_visuobject_new_name_missing");if(f==="project")return this.workspace&&this.projects.some(y=>y!==this.folder&&y.toLowerCase()===ge(m).toLowerCase())?d("web_visuobject_ws_taken",m):void 0;if(f==="folder")return!Je(m)||ue(this.project).includes(m)?d("web_visuobject_bad_folder",m):void 0;if(f==="package")return!Mt(m)||ce(this.project).includes(re(g,m))?d("web_visuobject_bad_package",m):void 0;if(!pe.test(m))return d("web_visuobject_bad_name",m);if(this.findClass(m)||this.project.files.some(y=>y.path===le(re(g,_),`${m}.java`)))return d("web_visuobject_new_exists",m);if(m.charAt(0)!==m.charAt(0).toUpperCase())return d("web_visuobject_new_upper")}});if(!i)return;const{name:n,root:o,pkg:r}=i;if(e==="project")return this.newProject({name:n,files:[],packages:[]},void 0,!0);if(this.message(""),e==="folder")return this.currentPackage=re(n,""),this.treeSelection=`root:${n}`,this.open.set(`root:${n}`,!0),this.setProject(bi(this.project,n));if(e==="package"){const f=re(o,n);return this.currentPackage=f,this.treeSelection=`pkg:${f}`,this.open.set(`root:${o}`,!0),this.setProject(fi(this.project,f))}const c=re(o,r),l=le(c,`${n}.java`);this.currentPackage=c,this.selection={cls:n},this.open.set(`root:${o}`,!0),this.open.set(`pkg:${c}`,!0),this.setProject(et(this.project,l,this.sectioned(sn(i.options),n)),l);const h=this.findClass(n);h&&this.showInCode(h),(u=this.canvas.querySelector(`.uml-class[data-class="${CSS.escape(n)}"]`))==null||u.scrollIntoView({block:"nearest",inline:"nearest"})}editProjectName(){this.treeSelection="project",this.renderTree(),this.startEditing(this.tree.querySelector('[data-node="project"] > .vo-row .vo-label'))}renderWorkspace(){const e=this.wsBox;e.hidden=!$t();const t=this.shell.querySelector("[data-action=save]");if(t.dataset.tip=d(this.workspace?"web_visuobject_save_ws_tip":"web_visuobject_save_tip"),e.hidden)return;const s=(i,n,o="text-button",r)=>``;this.workspace?(e.className="vo-ws",e.innerHTML=`${b(this.workspace.name)} ${s("zip",d("web_visuobject_ws_zip"),"text-button",d("web_visuobject_ws_zip_tip"))} ${s("switch",d("web_visuobject_ws_switch"),"text-button")}`):this.pendingFolder?(e.className="vo-ws",e.innerHTML=`${s("reopen",d("web_visuobject_ws_reopen",this.pendingFolder.name),"text-button primary")}${s("switch",d("web_visuobject_ws_switch"),"text-button")}`):se(rt)==="1"?(e.className="vo-ws",e.innerHTML=s("open",d("web_visuobject_ws_choose"),"text-button",d("web_visuobject_ws_hint"))):(e.className="vo-ws ask",e.innerHTML=`

    ${b(d("web_visuobject_ws_question"))}

    ${b(d("web_visuobject_ws_hint"))}

    diff --git a/website/app/assets/pl-C3HmQqUD.js b/website/app/assets/pl-DchXCt_R.js similarity index 99% rename from website/app/assets/pl-C3HmQqUD.js rename to website/app/assets/pl-DchXCt_R.js index d2d604d6..b362f27c 100644 --- a/website/app/assets/pl-C3HmQqUD.js +++ b/website/app/assets/pl-DchXCt_R.js @@ -135,6 +135,7 @@ const e=`/* Teksty dostępne tylko w wersji webowej. Wszystko inne pochodzi z pl "web_files_saved_fmt" = "Zapisano: %@"; "web_files_create" = "Utwórz"; "web_learn_ludwig_tip" = "Wskazówka Ludwiga"; +"web_learn_pro" = "Wiedza dla profesjonalistów z Ludwigiem"; "web_game_title" = "Gra: Prawda czy fałsz?"; "web_game_intro" = "Ludwig pokazuje wartości i warunek. Czy warunek jest prawdziwy (true), czy fałszywy (false)? Dziesięć rund, coraz trudniejszych."; "web_game_start" = "Zacznij grę"; diff --git a/website/app/assets/projectZip-DEvwTDaN.js b/website/app/assets/projectZip-Dv_LmKlY.js similarity index 99% rename from website/app/assets/projectZip-DEvwTDaN.js rename to website/app/assets/projectZip-Dv_LmKlY.js index d2ed2425..598e25bd 100644 --- a/website/app/assets/projectZip-DEvwTDaN.js +++ b/website/app/assets/projectZip-Dv_LmKlY.js @@ -1 +1 @@ -import{p as Br,d as Er,a as mr,i as Gr,b as Qr,c as Vr,u as Lr,n as _r,o as pr,e as br,r as dr,f as re,s as ee}from"./objectApp-ZNEjA-0f.js";import"./index-BVzzpk4y.js";var M=Uint8Array,K=Uint16Array,Tr=Int32Array,hr=new M([0,0,0,0,0,0,0,0,1,1,1,1,2,2,2,2,3,3,3,3,4,4,4,4,5,5,5,5,0,0,0,0]),gr=new M([0,0,0,0,1,1,2,2,3,3,4,4,5,5,6,6,7,7,8,8,9,9,10,10,11,11,12,12,13,13,0,0]),Sr=new M([16,17,18,0,8,7,9,6,10,5,11,4,12,3,13,2,14,1,15]),Wr=function(r,e){for(var n=new K(31),a=0;a<31;++a)n[a]=e+=1<>1|(F&21845)<<1;b=(b&52428)>>2|(b&13107)<<2,b=(b&61680)>>4|(b&3855)<<4,Cr[F]=((b&65280)>>8|(b&255)<<8)>>1}var V=(function(r,e,n){for(var a=r.length,f=0,v=new K(e);f>l]=c}else for(s=new K(a),f=0;f>15-r[f]);return s}),d=new M(288);for(var F=0;F<144;++F)d[F]=8;for(var F=144;F<256;++F)d[F]=9;for(var F=256;F<280;++F)d[F]=7;for(var F=280;F<288;++F)d[F]=8;var ir=new M(32);for(var F=0;F<32;++F)ir[F]=5;var ae=V(d,9,0),fe=V(d,9,1),ve=V(ir,5,0),te=V(ir,5,1),xr=function(r){for(var e=r[0],n=1;ne&&(e=r[n]);return e},X=function(r,e,n){var a=e/8|0;return(r[a]|r[a+1]<<8)>>(e&7)&n},yr=function(r,e){var n=e/8|0;return(r[n]|r[n+1]<<8|r[n+2]<<16)>>(e&7)},Ur=function(r){return(r+7)/8|0},lr=function(r,e,n){return(e==null||e<0)&&(e=0),(n==null||n>r.length)&&(n=r.length),new M(r.subarray(e,n))},oe=["unexpected EOF","invalid block type","invalid length/literal","invalid distance","stream finished","no stream handler",,"no callback","invalid UTF-8 data","extra field too long","date not in range 1980-2099","filename too long","stream finishing","invalid zip data"],I=function(r,e,n){var a=new Error(e||oe[r]);if(a.code=r,Error.captureStackTrace&&Error.captureStackTrace(a,I),!n)throw a;return a},ie=function(r,e,n,a){var f=r.length,v=a?a.length:0;if(!f||e.f&&!e.l)return n||new M(0);var i=!n,s=i||e.i!=2,l=e.i;i&&(n=new M(f*3));var c=function(fr){var vr=n.length;if(fr>vr){var nr=new M(Math.max(vr*2,fr));nr.set(n),n=nr}},t=e.f||0,o=e.p||0,u=e.b||0,h=e.l,y=e.d,w=e.m,x=e.n,T=f*8;do{if(!h){t=X(r,o,1);var z=X(r,o+1,3);if(o+=3,z)if(z==1)h=fe,y=te,w=9,x=5;else if(z==2){var U=X(r,o,31)+257,A=X(r,o+10,15)+4,m=U+X(r,o+5,31)+1;o+=14;for(var g=new M(m),B=new M(19),j=0;j>4;if(C<16)g[j++]=C;else{var E=0,k=0;for(C==16?(k=3+X(r,o,3),o+=2,E=g[j-1]):C==17?(k=3+X(r,o,7),o+=3):C==18&&(k=11+X(r,o,127),o+=7);k--;)g[j++]=E}}var W=g.subarray(0,U),J=g.subarray(U);w=xr(W),x=xr(J),h=V(W,w,1),y=V(J,x,1)}else I(1);else{var C=Ur(o)+4,O=r[C-4]|r[C-3]<<8,$=C+O;if($>f){l&&I(0);break}s&&c(u+O),n.set(r.subarray(C,$),u),e.b=u+=O,e.p=o=$*8,e.f=t;continue}if(o>T){l&&I(0);break}}s&&c(u+131072);for(var ar=(1<>4;if(o+=E&15,o>T){l&&I(0);break}if(E||I(2),q<256)n[u++]=q;else if(q==256){L=o,h=null;break}else{var H=q-254;if(q>264){var j=q-257,S=hr[j];H=X(r,o,(1<>4;G||I(3),o+=G&15;var J=ne[rr];if(rr>3){var S=gr[rr];J+=yr(r,o)&(1<T){l&&I(0);break}s&&c(u+131072);var er=u+H;if(u>8},tr=function(r,e,n){n<<=e&7;var a=e/8|0;r[a]|=n,r[a+1]|=n>>8,r[a+2]|=n>>16},Fr=function(r,e){for(var n=[],a=0;au&&(u=v[a].s);var h=new K(u+1),y=Or(n[t-1],h,0);if(y>e){var a=0,w=0,x=y-e,T=1<e)w+=T-(1<>=x;w>0;){var C=v[a].s;h[C]=0&&w;--a){var O=v[a].s;h[O]==e&&(--h[O],++w)}y=e}return{t:new M(h),l:y}},Or=function(r,e,n){return r.s==-1?Math.max(Or(r.l,e,n+1),Or(r.r,e,n+1)):e[r.s]=n},Nr=function(r){for(var e=r.length;e&&!r[--e];);for(var n=new K(++e),a=0,f=r[0],v=1,i=function(l){n[a++]=l},s=1;s<=e;++s)if(r[s]==f&&s!=e)++v;else{if(!f&&v>2){for(;v>138;v-=138)i(32754);v>2&&(i(v>10?v-11<<5|28690:v-3<<5|12305),v=0)}else if(v>3){for(i(f),--v;v>6;v-=6)i(8304);v>2&&(i(v-3<<5|8208),v=0)}for(;v--;)i(f);v=1,f=r[s]}return{c:n.subarray(0,a),n:e}},or=function(r,e){for(var n=0,a=0;a>8,r[f+2]=r[f]^255,r[f+3]=r[f+1]^255;for(var v=0;v4&&!B[Sr[D-1]];--D);var p=c+5<<3,Z=or(f,d)+or(v,ir)+i,P=or(f,u)+or(v,w)+i+14+3*D+or(A,B)+2*A[16]+3*A[17]+7*A[18];if(l>=0&&p<=Z&&p<=P)return Kr(e,t,r.subarray(l,l+c));var E,k,W,J;if(_(e,t,1+(P15&&(_(e,t,q[m]>>5&127),t+=q[m]>>12)}}else E=ae,k=d,W=ve,J=ir;for(var m=0;m255){var H=S>>18&31;tr(e,t,E[H+257]),t+=k[H+257],H>7&&(_(e,t,S>>23&31),t+=hr[H]);var G=S&31;tr(e,t,W[G]),t+=J[G],G>3&&(tr(e,t,S>>5&8191),t+=gr[G])}else tr(e,t,E[S]),t+=k[S]}return tr(e,t,E[256]),t+k[256]},le=new Tr([65540,131080,131088,131104,262176,1048704,1048832,2114560,2117632]),Rr=new M(0),se=function(r,e,n,a,f,v){var i=v.z||r.length,s=new M(a+i+5*(1+Math.ceil(i/7e3))+f),l=s.subarray(a,s.length-f),c=v.l,t=(v.r||0)&7;if(e){t&&(l[0]=v.r>>3);for(var o=le[e-1],u=o>>13,h=o&8191,y=(1<7e3||B>24576)&&(E>423||!c)){t=Dr(r,l,0,O,$,U,m,B,D,g-D,t),B=A=m=0,D=g;for(var k=0;k<286;++k)$[k]=0;for(var k=0;k<30;++k)U[k]=0}var W=2,J=0,ar=h,R=Z-P&32767;if(E>2&&p==C(g-R))for(var L=Math.min(u,E)-1,q=Math.min(32767,g),H=Math.min(258,E);R<=q&&--ar&&Z!=P;){if(r[g+W]==r[g+W-R]){for(var S=0;SW){if(W=S,J=R,S>L)break;for(var G=Math.min(R,S-2),rr=0,k=0;krr&&(rr=ur,P=er)}}}Z=P,P=w[Z],R+=Z-P&32767}if(J){O[B++]=268435456|Mr[W]<<18|Jr[J];var fr=Mr[W]&31,vr=Jr[J]&31;m+=hr[fr]+gr[vr],++$[257+fr],++U[vr],j=g+W,++A}else O[B++]=r[g],++$[r[g]]}}for(g=Math.max(g,j);g=i&&(l[t/8|0]=c,nr=i),t=Kr(l,t+1,r.subarray(g,nr))}v.i=i}return lr(s,0,a+Ur(t)+f)},ue=(function(){for(var r=new Int32Array(256),e=0;e<256;++e){for(var n=e,a=9;--a;)n=(n&1&&-306674912)^n>>>1;r[e]=n}return r})(),ce=function(){var r=-1;return{p:function(e){for(var n=r,a=0;a>>8;r=n},d:function(){return~r}}},he=function(r,e,n,a,f){if(!f&&(f={l:1},e.dictionary)){var v=e.dictionary.subarray(-32768),i=new M(v.length+r.length);i.set(v),i.set(r,v.length),r=i,f.w=v.length}return se(r,e.level==null?6:e.level,e.mem==null?f.l?Math.ceil(Math.max(8,Math.min(13,Math.log(r.length)))*1.5):20:12+e.mem,n,a,f)},Xr=function(r,e){var n={};for(var a in r)n[a]=r[a];for(var a in e)n[a]=e[a];return n},Q=function(r,e){return r[e]|r[e+1]<<8},Y=function(r,e){return(r[e]|r[e+1]<<8|r[e+2]<<16|r[e+3]<<24)>>>0},kr=function(r,e){return Y(r,e)+Y(r,e+4)*4294967296},N=function(r,e,n){for(;n;++e)r[e]=n,n>>>=8};function ge(r,e){return he(r,e||{},0,0)}function we(r,e){return ie(r,{i:2},e&&e.out,e&&e.dictionary)}var Yr=function(r,e,n,a){for(var f in r){var v=r[f],i=e+f,s=a;Array.isArray(v)&&(s=Xr(a,v[1]),v=v[0]),v instanceof M?n[i]=[v,s]:(n[i+="/"]=[new M(0),s],Yr(v,i,n,a))}},Ir=typeof TextEncoder<"u"&&new TextEncoder,Ar=typeof TextDecoder<"u"&&new TextDecoder,me=0;try{Ar.decode(Rr,{stream:!0}),me=1}catch{}var xe=function(r){for(var e="",n=0;;){var a=r[n++],f=(a>127)+(a>223)+(a>239);if(n+f>r.length)return{s:e,r:lr(r,n-1)};f?f==3?(a=((a&15)<<18|(r[n++]&63)<<12|(r[n++]&63)<<6|r[n++]&63)-65536,e+=String.fromCharCode(55296|a>>10,56320|a&1023)):f&1?e+=String.fromCharCode((a&31)<<6|r[n++]&63):e+=String.fromCharCode((a&15)<<12|(r[n++]&63)<<6|r[n++]&63):e+=String.fromCharCode(a)}};function cr(r,e){var n;if(Ir)return Ir.encode(r);for(var a=r.length,f=new M(r.length+(r.length>>1)),v=0,i=function(c){f[v++]=c},n=0;nf.length){var s=new M(v+8+(a-n<<1));s.set(f),f=s}var l=r.charCodeAt(n);l<128||e?i(l):l<2048?(i(192|l>>6),i(128|l&63)):l>55295&&l<57344?(l=65536+(l&1047552)|r.charCodeAt(++n)&1023,i(240|l>>18),i(128|l>>12&63),i(128|l>>6&63),i(128|l&63)):(i(224|l>>12),i(128|l>>6&63),i(128|l&63))}return lr(f,0,v)}function jr(r,e){if(e){for(var n="",a=0;a65535&&I(9),e+=a+4}return e},Pr=function(r,e,n,a,f,v,i,s){var l=a.length,c=n.extra,t=s&&s.length,o=zr(c);N(r,e,i!=null?33639248:67324752),e+=4,i!=null&&(r[e++]=20,r[e++]=n.os),r[e]=20,e+=2,r[e++]=n.flag<<1|(v<0&&8),r[e++]=f&&8,r[e++]=n.compression&255,r[e++]=n.compression>>8;var u=new Date(n.mtime==null?Date.now():n.mtime),h=u.getFullYear()-1980;if((h<0||h>119)&&I(10),N(r,e,h<<25|u.getMonth()+1<<21|u.getDate()<<16|u.getHours()<<11|u.getMinutes()<<5|u.getSeconds()>>1),e+=4,v!=-1&&(N(r,e,n.crc),N(r,e+4,v<0?-v-2:v),N(r,e+8,n.size)),N(r,e+12,l),N(r,e+14,o),e+=16,i!=null&&(N(r,e,t),N(r,e+6,n.attrs),N(r,e+10,i),e+=14),r.set(a,e),e+=l,o)for(var y in c){var w=c[y],x=w.length;N(r,e,+y),N(r,e+2,x),r.set(w,e+4),e+=4+x}return t&&(r.set(s,e),e+=t),e},Se=function(r,e,n,a,f){N(r,e,101010256),N(r,e+8,n),N(r,e+10,n),N(r,e+12,a),N(r,e+16,f)};function Me(r,e){e||(e={});var n={},a=[];Yr(r,"",n,e);var f=0,v=0;for(var i in n){var s=n[i],l=s[0],c=s[1],t=c.level==0?0:8,o=cr(i),u=o.length,h=c.comment,y=h&&cr(h),w=y&&y.length,x=zr(c.extra);u>65535&&I(11);var T=t?ge(l,c):l,z=T.length,C=ce();C.p(l),a.push(Xr(c,{size:l.length,crc:C.d(),c:T,f:o,m:y,u:u!=i.length||y&&h.length!=w,o:f,compression:t})),f+=30+u+x+z,v+=76+2*(u+x)+(w||0)+z}for(var O=new M(v+22),$=f,U=v-f,A=0;A65558)&&I(13);var f=Q(r,a+8);if(!f)return{};var v=Y(r,a+16),i=v==4294967295||f==65535;if(i){var s=Y(r,a-12);i=Y(r,s)==101075792,i&&(f=Y(r,s+32),v=Y(r,s+48))}for(var l=0;l|]/g,"_")||"Projekt",n={};for(const l of r.files)n[`${e}/${br(l.path)}`]=new Uint8Array(cr(l.text));const a=[...r.packages.map(l=>`${e}/${dr(l)}/${re(l).replace(/\./g,"/")}/`),...ee(r).map(l=>`${e}/${l}/`)];for(const l of a)Object.keys(n).some(c=>c.startsWith(l))||(n[l.replace(/\/\/$/,"/")]=new Uint8Array);return(r.uml&&Object.keys(r.uml).length||(f=r.notes)!=null&&f.length||(v=r.objects)!=null&&v.length)&&(n[`${e}/${$r}`]=new Uint8Array(cr(JSON.stringify({format:"visuobject",version:1,uml:r.uml??{},...(i=r.notes)!=null&&i.length?{notes:r.notes}:{},...(s=r.objects)!=null&&s.length?{objects:r.objects}:{}},null,2)))),Me(n,{level:6})}function ze(r,e){var c;const n=Ce(r),a=Object.entries(n).filter(([t])=>/\.java$/i.test(t)&&!t.startsWith("__MACOSX/")).map(([t,o])=>({name:t,text:jr(o)})),f=new Set(Object.keys(n).map(t=>t.split("/")[0])),v=f.size===1&&Object.keys(n).some(t=>t.includes("/"))?[...f][0]:e,i=v!==e,s=Br(v,[]);for(const t of a){const o=Br(v,[{name:t.name.slice(t.name.lastIndexOf("/")+1),text:t.text}]).files[0],u=t.name.split("/").slice(i?1:0,-1),h=Er(o.text).split(".").filter(Boolean),w=u.slice(u.length-h.length).join("/")===h.join("/")?u.slice(0,u.length-h.length).join("/"):"",x=w&&w!==mr&&w.split("/").every(Gr)&&!w.includes(":")?w:mr,T=Qr(Vr(x,Er(o.text)),o.path.slice(o.path.lastIndexOf("/")+1));s.files=[...s.files.filter(z=>z.path!==T),{...o,path:T}],x!==mr&&!((c=s.sourceFolders)!=null&&c.includes(x))&&(s.sourceFolders=[...s.sourceFolders??[],x])}const l=Object.entries(n).find(([t])=>t===$r||t.endsWith(`/${$r}`));if(l)try{const t=JSON.parse(jr(l[1])),o=Lr(t.uml);o&&(s.uml=o);const u=_r(t.notes);u&&(s.notes=u);const h=pr(t.objects);h&&(s.objects=h)}catch{}return s}export{ze as projectFromZip,je as projectToZip}; +import{p as Br,d as Er,a as mr,i as Gr,b as Qr,c as Vr,u as Lr,n as _r,o as pr,e as br,r as dr,f as re,s as ee}from"./objectApp-exr4obxz.js";import"./index-DqKA7YqL.js";var M=Uint8Array,K=Uint16Array,Tr=Int32Array,hr=new M([0,0,0,0,0,0,0,0,1,1,1,1,2,2,2,2,3,3,3,3,4,4,4,4,5,5,5,5,0,0,0,0]),gr=new M([0,0,0,0,1,1,2,2,3,3,4,4,5,5,6,6,7,7,8,8,9,9,10,10,11,11,12,12,13,13,0,0]),Sr=new M([16,17,18,0,8,7,9,6,10,5,11,4,12,3,13,2,14,1,15]),Wr=function(r,e){for(var n=new K(31),a=0;a<31;++a)n[a]=e+=1<>1|(F&21845)<<1;b=(b&52428)>>2|(b&13107)<<2,b=(b&61680)>>4|(b&3855)<<4,Cr[F]=((b&65280)>>8|(b&255)<<8)>>1}var V=(function(r,e,n){for(var a=r.length,f=0,v=new K(e);f>l]=c}else for(s=new K(a),f=0;f>15-r[f]);return s}),d=new M(288);for(var F=0;F<144;++F)d[F]=8;for(var F=144;F<256;++F)d[F]=9;for(var F=256;F<280;++F)d[F]=7;for(var F=280;F<288;++F)d[F]=8;var ir=new M(32);for(var F=0;F<32;++F)ir[F]=5;var ae=V(d,9,0),fe=V(d,9,1),ve=V(ir,5,0),te=V(ir,5,1),xr=function(r){for(var e=r[0],n=1;ne&&(e=r[n]);return e},X=function(r,e,n){var a=e/8|0;return(r[a]|r[a+1]<<8)>>(e&7)&n},yr=function(r,e){var n=e/8|0;return(r[n]|r[n+1]<<8|r[n+2]<<16)>>(e&7)},Ur=function(r){return(r+7)/8|0},lr=function(r,e,n){return(e==null||e<0)&&(e=0),(n==null||n>r.length)&&(n=r.length),new M(r.subarray(e,n))},oe=["unexpected EOF","invalid block type","invalid length/literal","invalid distance","stream finished","no stream handler",,"no callback","invalid UTF-8 data","extra field too long","date not in range 1980-2099","filename too long","stream finishing","invalid zip data"],I=function(r,e,n){var a=new Error(e||oe[r]);if(a.code=r,Error.captureStackTrace&&Error.captureStackTrace(a,I),!n)throw a;return a},ie=function(r,e,n,a){var f=r.length,v=a?a.length:0;if(!f||e.f&&!e.l)return n||new M(0);var i=!n,s=i||e.i!=2,l=e.i;i&&(n=new M(f*3));var c=function(fr){var vr=n.length;if(fr>vr){var nr=new M(Math.max(vr*2,fr));nr.set(n),n=nr}},t=e.f||0,o=e.p||0,u=e.b||0,h=e.l,y=e.d,w=e.m,x=e.n,T=f*8;do{if(!h){t=X(r,o,1);var z=X(r,o+1,3);if(o+=3,z)if(z==1)h=fe,y=te,w=9,x=5;else if(z==2){var U=X(r,o,31)+257,A=X(r,o+10,15)+4,m=U+X(r,o+5,31)+1;o+=14;for(var g=new M(m),B=new M(19),j=0;j>4;if(C<16)g[j++]=C;else{var E=0,k=0;for(C==16?(k=3+X(r,o,3),o+=2,E=g[j-1]):C==17?(k=3+X(r,o,7),o+=3):C==18&&(k=11+X(r,o,127),o+=7);k--;)g[j++]=E}}var W=g.subarray(0,U),J=g.subarray(U);w=xr(W),x=xr(J),h=V(W,w,1),y=V(J,x,1)}else I(1);else{var C=Ur(o)+4,O=r[C-4]|r[C-3]<<8,$=C+O;if($>f){l&&I(0);break}s&&c(u+O),n.set(r.subarray(C,$),u),e.b=u+=O,e.p=o=$*8,e.f=t;continue}if(o>T){l&&I(0);break}}s&&c(u+131072);for(var ar=(1<>4;if(o+=E&15,o>T){l&&I(0);break}if(E||I(2),q<256)n[u++]=q;else if(q==256){L=o,h=null;break}else{var H=q-254;if(q>264){var j=q-257,S=hr[j];H=X(r,o,(1<>4;G||I(3),o+=G&15;var J=ne[rr];if(rr>3){var S=gr[rr];J+=yr(r,o)&(1<T){l&&I(0);break}s&&c(u+131072);var er=u+H;if(u>8},tr=function(r,e,n){n<<=e&7;var a=e/8|0;r[a]|=n,r[a+1]|=n>>8,r[a+2]|=n>>16},Fr=function(r,e){for(var n=[],a=0;au&&(u=v[a].s);var h=new K(u+1),y=Or(n[t-1],h,0);if(y>e){var a=0,w=0,x=y-e,T=1<e)w+=T-(1<>=x;w>0;){var C=v[a].s;h[C]=0&&w;--a){var O=v[a].s;h[O]==e&&(--h[O],++w)}y=e}return{t:new M(h),l:y}},Or=function(r,e,n){return r.s==-1?Math.max(Or(r.l,e,n+1),Or(r.r,e,n+1)):e[r.s]=n},Nr=function(r){for(var e=r.length;e&&!r[--e];);for(var n=new K(++e),a=0,f=r[0],v=1,i=function(l){n[a++]=l},s=1;s<=e;++s)if(r[s]==f&&s!=e)++v;else{if(!f&&v>2){for(;v>138;v-=138)i(32754);v>2&&(i(v>10?v-11<<5|28690:v-3<<5|12305),v=0)}else if(v>3){for(i(f),--v;v>6;v-=6)i(8304);v>2&&(i(v-3<<5|8208),v=0)}for(;v--;)i(f);v=1,f=r[s]}return{c:n.subarray(0,a),n:e}},or=function(r,e){for(var n=0,a=0;a>8,r[f+2]=r[f]^255,r[f+3]=r[f+1]^255;for(var v=0;v4&&!B[Sr[D-1]];--D);var p=c+5<<3,Z=or(f,d)+or(v,ir)+i,P=or(f,u)+or(v,w)+i+14+3*D+or(A,B)+2*A[16]+3*A[17]+7*A[18];if(l>=0&&p<=Z&&p<=P)return Kr(e,t,r.subarray(l,l+c));var E,k,W,J;if(_(e,t,1+(P15&&(_(e,t,q[m]>>5&127),t+=q[m]>>12)}}else E=ae,k=d,W=ve,J=ir;for(var m=0;m255){var H=S>>18&31;tr(e,t,E[H+257]),t+=k[H+257],H>7&&(_(e,t,S>>23&31),t+=hr[H]);var G=S&31;tr(e,t,W[G]),t+=J[G],G>3&&(tr(e,t,S>>5&8191),t+=gr[G])}else tr(e,t,E[S]),t+=k[S]}return tr(e,t,E[256]),t+k[256]},le=new Tr([65540,131080,131088,131104,262176,1048704,1048832,2114560,2117632]),Rr=new M(0),se=function(r,e,n,a,f,v){var i=v.z||r.length,s=new M(a+i+5*(1+Math.ceil(i/7e3))+f),l=s.subarray(a,s.length-f),c=v.l,t=(v.r||0)&7;if(e){t&&(l[0]=v.r>>3);for(var o=le[e-1],u=o>>13,h=o&8191,y=(1<7e3||B>24576)&&(E>423||!c)){t=Dr(r,l,0,O,$,U,m,B,D,g-D,t),B=A=m=0,D=g;for(var k=0;k<286;++k)$[k]=0;for(var k=0;k<30;++k)U[k]=0}var W=2,J=0,ar=h,R=Z-P&32767;if(E>2&&p==C(g-R))for(var L=Math.min(u,E)-1,q=Math.min(32767,g),H=Math.min(258,E);R<=q&&--ar&&Z!=P;){if(r[g+W]==r[g+W-R]){for(var S=0;SW){if(W=S,J=R,S>L)break;for(var G=Math.min(R,S-2),rr=0,k=0;krr&&(rr=ur,P=er)}}}Z=P,P=w[Z],R+=Z-P&32767}if(J){O[B++]=268435456|Mr[W]<<18|Jr[J];var fr=Mr[W]&31,vr=Jr[J]&31;m+=hr[fr]+gr[vr],++$[257+fr],++U[vr],j=g+W,++A}else O[B++]=r[g],++$[r[g]]}}for(g=Math.max(g,j);g=i&&(l[t/8|0]=c,nr=i),t=Kr(l,t+1,r.subarray(g,nr))}v.i=i}return lr(s,0,a+Ur(t)+f)},ue=(function(){for(var r=new Int32Array(256),e=0;e<256;++e){for(var n=e,a=9;--a;)n=(n&1&&-306674912)^n>>>1;r[e]=n}return r})(),ce=function(){var r=-1;return{p:function(e){for(var n=r,a=0;a>>8;r=n},d:function(){return~r}}},he=function(r,e,n,a,f){if(!f&&(f={l:1},e.dictionary)){var v=e.dictionary.subarray(-32768),i=new M(v.length+r.length);i.set(v),i.set(r,v.length),r=i,f.w=v.length}return se(r,e.level==null?6:e.level,e.mem==null?f.l?Math.ceil(Math.max(8,Math.min(13,Math.log(r.length)))*1.5):20:12+e.mem,n,a,f)},Xr=function(r,e){var n={};for(var a in r)n[a]=r[a];for(var a in e)n[a]=e[a];return n},Q=function(r,e){return r[e]|r[e+1]<<8},Y=function(r,e){return(r[e]|r[e+1]<<8|r[e+2]<<16|r[e+3]<<24)>>>0},kr=function(r,e){return Y(r,e)+Y(r,e+4)*4294967296},N=function(r,e,n){for(;n;++e)r[e]=n,n>>>=8};function ge(r,e){return he(r,e||{},0,0)}function we(r,e){return ie(r,{i:2},e&&e.out,e&&e.dictionary)}var Yr=function(r,e,n,a){for(var f in r){var v=r[f],i=e+f,s=a;Array.isArray(v)&&(s=Xr(a,v[1]),v=v[0]),v instanceof M?n[i]=[v,s]:(n[i+="/"]=[new M(0),s],Yr(v,i,n,a))}},Ir=typeof TextEncoder<"u"&&new TextEncoder,Ar=typeof TextDecoder<"u"&&new TextDecoder,me=0;try{Ar.decode(Rr,{stream:!0}),me=1}catch{}var xe=function(r){for(var e="",n=0;;){var a=r[n++],f=(a>127)+(a>223)+(a>239);if(n+f>r.length)return{s:e,r:lr(r,n-1)};f?f==3?(a=((a&15)<<18|(r[n++]&63)<<12|(r[n++]&63)<<6|r[n++]&63)-65536,e+=String.fromCharCode(55296|a>>10,56320|a&1023)):f&1?e+=String.fromCharCode((a&31)<<6|r[n++]&63):e+=String.fromCharCode((a&15)<<12|(r[n++]&63)<<6|r[n++]&63):e+=String.fromCharCode(a)}};function cr(r,e){var n;if(Ir)return Ir.encode(r);for(var a=r.length,f=new M(r.length+(r.length>>1)),v=0,i=function(c){f[v++]=c},n=0;nf.length){var s=new M(v+8+(a-n<<1));s.set(f),f=s}var l=r.charCodeAt(n);l<128||e?i(l):l<2048?(i(192|l>>6),i(128|l&63)):l>55295&&l<57344?(l=65536+(l&1047552)|r.charCodeAt(++n)&1023,i(240|l>>18),i(128|l>>12&63),i(128|l>>6&63),i(128|l&63)):(i(224|l>>12),i(128|l>>6&63),i(128|l&63))}return lr(f,0,v)}function jr(r,e){if(e){for(var n="",a=0;a65535&&I(9),e+=a+4}return e},Pr=function(r,e,n,a,f,v,i,s){var l=a.length,c=n.extra,t=s&&s.length,o=zr(c);N(r,e,i!=null?33639248:67324752),e+=4,i!=null&&(r[e++]=20,r[e++]=n.os),r[e]=20,e+=2,r[e++]=n.flag<<1|(v<0&&8),r[e++]=f&&8,r[e++]=n.compression&255,r[e++]=n.compression>>8;var u=new Date(n.mtime==null?Date.now():n.mtime),h=u.getFullYear()-1980;if((h<0||h>119)&&I(10),N(r,e,h<<25|u.getMonth()+1<<21|u.getDate()<<16|u.getHours()<<11|u.getMinutes()<<5|u.getSeconds()>>1),e+=4,v!=-1&&(N(r,e,n.crc),N(r,e+4,v<0?-v-2:v),N(r,e+8,n.size)),N(r,e+12,l),N(r,e+14,o),e+=16,i!=null&&(N(r,e,t),N(r,e+6,n.attrs),N(r,e+10,i),e+=14),r.set(a,e),e+=l,o)for(var y in c){var w=c[y],x=w.length;N(r,e,+y),N(r,e+2,x),r.set(w,e+4),e+=4+x}return t&&(r.set(s,e),e+=t),e},Se=function(r,e,n,a,f){N(r,e,101010256),N(r,e+8,n),N(r,e+10,n),N(r,e+12,a),N(r,e+16,f)};function Me(r,e){e||(e={});var n={},a=[];Yr(r,"",n,e);var f=0,v=0;for(var i in n){var s=n[i],l=s[0],c=s[1],t=c.level==0?0:8,o=cr(i),u=o.length,h=c.comment,y=h&&cr(h),w=y&&y.length,x=zr(c.extra);u>65535&&I(11);var T=t?ge(l,c):l,z=T.length,C=ce();C.p(l),a.push(Xr(c,{size:l.length,crc:C.d(),c:T,f:o,m:y,u:u!=i.length||y&&h.length!=w,o:f,compression:t})),f+=30+u+x+z,v+=76+2*(u+x)+(w||0)+z}for(var O=new M(v+22),$=f,U=v-f,A=0;A65558)&&I(13);var f=Q(r,a+8);if(!f)return{};var v=Y(r,a+16),i=v==4294967295||f==65535;if(i){var s=Y(r,a-12);i=Y(r,s)==101075792,i&&(f=Y(r,s+32),v=Y(r,s+48))}for(var l=0;l|]/g,"_")||"Projekt",n={};for(const l of r.files)n[`${e}/${br(l.path)}`]=new Uint8Array(cr(l.text));const a=[...r.packages.map(l=>`${e}/${dr(l)}/${re(l).replace(/\./g,"/")}/`),...ee(r).map(l=>`${e}/${l}/`)];for(const l of a)Object.keys(n).some(c=>c.startsWith(l))||(n[l.replace(/\/\/$/,"/")]=new Uint8Array);return(r.uml&&Object.keys(r.uml).length||(f=r.notes)!=null&&f.length||(v=r.objects)!=null&&v.length)&&(n[`${e}/${$r}`]=new Uint8Array(cr(JSON.stringify({format:"visuobject",version:1,uml:r.uml??{},...(i=r.notes)!=null&&i.length?{notes:r.notes}:{},...(s=r.objects)!=null&&s.length?{objects:r.objects}:{}},null,2)))),Me(n,{level:6})}function ze(r,e){var c;const n=Ce(r),a=Object.entries(n).filter(([t])=>/\.java$/i.test(t)&&!t.startsWith("__MACOSX/")).map(([t,o])=>({name:t,text:jr(o)})),f=new Set(Object.keys(n).map(t=>t.split("/")[0])),v=f.size===1&&Object.keys(n).some(t=>t.includes("/"))?[...f][0]:e,i=v!==e,s=Br(v,[]);for(const t of a){const o=Br(v,[{name:t.name.slice(t.name.lastIndexOf("/")+1),text:t.text}]).files[0],u=t.name.split("/").slice(i?1:0,-1),h=Er(o.text).split(".").filter(Boolean),w=u.slice(u.length-h.length).join("/")===h.join("/")?u.slice(0,u.length-h.length).join("/"):"",x=w&&w!==mr&&w.split("/").every(Gr)&&!w.includes(":")?w:mr,T=Qr(Vr(x,Er(o.text)),o.path.slice(o.path.lastIndexOf("/")+1));s.files=[...s.files.filter(z=>z.path!==T),{...o,path:T}],x!==mr&&!((c=s.sourceFolders)!=null&&c.includes(x))&&(s.sourceFolders=[...s.sourceFolders??[],x])}const l=Object.entries(n).find(([t])=>t===$r||t.endsWith(`/${$r}`));if(l)try{const t=JSON.parse(jr(l[1])),o=Lr(t.uml);o&&(s.uml=o);const u=_r(t.notes);u&&(s.notes=u);const h=pr(t.objects);h&&(s.objects=h)}catch{}return s}export{ze as projectFromZip,je as projectToZip}; diff --git a/website/app/assets/pt-PT-2W9Vff48.js b/website/app/assets/pt-PT-Dq8KVIrs.js similarity index 99% rename from website/app/assets/pt-PT-2W9Vff48.js rename to website/app/assets/pt-PT-Dq8KVIrs.js index 50b08736..5e3d547b 100644 --- a/website/app/assets/pt-PT-2W9Vff48.js +++ b/website/app/assets/pt-PT-Dq8KVIrs.js @@ -219,6 +219,7 @@ const e=`/* Textos que só existem na versão web. Tudo o resto vem dos Localiza "web_files_saved_fmt" = "Guardado: %@"; "web_files_create" = "Criar"; "web_learn_ludwig_tip" = "Dica do Ludwig"; +"web_learn_pro" = "Saber de profissional com o Ludwig"; "web_game_title" = "Jogo: Verdadeiro ou falso?"; "web_game_intro" = "O Ludwig mostra-te valores e uma condição. A condição é verdadeira (true) ou falsa (false)? Dez rondas, cada vez mais difíceis."; "web_game_start" = "Começar o jogo"; diff --git a/website/app/assets/robot3d-B1TGngW1.js b/website/app/assets/robot3d-I0g91EHr.js similarity index 99% rename from website/app/assets/robot3d-B1TGngW1.js rename to website/app/assets/robot3d-I0g91EHr.js index db8b0a30..242722c8 100644 --- a/website/app/assets/robot3d-B1TGngW1.js +++ b/website/app/assets/robot3d-I0g91EHr.js @@ -1,4 +1,4 @@ -var gl=Object.defineProperty;var _l=(i,t,e)=>t in i?gl(i,t,{enumerable:!0,configurable:!0,writable:!0,value:e}):i[t]=e;var le=(i,t,e)=>_l(i,typeof t!="symbol"?t+"":t,e);import{C as rn,L as oo}from"./index-BVzzpk4y.js";/** +var gl=Object.defineProperty;var _l=(i,t,e)=>t in i?gl(i,t,{enumerable:!0,configurable:!0,writable:!0,value:e}):i[t]=e;var le=(i,t,e)=>_l(i,typeof t!="symbol"?t+"":t,e);import{C as rn,L as oo}from"./index-DqKA7YqL.js";/** * @license * Copyright 2010-2025 Three.js Authors * SPDX-License-Identifier: MIT diff --git a/website/app/assets/ru-B4vTuE57.js b/website/app/assets/ru-DGHs_3oc.js similarity index 99% rename from website/app/assets/ru-B4vTuE57.js rename to website/app/assets/ru-DGHs_3oc.js index a3d3cb73..f5b0dec3 100644 --- a/website/app/assets/ru-B4vTuE57.js +++ b/website/app/assets/ru-DGHs_3oc.js @@ -135,6 +135,7 @@ const e=`/* Тексты, которые есть только в веб-вер "web_files_saved_fmt" = "Сохранено: %@"; "web_files_create" = "Создать"; "web_learn_ludwig_tip" = "Совет Людвига"; +"web_learn_pro" = "Профи-знания с Людвигом"; "web_game_title" = "Игра: Истина или ложь?"; "web_game_intro" = "Людвиг показывает значения и условие. Условие истинно (true) или ложно (false)? Десять раундов, всё сложнее."; "web_game_start" = "Начать игру"; diff --git a/website/app/assets/sv-Dau75zUV.js b/website/app/assets/sv-zO9ikvt0.js similarity index 99% rename from website/app/assets/sv-Dau75zUV.js rename to website/app/assets/sv-zO9ikvt0.js index a13be35d..03af12bd 100644 --- a/website/app/assets/sv-Dau75zUV.js +++ b/website/app/assets/sv-zO9ikvt0.js @@ -135,6 +135,7 @@ const e=`/* Texter som bara finns i webbversionen. Allt annat kommer från appen "web_files_saved_fmt" = "Sparat: %@"; "web_files_create" = "Skapa"; "web_learn_ludwig_tip" = "Ludwigs tips"; +"web_learn_pro" = "Proffskunskap med Ludwig"; "web_game_title" = "Spel: Sant eller falskt?"; "web_game_intro" = "Ludwig visar värden och ett villkor. Är villkoret sant (true) eller falskt (false)? Tio rundor, allt svårare."; "web_game_start" = "Starta spelet"; diff --git a/website/app/assets/tr-DrZsTe-O.js b/website/app/assets/tr-zv5TxQHQ.js similarity index 99% rename from website/app/assets/tr-DrZsTe-O.js rename to website/app/assets/tr-zv5TxQHQ.js index 3cc2459f..327f8a97 100644 --- a/website/app/assets/tr-DrZsTe-O.js +++ b/website/app/assets/tr-zv5TxQHQ.js @@ -135,6 +135,7 @@ const e=`/* Yalnızca web sürümünde bulunan metinler. Geri kalan her şey uyg "web_files_saved_fmt" = "Kaydedildi: %@"; "web_files_create" = "Oluştur"; "web_learn_ludwig_tip" = "Ludwig’in ipucu"; +"web_learn_pro" = "Ludwig ile profesyonel bilgi"; "web_game_title" = "Oyun: Doğru mu yanlış mı?"; "web_game_intro" = "Ludwig sana değerler ve bir koşul gösterir. Koşul doğru (true) mu yanlış (false) mı? On tur, giderek zorlaşır."; "web_game_start" = "Oyunu başlat"; diff --git a/website/app/assets/uk-DQrOpK2W.js b/website/app/assets/uk-D5KOtCBD.js similarity index 99% rename from website/app/assets/uk-DQrOpK2W.js rename to website/app/assets/uk-D5KOtCBD.js index 4836970c..71210b14 100644 --- a/website/app/assets/uk-DQrOpK2W.js +++ b/website/app/assets/uk-D5KOtCBD.js @@ -135,6 +135,7 @@ const e=`/* Тексти, які є лише у веб-версії. Усі ін "web_files_saved_fmt" = "Збережено: %@"; "web_files_create" = "Створити"; "web_learn_ludwig_tip" = "Порада Людвіга"; +"web_learn_pro" = "Знання профі з Людвігом"; "web_game_title" = "Гра: Істина чи хиба?"; "web_game_intro" = "Людвіг показує значення й умову. Умова істинна (true) чи хибна (false)? Десять раундів, щоразу складніше."; "web_game_start" = "Почати гру"; diff --git a/website/app/assets/zh-Hans-CeIYjS3N.js b/website/app/assets/zh-Hans-C3na1U20.js similarity index 99% rename from website/app/assets/zh-Hans-CeIYjS3N.js rename to website/app/assets/zh-Hans-C3na1U20.js index 3c763aeb..7e5b6b52 100644 --- a/website/app/assets/zh-Hans-CeIYjS3N.js +++ b/website/app/assets/zh-Hans-C3na1U20.js @@ -135,6 +135,7 @@ const e=`/* 仅存在于网页版中的文本。其他所有文本均来自应 "web_files_saved_fmt" = "已保存:%@"; "web_files_create" = "新建"; "web_learn_ludwig_tip" = "路德维希的提示"; +"web_learn_pro" = "路德维希的专业知识"; "web_game_title" = "游戏:真还是假?"; "web_game_intro" = "路德维希给你看一些值和一个条件。这个条件是真(true)还是假(false)?共十轮,越来越难。"; "web_game_start" = "开始游戏"; diff --git a/website/app/assets/zh-Hant-7-ScZHAu.js b/website/app/assets/zh-Hant-BLjr78US.js similarity index 99% rename from website/app/assets/zh-Hant-7-ScZHAu.js rename to website/app/assets/zh-Hant-BLjr78US.js index cbcbdc06..3afd3e22 100644 --- a/website/app/assets/zh-Hant-7-ScZHAu.js +++ b/website/app/assets/zh-Hant-BLjr78US.js @@ -135,6 +135,7 @@ const e=`/* 僅存在於網頁版的文字。其他所有文字皆來自 App 的 "web_files_saved_fmt" = "已儲存:%@"; "web_files_create" = "新增"; "web_learn_ludwig_tip" = "路德維希的提示"; +"web_learn_pro" = "路德維希的專業知識"; "web_game_title" = "遊戲:真還是假?"; "web_game_intro" = "路德維希給你看一些值和一個條件。這個條件是真(true)還是假(false)?共十輪,越來越難。"; "web_game_start" = "開始遊戲"; diff --git a/website/app/index.html b/website/app/index.html index b65920ac..bd9378b3 100644 --- a/website/app/index.html +++ b/website/app/index.html @@ -6,7 +6,7 @@ VisuStruct Web - + From e987d19a73462e7519b523850967894fa8686ca1 Mon Sep 17 00:00:00 2001 From: Claude Date: Fri, 30 Oct 2026 23:44:55 +0000 Subject: [PATCH 2/3] =?UTF-8?q?Profiwissen-Kasten=20zur=C3=BCckgebaut,=20K?= =?UTF-8?q?onsolenbefehle=20als=20Angeberwissen=20(Holger)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-Authored-By: Claude Opus 5.5 Claude-Session: https://claude.ai/code/session_01Ugz28WToQoMzLJgvHWUb3d --- CHANGELOG.md | 2 +- web/lessons/README.md | 9 -------- web/lessons/de/20-java.md | 2 +- web/lessons/en/20-java.md | 2 +- web/lessons/pt/20-java.md | 2 +- web/src/i18n/ar.strings | 1 - web/src/i18n/da.strings | 1 - web/src/i18n/de.strings | 1 - web/src/i18n/el.strings | 1 - web/src/i18n/en.strings | 1 - web/src/i18n/es.strings | 1 - web/src/i18n/fr.strings | 1 - web/src/i18n/he.strings | 1 - web/src/i18n/it.strings | 1 - web/src/i18n/ja.strings | 1 - web/src/i18n/ko.strings | 1 - web/src/i18n/nb.strings | 1 - web/src/i18n/nl.strings | 1 - web/src/i18n/pl.strings | 1 - web/src/i18n/pt-PT.strings | 1 - web/src/i18n/ru.strings | 1 - web/src/i18n/sv.strings | 1 - web/src/i18n/tr.strings | 1 - web/src/i18n/uk.strings | 1 - web/src/i18n/zh-Hans.strings | 1 - web/src/i18n/zh-Hant.strings | 1 - web/src/learn/lessonFormat.ts | 5 +---- web/src/ui/learnPanel.ts | 8 +++---- .../assets/{ar-Dqb2o0I-.js => ar-DeE-RHam.js} | 1 - .../assets/{da-ey_ipgDe.js => da-D4INXE4p.js} | 1 - .../assets/{de-DMor0Vtb.js => de-NQF_CaEx.js} | 1 - .../assets/{el-DaQv4rR_.js => el-CtIZyj0I.js} | 1 - .../assets/{en-CEwI5dlH.js => en-DysVTM-W.js} | 1 - .../assets/{es-BHz7jCrz.js => es-BAduFB3L.js} | 1 - ...lowApp-4s69NVPv.js => flowApp-Bn4c4hPI.js} | 2 +- .../assets/{fr-CEc9fFV7.js => fr-C_mSEvw5.js} | 1 - .../assets/{he-B1FDwOEu.js => he-BAg3LrWK.js} | 1 - .../{index-DqKA7YqL.js => index-CzgrZgZa.js} | 21 +++++++++---------- .../assets/{it-Bsr1AlWk.js => it-ClGS2uQV.js} | 1 - .../assets/{ja-L0a84IMq.js => ja-JQ8MwNFB.js} | 1 - .../assets/{ko-U6EDne8i.js => ko-tfdKG8Fb.js} | 1 - .../assets/{nb-C9pwk403.js => nb-BpibUAkX.js} | 1 - .../assets/{nl-D1JTb8Xr.js => nl-HArZjiga.js} | 1 - ...tApp-exr4obxz.js => objectApp-Caze4o4v.js} | 6 +++--- .../assets/{pl-DchXCt_R.js => pl-C3HmQqUD.js} | 1 - ...Zip-Dv_LmKlY.js => projectZip-BKS-Blr6.js} | 2 +- .../{pt-PT-Dq8KVIrs.js => pt-PT-2W9Vff48.js} | 1 - ...obot3d-I0g91EHr.js => robot3d-BNw8Z2K3.js} | 2 +- .../assets/{ru-DGHs_3oc.js => ru-B4vTuE57.js} | 1 - .../assets/{sv-zO9ikvt0.js => sv-Dau75zUV.js} | 1 - .../assets/{tr-zv5TxQHQ.js => tr-DrZsTe-O.js} | 1 - .../assets/{uk-D5KOtCBD.js => uk-DQrOpK2W.js} | 1 - ...h-Hans-C3na1U20.js => zh-Hans-CeIYjS3N.js} | 1 - ...h-Hant-BLjr78US.js => zh-Hant-7-ScZHAu.js} | 1 - website/app/index.html | 2 +- 55 files changed, 26 insertions(+), 81 deletions(-) rename website/app/assets/{ar-Dqb2o0I-.js => ar-DeE-RHam.js} (99%) rename website/app/assets/{da-ey_ipgDe.js => da-D4INXE4p.js} (99%) rename website/app/assets/{de-DMor0Vtb.js => de-NQF_CaEx.js} (99%) rename website/app/assets/{el-DaQv4rR_.js => el-CtIZyj0I.js} (99%) rename website/app/assets/{en-CEwI5dlH.js => en-DysVTM-W.js} (99%) rename website/app/assets/{es-BHz7jCrz.js => es-BAduFB3L.js} (99%) rename website/app/assets/{flowApp-4s69NVPv.js => flowApp-Bn4c4hPI.js} (99%) rename website/app/assets/{fr-CEc9fFV7.js => fr-C_mSEvw5.js} (99%) rename website/app/assets/{he-B1FDwOEu.js => he-BAg3LrWK.js} (99%) rename website/app/assets/{index-DqKA7YqL.js => index-CzgrZgZa.js} (99%) rename website/app/assets/{it-Bsr1AlWk.js => it-ClGS2uQV.js} (99%) rename website/app/assets/{ja-L0a84IMq.js => ja-JQ8MwNFB.js} (99%) rename website/app/assets/{ko-U6EDne8i.js => ko-tfdKG8Fb.js} (99%) rename website/app/assets/{nb-C9pwk403.js => nb-BpibUAkX.js} (99%) rename website/app/assets/{nl-D1JTb8Xr.js => nl-HArZjiga.js} (99%) rename website/app/assets/{objectApp-exr4obxz.js => objectApp-Caze4o4v.js} (99%) rename website/app/assets/{pl-DchXCt_R.js => pl-C3HmQqUD.js} (99%) rename website/app/assets/{projectZip-Dv_LmKlY.js => projectZip-BKS-Blr6.js} (99%) rename website/app/assets/{pt-PT-Dq8KVIrs.js => pt-PT-2W9Vff48.js} (99%) rename website/app/assets/{robot3d-I0g91EHr.js => robot3d-BNw8Z2K3.js} (99%) rename website/app/assets/{ru-DGHs_3oc.js => ru-B4vTuE57.js} (99%) rename website/app/assets/{sv-zO9ikvt0.js => sv-Dau75zUV.js} (99%) rename website/app/assets/{tr-zv5TxQHQ.js => tr-DrZsTe-O.js} (99%) rename website/app/assets/{uk-D5KOtCBD.js => uk-DQrOpK2W.js} (99%) rename website/app/assets/{zh-Hans-C3na1U20.js => zh-Hans-CeIYjS3N.js} (99%) rename website/app/assets/{zh-Hant-BLjr78US.js => zh-Hant-7-ScZHAu.js} (99%) diff --git a/CHANGELOG.md b/CHANGELOG.md index 69f8af96..1c6c5775 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -15,7 +15,7 @@ The format is loosely inspired by Keep a Changelog. ### Added -- **Web 0.14.2, Profiwissen: Java in the console:** new box `::: profiwissen` („Profiwissen mit Ludwig“, looks like the Angeberwissen box, new string web_learn_pro in all 21 languages). Lesson 20 step „Wie Java auf jedem Computer läuft“ uses it for `java -version`, `javac Einmaleins.java` and `java Einmaleins`, plus the hint that a missing `javac -version` means only a JRE is installed (de/en/pt). Fix: the two diagrams in that step were missing their closing `:::`, so in 0.14.1 the text after the first diagram showed up as its caption; they now have short captions, and a new test flags overly long captions. +- **Web 0.14.2, Java in the console:** lesson 20 step „Wie Java auf jedem Computer läuft“ has a new Angeberwissen box on `java -version`, `javac Einmaleins.java` and `java Einmaleins`, plus the hint that a missing `javac -version` means only a JRE is installed (de/en/pt). Fix: the two diagrams in that step were missing their closing `:::`, so in 0.14.1 the text after the first diagram showed up as its caption; they now have short captions, and a new test flags overly long captions. - **Web 0.14.1, how Java runs on every computer:** lesson 20 has a new step „Wie Java auf jedem Computer läuft“ after „Snippet oder Class“: source code → compiler `javac` → bytecode (`.class`) → JVM on Windows/macOS/Linux, platform independence („Write once, run anywhere“), the JVM pictured as a small computer made of software (but a virtual machine, not an operating system), a table JRE vs. JDK, the JVM translating bytecode into machine code (JIT compiler), and a comparison with C++ (compiled directly to machine code, so once per system; second diagram l20-cpp.svg and a C++/Java table). New self-drawn diagram l20-jvm.svg (de/en/pt), the CAFEBABE Angeberwissen moved into the new step, three competences, three checklist lines and three quiz questions. Lesson 4 „Jetzt in Java“ points to lesson 20. New glossary entries Quellcode, Compiler, Bytecode, Maschinencode, JIT-Compiler, JVM, JRE, JDK, plattformunabhängig and Nachschlagen section „Java › Vom Code zum Programm“ (de/en/pt). - **Web 0.14.0, new world VisuFlow: draw flowcharts:** fourth world next to VisuStruct, VisuBot and VisuObject (…/app/?visuflow, colour violet, chosen at the start or in the gear menu; the world chooser now has two rows). Only drawing, no simulation and no code: drag the DIN 66001 symbols (Start, Anweisung, Ein-/Ausgabe, Verzweigung, Unterprogramm, Ende) from the bar onto the canvas, or tap a symbol to add it below the selected one, joined by an arrow; type the text right in the symbol (tap again or double click to change it). Drag an arrow from the dot at an exit to the next symbol; the diamond has the exits ja and nein (button „ja/nein tauschen“ swaps their sides), arrows run at right angles, loops go around on the right. Move with the mouse, finger or arrow keys on a 20 px grid, delete, undo/redo, title above the canvas, example „Tee kochen“ from lesson 1. Save and open as `.visuflow` file (the last plan stays in the browser), export as PNG, SVG or PDF (A4). Texts de/en/pt. - **Web 0.13.38, comments in Java:** lesson 6 has a new step „Kommentare im Code“ after „Jetzt in Java“: single-line `//` and multi-line `/* … */` comments, Java skips them and the structure chart stays the same; Javadoc `/** … */` is only mentioned. The IPO example (with „Im Editor öffnen“) shows the task in a multi-line comment, `// Eingabe`, `// Verarbeitung`, `// Ausgabe`, an explanation after a line, the expected output and a note for next time; plus a fill-in-the-gaps exercise, an Angeberwissen (PL/I 1964, BCPL 1967), a competence, a checklist line and two quiz questions. Lesson 14 marks closing brackets with `} // Ende if` / `} // Ende for`, lesson 20 the class frame with `} // Ende main` / `} // Ende Klasse`. New glossary entry Kommentar and Nachschlagen section „Java › Kommentare“ (de/en/pt). diff --git a/web/lessons/README.md b/web/lessons/README.md index 91b0e65d..19ab0d8a 100644 --- a/web/lessons/README.md +++ b/web/lessons/README.md @@ -168,15 +168,6 @@ Ben Shneiderman hatte die Idee 1972. [Mehr dazu](https://visustruct.org/de/angeb ::: ``` -Ein Kasten „Profiwissen mit Ludwig“ sieht genauso aus, ist aber für Profi-Tipps über den Unterricht hinaus, zum Beispiel -Befehle in der Konsole: - -``` -::: profiwissen -`java -version` zeigt, welche Java-Version installiert ist. -::: -``` - Ein Spiel „Wahr oder falsch?“: oben die Variablen (`name: von..bis` für ganze Zahlen, `name: boolean`), darunter mit `?` die Bedingungen vom leichten zum schweren. Zehn Runden; Werte knapp an den Grenzen der Vergleiche kommen öfter vor: diff --git a/web/lessons/de/20-java.md b/web/lessons/de/20-java.md index 1f00dc89..b4345bd4 100644 --- a/web/lessons/de/20-java.md +++ b/web/lessons/de/20-java.md @@ -149,7 +149,7 @@ Beim Installieren begegnen dir zwei Abkürzungen: Zum Programmieren brauchst du also das JDK. Heute lädt man meist nur noch das JDK herunter, die JRE steckt darin. Für VisuStruct im Browser musst du nichts davon installieren. -::: profiwissen +::: angeberwissen Mit einem JDK kannst du alles auch selbst in der Konsole machen, also im Terminal oder in der Eingabeaufforderung: ``` diff --git a/web/lessons/en/20-java.md b/web/lessons/en/20-java.md index 9a328f86..290826c2 100644 --- a/web/lessons/en/20-java.md +++ b/web/lessons/en/20-java.md @@ -149,7 +149,7 @@ When you install Java you meet two abbreviations: So to program you need the JDK. Today you usually only download the JDK, the JRE is inside it. For VisuStruct in the browser you don't need to install any of this. -::: profiwissen +::: angeberwissen With a JDK you can do all of this yourself in the console, that is in the terminal or the command prompt: ``` diff --git a/web/lessons/pt/20-java.md b/web/lessons/pt/20-java.md index 9d39377a..af6af256 100644 --- a/web/lessons/pt/20-java.md +++ b/web/lessons/pt/20-java.md @@ -149,7 +149,7 @@ Ao instalar o Java, encontras duas siglas: Para programar precisas, portanto, do JDK. Hoje em dia normalmente só se descarrega o JDK, o JRE vem lá dentro. Para usar o VisuStruct no browser não precisas de instalar nada disto. -::: profiwissen +::: angeberwissen Com um JDK podes fazer tudo isto tu próprio na consola, ou seja, no terminal ou na linha de comandos: ``` diff --git a/web/src/i18n/ar.strings b/web/src/i18n/ar.strings index 88bec8b3..e4c6b393 100644 --- a/web/src/i18n/ar.strings +++ b/web/src/i18n/ar.strings @@ -135,7 +135,6 @@ "web_files_saved_fmt" = "تم الحفظ: %@"; "web_files_create" = "إنشاء"; "web_learn_ludwig_tip" = "نصيحة لودفيغ"; -"web_learn_pro" = "معرفة المحترفين مع لودفيغ"; "web_game_title" = "لعبة: صحيح أم خطأ؟"; "web_game_intro" = "يعرض لك لودفيغ قيماً وشرطاً. هل الشرط صحيح (true) أم خطأ (false)؟ عشر جولات تزداد صعوبة."; "web_game_start" = "ابدأ اللعبة"; diff --git a/web/src/i18n/da.strings b/web/src/i18n/da.strings index 160b0ce8..a1e13ff7 100644 --- a/web/src/i18n/da.strings +++ b/web/src/i18n/da.strings @@ -135,7 +135,6 @@ "web_files_saved_fmt" = "Gemt: %@"; "web_files_create" = "Opret"; "web_learn_ludwig_tip" = "Ludwigs tip"; -"web_learn_pro" = "Profividen med Ludwig"; "web_game_title" = "Spil: Sandt eller falsk?"; "web_game_intro" = "Ludwig viser dig værdier og en betingelse. Er betingelsen sand (true) eller falsk (false)? Ti runder, sværere og sværere."; "web_game_start" = "Start spillet"; diff --git a/web/src/i18n/de.strings b/web/src/i18n/de.strings index edc02522..87354a19 100644 --- a/web/src/i18n/de.strings +++ b/web/src/i18n/de.strings @@ -221,7 +221,6 @@ "web_files_saved_fmt" = "Gespeichert: %@"; "web_files_create" = "Anlegen"; "web_learn_ludwig_tip" = "Ludwigs Tipp"; -"web_learn_pro" = "Profiwissen mit Ludwig"; "web_game_title" = "Spiel: Wahr oder falsch?"; "web_game_intro" = "Ludwig zeigt dir Werte und eine Bedingung. Ist die Bedingung wahr (true) oder falsch (false)? Zehn Runden, es wird von Runde zu Runde kniffliger."; "web_game_start" = "Spiel starten"; diff --git a/web/src/i18n/el.strings b/web/src/i18n/el.strings index 1fc02cd0..dd9bcf82 100644 --- a/web/src/i18n/el.strings +++ b/web/src/i18n/el.strings @@ -135,7 +135,6 @@ "web_files_saved_fmt" = "Αποθηκεύτηκε: %@"; "web_files_create" = "Δημιουργία"; "web_learn_ludwig_tip" = "Η συμβουλή του Ludwig"; -"web_learn_pro" = "Γνώσεις για επαγγελματίες με τον Ludwig"; "web_game_title" = "Παιχνίδι: Αληθές ή ψευδές;"; "web_game_intro" = "Ο Ludwig σου δείχνει τιμές και μια συνθήκη. Είναι αληθής (true) ή ψευδής (false); Δέκα γύροι, όλο και δυσκολότεροι."; "web_game_start" = "Έναρξη παιχνιδιού"; diff --git a/web/src/i18n/en.strings b/web/src/i18n/en.strings index adc228b0..226917db 100644 --- a/web/src/i18n/en.strings +++ b/web/src/i18n/en.strings @@ -221,7 +221,6 @@ "web_files_saved_fmt" = "Saved: %@"; "web_files_create" = "Create"; "web_learn_ludwig_tip" = "Ludwig’s tip"; -"web_learn_pro" = "Pro knowledge with Ludwig"; "web_game_title" = "Game: True or false?"; "web_game_intro" = "Ludwig shows you values and a condition. Is the condition true or false? Ten rounds, getting trickier each time."; "web_game_start" = "Start game"; diff --git a/web/src/i18n/es.strings b/web/src/i18n/es.strings index d441ce41..76ebf53e 100644 --- a/web/src/i18n/es.strings +++ b/web/src/i18n/es.strings @@ -135,7 +135,6 @@ "web_files_saved_fmt" = "Guardado: %@"; "web_files_create" = "Crear"; "web_learn_ludwig_tip" = "El consejo de Ludwig"; -"web_learn_pro" = "Saber de profesional con Ludwig"; "web_game_title" = "Juego: ¿Verdadero o falso?"; "web_game_intro" = "Ludwig te muestra valores y una condición. ¿Es verdadera (true) o falsa (false)? Diez rondas, cada vez más difíciles."; "web_game_start" = "Empezar el juego"; diff --git a/web/src/i18n/fr.strings b/web/src/i18n/fr.strings index b65a566a..ecb40127 100644 --- a/web/src/i18n/fr.strings +++ b/web/src/i18n/fr.strings @@ -135,7 +135,6 @@ "web_files_saved_fmt" = "Enregistré : %@"; "web_files_create" = "Créer"; "web_learn_ludwig_tip" = "Le conseil de Ludwig"; -"web_learn_pro" = "Savoir de pro avec Ludwig"; "web_game_title" = "Jeu : Vrai ou faux ?"; "web_game_intro" = "Ludwig te montre des valeurs et une condition. Est-elle vraie (true) ou fausse (false) ? Dix manches, de plus en plus difficiles."; "web_game_start" = "Commencer le jeu"; diff --git a/web/src/i18n/he.strings b/web/src/i18n/he.strings index d576e62f..ac7a7248 100644 --- a/web/src/i18n/he.strings +++ b/web/src/i18n/he.strings @@ -135,7 +135,6 @@ "web_files_saved_fmt" = "נשמר: %@"; "web_files_create" = "יצירה"; "web_learn_ludwig_tip" = "הטיפ של לודוויג"; -"web_learn_pro" = "ידע של מקצוענים עם לודוויג"; "web_game_title" = "משחק: אמת או שקר?"; "web_game_intro" = "לודוויג מראה ערכים ותנאי. האם התנאי אמת (true) או שקר (false)? עשרה סבבים, כל פעם קשה יותר."; "web_game_start" = "התחלת המשחק"; diff --git a/web/src/i18n/it.strings b/web/src/i18n/it.strings index 6f62c346..4b42e666 100644 --- a/web/src/i18n/it.strings +++ b/web/src/i18n/it.strings @@ -135,7 +135,6 @@ "web_files_saved_fmt" = "Salvato: %@"; "web_files_create" = "Crea"; "web_learn_ludwig_tip" = "Il consiglio di Ludwig"; -"web_learn_pro" = "Sapere da professionisti con Ludwig"; "web_game_title" = "Gioco: Vero o falso?"; "web_game_intro" = "Ludwig ti mostra dei valori e una condizione. È vera (true) o falsa (false)? Dieci turni, sempre più difficili."; "web_game_start" = "Inizia il gioco"; diff --git a/web/src/i18n/ja.strings b/web/src/i18n/ja.strings index 9b672a7f..0a0ec387 100644 --- a/web/src/i18n/ja.strings +++ b/web/src/i18n/ja.strings @@ -135,7 +135,6 @@ "web_files_saved_fmt" = "保存しました:%@"; "web_files_create" = "作成"; "web_learn_ludwig_tip" = "ルートヴィヒのヒント"; -"web_learn_pro" = "ルートヴィヒのプロ知識"; "web_game_title" = "ゲーム:真か偽か?"; "web_game_intro" = "ルートヴィヒが値と条件を見せます。条件は真(true)?それとも偽(false)?10ラウンド、だんだん難しくなります。"; "web_game_start" = "ゲームを始める"; diff --git a/web/src/i18n/ko.strings b/web/src/i18n/ko.strings index dcfc102f..d0ac8c28 100644 --- a/web/src/i18n/ko.strings +++ b/web/src/i18n/ko.strings @@ -135,7 +135,6 @@ "web_files_saved_fmt" = "저장됨: %@"; "web_files_create" = "만들기"; "web_learn_ludwig_tip" = "루트비히의 팁"; -"web_learn_pro" = "루트비히의 전문가 지식"; "web_game_title" = "게임: 참일까 거짓일까?"; "web_game_intro" = "루트비히가 값과 조건을 보여 줍니다. 조건이 참(true)일까요, 거짓(false)일까요? 10라운드, 점점 어려워집니다."; "web_game_start" = "게임 시작"; diff --git a/web/src/i18n/nb.strings b/web/src/i18n/nb.strings index 03116d84..da1ba87a 100644 --- a/web/src/i18n/nb.strings +++ b/web/src/i18n/nb.strings @@ -135,7 +135,6 @@ "web_files_saved_fmt" = "Lagret: %@"; "web_files_create" = "Lag"; "web_learn_ludwig_tip" = "Ludwigs tips"; -"web_learn_pro" = "Proffkunnskap med Ludwig"; "web_game_title" = "Spill: Sant eller usant?"; "web_game_intro" = "Ludwig viser deg verdier og en betingelse. Er betingelsen sann (true) eller usann (false)? Ti runder, stadig vanskeligere."; "web_game_start" = "Start spillet"; diff --git a/web/src/i18n/nl.strings b/web/src/i18n/nl.strings index 2b144e9d..41b30e58 100644 --- a/web/src/i18n/nl.strings +++ b/web/src/i18n/nl.strings @@ -135,7 +135,6 @@ "web_files_saved_fmt" = "Opgeslagen: %@"; "web_files_create" = "Maken"; "web_learn_ludwig_tip" = "Ludwigs tip"; -"web_learn_pro" = "Profkennis met Ludwig"; "web_game_title" = "Spel: Waar of onwaar?"; "web_game_intro" = "Ludwig laat je waarden en een voorwaarde zien. Is de voorwaarde waar (true) of onwaar (false)? Tien rondes, steeds lastiger."; "web_game_start" = "Spel starten"; diff --git a/web/src/i18n/pl.strings b/web/src/i18n/pl.strings index 24da49f8..54bb5061 100644 --- a/web/src/i18n/pl.strings +++ b/web/src/i18n/pl.strings @@ -135,7 +135,6 @@ "web_files_saved_fmt" = "Zapisano: %@"; "web_files_create" = "Utwórz"; "web_learn_ludwig_tip" = "Wskazówka Ludwiga"; -"web_learn_pro" = "Wiedza dla profesjonalistów z Ludwigiem"; "web_game_title" = "Gra: Prawda czy fałsz?"; "web_game_intro" = "Ludwig pokazuje wartości i warunek. Czy warunek jest prawdziwy (true), czy fałszywy (false)? Dziesięć rund, coraz trudniejszych."; "web_game_start" = "Zacznij grę"; diff --git a/web/src/i18n/pt-PT.strings b/web/src/i18n/pt-PT.strings index 09da5560..bc82d4ce 100644 --- a/web/src/i18n/pt-PT.strings +++ b/web/src/i18n/pt-PT.strings @@ -219,7 +219,6 @@ "web_files_saved_fmt" = "Guardado: %@"; "web_files_create" = "Criar"; "web_learn_ludwig_tip" = "Dica do Ludwig"; -"web_learn_pro" = "Saber de profissional com o Ludwig"; "web_game_title" = "Jogo: Verdadeiro ou falso?"; "web_game_intro" = "O Ludwig mostra-te valores e uma condição. A condição é verdadeira (true) ou falsa (false)? Dez rondas, cada vez mais difíceis."; "web_game_start" = "Começar o jogo"; diff --git a/web/src/i18n/ru.strings b/web/src/i18n/ru.strings index 42a29f40..71115318 100644 --- a/web/src/i18n/ru.strings +++ b/web/src/i18n/ru.strings @@ -135,7 +135,6 @@ "web_files_saved_fmt" = "Сохранено: %@"; "web_files_create" = "Создать"; "web_learn_ludwig_tip" = "Совет Людвига"; -"web_learn_pro" = "Профи-знания с Людвигом"; "web_game_title" = "Игра: Истина или ложь?"; "web_game_intro" = "Людвиг показывает значения и условие. Условие истинно (true) или ложно (false)? Десять раундов, всё сложнее."; "web_game_start" = "Начать игру"; diff --git a/web/src/i18n/sv.strings b/web/src/i18n/sv.strings index b88de94c..aa533939 100644 --- a/web/src/i18n/sv.strings +++ b/web/src/i18n/sv.strings @@ -135,7 +135,6 @@ "web_files_saved_fmt" = "Sparat: %@"; "web_files_create" = "Skapa"; "web_learn_ludwig_tip" = "Ludwigs tips"; -"web_learn_pro" = "Proffskunskap med Ludwig"; "web_game_title" = "Spel: Sant eller falskt?"; "web_game_intro" = "Ludwig visar värden och ett villkor. Är villkoret sant (true) eller falskt (false)? Tio rundor, allt svårare."; "web_game_start" = "Starta spelet"; diff --git a/web/src/i18n/tr.strings b/web/src/i18n/tr.strings index 1ba5eac4..5a79faf8 100644 --- a/web/src/i18n/tr.strings +++ b/web/src/i18n/tr.strings @@ -135,7 +135,6 @@ "web_files_saved_fmt" = "Kaydedildi: %@"; "web_files_create" = "Oluştur"; "web_learn_ludwig_tip" = "Ludwig’in ipucu"; -"web_learn_pro" = "Ludwig ile profesyonel bilgi"; "web_game_title" = "Oyun: Doğru mu yanlış mı?"; "web_game_intro" = "Ludwig sana değerler ve bir koşul gösterir. Koşul doğru (true) mu yanlış (false) mı? On tur, giderek zorlaşır."; "web_game_start" = "Oyunu başlat"; diff --git a/web/src/i18n/uk.strings b/web/src/i18n/uk.strings index e402549f..8a39b0c1 100644 --- a/web/src/i18n/uk.strings +++ b/web/src/i18n/uk.strings @@ -135,7 +135,6 @@ "web_files_saved_fmt" = "Збережено: %@"; "web_files_create" = "Створити"; "web_learn_ludwig_tip" = "Порада Людвіга"; -"web_learn_pro" = "Знання профі з Людвігом"; "web_game_title" = "Гра: Істина чи хиба?"; "web_game_intro" = "Людвіг показує значення й умову. Умова істинна (true) чи хибна (false)? Десять раундів, щоразу складніше."; "web_game_start" = "Почати гру"; diff --git a/web/src/i18n/zh-Hans.strings b/web/src/i18n/zh-Hans.strings index 37a08dca..0223fa3f 100644 --- a/web/src/i18n/zh-Hans.strings +++ b/web/src/i18n/zh-Hans.strings @@ -135,7 +135,6 @@ "web_files_saved_fmt" = "已保存:%@"; "web_files_create" = "新建"; "web_learn_ludwig_tip" = "路德维希的提示"; -"web_learn_pro" = "路德维希的专业知识"; "web_game_title" = "游戏:真还是假?"; "web_game_intro" = "路德维希给你看一些值和一个条件。这个条件是真(true)还是假(false)?共十轮,越来越难。"; "web_game_start" = "开始游戏"; diff --git a/web/src/i18n/zh-Hant.strings b/web/src/i18n/zh-Hant.strings index 70e22188..9b0a04a8 100644 --- a/web/src/i18n/zh-Hant.strings +++ b/web/src/i18n/zh-Hant.strings @@ -135,7 +135,6 @@ "web_files_saved_fmt" = "已儲存:%@"; "web_files_create" = "新增"; "web_learn_ludwig_tip" = "路德維希的提示"; -"web_learn_pro" = "路德維希的專業知識"; "web_game_title" = "遊戲:真還是假?"; "web_game_intro" = "路德維希給你看一些值和一個條件。這個條件是真(true)還是假(false)?共十輪,越來越難。"; "web_game_start" = "開始遊戲"; diff --git a/web/src/learn/lessonFormat.ts b/web/src/learn/lessonFormat.ts index 725e510f..305f69f9 100644 --- a/web/src/learn/lessonFormat.ts +++ b/web/src/learn/lessonFormat.ts @@ -19,7 +19,7 @@ export type Block = /** Kompetenzen am Anfang der Lektion („Diese Kompetenzen erwerbe ich jetzt“). */ | { kind: 'competences'; items: string[] } | { kind: 'quiz'; questions: QuizQuestion[] } - | { kind: 'brag'; text: string; tip?: boolean; pro?: boolean } + | { kind: 'brag'; text: string; tip?: boolean } | { kind: 'images'; files: string[]; caption: string } /** `labeled`: beschriftete Fassung, die ein Klick auf die Grafik ein- und ausblendet. */ | { kind: 'graphic'; file: string; labeled?: string; caption: string } @@ -378,9 +378,6 @@ export function parseBlocks(body: string, file: string): Block[] { throw new FormatError((err as Error).message) } break - case 'profiwissen': - blocks.push({ kind: 'brag', text: inner.join('\n').trim(), pro: true }) - break case 'ludwig': blocks.push({ kind: 'brag', text: inner.join('\n').trim(), tip: true }) break diff --git a/web/src/ui/learnPanel.ts b/web/src/ui/learnPanel.ts index 15e5fc35..1e8fe3d4 100644 --- a/web/src/ui/learnPanel.ts +++ b/web/src/ui/learnPanel.ts @@ -448,7 +448,7 @@ export class LearnPanel { case 'quiz': return this.renderQuiz(block.questions, key, lesson) case 'brag': - return this.renderBrag(block.text, block.tip, block.pro) + return this.renderBrag(block.text, block.tip) case 'images': return this.renderImages(block.files, block.caption) case 'graphic': @@ -474,11 +474,11 @@ export class LearnPanel { } } - /** Ludwig der Geißbock erzählt etwas zum Angeben, gibt einen Tipp oder Profiwissen. */ - private renderBrag(text: string, tip = false, pro = false): HTMLElement { + /** Ludwig der Geißbock erzählt etwas zum Angeben oder gibt einen Tipp. */ + private renderBrag(text: string, tip = false): HTMLElement { const box = h('aside', { class: 'learn-brag' }) box.append(h('img', { src: ludwigURL, alt: '', width: '48', height: '48' })) - const body = h('div', {}, h('p', { class: 'learn-brag-title' }, t(pro ? 'web_learn_pro' : tip ? 'web_learn_ludwig_tip' : 'web_learn_brag'))) + const body = h('div', {}, h('p', { class: 'learn-brag-title' }, t(tip ? 'web_learn_ludwig_tip' : 'web_learn_brag'))) body.append(html('div', { class: 'learn-text' }, markdownToHTML(text))) box.append(body) return box diff --git a/website/app/assets/ar-Dqb2o0I-.js b/website/app/assets/ar-DeE-RHam.js similarity index 99% rename from website/app/assets/ar-Dqb2o0I-.js rename to website/app/assets/ar-DeE-RHam.js index f77bca6b..5352e2b8 100644 --- a/website/app/assets/ar-Dqb2o0I-.js +++ b/website/app/assets/ar-DeE-RHam.js @@ -135,7 +135,6 @@ const e=`/* نصوص موجودة في نسخة الويب فقط. أما بقي "web_files_saved_fmt" = "تم الحفظ: %@"; "web_files_create" = "إنشاء"; "web_learn_ludwig_tip" = "نصيحة لودفيغ"; -"web_learn_pro" = "معرفة المحترفين مع لودفيغ"; "web_game_title" = "لعبة: صحيح أم خطأ؟"; "web_game_intro" = "يعرض لك لودفيغ قيماً وشرطاً. هل الشرط صحيح (true) أم خطأ (false)؟ عشر جولات تزداد صعوبة."; "web_game_start" = "ابدأ اللعبة"; diff --git a/website/app/assets/da-ey_ipgDe.js b/website/app/assets/da-D4INXE4p.js similarity index 99% rename from website/app/assets/da-ey_ipgDe.js rename to website/app/assets/da-D4INXE4p.js index 2713742e..635f9b95 100644 --- a/website/app/assets/da-ey_ipgDe.js +++ b/website/app/assets/da-D4INXE4p.js @@ -135,7 +135,6 @@ const e=`/* Tekster, der kun findes i webversionen. Alt andet kommer fra appens "web_files_saved_fmt" = "Gemt: %@"; "web_files_create" = "Opret"; "web_learn_ludwig_tip" = "Ludwigs tip"; -"web_learn_pro" = "Profividen med Ludwig"; "web_game_title" = "Spil: Sandt eller falsk?"; "web_game_intro" = "Ludwig viser dig værdier og en betingelse. Er betingelsen sand (true) eller falsk (false)? Ti runder, sværere og sværere."; "web_game_start" = "Start spillet"; diff --git a/website/app/assets/de-DMor0Vtb.js b/website/app/assets/de-NQF_CaEx.js similarity index 99% rename from website/app/assets/de-DMor0Vtb.js rename to website/app/assets/de-NQF_CaEx.js index c0b2b718..b06ca204 100644 --- a/website/app/assets/de-DMor0Vtb.js +++ b/website/app/assets/de-NQF_CaEx.js @@ -221,7 +221,6 @@ const e=`/* Texte, die es nur in der Web-Version gibt. Alle anderen kommen aus d "web_files_saved_fmt" = "Gespeichert: %@"; "web_files_create" = "Anlegen"; "web_learn_ludwig_tip" = "Ludwigs Tipp"; -"web_learn_pro" = "Profiwissen mit Ludwig"; "web_game_title" = "Spiel: Wahr oder falsch?"; "web_game_intro" = "Ludwig zeigt dir Werte und eine Bedingung. Ist die Bedingung wahr (true) oder falsch (false)? Zehn Runden, es wird von Runde zu Runde kniffliger."; "web_game_start" = "Spiel starten"; diff --git a/website/app/assets/el-DaQv4rR_.js b/website/app/assets/el-CtIZyj0I.js similarity index 99% rename from website/app/assets/el-DaQv4rR_.js rename to website/app/assets/el-CtIZyj0I.js index e0848569..0c996c1b 100644 --- a/website/app/assets/el-DaQv4rR_.js +++ b/website/app/assets/el-CtIZyj0I.js @@ -135,7 +135,6 @@ const e=`/* Κείμενα που υπάρχουν μόνο στην έκδοσ "web_files_saved_fmt" = "Αποθηκεύτηκε: %@"; "web_files_create" = "Δημιουργία"; "web_learn_ludwig_tip" = "Η συμβουλή του Ludwig"; -"web_learn_pro" = "Γνώσεις για επαγγελματίες με τον Ludwig"; "web_game_title" = "Παιχνίδι: Αληθές ή ψευδές;"; "web_game_intro" = "Ο Ludwig σου δείχνει τιμές και μια συνθήκη. Είναι αληθής (true) ή ψευδής (false); Δέκα γύροι, όλο και δυσκολότεροι."; "web_game_start" = "Έναρξη παιχνιδιού"; diff --git a/website/app/assets/en-CEwI5dlH.js b/website/app/assets/en-DysVTM-W.js similarity index 99% rename from website/app/assets/en-CEwI5dlH.js rename to website/app/assets/en-DysVTM-W.js index bd942593..6cbc0380 100644 --- a/website/app/assets/en-CEwI5dlH.js +++ b/website/app/assets/en-DysVTM-W.js @@ -221,7 +221,6 @@ const e=`/* Texts that exist only in the web version. Everything else comes from "web_files_saved_fmt" = "Saved: %@"; "web_files_create" = "Create"; "web_learn_ludwig_tip" = "Ludwig’s tip"; -"web_learn_pro" = "Pro knowledge with Ludwig"; "web_game_title" = "Game: True or false?"; "web_game_intro" = "Ludwig shows you values and a condition. Is the condition true or false? Ten rounds, getting trickier each time."; "web_game_start" = "Start game"; diff --git a/website/app/assets/es-BHz7jCrz.js b/website/app/assets/es-BAduFB3L.js similarity index 99% rename from website/app/assets/es-BHz7jCrz.js rename to website/app/assets/es-BAduFB3L.js index b6fa5864..b05a09bc 100644 --- a/website/app/assets/es-BHz7jCrz.js +++ b/website/app/assets/es-BAduFB3L.js @@ -135,7 +135,6 @@ const e=`/* Textos que solo existen en la versión web. Todo lo demás procede d "web_files_saved_fmt" = "Guardado: %@"; "web_files_create" = "Crear"; "web_learn_ludwig_tip" = "El consejo de Ludwig"; -"web_learn_pro" = "Saber de profesional con Ludwig"; "web_game_title" = "Juego: ¿Verdadero o falso?"; "web_game_intro" = "Ludwig te muestra valores y una condición. ¿Es verdadera (true) o falsa (false)? Diez rondas, cada vez más difíciles."; "web_game_start" = "Empezar el juego"; diff --git a/website/app/assets/flowApp-4s69NVPv.js b/website/app/assets/flowApp-Bn4c4hPI.js similarity index 99% rename from website/app/assets/flowApp-4s69NVPv.js rename to website/app/assets/flowApp-Bn4c4hPI.js index dd3c5dcc..39b49c76 100644 --- a/website/app/assets/flowApp-4s69NVPv.js +++ b/website/app/assets/flowApp-Bn4c4hPI.js @@ -1,4 +1,4 @@ -var dt=Object.defineProperty;var lt=(n,t,e)=>t in n?dt(n,t,{enumerable:!0,configurable:!0,writable:!0,value:e}):n[t]=e;var y=(n,t,e)=>lt(n,typeof t!="symbol"?t+"":t,e);import{t as h,g as ct,i as I,w as ht,n as ut,f as ft,o as G,q as pt,u as gt,v as wt,x as vt,y as mt,l as xt}from"./index-DqKA7YqL.js";const et=["start","anweisung","ein","verzweigung","unterprogramm","ende"],m=20,st={start:"#d1f2d9",ende:"#d1f2d9",anweisung:"#e5f0ff",ein:"#f2e6ff",verzweigung:"#fff4d6",unterprogramm:"#e5f0ff"},H=16,yt=170;function bt(n,t,e){const i=[];for(const s of n.split(` +var dt=Object.defineProperty;var lt=(n,t,e)=>t in n?dt(n,t,{enumerable:!0,configurable:!0,writable:!0,value:e}):n[t]=e;var y=(n,t,e)=>lt(n,typeof t!="symbol"?t+"":t,e);import{t as h,g as ct,i as I,w as ht,n as ut,f as ft,o as G,q as pt,u as gt,v as wt,x as vt,y as mt,l as xt}from"./index-CzgrZgZa.js";const et=["start","anweisung","ein","verzweigung","unterprogramm","ende"],m=20,st={start:"#d1f2d9",ende:"#d1f2d9",anweisung:"#e5f0ff",ein:"#f2e6ff",verzweigung:"#fff4d6",unterprogramm:"#e5f0ff"},H=16,yt=170;function bt(n,t,e){const i=[];for(const s of n.split(` `)){let o="";for(const r of s.split(/\s+/).filter(Boolean)){const a=o?`${o} ${r}`:r;o&&e(a)>t?(i.push(o),o=r):o=a}i.push(o)}return i.length?i:[""]}const q=n=>Math.round(n/m)*m;function C(n,t){const e=bt(n.text,yt,t),i=Math.max(0,...e.map(t)),s=e.length*H;let o,r;if(n.shape==="verzweigung")o=Math.max(140,i*1.7+30),r=Math.max(80,s*1.8+24);else{const a=n.shape==="ein"?44:n.shape==="unterprogramm"?40:n.shape==="anweisung"?24:36;o=Math.max(n.shape==="start"||n.shape==="ende"?100:120,i+a),r=Math.max(40,s+18)}return{x:n.x,y:n.y,w:Math.ceil(o/m)*m,h:Math.ceil(r/m)*m,lines:e}}function V(n){return n==="ende"?[]:n==="verzweigung"?["ja","nein"]:["out"]}const D=n=>n!=="start";function P(n,t,e){var s;if(e==="out")return"bottom";const i=((s=n.yesRight)==null?void 0:s.includes(t.id))??!1;return e==="ja"===i?"right":"bottom"}function F(n,t){return t==="bottom"?[n.x,n.y+n.h/2]:[n.x+n.w/2,n.y]}const _t=n=>[n.x,n.y-n.h/2];function $t(n,t,e,i=0){const[s,o]=F(n,t),[r,a]=_t(e),d=m,u=Math.max(n.x+n.w/2,e.x+e.w/2)+d*(1.5+i);if(t==="bottom"){if(a>=o+d){if(s===r)return[[s,o],[r,a]];const l=o+d;return[[s,o],[s,l],[r,l],[r,a]]}return[[s,o],[s,o+d],[u,o+d],[u,a-d],[r,a-d],[r,a]]}const p=e.x-e.w/2;if(p>=s+d&&Math.abs(e.y-o)=o+d){if(r>=s+d)return[[s,o],[r,o],[r,a]];const l=s+d;return[[s,o],[l,o],[l,a-d],[r,a-d],[r,a]]}const f=Math.max(s+d,u);return[[s,o],[f,o],[f,a-d],[r,a-d],[r,a]]}function nt(n=""){return{title:n,nodes:[],edges:[]}}function it(n,t){const e=new Set([...n.nodes.map(s=>s.id),...n.edges.map(s=>s.id)]);let i=1;for(;e.has(`${t}${i}`);)i++;return`${t}${i}`}function O(n,t,e,i,s){const o=it(n,"n");return{doc:{...n,nodes:[...n.nodes,{id:o,shape:t,x:q(e),y:q(i),text:s}]},id:o}}function J(n,t,e,i){return{...n,nodes:n.nodes.map(s=>s.id===t?{...s,x:Math.max(m*4,q(e)),y:Math.max(m*2,q(i))}:s)}}function Lt(n,t,e){return{...n,nodes:n.nodes.map(i=>i.id===t?{...i,text:e}:i)}}function _(n,t,e,i){const s=n.nodes.find(a=>a.id===t),o=n.nodes.find(a=>a.id===i);if(!s||!o||t===i||!V(s.shape).includes(e)||!D(o.shape))return n;const r=n.edges.filter(a=>!(a.from===t&&a.port===e));return{...n,edges:[...r,{id:it(n,"e"),from:t,port:e,to:i}]}}function Et(n,t){return V(t.shape).find(e=>!n.edges.some(i=>i.from===t.id&&i.port===e))}function kt(n,t){var e;return{...n,nodes:n.nodes.filter(i=>i.id!==t),edges:n.edges.filter(i=>i.from!==t&&i.to!==t),yesRight:(e=n.yesRight)==null?void 0:e.filter(i=>i!==t)}}function St(n,t){return{...n,edges:n.edges.filter(e=>e.id!==t)}}function ot(n,t){const e=new Set(n.yesRight??[]);return e.has(t)?e.delete(t):e.add(t),{...n,yesRight:[...e]}}function b(n){return JSON.stringify({format:"visuflow",version:1,...n},null,2)}function W(n){let t;try{t=JSON.parse(n)}catch{return}if(!t||typeof t!="object")return;const e=t;if(!Array.isArray(e.nodes)||!Array.isArray(e.edges))return;const i=[];for(const o of e.nodes)!o||typeof o.id!="string"||!et.includes(o.shape)||!Number.isFinite(o.x)||!Number.isFinite(o.y)||i.some(r=>r.id===o.id)||i.push({id:o.id,shape:o.shape,x:o.x,y:o.y,text:typeof o.text=="string"?o.text:""});let s={title:typeof e.title=="string"?e.title:"",nodes:i,edges:[]};for(const o of e.edges)!o||typeof o.from!="string"||typeof o.to!="string"||typeof o.port!="string"||(s=_(s,o.from,o.port,o.to));return Array.isArray(e.yesRight)&&(s.yesRight=e.yesRight.filter(o=>typeof o=="string"&&i.some(r=>r.id===o))),s}const z="http://www.w3.org/2000/svg",X="visuflow.doc",Mt=100,Y=14,rt=`${Y}px -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif`,T="#1c1c1e",w=n=>n.replace(/[&<>"]/g,t=>({"&":"&","<":"<",">":">",'"':"""})[t]);function At(n){try{return localStorage.getItem(n)}catch{return null}}function Z(n,t){try{localStorage.setItem(n,t)}catch{}}function It(){const n=xt(),t=n==="pt-PT"?"pt":n==="de"?"de":"en";return`${/\/app\/(index\.html)?$/.test(location.pathname)?"../":"https://visustruct.org/"}${t}/index.html`}function j(n,t,e){const i=URL.createObjectURL(new Blob([t],{type:e})),s=document.createElement("a");s.href=i,s.download=n,s.click(),setTimeout(()=>URL.revokeObjectURL(i),1e3)}function v(n,t={}){const e=document.createElementNS(z,n);for(const[i,s]of Object.entries(t))e.setAttribute(i,String(s));return e}let N;function R(n){return N===void 0&&(N=document.createElement("canvas").getContext("2d")),N?(N.font=rt,N.measureText(n).width):n.length*Y*.55}const Ct=n=>h(`web_visuflow_shape_${n}`),B=n=>h(`web_visuflow_text_${n}`);function at(n,t){const e=t.x-t.w/2,i=t.x+t.w/2,s=t.y-t.h/2,o=t.y+t.h/2;return n==="verzweigung"?v("path",{d:`M${t.x} ${s} L${i} ${t.y} L${t.x} ${o} L${e} ${t.y} Z`}):n==="ein"?v("path",{d:`M${e+14} ${s} L${i} ${s} L${i-14} ${o} L${e} ${o} Z`}):n==="unterprogramm"?v("path",{d:`M${e} ${s} H${i} V${o} H${e} Z M${e+10} ${s} V${o} M${i-10} ${s} V${o}`}):v("rect",{x:e,y:s,width:t.w,height:t.h,rx:n==="anweisung"?2:t.h/2})}function Rt(n){const t=v("text",{"text-anchor":"middle","font-size":Y,fill:T});return n.lines.forEach((e,i)=>{const s=v("tspan",{x:n.x,y:n.y+5+(i-(n.lines.length-1)/2)*H});s.textContent=e,t.append(s)}),t}function Q(n){const t=v("svg",{viewBox:"0 0 64 36",width:64,height:36,"aria-hidden":"true"}),e=at(n,{x:32,y:18,w:n==="verzweigung"?54:56,h:n==="verzweigung"?32:26});return e.setAttribute("fill",st[n]),e.setAttribute("stroke",T),e.setAttribute("stroke-width","1.5"),t.append(e),t.outerHTML}function tt(){let n=nt(h("web_visuflow_example_title"));const t=[],e=(p,f,l,c)=>{const g=O(n,p,f,l,c);n=g.doc,t.push(g.id)};e("start",240,60,B("start")),e("anweisung",240,160,h("web_visuflow_example_water")),e("anweisung",240,260,h("web_visuflow_example_bag")),e("verzweigung",240,380,h("web_visuflow_example_hot")),e("anweisung",480,380,h("web_visuflow_example_wait")),e("anweisung",240,500,h("web_visuflow_example_drink")),e("ende",240,600,B("ende"));const[i,s,o,r,a,d,u]=t;return n=_(n,i,"out",s),n=_(n,s,"out",o),n=_(n,o,"out",r),n=ot(n,r),n=_(n,r,"ja",a),n=_(n,a,"out",r),n=_(n,r,"nein",d),n=_(n,d,"out",u),n}function Tt(){return O(nt(),"start",240,60,B("start")).doc}class Pt{constructor(t){y(this,"shell");y(this,"svg");y(this,"scroller");y(this,"status");y(this,"titleInput");y(this,"doc");y(this,"selection");y(this,"history",[]);y(this,"future",[]);y(this,"editor");y(this,"dragLine");document.documentElement.classList.add("visuflow-theme"),history.replaceState(history.state,"",`${location.pathname}?visuflow${location.hash}`),this.doc=W(At(X)??"")??tt(),this.shell=document.createElement("div"),this.shell.className="shell visuflow",t.replaceWith(this.shell),this.build(),this.render(),window.addEventListener("keydown",e=>this.onKey(e))}build(){const t=(l,c,g,x=c)=>``,e=et.map(l=>``).join("");this.shell.innerHTML=`
    VisuFlow ${w(h("web_visuflow_subtitle"))} diff --git a/website/app/assets/fr-CEc9fFV7.js b/website/app/assets/fr-C_mSEvw5.js similarity index 99% rename from website/app/assets/fr-CEc9fFV7.js rename to website/app/assets/fr-C_mSEvw5.js index f5bc8d68..33ead673 100644 --- a/website/app/assets/fr-CEc9fFV7.js +++ b/website/app/assets/fr-C_mSEvw5.js @@ -135,7 +135,6 @@ const e=`/* Textes propres à la version web. Tout le reste provient des Localiz "web_files_saved_fmt" = "Enregistré : %@"; "web_files_create" = "Créer"; "web_learn_ludwig_tip" = "Le conseil de Ludwig"; -"web_learn_pro" = "Savoir de pro avec Ludwig"; "web_game_title" = "Jeu : Vrai ou faux ?"; "web_game_intro" = "Ludwig te montre des valeurs et une condition. Est-elle vraie (true) ou fausse (false) ? Dix manches, de plus en plus difficiles."; "web_game_start" = "Commencer le jeu"; diff --git a/website/app/assets/he-B1FDwOEu.js b/website/app/assets/he-BAg3LrWK.js similarity index 99% rename from website/app/assets/he-B1FDwOEu.js rename to website/app/assets/he-BAg3LrWK.js index e28b73c9..2f086eab 100644 --- a/website/app/assets/he-B1FDwOEu.js +++ b/website/app/assets/he-BAg3LrWK.js @@ -135,7 +135,6 @@ const e=`/* טקסטים שקיימים רק בגרסת הרשת. כל השאר "web_files_saved_fmt" = "נשמר: %@"; "web_files_create" = "יצירה"; "web_learn_ludwig_tip" = "הטיפ של לודוויג"; -"web_learn_pro" = "ידע של מקצוענים עם לודוויג"; "web_game_title" = "משחק: אמת או שקר?"; "web_game_intro" = "לודוויג מראה ערכים ותנאי. האם התנאי אמת (true) או שקר (false)? עשרה סבבים, כל פעם קשה יותר."; "web_game_start" = "התחלת המשחק"; diff --git a/website/app/assets/index-DqKA7YqL.js b/website/app/assets/index-CzgrZgZa.js similarity index 99% rename from website/app/assets/index-DqKA7YqL.js rename to website/app/assets/index-CzgrZgZa.js index d3e2afad..8efcae5e 100644 --- a/website/app/assets/index-DqKA7YqL.js +++ b/website/app/assets/index-CzgrZgZa.js @@ -8,7 +8,7 @@ var m2=Object.defineProperty;var c2=(i,e,t)=>e in i?m2(i,e,{enumerable:!0,config `}if(i.cases)for(const n of i.cases){t+=`${e} `;for(const a of n.elements)t+=go(a,e+" ");t+=`${e} `}return t+=`${e} -`,t}function qd(i){return i.replace(/&/g,"&").replace(/"/g,""").replace(//g,">")}function N2(i){return i.replace(/&/g,"&").replace(//g,">")}function au(i){return String(i.a<<24|i.r<<16|i.g<<8|i.b|0)}function Za(i,e){return Array.from(i.children).filter(t=>t.tagName===e)}function po(i){const e=[];for(const t of Za(i,"strelem")){const n=J2(t);n&&e.push(n)}return e}function J2(i){const e=si(i,"typ");if(e===void 0||S[e]===void 0)return;const t={type:e,zoomX:si(i,"zx")??0,zoomY:si(i,"zy")??0,textLines:Za(i,"text").map(o=>ho((o.textContent??"").trim()))},n=ru(i.getAttribute("textcolor"));n&&(t.textColor=n);const a=ru(i.getAttribute("bgcolor"));a&&(t.backgroundColor=a),t.textLines.length===0&&(t.textLines=[""]);const s=Za(i,"schleifeninhalt")[0];if(s){const o=po(s);o.length>0&&(t.loopBody=o)}const r=Za(i,"fall").map(o=>({name:ho(o.getAttribute("fallname")??""),elements:po(o)}));return r.length>0&&(t.cases=r),t}function su(i,e){const t=i.getAttribute(e);return t===null?void 0:ho(t)}function si(i,e){const t=i.getAttribute(e);if(!(t===null||!/^[+-]?\d+$/.test(t)))return Number(t)}function ru(i){if(i===null||!/^[+-]?\d+$/.test(i))return;const e=Number(i);if(e<-2147483648||e>2147483647)return;const t=e>>>0;return{a:t>>>24&255,r:t>>>16&255,g:t>>>8&255,b:t&255}}const F2="http://www.w3.org/2000/svg",We={diagramLineWidth:2,outerFrameLineWidth:2,selectionLineWidth:3.5,canvasOuterMargin:16,cellTextInsetX:18,cellTextInsetY:15,multiHeaderFirstLineY:14,branchLabelInsetX:10,fallauswahlCaseLabelBand:26,callSideBarInset:14,callTextInsetFromSideBar:20,loopBodyLeadingInset:20};function Ud(i){switch(i){case S.forSchleife:case S.whileSchleife:case S.doUntilSchleife:case S.endlosschleife:return"loop";case S.verzweigung:case S.fallauswahl:return"if";default:return}}function Se(i,e={}){const t=document.createElementNS(F2,i);for(const[n,a]of Object.entries(e))t.setAttribute(n,String(a));return t}class $d{constructor(e,t){y(this,"usesSimulationHighlight",!1);y(this,"fillsSelection",!1);this.metrics=e,this.measure=t}get lineHeight(){return this.metrics.lineHeight}get fontSize(){return this.metrics.fontSize}render(e,t,n,a=We.canvasOuterMargin){const s=Se("svg",{width:t.width,height:t.height,viewBox:`0 0 ${t.width} ${t.height}`,"font-family":Ns,"font-size":this.fontSize,class:"diagram"});s.append(Se("rect",{x:0,y:0,width:t.width,height:t.height,fill:"#fafafa"}));const r=a;s.append(Se("rect",{x:r,y:r,width:e.canvasSize.width-2*r-1,height:e.canvasSize.height-2*r-1,fill:"none",stroke:"black","stroke-width":We.outerFrameLineWidth}));const o=Se("g");for(const l of e.elements)this.drawNode(l,o,n,{},void 0,"method");return s.append(o),s}line(e,t){e.append(Se("polyline",{points:t.map(n=>n.join(",")).join(" "),fill:"none",stroke:"black","stroke-width":We.diagramLineWidth,"stroke-linejoin":"miter"}))}strokeCellBorder(e,t,n){const a=t.x,s=t.y,r=t.x+t.width,o=t.y+t.height;if(!n.top&&!n.left&&!n.bottom&&!n.right){e.append(Se("rect",{x:a,y:s,width:t.width,height:t.height,fill:"none",stroke:"black","stroke-width":We.diagramLineWidth}));return}n.top||this.line(e,[[a,s],[r,s]]),n.right||this.line(e,[[r,s],[r,o]]),n.bottom||this.line(e,[[r,o],[a,o]]),n.left||this.line(e,[[a,o],[a,s]])}textWidth(e){const t=U0(e);return t?this.measure(t.keyword,this.fontSize,"bold")+(t.rest===""?0:this.measure(" "+t.rest,this.fontSize,"medium")):this.measure(e,this.fontSize,"medium")}drawKeywordLine(e,t,n,a){const s=Se("text",{x:n,y:a+eu(this.fontSize,"medium").ascent,"font-weight":500});s.style.whiteSpace="pre";const r=U0(t);if(r){const o=Se("tspan",{"font-weight":700});if(o.textContent=r.keyword,s.append(o),r.rest!==""){const l=Se("tspan",{});l.textContent=" "+r.rest,s.append(l)}}else s.textContent=t;e.append(s)}drawLabel(e,t,n,a,s,r){const o=eu(this.fontSize,s?"bold":"medium"),l=Se("text",{x:n,y:r==="top"?a+o.ascent:a-o.descent,"font-weight":s?700:500});l.style.whiteSpace="pre",l.textContent=t,e.append(l)}roofMetrics(e,t,n,a){const s=t.y+n,r=e.dividerYInset??0,o=12,l=Math.max(e.element.textLines.length,1)*this.lineHeight,u=t.y+We.multiHeaderFirstLineY;if(e.element.type===S.fallauswahl){const c=Math.max(We.fallauswahlCaseLabelBand,this.lineHeight+10),d=s-c,h=Math.min(s+r,d-8),g=Math.max(h,u+l+6);return{apex:{x:a,y:g},maxTextBottom:d-o,roofBottom:s}}const m={x:a,y:s+r};return{apex:m,maxTextBottom:m.y-o,roofBottom:s}}drawNode(e,t,n,a,s,r){var j;const o=e.frame,l=e.element,u=o.x+o.width,m=o.y+o.height,c=l.type===S.verzweigung||l.type===S.fallauswahl,d=c?e.headerBandHeight:0,h=n!==void 0&&fo(e.idPath,n),g=Zl(l),f=Se("g",{"data-path":e.idPath.join(",")});t.append(f);const b=this.usesSimulationHighlight,x=l.backgroundColor,v=x&&x.a>0?`rgba(${x.r}, ${x.g}, ${x.b}, ${x.a/255})`:"white",w=h&&(b||this.fillsSelection)?"rgba(199, 230, 255, 0.55)":v,I=Ud(l.type)??(l.type===S.leerElement?r:"method"),z=Se("rect",{x:o.x,y:o.y,width:o.width,height:o.height,fill:w});w==="white"&&I&&z.setAttribute("class",`ns-scope ns-scope-${I}`),f.append(z),this.strokeCellBorder(f,o,a);const k=We.callSideBarInset;if(l.type===S.aufruf?(this.line(f,[[o.x+k,o.y],[o.x+k,m]]),this.line(f,[[u-k,o.y],[u-k,m]])):l.type===S.aussprung&&this.line(f,[[o.x+k,o.y],[o.x,o.y+o.height/2],[o.x+k,m]]),c&&e.dividerX!==void 0){const D=e.dividerX,O=this.roofMetrics(e,o,d,D),C=Math.max(g.length,1)*this.lineHeight,A=o.y+We.multiHeaderFirstLineY;this.line(f,[[o.x,o.y],[O.apex.x,O.apex.y],[u,o.y]]),l.type===S.fallauswahl&&this.line(f,[[o.x,O.roofBottom],[u,O.roofBottom]]);let B;A+C<=O.maxTextBottom?B=A:B=Math.max(o.y+2,O.maxTextBottom-(Math.max(g.length,1)-1)*this.lineHeight-this.lineHeight),g.forEach((E,U)=>{const ee=this.textWidth(E);let he;if(l.type===S.verzweigung){const Ie=o.x+We.cellTextInsetX,fe=u-ee-We.cellTextInsetX;he=Math.min(Math.max(D-ee/2,Ie),fe)}else he=o.x+o.width/2-ee/2;this.drawKeywordLine(f,E,he,B+U*this.lineHeight)})}else if(l.type!==S.doUntilSchleife)if(l.type===S.anweisung||l.type===S.aufruf||l.type===S.aussprung){const D=We.cellTextInsetX;let O=o.x+D,C=u-D;l.type===S.aufruf?(O=o.x+k+We.callTextInsetFromSideBar,C=u-k-We.callTextInsetFromSideBar):l.type===S.aussprung&&(O=o.x+k+D);const A=Math.max(0,C-O);let B=o.y+o.height/2-Math.max(1,g.length)*this.lineHeight/2;for(const E of g)this.drawKeywordLine(f,E,O+(A-this.textWidth(E))/2,B),B+=this.lineHeight}else{const D=Math.max(1,g.length)*this.lineHeight;let O=s===S.doUntilSchleife?o.y+o.height/2-D/2:o.y+We.cellTextInsetY;for(const C of g)this.drawKeywordLine(f,C,o.x+We.cellTextInsetX,O),O+=this.lineHeight}e.children.forEach((D,O)=>{const C=l.type===S.doUntilSchleife&&O===0?{top:!0,left:!0}:{};this.drawNode(D,t,n,C,l.type,I)});const T=Se("g");if(t.append(T),l.type===S.doUntilSchleife){const D=((j=e.children[0])==null?void 0:j.frame.x)??o.x+(e.loopBodyLeadingInset>0?e.loopBodyLeadingInset:We.loopBodyLeadingInset);this.drawLabel(T,"do",o.x+4,o.y+this.metrics.doUntilDoLabelTopInset,!0,"top");const O=m-e.headerBandHeight;this.line(T,[[D,O],[u,O]]),this.line(T,[[D,o.y],[D,O]]);let C=O+this.metrics.doUntilFooterTopInset;for(const A of g)this.drawKeywordLine(T,A,o.x+We.cellTextInsetX,C),C+=this.lineHeight}if(c&&e.dividerX!==void 0&&e.caseColumnFrames.length>1){const D=this.roofMetrics(e,o,d,e.dividerX),O=D.apex;e.caseColumnFrames.forEach((A,B)=>{if(B>=e.caseColumnFrames.length-1)return;const E=A.x+A.width,U=R2(E,o,O),ee=Number.isFinite(U)?Math.min(Math.max(U,o.y),m):o.y;this.line(T,[[E,m],[E,ee]])});const C=l.cases;if(C&&C.length===e.caseColumnFrames.length){const A=l.type===S.fallauswahl?D.roofBottom-6:o.y+d-8,B=We.branchLabelInsetX;if(l.type===S.verzweigung&&C.length===2){this.drawLabel(T,"true",o.x+B,A,!0,"bottom");const E=e.caseColumnFrames[1],U=this.measure("false",this.fontSize,"bold");this.drawLabel(T,"false",E.x+E.width-B-U,A,!0,"bottom")}else C.forEach((E,U)=>{const ee=e.caseColumnFrames[U],he=["default","true","false"].includes(E.name.toLowerCase()),Ie=this.measure(E.name,this.fontSize,he?"bold":"medium");this.drawLabel(T,E.name,ee.x+ee.width/2-Ie/2,A,he,"bottom")})}}h&&T.append(Se("rect",{x:o.x,y:o.y,width:o.width,height:o.height,class:"selection-frame",fill:"none",stroke:b?"rgba(66, 140, 242, 0.78)":"rgba(0, 122, 255, 0.9)","stroke-width":We.selectionLineWidth}))}}function R2(i,e,t){const n=e.y;if(i<=t.x){const s=t.x-e.x;return Math.abs(s)<.5?t.y:n+(t.y-n)/s*(i-e.x)}const a=e.x+e.width-t.x;return Math.abs(a)<.5?t.y:t.y+(n-t.y)/a*(i-t.x)}function fo(i,e){return i.length===e.length&&i.every((t,n)=>t===e[n])}function G2(i){const e=[],t=n=>{e.push(n),n.children.forEach(t)};return i.forEach(t),e}function Xa(i){var e,t;return{...i,textLines:Zl(i),loopBody:(e=i.loopBody)==null?void 0:e.map(Xa),cases:(t=i.cases)==null?void 0:t.map(n=>({name:n.name,elements:n.elements.map(Xa)}))}}const H2=[{code:"de",name:"Deutsch"},{code:"en",name:"English"},{code:"es",name:"Español"},{code:"fr",name:"Français"},{code:"it",name:"Italiano"},{code:"pl",name:"Polski"},{code:"tr",name:"Türkçe"},{code:"ko",name:"한국어"},{code:"ja",name:"日本語"},{code:"el",name:"Ελληνικά"},{code:"uk",name:"Українська"},{code:"ar",name:"العربية"},{code:"ru",name:"Русский"},{code:"he",name:"עברית"},{code:"nl",name:"Nederlands"},{code:"sv",name:"Svenska"},{code:"da",name:"Dansk"},{code:"nb",name:"Norsk bokmål"},{code:"zh-Hans",name:"中文(简体)"},{code:"zh-Hant",name:"中文(繁體)"},{code:"pt-PT",name:"Português"},{code:"java",name:"Java (Keywords)"}],Yd=["de","en","pt-PT"],Xd=H2.filter(i=>Yd.includes(i.code)),ou=i=>Yd.includes(i),V2=Object.assign({"../../../VisuStruct-iOS/VisuStructXcodeOpen/VisuStruct/ar.lproj/Localizable.strings":()=>K(()=>import("./Localizable-CxCno28C.js"),[],import.meta.url).then(i=>i.default),"../../../VisuStruct-iOS/VisuStructXcodeOpen/VisuStruct/da.lproj/Localizable.strings":()=>K(()=>import("./Localizable-BAutdlBb.js"),[],import.meta.url).then(i=>i.default),"../../../VisuStruct-iOS/VisuStructXcodeOpen/VisuStruct/de.lproj/Localizable.strings":()=>K(()=>import("./Localizable-Dk8F86qS.js"),[],import.meta.url).then(i=>i.default),"../../../VisuStruct-iOS/VisuStructXcodeOpen/VisuStruct/el.lproj/Localizable.strings":()=>K(()=>import("./Localizable-rqA-20hM.js"),[],import.meta.url).then(i=>i.default),"../../../VisuStruct-iOS/VisuStructXcodeOpen/VisuStruct/en.lproj/Localizable.strings":()=>K(()=>import("./Localizable-DBLIUcBd.js"),[],import.meta.url).then(i=>i.default),"../../../VisuStruct-iOS/VisuStructXcodeOpen/VisuStruct/es.lproj/Localizable.strings":()=>K(()=>import("./Localizable-LSTVB2Q5.js"),[],import.meta.url).then(i=>i.default),"../../../VisuStruct-iOS/VisuStructXcodeOpen/VisuStruct/fr.lproj/Localizable.strings":()=>K(()=>import("./Localizable-ByPZS4RL.js"),[],import.meta.url).then(i=>i.default),"../../../VisuStruct-iOS/VisuStructXcodeOpen/VisuStruct/he.lproj/Localizable.strings":()=>K(()=>import("./Localizable-R-16GCrk.js"),[],import.meta.url).then(i=>i.default),"../../../VisuStruct-iOS/VisuStructXcodeOpen/VisuStruct/it.lproj/Localizable.strings":()=>K(()=>import("./Localizable-DXAPah1g.js"),[],import.meta.url).then(i=>i.default),"../../../VisuStruct-iOS/VisuStructXcodeOpen/VisuStruct/ja.lproj/Localizable.strings":()=>K(()=>import("./Localizable-CkJEmEEP.js"),[],import.meta.url).then(i=>i.default),"../../../VisuStruct-iOS/VisuStructXcodeOpen/VisuStruct/ko.lproj/Localizable.strings":()=>K(()=>import("./Localizable-BudCXCER.js"),[],import.meta.url).then(i=>i.default),"../../../VisuStruct-iOS/VisuStructXcodeOpen/VisuStruct/nb.lproj/Localizable.strings":()=>K(()=>import("./Localizable-DSvkBkp-.js"),[],import.meta.url).then(i=>i.default),"../../../VisuStruct-iOS/VisuStructXcodeOpen/VisuStruct/nl.lproj/Localizable.strings":()=>K(()=>import("./Localizable-BJ55WGVD.js"),[],import.meta.url).then(i=>i.default),"../../../VisuStruct-iOS/VisuStructXcodeOpen/VisuStruct/pl.lproj/Localizable.strings":()=>K(()=>import("./Localizable-BYJK0mdR.js"),[],import.meta.url).then(i=>i.default),"../../../VisuStruct-iOS/VisuStructXcodeOpen/VisuStruct/pt-PT.lproj/Localizable.strings":()=>K(()=>import("./Localizable-CHv0OL9S.js"),[],import.meta.url).then(i=>i.default),"../../../VisuStruct-iOS/VisuStructXcodeOpen/VisuStruct/ru.lproj/Localizable.strings":()=>K(()=>import("./Localizable-1QZ0wfvJ.js"),[],import.meta.url).then(i=>i.default),"../../../VisuStruct-iOS/VisuStructXcodeOpen/VisuStruct/sv.lproj/Localizable.strings":()=>K(()=>import("./Localizable-M33nNbEe.js"),[],import.meta.url).then(i=>i.default),"../../../VisuStruct-iOS/VisuStructXcodeOpen/VisuStruct/tr.lproj/Localizable.strings":()=>K(()=>import("./Localizable-BM86Igqt.js"),[],import.meta.url).then(i=>i.default),"../../../VisuStruct-iOS/VisuStructXcodeOpen/VisuStruct/uk.lproj/Localizable.strings":()=>K(()=>import("./Localizable-UGog_aku.js"),[],import.meta.url).then(i=>i.default),"../../../VisuStruct-iOS/VisuStructXcodeOpen/VisuStruct/zh-Hans.lproj/Localizable.strings":()=>K(()=>import("./Localizable-CaVEL1es.js"),[],import.meta.url).then(i=>i.default),"../../../VisuStruct-iOS/VisuStructXcodeOpen/VisuStruct/zh-Hant.lproj/Localizable.strings":()=>K(()=>import("./Localizable-DqIDp_hh.js"),[],import.meta.url).then(i=>i.default)}),Kd=Object.assign({"../../../VisuStruct-iOS/VisuStructXcodeOpen/VisuStruct/Java.strings":()=>K(()=>import("./Java-Bpx1Vwvg.js"),[],import.meta.url).then(i=>i.default)}),Q2=Object.assign({"../i18n/ar.strings":()=>K(()=>import("./ar-Dqb2o0I-.js"),[],import.meta.url).then(i=>i.default),"../i18n/da.strings":()=>K(()=>import("./da-ey_ipgDe.js"),[],import.meta.url).then(i=>i.default),"../i18n/de.strings":()=>K(()=>import("./de-DMor0Vtb.js"),[],import.meta.url).then(i=>i.default),"../i18n/el.strings":()=>K(()=>import("./el-DaQv4rR_.js"),[],import.meta.url).then(i=>i.default),"../i18n/en.strings":()=>K(()=>import("./en-CEwI5dlH.js"),[],import.meta.url).then(i=>i.default),"../i18n/es.strings":()=>K(()=>import("./es-BHz7jCrz.js"),[],import.meta.url).then(i=>i.default),"../i18n/fr.strings":()=>K(()=>import("./fr-CEc9fFV7.js"),[],import.meta.url).then(i=>i.default),"../i18n/he.strings":()=>K(()=>import("./he-B1FDwOEu.js"),[],import.meta.url).then(i=>i.default),"../i18n/it.strings":()=>K(()=>import("./it-Bsr1AlWk.js"),[],import.meta.url).then(i=>i.default),"../i18n/ja.strings":()=>K(()=>import("./ja-L0a84IMq.js"),[],import.meta.url).then(i=>i.default),"../i18n/ko.strings":()=>K(()=>import("./ko-U6EDne8i.js"),[],import.meta.url).then(i=>i.default),"../i18n/nb.strings":()=>K(()=>import("./nb-C9pwk403.js"),[],import.meta.url).then(i=>i.default),"../i18n/nl.strings":()=>K(()=>import("./nl-D1JTb8Xr.js"),[],import.meta.url).then(i=>i.default),"../i18n/pl.strings":()=>K(()=>import("./pl-DchXCt_R.js"),[],import.meta.url).then(i=>i.default),"../i18n/pt-PT.strings":()=>K(()=>import("./pt-PT-Dq8KVIrs.js"),[],import.meta.url).then(i=>i.default),"../i18n/ru.strings":()=>K(()=>import("./ru-DGHs_3oc.js"),[],import.meta.url).then(i=>i.default),"../i18n/sv.strings":()=>K(()=>import("./sv-zO9ikvt0.js"),[],import.meta.url).then(i=>i.default),"../i18n/tr.strings":()=>K(()=>import("./tr-zv5TxQHQ.js"),[],import.meta.url).then(i=>i.default),"../i18n/uk.strings":()=>K(()=>import("./uk-D5KOtCBD.js"),[],import.meta.url).then(i=>i.default),"../i18n/zh-Hans.strings":()=>K(()=>import("./zh-Hans-C3na1U20.js"),[],import.meta.url).then(i=>i.default),"../i18n/zh-Hant.strings":()=>K(()=>import("./zh-Hant-BLjr78US.js"),[],import.meta.url).then(i=>i.default)});function Ba(i,e){var t;return(t=Object.entries(i).find(([n])=>n.endsWith(e)))==null?void 0:t[1]}function eh(i){const e=new Map,t=i.replace(/\/\*[\s\S]*?\*\//g,"").replace(/^\s*\/\/.*$/gm,""),n=/"((?:[^"\\]|\\.)*)"\s*=\s*"((?:[^"\\]|\\.)*)"\s*;/g,a=s=>s.replace(/\\(u[0-9a-fA-F]{4}|.)/g,(r,o)=>o==="n"?` +`,t}function qd(i){return i.replace(/&/g,"&").replace(/"/g,""").replace(//g,">")}function N2(i){return i.replace(/&/g,"&").replace(//g,">")}function au(i){return String(i.a<<24|i.r<<16|i.g<<8|i.b|0)}function Za(i,e){return Array.from(i.children).filter(t=>t.tagName===e)}function po(i){const e=[];for(const t of Za(i,"strelem")){const n=J2(t);n&&e.push(n)}return e}function J2(i){const e=si(i,"typ");if(e===void 0||S[e]===void 0)return;const t={type:e,zoomX:si(i,"zx")??0,zoomY:si(i,"zy")??0,textLines:Za(i,"text").map(o=>ho((o.textContent??"").trim()))},n=ru(i.getAttribute("textcolor"));n&&(t.textColor=n);const a=ru(i.getAttribute("bgcolor"));a&&(t.backgroundColor=a),t.textLines.length===0&&(t.textLines=[""]);const s=Za(i,"schleifeninhalt")[0];if(s){const o=po(s);o.length>0&&(t.loopBody=o)}const r=Za(i,"fall").map(o=>({name:ho(o.getAttribute("fallname")??""),elements:po(o)}));return r.length>0&&(t.cases=r),t}function su(i,e){const t=i.getAttribute(e);return t===null?void 0:ho(t)}function si(i,e){const t=i.getAttribute(e);if(!(t===null||!/^[+-]?\d+$/.test(t)))return Number(t)}function ru(i){if(i===null||!/^[+-]?\d+$/.test(i))return;const e=Number(i);if(e<-2147483648||e>2147483647)return;const t=e>>>0;return{a:t>>>24&255,r:t>>>16&255,g:t>>>8&255,b:t&255}}const F2="http://www.w3.org/2000/svg",We={diagramLineWidth:2,outerFrameLineWidth:2,selectionLineWidth:3.5,canvasOuterMargin:16,cellTextInsetX:18,cellTextInsetY:15,multiHeaderFirstLineY:14,branchLabelInsetX:10,fallauswahlCaseLabelBand:26,callSideBarInset:14,callTextInsetFromSideBar:20,loopBodyLeadingInset:20};function Ud(i){switch(i){case S.forSchleife:case S.whileSchleife:case S.doUntilSchleife:case S.endlosschleife:return"loop";case S.verzweigung:case S.fallauswahl:return"if";default:return}}function Se(i,e={}){const t=document.createElementNS(F2,i);for(const[n,a]of Object.entries(e))t.setAttribute(n,String(a));return t}class $d{constructor(e,t){y(this,"usesSimulationHighlight",!1);y(this,"fillsSelection",!1);this.metrics=e,this.measure=t}get lineHeight(){return this.metrics.lineHeight}get fontSize(){return this.metrics.fontSize}render(e,t,n,a=We.canvasOuterMargin){const s=Se("svg",{width:t.width,height:t.height,viewBox:`0 0 ${t.width} ${t.height}`,"font-family":Ns,"font-size":this.fontSize,class:"diagram"});s.append(Se("rect",{x:0,y:0,width:t.width,height:t.height,fill:"#fafafa"}));const r=a;s.append(Se("rect",{x:r,y:r,width:e.canvasSize.width-2*r-1,height:e.canvasSize.height-2*r-1,fill:"none",stroke:"black","stroke-width":We.outerFrameLineWidth}));const o=Se("g");for(const l of e.elements)this.drawNode(l,o,n,{},void 0,"method");return s.append(o),s}line(e,t){e.append(Se("polyline",{points:t.map(n=>n.join(",")).join(" "),fill:"none",stroke:"black","stroke-width":We.diagramLineWidth,"stroke-linejoin":"miter"}))}strokeCellBorder(e,t,n){const a=t.x,s=t.y,r=t.x+t.width,o=t.y+t.height;if(!n.top&&!n.left&&!n.bottom&&!n.right){e.append(Se("rect",{x:a,y:s,width:t.width,height:t.height,fill:"none",stroke:"black","stroke-width":We.diagramLineWidth}));return}n.top||this.line(e,[[a,s],[r,s]]),n.right||this.line(e,[[r,s],[r,o]]),n.bottom||this.line(e,[[r,o],[a,o]]),n.left||this.line(e,[[a,o],[a,s]])}textWidth(e){const t=U0(e);return t?this.measure(t.keyword,this.fontSize,"bold")+(t.rest===""?0:this.measure(" "+t.rest,this.fontSize,"medium")):this.measure(e,this.fontSize,"medium")}drawKeywordLine(e,t,n,a){const s=Se("text",{x:n,y:a+eu(this.fontSize,"medium").ascent,"font-weight":500});s.style.whiteSpace="pre";const r=U0(t);if(r){const o=Se("tspan",{"font-weight":700});if(o.textContent=r.keyword,s.append(o),r.rest!==""){const l=Se("tspan",{});l.textContent=" "+r.rest,s.append(l)}}else s.textContent=t;e.append(s)}drawLabel(e,t,n,a,s,r){const o=eu(this.fontSize,s?"bold":"medium"),l=Se("text",{x:n,y:r==="top"?a+o.ascent:a-o.descent,"font-weight":s?700:500});l.style.whiteSpace="pre",l.textContent=t,e.append(l)}roofMetrics(e,t,n,a){const s=t.y+n,r=e.dividerYInset??0,o=12,l=Math.max(e.element.textLines.length,1)*this.lineHeight,u=t.y+We.multiHeaderFirstLineY;if(e.element.type===S.fallauswahl){const c=Math.max(We.fallauswahlCaseLabelBand,this.lineHeight+10),d=s-c,h=Math.min(s+r,d-8),g=Math.max(h,u+l+6);return{apex:{x:a,y:g},maxTextBottom:d-o,roofBottom:s}}const m={x:a,y:s+r};return{apex:m,maxTextBottom:m.y-o,roofBottom:s}}drawNode(e,t,n,a,s,r){var j;const o=e.frame,l=e.element,u=o.x+o.width,m=o.y+o.height,c=l.type===S.verzweigung||l.type===S.fallauswahl,d=c?e.headerBandHeight:0,h=n!==void 0&&fo(e.idPath,n),g=Zl(l),f=Se("g",{"data-path":e.idPath.join(",")});t.append(f);const b=this.usesSimulationHighlight,x=l.backgroundColor,v=x&&x.a>0?`rgba(${x.r}, ${x.g}, ${x.b}, ${x.a/255})`:"white",w=h&&(b||this.fillsSelection)?"rgba(199, 230, 255, 0.55)":v,I=Ud(l.type)??(l.type===S.leerElement?r:"method"),z=Se("rect",{x:o.x,y:o.y,width:o.width,height:o.height,fill:w});w==="white"&&I&&z.setAttribute("class",`ns-scope ns-scope-${I}`),f.append(z),this.strokeCellBorder(f,o,a);const k=We.callSideBarInset;if(l.type===S.aufruf?(this.line(f,[[o.x+k,o.y],[o.x+k,m]]),this.line(f,[[u-k,o.y],[u-k,m]])):l.type===S.aussprung&&this.line(f,[[o.x+k,o.y],[o.x,o.y+o.height/2],[o.x+k,m]]),c&&e.dividerX!==void 0){const D=e.dividerX,O=this.roofMetrics(e,o,d,D),C=Math.max(g.length,1)*this.lineHeight,A=o.y+We.multiHeaderFirstLineY;this.line(f,[[o.x,o.y],[O.apex.x,O.apex.y],[u,o.y]]),l.type===S.fallauswahl&&this.line(f,[[o.x,O.roofBottom],[u,O.roofBottom]]);let B;A+C<=O.maxTextBottom?B=A:B=Math.max(o.y+2,O.maxTextBottom-(Math.max(g.length,1)-1)*this.lineHeight-this.lineHeight),g.forEach((E,U)=>{const ee=this.textWidth(E);let he;if(l.type===S.verzweigung){const Ie=o.x+We.cellTextInsetX,fe=u-ee-We.cellTextInsetX;he=Math.min(Math.max(D-ee/2,Ie),fe)}else he=o.x+o.width/2-ee/2;this.drawKeywordLine(f,E,he,B+U*this.lineHeight)})}else if(l.type!==S.doUntilSchleife)if(l.type===S.anweisung||l.type===S.aufruf||l.type===S.aussprung){const D=We.cellTextInsetX;let O=o.x+D,C=u-D;l.type===S.aufruf?(O=o.x+k+We.callTextInsetFromSideBar,C=u-k-We.callTextInsetFromSideBar):l.type===S.aussprung&&(O=o.x+k+D);const A=Math.max(0,C-O);let B=o.y+o.height/2-Math.max(1,g.length)*this.lineHeight/2;for(const E of g)this.drawKeywordLine(f,E,O+(A-this.textWidth(E))/2,B),B+=this.lineHeight}else{const D=Math.max(1,g.length)*this.lineHeight;let O=s===S.doUntilSchleife?o.y+o.height/2-D/2:o.y+We.cellTextInsetY;for(const C of g)this.drawKeywordLine(f,C,o.x+We.cellTextInsetX,O),O+=this.lineHeight}e.children.forEach((D,O)=>{const C=l.type===S.doUntilSchleife&&O===0?{top:!0,left:!0}:{};this.drawNode(D,t,n,C,l.type,I)});const T=Se("g");if(t.append(T),l.type===S.doUntilSchleife){const D=((j=e.children[0])==null?void 0:j.frame.x)??o.x+(e.loopBodyLeadingInset>0?e.loopBodyLeadingInset:We.loopBodyLeadingInset);this.drawLabel(T,"do",o.x+4,o.y+this.metrics.doUntilDoLabelTopInset,!0,"top");const O=m-e.headerBandHeight;this.line(T,[[D,O],[u,O]]),this.line(T,[[D,o.y],[D,O]]);let C=O+this.metrics.doUntilFooterTopInset;for(const A of g)this.drawKeywordLine(T,A,o.x+We.cellTextInsetX,C),C+=this.lineHeight}if(c&&e.dividerX!==void 0&&e.caseColumnFrames.length>1){const D=this.roofMetrics(e,o,d,e.dividerX),O=D.apex;e.caseColumnFrames.forEach((A,B)=>{if(B>=e.caseColumnFrames.length-1)return;const E=A.x+A.width,U=R2(E,o,O),ee=Number.isFinite(U)?Math.min(Math.max(U,o.y),m):o.y;this.line(T,[[E,m],[E,ee]])});const C=l.cases;if(C&&C.length===e.caseColumnFrames.length){const A=l.type===S.fallauswahl?D.roofBottom-6:o.y+d-8,B=We.branchLabelInsetX;if(l.type===S.verzweigung&&C.length===2){this.drawLabel(T,"true",o.x+B,A,!0,"bottom");const E=e.caseColumnFrames[1],U=this.measure("false",this.fontSize,"bold");this.drawLabel(T,"false",E.x+E.width-B-U,A,!0,"bottom")}else C.forEach((E,U)=>{const ee=e.caseColumnFrames[U],he=["default","true","false"].includes(E.name.toLowerCase()),Ie=this.measure(E.name,this.fontSize,he?"bold":"medium");this.drawLabel(T,E.name,ee.x+ee.width/2-Ie/2,A,he,"bottom")})}}h&&T.append(Se("rect",{x:o.x,y:o.y,width:o.width,height:o.height,class:"selection-frame",fill:"none",stroke:b?"rgba(66, 140, 242, 0.78)":"rgba(0, 122, 255, 0.9)","stroke-width":We.selectionLineWidth}))}}function R2(i,e,t){const n=e.y;if(i<=t.x){const s=t.x-e.x;return Math.abs(s)<.5?t.y:n+(t.y-n)/s*(i-e.x)}const a=e.x+e.width-t.x;return Math.abs(a)<.5?t.y:t.y+(n-t.y)/a*(i-t.x)}function fo(i,e){return i.length===e.length&&i.every((t,n)=>t===e[n])}function G2(i){const e=[],t=n=>{e.push(n),n.children.forEach(t)};return i.forEach(t),e}function Xa(i){var e,t;return{...i,textLines:Zl(i),loopBody:(e=i.loopBody)==null?void 0:e.map(Xa),cases:(t=i.cases)==null?void 0:t.map(n=>({name:n.name,elements:n.elements.map(Xa)}))}}const H2=[{code:"de",name:"Deutsch"},{code:"en",name:"English"},{code:"es",name:"Español"},{code:"fr",name:"Français"},{code:"it",name:"Italiano"},{code:"pl",name:"Polski"},{code:"tr",name:"Türkçe"},{code:"ko",name:"한국어"},{code:"ja",name:"日本語"},{code:"el",name:"Ελληνικά"},{code:"uk",name:"Українська"},{code:"ar",name:"العربية"},{code:"ru",name:"Русский"},{code:"he",name:"עברית"},{code:"nl",name:"Nederlands"},{code:"sv",name:"Svenska"},{code:"da",name:"Dansk"},{code:"nb",name:"Norsk bokmål"},{code:"zh-Hans",name:"中文(简体)"},{code:"zh-Hant",name:"中文(繁體)"},{code:"pt-PT",name:"Português"},{code:"java",name:"Java (Keywords)"}],Yd=["de","en","pt-PT"],Xd=H2.filter(i=>Yd.includes(i.code)),ou=i=>Yd.includes(i),V2=Object.assign({"../../../VisuStruct-iOS/VisuStructXcodeOpen/VisuStruct/ar.lproj/Localizable.strings":()=>K(()=>import("./Localizable-CxCno28C.js"),[],import.meta.url).then(i=>i.default),"../../../VisuStruct-iOS/VisuStructXcodeOpen/VisuStruct/da.lproj/Localizable.strings":()=>K(()=>import("./Localizable-BAutdlBb.js"),[],import.meta.url).then(i=>i.default),"../../../VisuStruct-iOS/VisuStructXcodeOpen/VisuStruct/de.lproj/Localizable.strings":()=>K(()=>import("./Localizable-Dk8F86qS.js"),[],import.meta.url).then(i=>i.default),"../../../VisuStruct-iOS/VisuStructXcodeOpen/VisuStruct/el.lproj/Localizable.strings":()=>K(()=>import("./Localizable-rqA-20hM.js"),[],import.meta.url).then(i=>i.default),"../../../VisuStruct-iOS/VisuStructXcodeOpen/VisuStruct/en.lproj/Localizable.strings":()=>K(()=>import("./Localizable-DBLIUcBd.js"),[],import.meta.url).then(i=>i.default),"../../../VisuStruct-iOS/VisuStructXcodeOpen/VisuStruct/es.lproj/Localizable.strings":()=>K(()=>import("./Localizable-LSTVB2Q5.js"),[],import.meta.url).then(i=>i.default),"../../../VisuStruct-iOS/VisuStructXcodeOpen/VisuStruct/fr.lproj/Localizable.strings":()=>K(()=>import("./Localizable-ByPZS4RL.js"),[],import.meta.url).then(i=>i.default),"../../../VisuStruct-iOS/VisuStructXcodeOpen/VisuStruct/he.lproj/Localizable.strings":()=>K(()=>import("./Localizable-R-16GCrk.js"),[],import.meta.url).then(i=>i.default),"../../../VisuStruct-iOS/VisuStructXcodeOpen/VisuStruct/it.lproj/Localizable.strings":()=>K(()=>import("./Localizable-DXAPah1g.js"),[],import.meta.url).then(i=>i.default),"../../../VisuStruct-iOS/VisuStructXcodeOpen/VisuStruct/ja.lproj/Localizable.strings":()=>K(()=>import("./Localizable-CkJEmEEP.js"),[],import.meta.url).then(i=>i.default),"../../../VisuStruct-iOS/VisuStructXcodeOpen/VisuStruct/ko.lproj/Localizable.strings":()=>K(()=>import("./Localizable-BudCXCER.js"),[],import.meta.url).then(i=>i.default),"../../../VisuStruct-iOS/VisuStructXcodeOpen/VisuStruct/nb.lproj/Localizable.strings":()=>K(()=>import("./Localizable-DSvkBkp-.js"),[],import.meta.url).then(i=>i.default),"../../../VisuStruct-iOS/VisuStructXcodeOpen/VisuStruct/nl.lproj/Localizable.strings":()=>K(()=>import("./Localizable-BJ55WGVD.js"),[],import.meta.url).then(i=>i.default),"../../../VisuStruct-iOS/VisuStructXcodeOpen/VisuStruct/pl.lproj/Localizable.strings":()=>K(()=>import("./Localizable-BYJK0mdR.js"),[],import.meta.url).then(i=>i.default),"../../../VisuStruct-iOS/VisuStructXcodeOpen/VisuStruct/pt-PT.lproj/Localizable.strings":()=>K(()=>import("./Localizable-CHv0OL9S.js"),[],import.meta.url).then(i=>i.default),"../../../VisuStruct-iOS/VisuStructXcodeOpen/VisuStruct/ru.lproj/Localizable.strings":()=>K(()=>import("./Localizable-1QZ0wfvJ.js"),[],import.meta.url).then(i=>i.default),"../../../VisuStruct-iOS/VisuStructXcodeOpen/VisuStruct/sv.lproj/Localizable.strings":()=>K(()=>import("./Localizable-M33nNbEe.js"),[],import.meta.url).then(i=>i.default),"../../../VisuStruct-iOS/VisuStructXcodeOpen/VisuStruct/tr.lproj/Localizable.strings":()=>K(()=>import("./Localizable-BM86Igqt.js"),[],import.meta.url).then(i=>i.default),"../../../VisuStruct-iOS/VisuStructXcodeOpen/VisuStruct/uk.lproj/Localizable.strings":()=>K(()=>import("./Localizable-UGog_aku.js"),[],import.meta.url).then(i=>i.default),"../../../VisuStruct-iOS/VisuStructXcodeOpen/VisuStruct/zh-Hans.lproj/Localizable.strings":()=>K(()=>import("./Localizable-CaVEL1es.js"),[],import.meta.url).then(i=>i.default),"../../../VisuStruct-iOS/VisuStructXcodeOpen/VisuStruct/zh-Hant.lproj/Localizable.strings":()=>K(()=>import("./Localizable-DqIDp_hh.js"),[],import.meta.url).then(i=>i.default)}),Kd=Object.assign({"../../../VisuStruct-iOS/VisuStructXcodeOpen/VisuStruct/Java.strings":()=>K(()=>import("./Java-Bpx1Vwvg.js"),[],import.meta.url).then(i=>i.default)}),Q2=Object.assign({"../i18n/ar.strings":()=>K(()=>import("./ar-DeE-RHam.js"),[],import.meta.url).then(i=>i.default),"../i18n/da.strings":()=>K(()=>import("./da-D4INXE4p.js"),[],import.meta.url).then(i=>i.default),"../i18n/de.strings":()=>K(()=>import("./de-NQF_CaEx.js"),[],import.meta.url).then(i=>i.default),"../i18n/el.strings":()=>K(()=>import("./el-CtIZyj0I.js"),[],import.meta.url).then(i=>i.default),"../i18n/en.strings":()=>K(()=>import("./en-DysVTM-W.js"),[],import.meta.url).then(i=>i.default),"../i18n/es.strings":()=>K(()=>import("./es-BAduFB3L.js"),[],import.meta.url).then(i=>i.default),"../i18n/fr.strings":()=>K(()=>import("./fr-C_mSEvw5.js"),[],import.meta.url).then(i=>i.default),"../i18n/he.strings":()=>K(()=>import("./he-BAg3LrWK.js"),[],import.meta.url).then(i=>i.default),"../i18n/it.strings":()=>K(()=>import("./it-ClGS2uQV.js"),[],import.meta.url).then(i=>i.default),"../i18n/ja.strings":()=>K(()=>import("./ja-JQ8MwNFB.js"),[],import.meta.url).then(i=>i.default),"../i18n/ko.strings":()=>K(()=>import("./ko-tfdKG8Fb.js"),[],import.meta.url).then(i=>i.default),"../i18n/nb.strings":()=>K(()=>import("./nb-BpibUAkX.js"),[],import.meta.url).then(i=>i.default),"../i18n/nl.strings":()=>K(()=>import("./nl-HArZjiga.js"),[],import.meta.url).then(i=>i.default),"../i18n/pl.strings":()=>K(()=>import("./pl-C3HmQqUD.js"),[],import.meta.url).then(i=>i.default),"../i18n/pt-PT.strings":()=>K(()=>import("./pt-PT-2W9Vff48.js"),[],import.meta.url).then(i=>i.default),"../i18n/ru.strings":()=>K(()=>import("./ru-B4vTuE57.js"),[],import.meta.url).then(i=>i.default),"../i18n/sv.strings":()=>K(()=>import("./sv-Dau75zUV.js"),[],import.meta.url).then(i=>i.default),"../i18n/tr.strings":()=>K(()=>import("./tr-DrZsTe-O.js"),[],import.meta.url).then(i=>i.default),"../i18n/uk.strings":()=>K(()=>import("./uk-DQrOpK2W.js"),[],import.meta.url).then(i=>i.default),"../i18n/zh-Hans.strings":()=>K(()=>import("./zh-Hans-CeIYjS3N.js"),[],import.meta.url).then(i=>i.default),"../i18n/zh-Hant.strings":()=>K(()=>import("./zh-Hant-7-ScZHAu.js"),[],import.meta.url).then(i=>i.default)});function Ba(i,e){var t;return(t=Object.entries(i).find(([n])=>n.endsWith(e)))==null?void 0:t[1]}function eh(i){const e=new Map,t=i.replace(/\/\*[\s\S]*?\*\//g,"").replace(/^\s*\/\/.*$/gm,""),n=/"((?:[^"\\]|\\.)*)"\s*=\s*"((?:[^"\\]|\\.)*)"\s*;/g,a=s=>s.replace(/\\(u[0-9a-fA-F]{4}|.)/g,(r,o)=>o==="n"?` `:o==="t"?" ":o.startsWith("u")&&o.length===5?String.fromCharCode(parseInt(o.slice(1),16)):o);for(const s of t.matchAll(n))e.set(a(s[1]),a(s[2]));return e}async function bo(i){const e=i==="java"?Ba(Kd,"/Java.strings"):Ba(V2,`/${i}.lproj/Localizable.strings`),t=Ba(Q2,`/${i}.strings`),n=new Map;for(const a of[e,t])if(a)for(const[s,r]of eh(await a()))n.set(s,r);return n}let th="en",nh=new Map,Xn=new Map;const Ka="appLanguageCode",Jl="visustruct.keywords";let xo=new Map,Fl=!1;const q2=i=>i.startsWith("element_")||i.startsWith("canvas_stub_");function U2(){try{const i=new URLSearchParams(location.search).get("lang")==="java"||localStorage.getItem(Ka)==="java";return i&&(localStorage.setItem(Ka,"en"),localStorage.setItem(Jl,"1")),i}catch{return!1}}function $2(){try{return localStorage.getItem(Jl)==="1"}catch{return!1}}async function ih(i,e=!0){if(i&&xo.size===0){Xn.size===0&&(Xn=await bo("en"));const t=Ba(Kd,"/Java.strings");if(t)for(const[n,a]of eh(await t()))q2(n)&&a!==Xn.get(n)&&xo.set(n,a)}if(Fl=i,e)try{localStorage.setItem(Jl,i?"1":"0")}catch{}}function Y2(){return Fl}function X2(){if(U2())return"en";const i=new URLSearchParams(location.search).get("lang");if(i&&ou(i))return i;try{const e=localStorage.getItem(Ka);if(e&&ou(e))return e}catch{}for(const e of navigator.languages??[navigator.language]){const t=e.toLowerCase();if(t.startsWith("pt"))return"pt-PT";const n=Xd.find(a=>a.code===t.split("-")[0]);if(n)return n.code}return"en"}async function ah(i,e=!0){if(Xn.size===0&&(Xn=await bo("en")),nh=i==="en"?Xn:await bo(i),th=i,e)try{localStorage.setItem(Ka,i)}catch{}const t=document.documentElement;t.lang=i==="java"?"en":i,t.dir=i==="ar"||i==="he"?"rtl":"ltr"}function s1(){return th}function p(i,...e){const t=(Fl?xo.get(i):void 0)??nh.get(i)??Xn.get(i)??i;if(e.length===0)return t;let n=0;return t.replace(/%(?:(\d+)\$)?[@d]/g,(a,s)=>String(e[s?Number(s)-1:n++]??""))}const es=243,K2=244,sh=40,pr=4,e3=1;function Rl(i){const e=i.length,t=es+(e&255)+(e>>8)&255,n=i.reduce((a,s)=>a+s,0)&255;return Uint8Array.from([es,t,e&255,e>>8,...i,n,K2])}function t3(i,e,t){const n=Array.from(new TextEncoder().encode(i));return Rl([sh,e,t&255,t>>8&255,n.length&255,n.length>>8,...n])}function n3(i){if(i[0]!==sh||i.length<6)return;const e=new TextDecoder().decode(Uint8Array.from(i.slice(6))),t=/"ret"\s*:\s*([^}]*)\}/.exec(e);return t?{idx:i[2]|i[3]<<8,value:a3(t[1].trim())}:void 0}function i3(i){const e=[];for(;;){const t=i.indexOf(es);if(t<0){i.length=0;break}if(i.splice(0,t),i.length<4)break;const n=i[2]|i[3]<<8;if(i[1]!==(es+i[2]+i[3]&255)||n>4096){i.splice(0,1);continue}if(i.length")){const s=t.at(-1);s&&(s.explanation=((s.explanation?s.explanation+" ":"")+a.slice(1).trim()).trim())}}for(const n of t){if(n.pairs){const a=new Set(n.pairs.map(s=>s.right));if(n.options.length>0||n.pairs.length<2||a.size!==n.pairs.length)throw new ne(`${e}: Zuordnung „${n.question}“ braucht mindestens zwei Paare mit verschiedenen rechten Seiten und keine Antworten.`);continue}if(n.options.length<2||!n.options.some(a=>a.correct))throw new ne(`${e}: Quizfrage „${n.question}“ braucht mindestens zwei Antworten, davon eine richtige.`)}return t}function Xh(i,e){const t=[],n=i.split(` `);let a=[];const s=()=>{const r=a.join(` `).trim();r&&t.push({kind:"markdown",text:r}),a=[]};for(let r=0;r=n.length)throw new ne(`${e}: Block „::: ${o[1]}“ wird nicht mit „:::“ geschlossen.`);const m=o[1].toLowerCase(),c=o[2].trim();switch(m){case"diagramm":if(!c)throw new ne(`${e}: „::: diagramm“ braucht einen Dateinamen.`);t.push({kind:"diagram",file:c,caption:l.join(" ").trim()});break;case"übung":case"uebung":if(!c)throw new ne(`${e}: „::: übung“ braucht eine Kennung.`);t.push({kind:"exercise",exercise:jM(c,l,e)});break;case"checkliste":t.push({kind:"checklist",items:l.map(d=>d.trim()).filter(d=>d.startsWith("- ")).map(d=>PM(d.slice(2).trim()))});break;case"kompetenzen":t.push({kind:"competences",items:l.map(d=>d.trim()).filter(d=>d.startsWith("- ")).map(d=>d.slice(2).trim())});break;case"quiz":t.push({kind:"quiz",questions:AM(l,e)});break;case"bild":if(!c)throw new ne(`${e}: „::: bild“ braucht einen Dateinamen.`);t.push({kind:"images",files:c.split(/\s+/),caption:l.join(" ").trim()});break;case"grafik":if(!c)throw new ne(`${e}: „::: grafik“ braucht einen Dateinamen.`);{const[d,h]=c.split(/\s+/);t.push({kind:"graphic",file:d,...h?{labeled:h}:{},caption:l.join(" ").trim()})}break;case"angeberwissen":t.push({kind:"brag",text:l.join(` -`).trim()});break;case"spiel":try{if(rM(c))t.push({kind:"roundGame",game:oM(c,l,e)});else if(c==="prinzessin")t.push({kind:"rescueGame",game:dM(l,e)});else{if(c)throw new ne(`${e}: Unbekanntes Spiel „${c}“ (zuhoerer, vertrag, layout, bombe, frage, reihenfolge oder prinzessin).`);t.push({kind:"game",game:rx(l,e)})}}catch(d){throw new ne(d.message)}break;case"lückentext":case"lueckentext":try{t.push({kind:"cloze",cloze:gM(l,e)})}catch(d){throw new ne(d.message)}break;case"pap":try{t.push({kind:"pap",pap:xM(l,e)})}catch(d){throw new ne(d.message)}break;case"profiwissen":t.push({kind:"brag",text:l.join(` -`).trim(),pro:!0});break;case"ludwig":t.push({kind:"brag",text:l.join(` +`).trim()});break;case"spiel":try{if(rM(c))t.push({kind:"roundGame",game:oM(c,l,e)});else if(c==="prinzessin")t.push({kind:"rescueGame",game:dM(l,e)});else{if(c)throw new ne(`${e}: Unbekanntes Spiel „${c}“ (zuhoerer, vertrag, layout, bombe, frage, reihenfolge oder prinzessin).`);t.push({kind:"game",game:rx(l,e)})}}catch(d){throw new ne(d.message)}break;case"lückentext":case"lueckentext":try{t.push({kind:"cloze",cloze:gM(l,e)})}catch(d){throw new ne(d.message)}break;case"pap":try{t.push({kind:"pap",pap:xM(l,e)})}catch(d){throw new ne(d.message)}break;case"ludwig":t.push({kind:"brag",text:l.join(` `).trim(),tip:!0});break;case"caesar":{const d=c?Number(c):3;if(!Number.isInteger(d)||d<0||d>25)throw new ne(`${e}: „::: caesar“ braucht einen Schlüssel von 0 bis 25.`);t.push({kind:"caesar",key:d,text:l.join(" ").trim()});break}case"mbot2":{const d={kind:"robotModel",focus:[]};for(const h of l.filter(g=>g.trim())){const g=/^\s*(fokus|focus|ansicht|view|drehen|spin):\s*(.*)$/i.exec(h);if(!g)throw new ne(`${e}: „::: mbot2“ kennt nur Zeilen „fokus:“, „ansicht:“ und „drehen:“.`);const f=g[1].toLowerCase();f==="fokus"||f==="focus"?d.focus=Fu(g[2],e):f==="ansicht"||f==="view"?d.view=g[2].trim().toLowerCase():d.spin=/^(ja|yes|true|sim)$/i.test(g[2].trim())}t.push(d);break}case"mbot2quiz":{const d={kind:"robotQuiz",tasks:[]};for(const h of l.filter(g=>g.trim())){const g=/^\s*-\s*(\w+)\s*:\s*(.+)$/.exec(h),f=/^\s*(fertig|done):\s*(.+)$/i.exec(h);if(g)d.tasks.push({part:Fu(g[1],e)[0],question:g[2].trim()});else if(f)d.done=f[2].trim();else throw new ne(`${e}: „::: mbot2quiz“ braucht Zeilen „- teil: Frage“ und optional „fertig: Text“.`)}if(!d.tasks.length)throw new ne(`${e}: „::: mbot2quiz“ hat keine Fragen.`);t.push(d);break}case"datei":{if(!/^[\w.-]+\.(txt|csv|json)$/u.test(c))throw new ne(`${e}: „::: datei“ braucht einen Dateinamen wie brief.txt, liste.csv oder daten.json.`);for(;l.length&&l[0].trim()==="";)l.shift();for(;l.length&&l[l.length-1].trim()==="";)l.pop();t.push({kind:"textFile",name:c,content:l.join(` `)});break}default:throw new ne(`${e}: Unbekannter Block „::: ${o[1]}“.`)}r=u}return s(),t}function PM(i){const e=/^(.*?)\s+→\s+(.+)$/.exec(i);return e?{text:e[1],ref:e[2].trim()}:{text:i}}function CM(i,e){const t=new Map(i.map((a,s)=>[a.title.toLowerCase(),s]));for(const a of i.flatMap(s=>s.blocks))if(a.kind==="checklist"){for(const s of a.items)if(s.ref!==void 0&&(s.step=t.get(s.ref.toLowerCase()),s.step===void 0))throw new ne(`${e}: Checkliste verweist auf unbekannten Schritt „${s.ref}“.`)}const n=new Set(i.flatMap(a=>a.blocks).flatMap(a=>a.kind==="checklist"?a.items.map(s=>s.step):[]));for(const a of i.flatMap(s=>s.blocks))if(a.kind==="quiz"){for(const s of a.questions)if(s.ref!==void 0){if(s.step=t.get(s.ref.toLowerCase()),s.step===void 0)throw new ne(`${e}: Quizfrage „${s.question}“ verweist auf unbekannten Schritt „${s.ref}“.`);if(!n.has(s.step))throw new ne(`${e}: Zu „${s.ref}“ (Quizfrage „${s.question}“) gibt es keinen Checklistenpunkt.`)}}}function OM(i,e){var c;const{meta:t,body:n}=$h(i,e),a=e.replace(/^.*\//,"").replace(/\.md$/,""),s=Number((c=/^(\d+)/.exec(a))==null?void 0:c[1]);if(!Number.isFinite(s))throw new ne(`${e}: Dateiname muss mit der Nummer beginnen (z. B. 01-…).`);const r=[];let o=[],l;const u=()=>{l&&r.push({title:l.title,blocks:Xh(l.lines.join(` `),e)})};for(const d of n.split(` @@ -64285,7 +64284,7 @@ ${l}`)}Na=aM(((o=e.find(([l])=>l==="begriffe.md"))==null?void 0:o[1])??"")}const

    ${Me(p("simulation_trace"))}

    ${Me(p("simulation_variables"))}

    ${Me(p("simulation_output"))}

    - `;const e=a=>this.element.querySelector(a);this.buttons={play:e("[data-sim=play]"),pause:e("[data-sim=pause]"),step:e("[data-sim=step]"),stop:e("[data-sim=stop]")},this.buttons.play.addEventListener("click",()=>this.play()),this.buttons.pause.addEventListener("click",()=>this.pause()),this.buttons.step.addEventListener("click",()=>this.step()),this.buttons.stop.addEventListener("click",()=>this.reset()),this.editButton=e(".sim-edit"),this.editButton.addEventListener("click",()=>this.onEdit());const t=e("[data-sim=highlight]");t.value=this.highlightMode,t.addEventListener("change",()=>{this.highlightMode=t.value,Ku(Xu,this.highlightMode)});const n=e("[data-sim=delay]");n.value=this.delay,n.addEventListener("change",()=>{this.delay=n.value,Ku(Ir,this.delay)}),this.inputSection=e(".sim-input > div"),this.trace=e(".sim-trace"),this.variables=e(".sim-vars"),this.output=e(".sim-output"),this.notice=e(".sim-notice")}collectOutput(){const e=this.engine.state.outputLines;for(;this.printedr.localeCompare(o));if(n.length===0)this.variables.innerHTML=`

    ${Me(p("simulation_variables_placeholder"))}

    `;else{const r=document.createElement("table");for(const o of n){const l=r.insertRow();l.insertCell().textContent=o;const u=e.variables.get(o),m=l.insertCell();u.kind==="grid"?m.append(sg(u)):m.textContent=_e(u)}this.variables.replaceChildren(r)}e.outputLines.length===0&&e.files.size===0?this.output.innerHTML=`

    ${Me(p("simulation_output_placeholder"))}

    `:(this.output.replaceChildren(...e.outputLines.map(r=>{const o=document.createElement("div");return o.textContent=r,o}),...ag(e.files)),this.output.scrollTop=this.output.scrollHeight)}updateInput(){const e=this.engine.state.inputRequest,t=this.inputSection;if(t.parentElement.classList.toggle("active",!!e),!e){t.innerHTML=`

    ${Me(p("simulation_input_placeholder"))}

    `;return}let n=t.querySelector("form");if(!n){n=document.createElement("form"),n.innerHTML=`

    `;const l=n.querySelector("input");n.addEventListener("submit",u=>{u.preventDefault(),this.submitInput(l)}),t.replaceChildren(n),requestAnimationFrame(()=>l.focus())}const a=this.engine.state.outputLines;n.querySelector(".sim-prompt").textContent=e.prompt||(a[a.length-1]??"");const s=n.querySelector("input");s.inputMode=e.valueType==="string"||e.valueType==="boolean"?"text":"decimal";const r=this.engine.state.inputErrorNotice,o=n.querySelector(".sim-input-error");o.textContent=r?t1(r):"",o.hidden=!r}}function sg(i){const e=document.createElement("table");e.className="sim-grid";for(const t of i.value){const n=e.insertRow();for(const a of t){const s=n.insertCell();s.textContent=String(a),a===!0&&(s.className="sim-grid-true")}}return e}const x1=Array.from("ABCDEFGHIJKLMNOPQRSTUVWXYZ"),Gn=360/x1.length,UM="http://www.w3.org/2000/svg";function Fe(i,e={},...t){const n=document.createElement(i);for(const[a,s]of Object.entries(e))n.setAttribute(a,s);return n.append(...t),n}function xt(i,e={},t){const n=document.createElementNS(UM,i);for(const[a,s]of Object.entries(e))n.setAttribute(a,String(s));return t!==void 0&&(n.textContent=t),n}function $M(i,e){const t=(e%26+26)%26;return Array.from(i).map(n=>{const a=n.charCodeAt(0);return a>=65&&a<=90?String.fromCharCode((a-65+t)%26+65):a>=97&&a<=122?String.fromCharCode((a-97+t)%26+97):n}).join("")}function em(i,e){const t=xt("g",{class:e}),n=x1.map((a,s)=>{const r=xt("g",{transform:`rotate(${s*Gn})`});return r.append(xt("text",{x:0,y:-i,"text-anchor":"middle","dominant-baseline":"central"},a)),t.append(r),r});return{group:t,cells:n}}function YM(i,e){let t=i,n=!1,a=-t*Gn;const s=Fe("section",{class:"learn-game learn-caesar"});s.append(Fe("div",{class:"learn-game-head"},Fe("strong",{},p("web_learn_caesar_title")))),s.append(Fe("p",{class:"learn-game-status"},p("web_learn_caesar_hint")));const r=xt("svg",{viewBox:"-200 -200 400 400",class:"learn-caesar-disc",role:"img"});r.append(xt("circle",{r:196,class:"outer-disc"})),r.append(xt("path",{d:XM(196,92,Gn/2),class:"window"}));const o=em(168,"outer-letters");r.append(o.group);for(let A=0;A{o.cells.forEach((B,E)=>B.classList.toggle("marked",E===A)),u.cells.forEach((B,E)=>B.classList.toggle("marked",A!==void 0&&E===(A+t)%26))},T=()=>{m.textContent=String(t),l.setAttribute("transform",`rotate(${a})`),r.setAttribute("aria-label",p("web_learn_caesar_key_fmt",t)),x.textContent=p(n?"web_learn_caesar_secret":"web_learn_caesar_plain"),w.textContent=p(n?"web_learn_caesar_plain":"web_learn_caesar_secret"),f.classList.toggle("active",!n),b.classList.toggle("active",n),I.textContent=$M(v.value,n?-t:t)||" ";const A=Array.from(v.value.toUpperCase()).reverse().find(E=>x1.includes(E));if(A===void 0)return k();const B=x1.indexOf(A);k(n?(B-t+26)%26:B)},j=A=>{t=(A%26+26)%26,a=-t*Gn,T()};c.addEventListener("click",()=>j(t-1)),d.addEventListener("click",()=>j(t+1)),f.addEventListener("click",()=>{var A;n&&(v.value=((A=I.textContent)==null?void 0:A.trim())??""),n=!1,T()}),b.addEventListener("click",()=>{var A;n||(v.value=((A=I.textContent)==null?void 0:A.trim())??""),n=!0,T()}),v.addEventListener("input",T),o.cells.forEach((A,B)=>A.addEventListener("click",()=>k(B)));let D;const O=A=>{const B=r.getBoundingClientRect();return Math.atan2(A.clientY-(B.top+B.height/2),A.clientX-(B.left+B.width/2))*180/Math.PI};l.addEventListener("pointerdown",A=>{const B=A;D=O(B)-a,l.classList.add("dragging"),r.setPointerCapture(B.pointerId),B.preventDefault()}),r.addEventListener("pointermove",A=>{if(D===void 0)return;a=O(A)-D,l.setAttribute("transform",`rotate(${a})`);const B=Math.round(-a/Gn);if((B%26+26)%26!==t){t=(B%26+26)%26;const E=a;T(),a=E,l.setAttribute("transform",`rotate(${a})`)}});const C=()=>{D!==void 0&&(D=void 0,l.classList.remove("dragging"),j(t))};return r.addEventListener("pointerup",C),r.addEventListener("pointercancel",C),T(),s}function XM(i,e,t){const n=(a,s)=>{const r=(s-90)*Math.PI/180;return`${(a*Math.cos(r)).toFixed(2)} ${(a*Math.sin(r)).toFixed(2)}`};return`M ${n(i,-t)} A ${i} ${i} 0 0 1 ${n(i,t)} L ${n(e,t)} A ${e} ${e} 0 0 0 ${n(e,-t)} Z`}const l0=i=>p(`web_visubot_part_${i}`),rg=new WeakMap;function og(i,e,t,n){const a=document.createElement("div");a.className="visubot-model";const s=document.createElement("div");s.className="visubot-stage";const r=document.createElement("div");r.className="visubot-part-label",r.hidden=!0,s.append(r);const o=(c,d,h)=>{r.hidden=!1,r.textContent=l0(c),r.style.left=`${Math.min(d+12,s.clientWidth-140)}px`,r.style.top=`${h+12}px`},l=document.createElement("p");l.className="visubot-model-hint hint",l.textContent=p("web_visubot_tap_part"),l.hidden=!!n,a.append(s,l);const u=K(async()=>{const{Robot3D:c}=await import("./robot3d-I0g91EHr.js");return{Robot3D:c}},[],import.meta.url).then(({Robot3D:c})=>{const d=new c(s);d.showcase(),d.highlight(i),i.includes("leds")&&d.setLed([40,90,255]),d.focusOn([],e==="unten"||e==="bottom"?"":e,!1,1),d.focusOn(i,e,t);let h;return s.addEventListener("pointerdown",g=>h={x:g.clientX,y:g.clientY}),s.addEventListener("pointerup",g=>{if(!h||Math.hypot(g.clientX-h.x,g.clientY-h.y)>5)return;const f=d.partAt(g.clientX,g.clientY);if(!f)return;if(n)return n(f);d.highlight(f);const b=s.getBoundingClientRect();o(f,g.clientX-b.left,g.clientY-b.top)}),s.addEventListener("pointermove",g=>{if(g.pointerType!=="mouse"||n)return;const f=d.partAt(g.clientX,g.clientY);if(r.hidden=!f,!f)return;const b=s.getBoundingClientRect();o(f,g.clientX-b.left,g.clientY-b.top)}),s.addEventListener("pointerleave",()=>r.hidden=!0),d}).catch(c=>{console.error(c),s.textContent=p("web_visubot_no_3d")}),m={box:a,ready:u,focus:i,view:e};return rg.set(a,m),m}function KM(i,e,t=!1){return og(i,e,t).box}function eZ(i){const e=i.querySelector(".visubot-model"),t=e&&rg.get(e);for(const n of i.querySelectorAll("[data-robot-part]")){const a=(n.dataset.robotPart??"").split(",").filter(Boolean);if(n.title=a.map(l0).join(", "),!t)continue;const s=()=>void t.ready.then(o=>o==null?void 0:o.highlight(a)),r=()=>void t.ready.then(o=>o==null?void 0:o.highlight(t.focus));n.addEventListener("mouseenter",s),n.addEventListener("focus",s),n.addEventListener("mouseleave",r),n.addEventListener("blur",r),n.addEventListener("click",()=>{t.ready.then(o=>{o==null||o.highlight(a),o==null||o.focusOn(a,t.view)}),t.box.scrollIntoView({block:"nearest",behavior:"smooth"})})}}function tZ(i,e){let t=0;const n=document.createElement("div");n.className="visubot-quiz-question";const a=document.createElement("p");a.className="visubot-quiz-feedback",a.setAttribute("aria-live","polite");const s=()=>{n.innerHTML=Tn(`**${t+1}/${i.length}** ${i[t].question}`)},r=og([],void 0,!1,l=>{if(!(t>=i.length)){if(r.ready.then(u=>u==null?void 0:u.highlight(l)),l!==i[t].part){a.className="visubot-quiz-feedback wrong",a.textContent=p("web_visubot_quiz_wrong_fmt",l0(l));return}t++,a.className="visubot-quiz-feedback right",t{u.forEach(v=>{window.clearTimeout(v),window.clearInterval(v)}),u=[]},c=()=>{a.textContent=`${p("web_game_round_fmt",o+1,r)} · ${p("web_game_score_fmt",l)}`},d=()=>{const v=$("button",{class:"primary"},o+1{o++,o{const v=i.rounds[o],w=i.seconds,I=$("div",{class:"learn-bomb-fuse"},$("span",{})),z=$("span",{class:"learn-bomb-time"}),k=$("div",{class:"learn-bomb","aria-live":"polite"},$("span",{class:"learn-bomb-icon","aria-hidden":"true"},"💣"),z,I),T=$("div",{class:"learn-game-feedback",role:"status"}),j=v.code.split(` + `;const e=a=>this.element.querySelector(a);this.buttons={play:e("[data-sim=play]"),pause:e("[data-sim=pause]"),step:e("[data-sim=step]"),stop:e("[data-sim=stop]")},this.buttons.play.addEventListener("click",()=>this.play()),this.buttons.pause.addEventListener("click",()=>this.pause()),this.buttons.step.addEventListener("click",()=>this.step()),this.buttons.stop.addEventListener("click",()=>this.reset()),this.editButton=e(".sim-edit"),this.editButton.addEventListener("click",()=>this.onEdit());const t=e("[data-sim=highlight]");t.value=this.highlightMode,t.addEventListener("change",()=>{this.highlightMode=t.value,Ku(Xu,this.highlightMode)});const n=e("[data-sim=delay]");n.value=this.delay,n.addEventListener("change",()=>{this.delay=n.value,Ku(Ir,this.delay)}),this.inputSection=e(".sim-input > div"),this.trace=e(".sim-trace"),this.variables=e(".sim-vars"),this.output=e(".sim-output"),this.notice=e(".sim-notice")}collectOutput(){const e=this.engine.state.outputLines;for(;this.printedr.localeCompare(o));if(n.length===0)this.variables.innerHTML=`

    ${Me(p("simulation_variables_placeholder"))}

    `;else{const r=document.createElement("table");for(const o of n){const l=r.insertRow();l.insertCell().textContent=o;const u=e.variables.get(o),m=l.insertCell();u.kind==="grid"?m.append(sg(u)):m.textContent=_e(u)}this.variables.replaceChildren(r)}e.outputLines.length===0&&e.files.size===0?this.output.innerHTML=`

    ${Me(p("simulation_output_placeholder"))}

    `:(this.output.replaceChildren(...e.outputLines.map(r=>{const o=document.createElement("div");return o.textContent=r,o}),...ag(e.files)),this.output.scrollTop=this.output.scrollHeight)}updateInput(){const e=this.engine.state.inputRequest,t=this.inputSection;if(t.parentElement.classList.toggle("active",!!e),!e){t.innerHTML=`

    ${Me(p("simulation_input_placeholder"))}

    `;return}let n=t.querySelector("form");if(!n){n=document.createElement("form"),n.innerHTML=`

    `;const l=n.querySelector("input");n.addEventListener("submit",u=>{u.preventDefault(),this.submitInput(l)}),t.replaceChildren(n),requestAnimationFrame(()=>l.focus())}const a=this.engine.state.outputLines;n.querySelector(".sim-prompt").textContent=e.prompt||(a[a.length-1]??"");const s=n.querySelector("input");s.inputMode=e.valueType==="string"||e.valueType==="boolean"?"text":"decimal";const r=this.engine.state.inputErrorNotice,o=n.querySelector(".sim-input-error");o.textContent=r?t1(r):"",o.hidden=!r}}function sg(i){const e=document.createElement("table");e.className="sim-grid";for(const t of i.value){const n=e.insertRow();for(const a of t){const s=n.insertCell();s.textContent=String(a),a===!0&&(s.className="sim-grid-true")}}return e}const x1=Array.from("ABCDEFGHIJKLMNOPQRSTUVWXYZ"),Gn=360/x1.length,UM="http://www.w3.org/2000/svg";function Fe(i,e={},...t){const n=document.createElement(i);for(const[a,s]of Object.entries(e))n.setAttribute(a,s);return n.append(...t),n}function xt(i,e={},t){const n=document.createElementNS(UM,i);for(const[a,s]of Object.entries(e))n.setAttribute(a,String(s));return t!==void 0&&(n.textContent=t),n}function $M(i,e){const t=(e%26+26)%26;return Array.from(i).map(n=>{const a=n.charCodeAt(0);return a>=65&&a<=90?String.fromCharCode((a-65+t)%26+65):a>=97&&a<=122?String.fromCharCode((a-97+t)%26+97):n}).join("")}function em(i,e){const t=xt("g",{class:e}),n=x1.map((a,s)=>{const r=xt("g",{transform:`rotate(${s*Gn})`});return r.append(xt("text",{x:0,y:-i,"text-anchor":"middle","dominant-baseline":"central"},a)),t.append(r),r});return{group:t,cells:n}}function YM(i,e){let t=i,n=!1,a=-t*Gn;const s=Fe("section",{class:"learn-game learn-caesar"});s.append(Fe("div",{class:"learn-game-head"},Fe("strong",{},p("web_learn_caesar_title")))),s.append(Fe("p",{class:"learn-game-status"},p("web_learn_caesar_hint")));const r=xt("svg",{viewBox:"-200 -200 400 400",class:"learn-caesar-disc",role:"img"});r.append(xt("circle",{r:196,class:"outer-disc"})),r.append(xt("path",{d:XM(196,92,Gn/2),class:"window"}));const o=em(168,"outer-letters");r.append(o.group);for(let A=0;A{o.cells.forEach((B,E)=>B.classList.toggle("marked",E===A)),u.cells.forEach((B,E)=>B.classList.toggle("marked",A!==void 0&&E===(A+t)%26))},T=()=>{m.textContent=String(t),l.setAttribute("transform",`rotate(${a})`),r.setAttribute("aria-label",p("web_learn_caesar_key_fmt",t)),x.textContent=p(n?"web_learn_caesar_secret":"web_learn_caesar_plain"),w.textContent=p(n?"web_learn_caesar_plain":"web_learn_caesar_secret"),f.classList.toggle("active",!n),b.classList.toggle("active",n),I.textContent=$M(v.value,n?-t:t)||" ";const A=Array.from(v.value.toUpperCase()).reverse().find(E=>x1.includes(E));if(A===void 0)return k();const B=x1.indexOf(A);k(n?(B-t+26)%26:B)},j=A=>{t=(A%26+26)%26,a=-t*Gn,T()};c.addEventListener("click",()=>j(t-1)),d.addEventListener("click",()=>j(t+1)),f.addEventListener("click",()=>{var A;n&&(v.value=((A=I.textContent)==null?void 0:A.trim())??""),n=!1,T()}),b.addEventListener("click",()=>{var A;n||(v.value=((A=I.textContent)==null?void 0:A.trim())??""),n=!0,T()}),v.addEventListener("input",T),o.cells.forEach((A,B)=>A.addEventListener("click",()=>k(B)));let D;const O=A=>{const B=r.getBoundingClientRect();return Math.atan2(A.clientY-(B.top+B.height/2),A.clientX-(B.left+B.width/2))*180/Math.PI};l.addEventListener("pointerdown",A=>{const B=A;D=O(B)-a,l.classList.add("dragging"),r.setPointerCapture(B.pointerId),B.preventDefault()}),r.addEventListener("pointermove",A=>{if(D===void 0)return;a=O(A)-D,l.setAttribute("transform",`rotate(${a})`);const B=Math.round(-a/Gn);if((B%26+26)%26!==t){t=(B%26+26)%26;const E=a;T(),a=E,l.setAttribute("transform",`rotate(${a})`)}});const C=()=>{D!==void 0&&(D=void 0,l.classList.remove("dragging"),j(t))};return r.addEventListener("pointerup",C),r.addEventListener("pointercancel",C),T(),s}function XM(i,e,t){const n=(a,s)=>{const r=(s-90)*Math.PI/180;return`${(a*Math.cos(r)).toFixed(2)} ${(a*Math.sin(r)).toFixed(2)}`};return`M ${n(i,-t)} A ${i} ${i} 0 0 1 ${n(i,t)} L ${n(e,t)} A ${e} ${e} 0 0 0 ${n(e,-t)} Z`}const l0=i=>p(`web_visubot_part_${i}`),rg=new WeakMap;function og(i,e,t,n){const a=document.createElement("div");a.className="visubot-model";const s=document.createElement("div");s.className="visubot-stage";const r=document.createElement("div");r.className="visubot-part-label",r.hidden=!0,s.append(r);const o=(c,d,h)=>{r.hidden=!1,r.textContent=l0(c),r.style.left=`${Math.min(d+12,s.clientWidth-140)}px`,r.style.top=`${h+12}px`},l=document.createElement("p");l.className="visubot-model-hint hint",l.textContent=p("web_visubot_tap_part"),l.hidden=!!n,a.append(s,l);const u=K(async()=>{const{Robot3D:c}=await import("./robot3d-BNw8Z2K3.js");return{Robot3D:c}},[],import.meta.url).then(({Robot3D:c})=>{const d=new c(s);d.showcase(),d.highlight(i),i.includes("leds")&&d.setLed([40,90,255]),d.focusOn([],e==="unten"||e==="bottom"?"":e,!1,1),d.focusOn(i,e,t);let h;return s.addEventListener("pointerdown",g=>h={x:g.clientX,y:g.clientY}),s.addEventListener("pointerup",g=>{if(!h||Math.hypot(g.clientX-h.x,g.clientY-h.y)>5)return;const f=d.partAt(g.clientX,g.clientY);if(!f)return;if(n)return n(f);d.highlight(f);const b=s.getBoundingClientRect();o(f,g.clientX-b.left,g.clientY-b.top)}),s.addEventListener("pointermove",g=>{if(g.pointerType!=="mouse"||n)return;const f=d.partAt(g.clientX,g.clientY);if(r.hidden=!f,!f)return;const b=s.getBoundingClientRect();o(f,g.clientX-b.left,g.clientY-b.top)}),s.addEventListener("pointerleave",()=>r.hidden=!0),d}).catch(c=>{console.error(c),s.textContent=p("web_visubot_no_3d")}),m={box:a,ready:u,focus:i,view:e};return rg.set(a,m),m}function KM(i,e,t=!1){return og(i,e,t).box}function eZ(i){const e=i.querySelector(".visubot-model"),t=e&&rg.get(e);for(const n of i.querySelectorAll("[data-robot-part]")){const a=(n.dataset.robotPart??"").split(",").filter(Boolean);if(n.title=a.map(l0).join(", "),!t)continue;const s=()=>void t.ready.then(o=>o==null?void 0:o.highlight(a)),r=()=>void t.ready.then(o=>o==null?void 0:o.highlight(t.focus));n.addEventListener("mouseenter",s),n.addEventListener("focus",s),n.addEventListener("mouseleave",r),n.addEventListener("blur",r),n.addEventListener("click",()=>{t.ready.then(o=>{o==null||o.highlight(a),o==null||o.focusOn(a,t.view)}),t.box.scrollIntoView({block:"nearest",behavior:"smooth"})})}}function tZ(i,e){let t=0;const n=document.createElement("div");n.className="visubot-quiz-question";const a=document.createElement("p");a.className="visubot-quiz-feedback",a.setAttribute("aria-live","polite");const s=()=>{n.innerHTML=Tn(`**${t+1}/${i.length}** ${i[t].question}`)},r=og([],void 0,!1,l=>{if(!(t>=i.length)){if(r.ready.then(u=>u==null?void 0:u.highlight(l)),l!==i[t].part){a.className="visubot-quiz-feedback wrong",a.textContent=p("web_visubot_quiz_wrong_fmt",l0(l));return}t++,a.className="visubot-quiz-feedback right",t{u.forEach(v=>{window.clearTimeout(v),window.clearInterval(v)}),u=[]},c=()=>{a.textContent=`${p("web_game_round_fmt",o+1,r)} · ${p("web_game_score_fmt",l)}`},d=()=>{const v=$("button",{class:"primary"},o+1{o++,o{const v=i.rounds[o],w=i.seconds,I=$("div",{class:"learn-bomb-fuse"},$("span",{})),z=$("span",{class:"learn-bomb-time"}),k=$("div",{class:"learn-bomb","aria-live":"polite"},$("span",{class:"learn-bomb-icon","aria-hidden":"true"},"💣"),z,I),T=$("div",{class:"learn-game-feedback",role:"status"}),j=v.code.split(` `).map((E,U)=>{const ee=$("button",{class:"ln",type:"button"},E||" ");return ee.disabled=!E.trim(),ee.addEventListener("click",()=>A(U+1===v.wrongLine?"right":"wrong",ee)),ee}),D=$("div",{class:"learn-game-code learn-bomb-code mono",dir:"ltr"},...j),O=Date.now(),C=()=>{if(!t.isConnected&&Date.now()-O>1e3)return m();const E=Math.max(0,w-(Date.now()-O)/1e3);z.textContent=p("web_game_time_fmt",Math.ceil(E)),I.firstChild.style.width=`${E/w*100}%`,k.classList.toggle("hurry",E<=5),E<=0&&A("time")},A=(E,U)=>{m(),j.forEach((Ie,fe)=>{Ie.disabled=!0,fe+1===v.wrongLine&&Ie.classList.add("right")}),U&&E==="wrong"&&U.classList.add("wrong");const ee=E==="right";ee&&l++,c(),k.classList.add(ee?"defused":"boom"),k.firstChild.textContent=ee?"✂️":"💥",T.className=`learn-game-feedback ${ee?"right":"wrong"}`;const he=d();T.replaceChildren($("p",{},p(ee?"web_game_defused":E==="time"?"web_game_boom_time":"web_game_boom_wrong")),Fn("div",{class:"learn-game-explain"},v.explanation),$("p",{class:"learn-bomb-fix"},`${p("web_game_fix")} `,$("code",{},v.fix.trim())),he),he.focus({preventScroll:!0})};s.replaceChildren(k,Fn("p",{class:"learn-game-question"},v.question),D,T),C();const B=window.setInterval(C,200);u.push(B)},g=()=>{const v=i.rounds[o],w=[];v.code.trim()&&w.push(nm(v.code).element),w.push(Fn("p",{class:"learn-game-question"},v.question),$("p",{class:"learn-order-hint"},p("web_game_order_hint")));const I=$("div",{class:"learn-game-options learn-order"}),z=$("div",{class:"learn-game-feedback",role:"status"});let k=0;const T=iZ(v.options.length).map(D=>{const O=$("span",{class:"learn-order-badge","aria-hidden":"true"}),C=$("span",{});C.innerHTML=Ce(v.options[D].text);const A=$("button",{},O,C);return A.addEventListener("click",()=>{if(D!==k)return A.classList.add("wrong"),j(!1);A.classList.add("right"),O.textContent=String(++k),A.disabled=!0,k===v.options.length&&j(!0)}),I.append(A),{k:D,b:A,badge:O}}),j=D=>{for(const{k:C,b:A,badge:B}of[...T].sort((E,U)=>E.k-U.k))A.disabled=!0,B.textContent=String(C+1),I.append(A);D&&l++,c(),z.className=`learn-game-feedback ${D?"right":"wrong"}`;const O=d();z.replaceChildren($("p",{},p(D?"web_game_right":"web_game_wrong_short")),Fn("div",{class:"learn-game-explain"},v.explanation),O),O.focus({preventScroll:!0})};s.replaceChildren(...w,I,z)},f=()=>{if(m(),i.kind==="bombe"||i.kind==="reihenfolge"){c(),i.kind==="bombe"?h():g();return}const v=i.rounds[o];c();const w=nm(v.code),I=[];let z;i.kind==="zuhoerer"?(z=aZ(Gh(v.code),w),I.push($("div",{class:"learn-swing-row"},w.element,z.element)),v.clicks.length&&I.push($("p",{class:"learn-swing-clicks"},`${p("web_game_clicks")} `,...v.clicks.flatMap((O,C)=>[...C?[" → "]:[],$("code",{},O)])))):v.code.trim()&&I.push(w.element),I.push(Fn("p",{class:"learn-game-question"},v.question));const k=$("div",{class:`learn-game-options ${i.kind==="layout"?"pictures":""}`}),T=$("div",{class:"learn-game-feedback",role:"status"}),j=v.options.map(O=>{const C=$("button",{});return i.kind==="layout"?C.append(rZ(O.text)):O.text.includes(` `)?C.append(sZ(O.text)):C.innerHTML=Ce(O.text),C.addEventListener("click",()=>D(O.right,C)),k.append(C),C}),D=(O,C)=>{j.forEach((B,E)=>{B.disabled=!0,v.options[E].right&&B.classList.add("right")}),O||C.classList.add("wrong"),O&&l++,c(),T.className=`learn-game-feedback ${O?"right":"wrong"}`;const A=d();T.replaceChildren($("p",{},p(O?"web_game_right":"web_game_wrong_short")),Fn("div",{class:"learn-game-explain"},v.explanation)),T.append(A),z&&(u=z.replay(v.clicks,()=>A.before($("p",{class:"learn-swing-try"},p("web_game_try"))))),A.focus({preventScroll:!0})};s.replaceChildren(...I,k,T)},b=()=>{m(),a.textContent="";const v=$("button",{class:"primary"},p("web_game_again"));v.addEventListener("click",()=>{o=l=0,f()}),s.replaceChildren($("p",{class:"learn-game-result"},p("web_game_done_fmt",l,r)),$("p",{},p(l===r?"web_game_perfect":l>=r*.7?"web_game_good":"web_game_practice_short")),v)},x=$("button",{class:"primary"},p("web_game_start"));return x.addEventListener("click",f),s.append(Fn("p",{},i.intro),x),t}function iZ(i){const e=[...Array(i).keys()];for(;e.every((t,n)=>t===n);)for(let t=i-1;t>0;t--){const n=Math.floor(Math.random()*(t+1));[e[t],e[n]]=[e[n],e[t]]}return e}function nm(i){const e=i.split(` `).map(n=>$("div",{class:"ln"},n||" "));return{element:$("pre",{class:"learn-game-code mono",dir:"ltr"},...e),highlight(n,a){e.forEach((s,r)=>s.classList.toggle("hit",n!==void 0&&r>=n&&r<=(a??n)))}}}function aZ(i,e){const t=Hh(i),n=$("div",{class:"learn-swing-window",dir:"ltr"});n.append($("div",{class:"learn-swing-title"},i.title||" "));const a=$("div",{class:"learn-swing-body"}),s=new Map;for(const c of i.labels){const d=$("div",{class:"learn-swing-label"},t.texts[c.name]);s.set(c.name,d),a.append(d)}const r=i.buttons.map(c=>{const d=$("button",{class:"learn-swing-button",disabled:""},t.texts[c.name]);return s.set(c.name,d),a.append(d),d}),o=$("p",{class:"learn-swing-event",role:"status"}),l=$("pre",{class:"learn-swing-console mono",hidden:""});n.append(a,o,l);const u=c=>{var h,g;const d=s.get(c.button);d.classList.add("pressed"),window.setTimeout(()=>d.classList.remove("pressed"),350),e.highlight((h=c.listener)==null?void 0:h.from,(g=c.listener)==null?void 0:g.to),o.textContent=c.listener?p("web_game_event_fmt",d.textContent??""):p("web_game_nobody"),o.className=`learn-swing-event ${c.listener?"heard":"nobody"}`;for(const[f,b]of Object.entries(c.texts)){const x=s.get(f);x&&x.textContent!==b&&(x.textContent=b,x.classList.remove("changed"),x.offsetWidth,x.classList.add("changed"))}c.console.length&&(l.hidden=!1,l.textContent+=c.console.map(f=>`${f} @@ -64297,10 +64296,10 @@ ${l}`)}Na=aM(((o=e.find(([l])=>l==="begriffe.md"))==null?void 0:o[1])??"")}const ## ${p("web_learn_terms")} -${a}`));this.body.append(s),this.foldReference(s)}}foldReference(e){const t="visustruct.reference.open";let n=[];try{n=JSON.parse(localStorage.getItem(t)??"[]")}catch{}for(const a of[...e.querySelectorAll("h2")]){const s=a.textContent??"",r=_("details",{class:"reference-group"});r.open=n.includes(s);const o=_("summary",{},s);for(a.replaceWith(r),r.append(o);r.nextSibling&&r.nextSibling.nodeName!=="H2";)r.append(r.nextSibling);r.addEventListener("toggle",()=>{n=r.open?[...new Set([...n,s])]:n.filter(l=>l!==s);try{localStorage.setItem(t,JSON.stringify(n))}catch{}})}}showReference(){this.tab="reference",this.persist(),this.render()}persist(){be.setView({tab:this.tab,lesson:this.lessonId,task:this.taskId})}openLesson(e){this.tab="lessons",this.lessonId=e,this.returnTo=void 0,this.persist(),this.render(),this.body.scrollTop=0}renderLessonList(){this.body.append(_("p",{class:"hint"},p("web_learn_intro")));for(const e of IZ()){this.body.append(_("h3",{class:"learn-section"},e.name));const t=_("ol",{class:"learn-list"});for(const n of e.lessons){const a=be.lesson(n.id),s=a.done?"✓":a.step>0?p("web_learn_step_of_fmt",a.step+1,n.steps.length):"",r=_("button",{class:"learn-item"+(a.done?" done":""),"data-lesson":n.id},_("span",{class:"learn-num"},String(n.number)),_("span",{class:"learn-item-text"},_("strong",{},n.robot?`🤖 ${n.title}`:n.title),_("small",{},n.summary)),_("span",{class:"learn-status"},s));r.addEventListener("click",()=>this.openLesson(n.id)),t.append(_("li",{},r))}this.body.append(t)}this.body.append(this.renderTeacherBox())}renderLesson(e){var u;const t=be.lesson(e.id),n=Math.min(t.step,e.steps.length-1),a=e.steps[n],s=_("button",{class:"learn-back"},`← ${p("web_learn_all_lessons")}`);s.addEventListener("click",()=>this.openLesson(void 0));const r=_("nav",{class:"learn-progress","aria-label":p("web_learn_step_of_fmt",n+1,e.steps.length)});r.append(...e.steps.map((m,c)=>{const d=p("web_learn_step_fmt",c+1,m.title),h=cthis.goToStep(e,c)),g})),this.body.append(_("div",{class:"learn-lesson-head"},_("div",{class:"learn-head-row"},s,this.stepNav(e,n,t.done,"learn-nav learn-nav-top")),_("p",{class:"learn-kicker"},`${p("web_learn_lesson_fmt",e.number)} · ${e.section}${e.robot?" · 🤖 VisuBot":""}`),_("h2",{class:"learn-title"},_("span",{class:"learn-num","aria-hidden":"true"},String(e.number)),e.title),r,_("h3",{class:"learn-step-title"},`${n+1}. ${a.title}`)));const o=((u=this.returnTo)==null?void 0:u.lesson)===e.id&&this.returnTo.step!==n?this.returnTo:void 0,l=()=>{const m=_("button",{class:"learn-return"},`↩ ${p("web_learn_back_to_checklist")}`);return m.addEventListener("click",()=>{this.returnTo=void 0,this.goToStep(e,o.step),this.body.scrollTop=o.scroll}),m};o&&this.body.append(l()),a.blocks.forEach((m,c)=>this.body.append(this.renderBlock(m,`${n}-${c}`,e))),lm(this.body),eZ(this.body),this.openNeededColumns(a.blocks),rm(this.body,Na),this.body.append(this.stepNav(e,n,t.done,"learn-nav")),o&&this.body.append(l())}stepNav(e,t,n,a){const s=_("div",{class:a}),r=_("button",{},`← ${p("web_learn_back")}`);if(r.disabled=t===0,r.addEventListener("click",()=>this.goToStep(e,t-1)),s.append(r),tthis.goToStep(e,t+1)),s.append(o)}else{const o=_("button",{class:"primary"},n?`✓ ${p("web_learn_done")}`:p("web_learn_finish"));o.addEventListener("click",()=>{be.updateLesson(e.id,{done:!0});const l=Ct.find(u=>u.number===e.number+1);this.openLesson(l==null?void 0:l.id)}),s.append(o)}return s}goToStep(e,t){be.updateLesson(e.id,{step:t}),this.render(),this.body.scrollTop=0}openNeededColumns(e){const t=e.flatMap(n=>n.kind==="exercise"?[n.exercise]:[]);yZ(this.body)?(this.host.showEditor(),xZ(this.body)&&this.host.reveal(["palette"])):vZ(this.body)?this.host.showFiles():t.some(n=>n.code!=="java")?this.host.showEditor():(t.length>0||this.body.querySelector(".lesson-code[data-lang=java]"))&&this.host.showJava(),wZ(this.body)&&this.host.showLiveCode()}renderTaskList(){this.body.append(_("p",{class:"hint"},p("web_learn_tasks_intro")));const e=_("ul",{class:"learn-list"});for(const t of An){const n=this.taskExercises(t),a=n.length>0&&n.every(o=>be.exercise(o.id).done),s=Ct.find(o=>o.number===t.after),r=_("button",{class:"learn-item"+(a?" done":""),"data-task":t.id},_("span",{class:"learn-num","aria-label":p("web_learn_level_fmt",t.level)},"★".repeat(t.level)),_("span",{class:"learn-item-text"},_("strong",{},t.title),_("small",{},s?p("web_learn_after_fmt",s.number,s.title):"")),_("span",{class:"learn-status"},a?"✓":""));r.addEventListener("click",()=>{this.taskId=t.id,this.persist(),this.render(),this.body.scrollTop=0}),e.append(_("li",{},r))}this.body.append(e,this.renderTeacherBox())}renderTeacherBox(){const e=_("details",{class:"learn-teacher"},_("summary",{},p("web_learn_teacher")));if($u()){e.setAttribute("open","");const s=_("button",{},p("web_learn_teacher_off"));return s.addEventListener("click",()=>{VM(),this.render()}),e.append(_("p",{},p("web_learn_teacher_on")),s),e}const t=_("input",{type:"password",autocomplete:"off","aria-label":p("web_learn_teacher_code"),placeholder:p("web_learn_teacher_code")}),n=_("p",{class:"learn-result",role:"status"}),a=_("form",{class:"group"},t,_("button",{type:"submit"},p("web_learn_teacher_unlock")));return a.addEventListener("submit",async s=>{s.preventDefault(),await HM(t.value)?this.render():(n.className="learn-result info",n.textContent=p("web_learn_teacher_wrong"))}),e.append(_("p",{class:"hint"},p("web_learn_teacher_intro")),a,n),e}taskExercises(e){return e.blocks.flatMap(t=>t.kind==="exercise"?[t.exercise]:[])}renderTask(e){const t=_("button",{class:"learn-back"},`← ${p("web_learn_all_tasks")}`);t.addEventListener("click",()=>{this.taskId=void 0,this.persist(),this.render()});const n=Ct.find(a=>a.number===e.after);if(this.body.append(t,_("h2",{class:"learn-title"},e.title)),n){const a=_("button",{class:"link-button"},p("web_learn_after_fmt",n.number,n.title));a.addEventListener("click",()=>this.openLesson(n.id)),this.body.append(_("p",{class:"learn-kicker"},a))}e.blocks.forEach((a,s)=>this.body.append(this.renderBlock(a,`task-${s}`))),lm(this.body),this.openNeededColumns(e.blocks),rm(this.body,Na)}renderBlock(e,t,n){switch(e.kind){case"markdown":return this.withOpenButtons(tt("div",{class:"learn-text"},Tn(e.text)));case"diagram":return this.renderDiagram(e.file,e.caption);case"exercise":return this.renderExercise(e.exercise);case"competences":return this.renderCompetences(e.items);case"checklist":return this.renderChecklist(e.items,t,n);case"quiz":return this.renderQuiz(e.questions,t,n);case"brag":return this.renderBrag(e.text,e.tip,e.pro);case"images":return this.renderImages(e.files,e.caption);case"graphic":return this.renderGraphic(e.file,e.caption,e.labeled);case"game":return this.renderGame(e.game);case"roundGame":return nZ(e.game,ra);case"rescueGame":return oZ(e.game,ra);case"caesar":return YM(e.key,e.text);case"cloze":return uZ(e.cloze);case"pap":return pZ(e.pap);case"textFile":return ig(e.name,e.content);case"robotModel":return KM(e.focus,e.view,e.spin);case"robotQuiz":return tZ(e.tasks,e.done)}}renderBrag(e,t=!1,n=!1){const a=_("aside",{class:"learn-brag"});a.append(_("img",{src:ra,alt:"",width:"48",height:"48"}));const s=_("div",{},_("p",{class:"learn-brag-title"},p(n?"web_learn_pro":t?"web_learn_ludwig_tip":"web_learn_brag")));return s.append(tt("div",{class:"learn-text"},Tn(e))),a.append(s),a}renderGame(e){const n=_("section",{class:"learn-game"}),a=_("div",{class:"learn-game-head"});a.append(_("img",{src:ra,alt:"",width:"40",height:"40"}),_("strong",{},p("web_game_title")));const s=_("p",{class:"learn-game-status"}),r=_("div",{class:"learn-game-stage"});n.append(a,s,r);let o=0,l=0;const u=()=>{const d=cx(e,o,10);s.textContent=`${p("web_game_round_fmt",o+1,10)} · ${p("web_game_score_fmt",l)}`;const h=_("div",{class:"learn-game-values mono"});for(const[w,I]of dx(d))h.append(_("code",{},`${w} = ${I}`));const g=_("div",{class:"group learn-game-answers"}),f=_("button",{class:"learn-game-true"},`✓ ${p("web_game_true")}`),b=_("button",{class:"learn-game-false"},`✗ ${p("web_game_false")}`);g.append(f,b);const x=_("div",{class:"learn-game-feedback",role:"status"}),v=w=>{f.disabled=b.disabled=!0;const I=w===d.answer;I&&l++,s.textContent=`${p("web_game_round_fmt",o+1,10)} · ${p("web_game_score_fmt",l)}`,x.className=`learn-game-feedback ${I?"right":"wrong"}`;const z=_("div",{class:"learn-game-steps mono"});ux(d.condition,d.values).forEach((T,j)=>z.append(_("div",{},`${j?"→ ":""}${T}`)));const k=_("button",{class:"primary"},o+1<10?p("web_game_next"):p("web_game_finish"));k.addEventListener("click",()=>{o++,o<10?u():m()}),x.replaceChildren(_("p",{},p(I?"web_game_right":"web_game_wrong")),z,k),k.focus()};f.addEventListener("click",()=>v(!0)),b.addEventListener("click",()=>v(!1)),r.replaceChildren(h,_("div",{class:"learn-game-condition mono"},d.condition),g,x)},m=()=>{s.textContent="";const d=_("button",{class:"primary"},p("web_game_again"));d.addEventListener("click",()=>{o=l=0,u()}),r.replaceChildren(_("p",{class:"learn-game-result"},p("web_game_done_fmt",l,10)),_("p",{},p(l===10?"web_game_perfect":l>=10*.7?"web_game_good":"web_game_practice")),d)},c=_("button",{class:"primary"},p("web_game_start"));return c.addEventListener("click",u),r.append(_("p",{},p("web_game_intro")),c),n}renderImages(e,t){const n=_("figure",{class:"learn-figure"}),a=_("div",{class:"learn-images"});for(const s of e){const r=zr(s);r&&a.append(_("img",{src:r,alt:"",loading:"lazy"}))}return n.append(a),t&&n.append(tt("figcaption",{},Ce(t))),n}renderGraphic(e,t,n){const a=_("figure",{class:"learn-figure"}),s=zr(e),r=n?zr(n):void 0;if(s&&r){const o=_("img",{class:"learn-graphic",src:s,alt:"",loading:"lazy"}),l=_("button",{class:"learn-graphic-toggle",type:"button",title:p("web_learn_graphic_labels"),"aria-pressed":"false"},o);l.addEventListener("click",()=>{const u=l.getAttribute("aria-pressed")!=="true";l.setAttribute("aria-pressed",String(u)),o.src=u?r:s}),a.append(l,_("p",{class:"learn-graphic-hint"},p("web_learn_graphic_labels")))}else s&&a.append(_("img",{class:"learn-graphic",src:s,alt:"",loading:"lazy"}));return t&&a.append(tt("figcaption",{},Ce(t))),a}withOpenButtons(e){for(const t of e.querySelectorAll("pre.lesson-code[data-open=editor]")){const n=t.textContent??"",a=_("button",{class:"learn-open-code"},p("web_learn_open_in_editor"));a.addEventListener("click",()=>this.host.openJavaCode(n)),t.after(a)}return e}renderDiagram(e,t){const n=ti(e),a=_("figure",{class:"learn-figure"});if(!n)return a;const s=this.host.preview(n);s&&a.append(_("div",{class:"learn-preview",dir:"ltr"},s)),t&&a.append(tt("figcaption",{},Ce(t)));const r=_("button",{},p("web_learn_open_in_editor"));return r.addEventListener("click",()=>this.host.openDiagram(n,e)),a.append(r),a}renderExercise(e){const t=_("section",{class:"learn-exercise","data-exercise":e.id}),n=()=>be.exercise(e.id),a=_("span",{class:"learn-badge"},`✓ ${p("web_learn_solved")}`);a.hidden=!n().done;const s=e.code==="java"?p("web_learn_solve_in_code",p("web_live_title")):p("web_learn_solve_in_editor",p("web_editor_title"));t.append(_("h4",{},`${p("web_learn_exercise")}: ${e.title}`,a),_("p",{class:"learn-where"},s),tt("div",{class:"learn-text"},Tn(e.task)));const r=_("div",{class:"learn-result",role:"status"}),o=_("div",{class:"learn-hints"}),l=_("div",{class:"group"}),u=_("button",{class:"primary"},p("web_learn_open_exercise"));u.addEventListener("click",()=>{const d=n().xml;let h=um(e);if(d)try{h=Nl(d)}catch{}this.host.openExercise(e,h)});const m=_("button",{},p("web_learn_check"));if(m.addEventListener("click",()=>{const d=this.host.exerciseDocument(e.id);if(!d){r.className="learn-result info",r.textContent=p("web_learn_open_first");return}if(d.elements.every(Bl)){r.className="learn-result info",r.textContent=p("web_learn_empty");return}this.host.stopSimulation();const h=ax(d,e.tests,this.host.subprogramsFor(e.id),Ja),g=sx(d),f=e.requires.map(v=>v==="forZaehlSchleife"?"forSchleife":v).filter(v=>v in S&&!g.has(S[v])),b=e.loopDepth!==void 0&&Do(d.elements)v.passed)&&f.length===0&&!b;this.showResult(r,h,f,x,b),x&&(be.updateExercise(e.id,{done:!0}),a.hidden=!1)}),l.append(u,m),e.hints.length>0){const d=_("button",{},p("web_learn_hint"));d.addEventListener("click",()=>{const h=o.children.length;if(h>=e.hints.length)return;const g=e.hints.length>1?`**${p("web_learn_hint_fmt",h+1,e.hints.length)}:** `:"";o.append(tt("aside",{class:"lesson-note"},Tn(g+e.hints[h]))),d.textContent=p("web_learn_hint_more"),d.toggleAttribute("disabled",h+1>=e.hints.length)}),l.append(d)}const c=_("button",{class:"danger-text"},p("web_learn_reset"));if(c.addEventListener("click",()=>{if(c.dataset.confirm!=="1"){c.dataset.confirm="1",c.textContent=p("web_learn_reset_confirm"),setTimeout(()=>{c.dataset.confirm="",c.textContent=p("web_learn_reset")},4e3);return}be.resetExercise(e.id),this.host.resetExercise(e.id,um(e)),a.hidden=!0,r.replaceChildren(),r.className="learn-result",c.dataset.confirm="",c.textContent=p("web_learn_reset")}),l.append(c),t.append(l,o,r),$u()&&e.solution){const d=ti(e.solution);if(d){const h=_("details",{class:"learn-solution"},_("summary",{},p("web_learn_solution")));h.addEventListener("toggle",()=>{if(!h.open||h.querySelector(".learn-preview"))return;const g=this.host.preview(d);g&&h.append(_("div",{class:"learn-preview",dir:"ltr"},g));const f=_("button",{},p("web_learn_open_in_editor"));f.addEventListener("click",()=>{this.host.openDiagram(d,e.solution);for(const b of e.subprograms){const x=ti(b);x&&this.host.openDiagram(x,b)}});for(const b of e.subprograms){const x=ti(b),v=x&&this.host.preview(x);v&&h.append(_("div",{class:"learn-preview",dir:"ltr"},v))}h.append(f)}),t.append(h)}}return t}showResult(e,t,n,a,s){var o,l,u,m,c;e.className="learn-result "+(a?"ok":"fail"),e.replaceChildren(_("p",{class:"learn-result-head"},a?`🎉 ${p("web_learn_passed")}`:p("web_learn_failed")));for(const d of n)e.append(_("p",{},`✗ ${p("web_learn_missing_fmt",kZ(S[d]))}`));s&&e.append(_("p",{},`✗ ${p("web_visubot_depth_fmt",s)}`));const r=_("ul",{class:"learn-tests",dir:"auto"});for(const d of t){const h=d.test.world?t.filter(x=>x.test.world).indexOf(d)+1:0,g=d.test.world?`🗺 ${p("web_visubot_world_fmt",h)}`:d.test.actions?`🤖 ${p("web_visubot_actions")}`:d.test.sensors?`🎛 ${Object.entries(d.test.sensors).map(([x,v])=>`mbot.${x}() = ${v.join(" → ")}`).join(", ")}`:d.test.drive?`🤖 ${p("web_visubot_drive")}`:d.test.inputs.length?p("web_learn_input_fmt",d.test.inputs.join(", ")):p("web_learn_no_input"),f=[`${d.passed?"✓":"✗"} ${g}`],b=_("div",{class:"learn-test-detail"});if(d.test.drive&&b.append(_("span",{},`${p("web_learn_expected")}: `,_("code",{},X1(d.test.drive)||"–")),_("span",{},`${p("web_learn_actual")}: `,_("code",{},X1(d.result.drive??[])||"–"))),d.test.actions&&b.append(_("span",{},`${p("web_learn_expected")}: `,_("code",{},X1(d.test.actions)||"–")),_("span",{},`${p("web_learn_actual")}: `,_("code",{},X1(d.result.actions??[])||"–"))),d.test.led!==void 0){const x=v=>p(v?"web_visubot_led_on":"web_visubot_led_off");b.append(_("span",{},`💡 ${p("web_learn_expected")}: ${x(d.test.led)} · ${p("web_learn_actual")}: ${x(d.result.led)}`))}if(d.test.tone!==void 0){const x=v=>p(v?"web_visubot_tone_yes":"web_visubot_tone_no");b.append(_("span",{},`🔊 ${p("web_learn_expected")}: ${x(d.test.tone)} · ${p("web_learn_actual")}: ${x(d.result.tone)}`))}d.test.screen!==void 0&&b.append(_("span",{},`📺 ${p("web_learn_expected")}: `,_("code",{},d.test.screen),` · ${p("web_learn_actual")}: `,_("code",{},d.result.screen??"–"))),d.test.world&&(((l=(o=Ja(d.test.world))==null?void 0:o.goals)!=null&&l.length||(m=(u=Ja(d.test.world))==null?void 0:u.targets)!=null&&m.length)&&b.append(_("span",{},d.result.atGoal?`✓ ${p("web_visubot_goal_reached")}`:`✗ ${p("web_visubot_goal_missed")}`)),d.result.bumps&&b.append(_("span",{class:"learn-error"},`⚠︎ ${p("web_visubot_bumps")}: ${d.result.bumps}`))),(!d.test.drive&&!d.test.world&&!d.test.sensors&&!d.test.actions||d.result.outputs.length)&&b.append(_("span",{},`${p("web_learn_expected")}: `,_("code",{},d.test.expected.join(" | ")||"–")),_("span",{},`${p("web_learn_actual")}: `,_("code",{},d.result.outputs.join(" | ")||"–")));for(const x of d.test.files??[])b.append(_("span",{},`📄 ${x.name}, ${p("web_learn_expected")}: `,_("code",{},x.lines.join(" | ")||"–")),_("span",{},`📄 ${x.name}, ${p("web_learn_actual")}: `,_("code",{},Fh((c=d.result.files)==null?void 0:c.get(x.name)).join(" | ")||"–")));d.result.error&&b.append(_("span",{class:"learn-error"},t1(d.result.error))),d.result.missingInput&&b.append(_("span",{class:"learn-error"},p("web_learn_missing_input"))),d.result.tooManySteps&&b.append(_("span",{class:"learn-error"},p("web_learn_too_many_steps"))),!d.passed&&d.result.unusedInputs&&b.append(_("span",{class:"learn-error"},p("web_learn_unused_input"))),r.append(_("li",{class:d.passed?"ok":"fail"},...f,b))}e.append(r)}renderCompetences(e){const t=_("aside",{class:"learn-competences"},_("p",{class:"learn-competences-title"},p("web_learn_competences_intro"))),n=_("ul",{});for(const a of e)n.append(tt("li",{},Ce(a)));return t.append(n),t}renderChecklist(e,t,n){const a=[{value:"umbrella",icon:"☂️",label:p("web_learn_rating_umbrella")},{value:"cloud",icon:"⛅",label:p("web_learn_rating_cloud")},{value:"sun",icon:"☀️",label:p("web_learn_rating_sun")}],s=_("div",{class:"learn-checklist-wrap"}),r=_("p",{class:"learn-rating-legend"});for(const l of a)r.append(_("span",{},`${l.icon} ${l.label}`));const o=_("ul",{class:"learn-checklist"});return s.append(r,o),e.forEach((l,u)=>{var v;const m=`${t}-${u}`,c=n?(v=be.lesson(n.id).checks)==null?void 0:v[m]:void 0;let d=c===!0?"sun":c||void 0;const h=tt("span",{class:"learn-check-text"},Ce(l.text)),g=_("span",{class:"learn-rating",role:"group","aria-label":h.textContent??""}),f=a.map(w=>{const I=_("button",{class:"learn-rating-button",title:w.label,"aria-label":w.label},w.icon);return I.addEventListener("click",()=>{if(d=d===w.value?void 0:w.value,b(),!n)return;const z={...be.lesson(n.id).checks??{}};d?z[m]=d:delete z[m],be.updateLesson(n.id,{checks:Object.keys(z).length?z:void 0})}),I}),b=()=>{f.forEach((w,I)=>w.setAttribute("aria-pressed",String(a[I].value===d))),x.dataset.rating=d??""};g.append(...f);const x=_("li",{},h,g);if(n&&l.step!==void 0){const w=l.step,I=p("web_learn_step_fmt",w+1,n.steps[w].title),z=_("button",{class:"link-button learn-check-link",title:I,"aria-label":`${p("web_learn_review")}: ${I}`},p("web_learn_review"));z.addEventListener("click",()=>{this.returnTo={lesson:n.id,step:be.lesson(n.id).step,scroll:this.body.scrollTop},this.goToStep(n,w)}),x.append(z)}b(),o.append(x)}),s}renderQuiz(e,t,n){const a=_("div",{class:"learn-quiz"}),s=_("p",{class:"learn-score",role:"status"}),r=()=>n?be.lesson(n.id).quiz??{}:{},o=_("div",{class:"learn-review"}),l=()=>{const u=r(),m=(f,b)=>f.pairs?f.pairs.every((x,v)=>u[`${t}-${b}-${v}`]!==void 0):u[`${t}-${b}`]!==void 0,c=(f,b)=>{var x;return!!(f.pairs?f.pairs.every((v,w)=>mm(f)[u[`${t}-${b}-${w}`]]===f.pairs[w].right):(x=f.options[u[`${t}-${b}`]])!=null&&x.correct)},d=e.filter(m).length,h=e.filter(c).length,g=d===e.length;s.textContent=g?p("web_learn_score_fmt",h,e.length):"",o.replaceChildren(),g&&n&&this.fillChecklistReview(o,n,e,f=>c(e[f],f))};return e.forEach((u,m)=>{const c=`${t}-${m}`,d=_("fieldset",{},tt("legend",{},Ce(u.question))),h=tt("p",{class:"learn-explanation"},Ce(u.explanation??""));if(u.pairs){d.append(this.renderMatch(u,c,r,n,h,l),h),a.append(d);return}const g=f=>{d.querySelectorAll("button").forEach((b,x)=>{b.classList.toggle("right",f!==void 0&&u.options[x].correct),b.classList.toggle("wrong",f===x&&!u.options[x].correct),b.setAttribute("aria-pressed",String(f===x))}),h.hidden=f===void 0||!u.explanation};u.options.forEach((f,b)=>{const x=tt("button",{class:"learn-option"},Ce(f.text));x.addEventListener("click",()=>{n&&be.updateLesson(n.id,{quiz:{...r(),[c]:b}}),g(b),l()}),d.append(x)}),d.append(h),g(r()[c]),a.append(d)}),a.append(s,o),l(),a}fillChecklistReview(e,t,n,a){const s={sun:"☀️",cloud:"⛅",umbrella:"☂️"},r=be.lesson(t.id).checks??{},o=[];let l=0;t.steps.forEach((u,m)=>u.blocks.forEach((c,d)=>{c.kind==="checklist"&&c.items.forEach((h,g)=>{const f=r[`${m}-${d}-${g}`],b=f===!0?"sun":f||void 0,x=h.step===void 0?[]:n.map((k,T)=>k.step===h.step?T:-1).filter(k=>k>=0),v=x.filter(k=>!a(k));let w="";b==="sun"&&v.length?w=p("web_learn_review_overrated_fmt",v.map(k=>k+1).join(", ")):b&&b!=="sun"&&x.length&&!v.length&&(w=p("web_learn_review_underrated")),w&&l++;const I=_("li",{class:w?"learn-review-deviation":""}),z=tt("span",{class:"learn-check-text"},Ce(h.text));if(w&&z.append(_("br",{}),_("em",{},w)),I.append(z,_("span",{class:"learn-review-icon","aria-label":p(b?`web_learn_rating_${b}`:"web_learn_review_unrated")},b?s[b]:"–")),w&&b==="sun"&&h.step!==void 0){const k=h.step,T=_("button",{class:"link-button learn-check-link"},p("web_learn_review"));T.addEventListener("click",()=>{this.returnTo={lesson:t.id,step:be.lesson(t.id).step,scroll:this.body.scrollTop},this.goToStep(t,k)}),I.append(T)}o.push(I)})})),o.length&&e.append(_("p",{class:"learn-review-title"},`📋 ${p("web_learn_review_title")}`),_("p",{},p(l?"web_learn_review_hint":"web_learn_review_match")),_("ul",{class:"learn-checklist"},...o))}renderMatch(e,t,n,a,s,r){const o=e.pairs,l=mm(e),u=_("div",{class:"learn-match"});let m={};const c=()=>a?n():m,d=b=>a?be.updateLesson(a.id,{quiz:b}):m=b,h=b=>c()[`${t}-${b}`],g=o.map(b=>{const x=_("select",{class:"learn-match-select"});x.append(_("option",{value:""},"–")),l.forEach((w,I)=>x.append(_("option",{value:String(I)},w)));const v=tt("label",{class:"learn-match-left"},Ce(b.left));return v.append(x),u.append(v),x}),f=()=>{const b=o.every((x,v)=>h(v)!==void 0);g.forEach((x,v)=>{const w=h(v);x.value=w===void 0?"":String(w),x.classList.toggle("right",b&&l[w]===o[v].right),x.classList.toggle("wrong",b&&l[w]!==o[v].right)}),s.hidden=!b||!e.explanation};return g.forEach((b,x)=>b.addEventListener("change",()=>{const v={...c()};b.value===""?delete v[`${t}-${x}`]:v[`${t}-${x}`]=Number(b.value),d(v),f(),r()})),f(),u}}function mm(i){return(i.pairs??[]).map(e=>e.right).sort((e,t)=>e.localeCompare(t,"de"))}const _Z=""+new URL("visubot-CyGFOI9V.webp",import.meta.url).href,Us="visustruct.visubot";function $s(){try{return localStorage.getItem(Us)}catch{return null}}function ui(){const i=$s();return i==="1"||i==="kurs"?"on":"off"}const dg=()=>$s()==="2";function hg(){try{localStorage.setItem(Us,"2")}catch{}}const gg=()=>$s()==="3";function pg(){try{localStorage.setItem(Us,"3")}catch{}}const jZ=()=>$s()!==null;function Sr(i){try{localStorage.setItem(Us,i==="on"?"1":"0")}catch{}}const AZ=`VisuBot`,Hn=()=>ui()!=="off",cm=i=>i.replace(/[&<>"]/g,e=>({"&":"&","<":"<",">":">",'"':"""})[e]);function Lo(){const i=dg()?"object":gg()?"flow":ui(),e=(n,a)=>``,t={off:"web_visubot_world_visustruct_hint",on:"web_visubot_world_visubot_hint",object:"web_visuobject_world_hint",flow:"web_visuflow_world_hint"}[i];return`
    +${a}`));this.body.append(s),this.foldReference(s)}}foldReference(e){const t="visustruct.reference.open";let n=[];try{n=JSON.parse(localStorage.getItem(t)??"[]")}catch{}for(const a of[...e.querySelectorAll("h2")]){const s=a.textContent??"",r=_("details",{class:"reference-group"});r.open=n.includes(s);const o=_("summary",{},s);for(a.replaceWith(r),r.append(o);r.nextSibling&&r.nextSibling.nodeName!=="H2";)r.append(r.nextSibling);r.addEventListener("toggle",()=>{n=r.open?[...new Set([...n,s])]:n.filter(l=>l!==s);try{localStorage.setItem(t,JSON.stringify(n))}catch{}})}}showReference(){this.tab="reference",this.persist(),this.render()}persist(){be.setView({tab:this.tab,lesson:this.lessonId,task:this.taskId})}openLesson(e){this.tab="lessons",this.lessonId=e,this.returnTo=void 0,this.persist(),this.render(),this.body.scrollTop=0}renderLessonList(){this.body.append(_("p",{class:"hint"},p("web_learn_intro")));for(const e of IZ()){this.body.append(_("h3",{class:"learn-section"},e.name));const t=_("ol",{class:"learn-list"});for(const n of e.lessons){const a=be.lesson(n.id),s=a.done?"✓":a.step>0?p("web_learn_step_of_fmt",a.step+1,n.steps.length):"",r=_("button",{class:"learn-item"+(a.done?" done":""),"data-lesson":n.id},_("span",{class:"learn-num"},String(n.number)),_("span",{class:"learn-item-text"},_("strong",{},n.robot?`🤖 ${n.title}`:n.title),_("small",{},n.summary)),_("span",{class:"learn-status"},s));r.addEventListener("click",()=>this.openLesson(n.id)),t.append(_("li",{},r))}this.body.append(t)}this.body.append(this.renderTeacherBox())}renderLesson(e){var u;const t=be.lesson(e.id),n=Math.min(t.step,e.steps.length-1),a=e.steps[n],s=_("button",{class:"learn-back"},`← ${p("web_learn_all_lessons")}`);s.addEventListener("click",()=>this.openLesson(void 0));const r=_("nav",{class:"learn-progress","aria-label":p("web_learn_step_of_fmt",n+1,e.steps.length)});r.append(...e.steps.map((m,c)=>{const d=p("web_learn_step_fmt",c+1,m.title),h=cthis.goToStep(e,c)),g})),this.body.append(_("div",{class:"learn-lesson-head"},_("div",{class:"learn-head-row"},s,this.stepNav(e,n,t.done,"learn-nav learn-nav-top")),_("p",{class:"learn-kicker"},`${p("web_learn_lesson_fmt",e.number)} · ${e.section}${e.robot?" · 🤖 VisuBot":""}`),_("h2",{class:"learn-title"},_("span",{class:"learn-num","aria-hidden":"true"},String(e.number)),e.title),r,_("h3",{class:"learn-step-title"},`${n+1}. ${a.title}`)));const o=((u=this.returnTo)==null?void 0:u.lesson)===e.id&&this.returnTo.step!==n?this.returnTo:void 0,l=()=>{const m=_("button",{class:"learn-return"},`↩ ${p("web_learn_back_to_checklist")}`);return m.addEventListener("click",()=>{this.returnTo=void 0,this.goToStep(e,o.step),this.body.scrollTop=o.scroll}),m};o&&this.body.append(l()),a.blocks.forEach((m,c)=>this.body.append(this.renderBlock(m,`${n}-${c}`,e))),lm(this.body),eZ(this.body),this.openNeededColumns(a.blocks),rm(this.body,Na),this.body.append(this.stepNav(e,n,t.done,"learn-nav")),o&&this.body.append(l())}stepNav(e,t,n,a){const s=_("div",{class:a}),r=_("button",{},`← ${p("web_learn_back")}`);if(r.disabled=t===0,r.addEventListener("click",()=>this.goToStep(e,t-1)),s.append(r),tthis.goToStep(e,t+1)),s.append(o)}else{const o=_("button",{class:"primary"},n?`✓ ${p("web_learn_done")}`:p("web_learn_finish"));o.addEventListener("click",()=>{be.updateLesson(e.id,{done:!0});const l=Ct.find(u=>u.number===e.number+1);this.openLesson(l==null?void 0:l.id)}),s.append(o)}return s}goToStep(e,t){be.updateLesson(e.id,{step:t}),this.render(),this.body.scrollTop=0}openNeededColumns(e){const t=e.flatMap(n=>n.kind==="exercise"?[n.exercise]:[]);yZ(this.body)?(this.host.showEditor(),xZ(this.body)&&this.host.reveal(["palette"])):vZ(this.body)?this.host.showFiles():t.some(n=>n.code!=="java")?this.host.showEditor():(t.length>0||this.body.querySelector(".lesson-code[data-lang=java]"))&&this.host.showJava(),wZ(this.body)&&this.host.showLiveCode()}renderTaskList(){this.body.append(_("p",{class:"hint"},p("web_learn_tasks_intro")));const e=_("ul",{class:"learn-list"});for(const t of An){const n=this.taskExercises(t),a=n.length>0&&n.every(o=>be.exercise(o.id).done),s=Ct.find(o=>o.number===t.after),r=_("button",{class:"learn-item"+(a?" done":""),"data-task":t.id},_("span",{class:"learn-num","aria-label":p("web_learn_level_fmt",t.level)},"★".repeat(t.level)),_("span",{class:"learn-item-text"},_("strong",{},t.title),_("small",{},s?p("web_learn_after_fmt",s.number,s.title):"")),_("span",{class:"learn-status"},a?"✓":""));r.addEventListener("click",()=>{this.taskId=t.id,this.persist(),this.render(),this.body.scrollTop=0}),e.append(_("li",{},r))}this.body.append(e,this.renderTeacherBox())}renderTeacherBox(){const e=_("details",{class:"learn-teacher"},_("summary",{},p("web_learn_teacher")));if($u()){e.setAttribute("open","");const s=_("button",{},p("web_learn_teacher_off"));return s.addEventListener("click",()=>{VM(),this.render()}),e.append(_("p",{},p("web_learn_teacher_on")),s),e}const t=_("input",{type:"password",autocomplete:"off","aria-label":p("web_learn_teacher_code"),placeholder:p("web_learn_teacher_code")}),n=_("p",{class:"learn-result",role:"status"}),a=_("form",{class:"group"},t,_("button",{type:"submit"},p("web_learn_teacher_unlock")));return a.addEventListener("submit",async s=>{s.preventDefault(),await HM(t.value)?this.render():(n.className="learn-result info",n.textContent=p("web_learn_teacher_wrong"))}),e.append(_("p",{class:"hint"},p("web_learn_teacher_intro")),a,n),e}taskExercises(e){return e.blocks.flatMap(t=>t.kind==="exercise"?[t.exercise]:[])}renderTask(e){const t=_("button",{class:"learn-back"},`← ${p("web_learn_all_tasks")}`);t.addEventListener("click",()=>{this.taskId=void 0,this.persist(),this.render()});const n=Ct.find(a=>a.number===e.after);if(this.body.append(t,_("h2",{class:"learn-title"},e.title)),n){const a=_("button",{class:"link-button"},p("web_learn_after_fmt",n.number,n.title));a.addEventListener("click",()=>this.openLesson(n.id)),this.body.append(_("p",{class:"learn-kicker"},a))}e.blocks.forEach((a,s)=>this.body.append(this.renderBlock(a,`task-${s}`))),lm(this.body),this.openNeededColumns(e.blocks),rm(this.body,Na)}renderBlock(e,t,n){switch(e.kind){case"markdown":return this.withOpenButtons(tt("div",{class:"learn-text"},Tn(e.text)));case"diagram":return this.renderDiagram(e.file,e.caption);case"exercise":return this.renderExercise(e.exercise);case"competences":return this.renderCompetences(e.items);case"checklist":return this.renderChecklist(e.items,t,n);case"quiz":return this.renderQuiz(e.questions,t,n);case"brag":return this.renderBrag(e.text,e.tip);case"images":return this.renderImages(e.files,e.caption);case"graphic":return this.renderGraphic(e.file,e.caption,e.labeled);case"game":return this.renderGame(e.game);case"roundGame":return nZ(e.game,ra);case"rescueGame":return oZ(e.game,ra);case"caesar":return YM(e.key,e.text);case"cloze":return uZ(e.cloze);case"pap":return pZ(e.pap);case"textFile":return ig(e.name,e.content);case"robotModel":return KM(e.focus,e.view,e.spin);case"robotQuiz":return tZ(e.tasks,e.done)}}renderBrag(e,t=!1){const n=_("aside",{class:"learn-brag"});n.append(_("img",{src:ra,alt:"",width:"48",height:"48"}));const a=_("div",{},_("p",{class:"learn-brag-title"},p(t?"web_learn_ludwig_tip":"web_learn_brag")));return a.append(tt("div",{class:"learn-text"},Tn(e))),n.append(a),n}renderGame(e){const n=_("section",{class:"learn-game"}),a=_("div",{class:"learn-game-head"});a.append(_("img",{src:ra,alt:"",width:"40",height:"40"}),_("strong",{},p("web_game_title")));const s=_("p",{class:"learn-game-status"}),r=_("div",{class:"learn-game-stage"});n.append(a,s,r);let o=0,l=0;const u=()=>{const d=cx(e,o,10);s.textContent=`${p("web_game_round_fmt",o+1,10)} · ${p("web_game_score_fmt",l)}`;const h=_("div",{class:"learn-game-values mono"});for(const[w,I]of dx(d))h.append(_("code",{},`${w} = ${I}`));const g=_("div",{class:"group learn-game-answers"}),f=_("button",{class:"learn-game-true"},`✓ ${p("web_game_true")}`),b=_("button",{class:"learn-game-false"},`✗ ${p("web_game_false")}`);g.append(f,b);const x=_("div",{class:"learn-game-feedback",role:"status"}),v=w=>{f.disabled=b.disabled=!0;const I=w===d.answer;I&&l++,s.textContent=`${p("web_game_round_fmt",o+1,10)} · ${p("web_game_score_fmt",l)}`,x.className=`learn-game-feedback ${I?"right":"wrong"}`;const z=_("div",{class:"learn-game-steps mono"});ux(d.condition,d.values).forEach((T,j)=>z.append(_("div",{},`${j?"→ ":""}${T}`)));const k=_("button",{class:"primary"},o+1<10?p("web_game_next"):p("web_game_finish"));k.addEventListener("click",()=>{o++,o<10?u():m()}),x.replaceChildren(_("p",{},p(I?"web_game_right":"web_game_wrong")),z,k),k.focus()};f.addEventListener("click",()=>v(!0)),b.addEventListener("click",()=>v(!1)),r.replaceChildren(h,_("div",{class:"learn-game-condition mono"},d.condition),g,x)},m=()=>{s.textContent="";const d=_("button",{class:"primary"},p("web_game_again"));d.addEventListener("click",()=>{o=l=0,u()}),r.replaceChildren(_("p",{class:"learn-game-result"},p("web_game_done_fmt",l,10)),_("p",{},p(l===10?"web_game_perfect":l>=10*.7?"web_game_good":"web_game_practice")),d)},c=_("button",{class:"primary"},p("web_game_start"));return c.addEventListener("click",u),r.append(_("p",{},p("web_game_intro")),c),n}renderImages(e,t){const n=_("figure",{class:"learn-figure"}),a=_("div",{class:"learn-images"});for(const s of e){const r=zr(s);r&&a.append(_("img",{src:r,alt:"",loading:"lazy"}))}return n.append(a),t&&n.append(tt("figcaption",{},Ce(t))),n}renderGraphic(e,t,n){const a=_("figure",{class:"learn-figure"}),s=zr(e),r=n?zr(n):void 0;if(s&&r){const o=_("img",{class:"learn-graphic",src:s,alt:"",loading:"lazy"}),l=_("button",{class:"learn-graphic-toggle",type:"button",title:p("web_learn_graphic_labels"),"aria-pressed":"false"},o);l.addEventListener("click",()=>{const u=l.getAttribute("aria-pressed")!=="true";l.setAttribute("aria-pressed",String(u)),o.src=u?r:s}),a.append(l,_("p",{class:"learn-graphic-hint"},p("web_learn_graphic_labels")))}else s&&a.append(_("img",{class:"learn-graphic",src:s,alt:"",loading:"lazy"}));return t&&a.append(tt("figcaption",{},Ce(t))),a}withOpenButtons(e){for(const t of e.querySelectorAll("pre.lesson-code[data-open=editor]")){const n=t.textContent??"",a=_("button",{class:"learn-open-code"},p("web_learn_open_in_editor"));a.addEventListener("click",()=>this.host.openJavaCode(n)),t.after(a)}return e}renderDiagram(e,t){const n=ti(e),a=_("figure",{class:"learn-figure"});if(!n)return a;const s=this.host.preview(n);s&&a.append(_("div",{class:"learn-preview",dir:"ltr"},s)),t&&a.append(tt("figcaption",{},Ce(t)));const r=_("button",{},p("web_learn_open_in_editor"));return r.addEventListener("click",()=>this.host.openDiagram(n,e)),a.append(r),a}renderExercise(e){const t=_("section",{class:"learn-exercise","data-exercise":e.id}),n=()=>be.exercise(e.id),a=_("span",{class:"learn-badge"},`✓ ${p("web_learn_solved")}`);a.hidden=!n().done;const s=e.code==="java"?p("web_learn_solve_in_code",p("web_live_title")):p("web_learn_solve_in_editor",p("web_editor_title"));t.append(_("h4",{},`${p("web_learn_exercise")}: ${e.title}`,a),_("p",{class:"learn-where"},s),tt("div",{class:"learn-text"},Tn(e.task)));const r=_("div",{class:"learn-result",role:"status"}),o=_("div",{class:"learn-hints"}),l=_("div",{class:"group"}),u=_("button",{class:"primary"},p("web_learn_open_exercise"));u.addEventListener("click",()=>{const d=n().xml;let h=um(e);if(d)try{h=Nl(d)}catch{}this.host.openExercise(e,h)});const m=_("button",{},p("web_learn_check"));if(m.addEventListener("click",()=>{const d=this.host.exerciseDocument(e.id);if(!d){r.className="learn-result info",r.textContent=p("web_learn_open_first");return}if(d.elements.every(Bl)){r.className="learn-result info",r.textContent=p("web_learn_empty");return}this.host.stopSimulation();const h=ax(d,e.tests,this.host.subprogramsFor(e.id),Ja),g=sx(d),f=e.requires.map(v=>v==="forZaehlSchleife"?"forSchleife":v).filter(v=>v in S&&!g.has(S[v])),b=e.loopDepth!==void 0&&Do(d.elements)v.passed)&&f.length===0&&!b;this.showResult(r,h,f,x,b),x&&(be.updateExercise(e.id,{done:!0}),a.hidden=!1)}),l.append(u,m),e.hints.length>0){const d=_("button",{},p("web_learn_hint"));d.addEventListener("click",()=>{const h=o.children.length;if(h>=e.hints.length)return;const g=e.hints.length>1?`**${p("web_learn_hint_fmt",h+1,e.hints.length)}:** `:"";o.append(tt("aside",{class:"lesson-note"},Tn(g+e.hints[h]))),d.textContent=p("web_learn_hint_more"),d.toggleAttribute("disabled",h+1>=e.hints.length)}),l.append(d)}const c=_("button",{class:"danger-text"},p("web_learn_reset"));if(c.addEventListener("click",()=>{if(c.dataset.confirm!=="1"){c.dataset.confirm="1",c.textContent=p("web_learn_reset_confirm"),setTimeout(()=>{c.dataset.confirm="",c.textContent=p("web_learn_reset")},4e3);return}be.resetExercise(e.id),this.host.resetExercise(e.id,um(e)),a.hidden=!0,r.replaceChildren(),r.className="learn-result",c.dataset.confirm="",c.textContent=p("web_learn_reset")}),l.append(c),t.append(l,o,r),$u()&&e.solution){const d=ti(e.solution);if(d){const h=_("details",{class:"learn-solution"},_("summary",{},p("web_learn_solution")));h.addEventListener("toggle",()=>{if(!h.open||h.querySelector(".learn-preview"))return;const g=this.host.preview(d);g&&h.append(_("div",{class:"learn-preview",dir:"ltr"},g));const f=_("button",{},p("web_learn_open_in_editor"));f.addEventListener("click",()=>{this.host.openDiagram(d,e.solution);for(const b of e.subprograms){const x=ti(b);x&&this.host.openDiagram(x,b)}});for(const b of e.subprograms){const x=ti(b),v=x&&this.host.preview(x);v&&h.append(_("div",{class:"learn-preview",dir:"ltr"},v))}h.append(f)}),t.append(h)}}return t}showResult(e,t,n,a,s){var o,l,u,m,c;e.className="learn-result "+(a?"ok":"fail"),e.replaceChildren(_("p",{class:"learn-result-head"},a?`🎉 ${p("web_learn_passed")}`:p("web_learn_failed")));for(const d of n)e.append(_("p",{},`✗ ${p("web_learn_missing_fmt",kZ(S[d]))}`));s&&e.append(_("p",{},`✗ ${p("web_visubot_depth_fmt",s)}`));const r=_("ul",{class:"learn-tests",dir:"auto"});for(const d of t){const h=d.test.world?t.filter(x=>x.test.world).indexOf(d)+1:0,g=d.test.world?`🗺 ${p("web_visubot_world_fmt",h)}`:d.test.actions?`🤖 ${p("web_visubot_actions")}`:d.test.sensors?`🎛 ${Object.entries(d.test.sensors).map(([x,v])=>`mbot.${x}() = ${v.join(" → ")}`).join(", ")}`:d.test.drive?`🤖 ${p("web_visubot_drive")}`:d.test.inputs.length?p("web_learn_input_fmt",d.test.inputs.join(", ")):p("web_learn_no_input"),f=[`${d.passed?"✓":"✗"} ${g}`],b=_("div",{class:"learn-test-detail"});if(d.test.drive&&b.append(_("span",{},`${p("web_learn_expected")}: `,_("code",{},X1(d.test.drive)||"–")),_("span",{},`${p("web_learn_actual")}: `,_("code",{},X1(d.result.drive??[])||"–"))),d.test.actions&&b.append(_("span",{},`${p("web_learn_expected")}: `,_("code",{},X1(d.test.actions)||"–")),_("span",{},`${p("web_learn_actual")}: `,_("code",{},X1(d.result.actions??[])||"–"))),d.test.led!==void 0){const x=v=>p(v?"web_visubot_led_on":"web_visubot_led_off");b.append(_("span",{},`💡 ${p("web_learn_expected")}: ${x(d.test.led)} · ${p("web_learn_actual")}: ${x(d.result.led)}`))}if(d.test.tone!==void 0){const x=v=>p(v?"web_visubot_tone_yes":"web_visubot_tone_no");b.append(_("span",{},`🔊 ${p("web_learn_expected")}: ${x(d.test.tone)} · ${p("web_learn_actual")}: ${x(d.result.tone)}`))}d.test.screen!==void 0&&b.append(_("span",{},`📺 ${p("web_learn_expected")}: `,_("code",{},d.test.screen),` · ${p("web_learn_actual")}: `,_("code",{},d.result.screen??"–"))),d.test.world&&(((l=(o=Ja(d.test.world))==null?void 0:o.goals)!=null&&l.length||(m=(u=Ja(d.test.world))==null?void 0:u.targets)!=null&&m.length)&&b.append(_("span",{},d.result.atGoal?`✓ ${p("web_visubot_goal_reached")}`:`✗ ${p("web_visubot_goal_missed")}`)),d.result.bumps&&b.append(_("span",{class:"learn-error"},`⚠︎ ${p("web_visubot_bumps")}: ${d.result.bumps}`))),(!d.test.drive&&!d.test.world&&!d.test.sensors&&!d.test.actions||d.result.outputs.length)&&b.append(_("span",{},`${p("web_learn_expected")}: `,_("code",{},d.test.expected.join(" | ")||"–")),_("span",{},`${p("web_learn_actual")}: `,_("code",{},d.result.outputs.join(" | ")||"–")));for(const x of d.test.files??[])b.append(_("span",{},`📄 ${x.name}, ${p("web_learn_expected")}: `,_("code",{},x.lines.join(" | ")||"–")),_("span",{},`📄 ${x.name}, ${p("web_learn_actual")}: `,_("code",{},Fh((c=d.result.files)==null?void 0:c.get(x.name)).join(" | ")||"–")));d.result.error&&b.append(_("span",{class:"learn-error"},t1(d.result.error))),d.result.missingInput&&b.append(_("span",{class:"learn-error"},p("web_learn_missing_input"))),d.result.tooManySteps&&b.append(_("span",{class:"learn-error"},p("web_learn_too_many_steps"))),!d.passed&&d.result.unusedInputs&&b.append(_("span",{class:"learn-error"},p("web_learn_unused_input"))),r.append(_("li",{class:d.passed?"ok":"fail"},...f,b))}e.append(r)}renderCompetences(e){const t=_("aside",{class:"learn-competences"},_("p",{class:"learn-competences-title"},p("web_learn_competences_intro"))),n=_("ul",{});for(const a of e)n.append(tt("li",{},Ce(a)));return t.append(n),t}renderChecklist(e,t,n){const a=[{value:"umbrella",icon:"☂️",label:p("web_learn_rating_umbrella")},{value:"cloud",icon:"⛅",label:p("web_learn_rating_cloud")},{value:"sun",icon:"☀️",label:p("web_learn_rating_sun")}],s=_("div",{class:"learn-checklist-wrap"}),r=_("p",{class:"learn-rating-legend"});for(const l of a)r.append(_("span",{},`${l.icon} ${l.label}`));const o=_("ul",{class:"learn-checklist"});return s.append(r,o),e.forEach((l,u)=>{var v;const m=`${t}-${u}`,c=n?(v=be.lesson(n.id).checks)==null?void 0:v[m]:void 0;let d=c===!0?"sun":c||void 0;const h=tt("span",{class:"learn-check-text"},Ce(l.text)),g=_("span",{class:"learn-rating",role:"group","aria-label":h.textContent??""}),f=a.map(w=>{const I=_("button",{class:"learn-rating-button",title:w.label,"aria-label":w.label},w.icon);return I.addEventListener("click",()=>{if(d=d===w.value?void 0:w.value,b(),!n)return;const z={...be.lesson(n.id).checks??{}};d?z[m]=d:delete z[m],be.updateLesson(n.id,{checks:Object.keys(z).length?z:void 0})}),I}),b=()=>{f.forEach((w,I)=>w.setAttribute("aria-pressed",String(a[I].value===d))),x.dataset.rating=d??""};g.append(...f);const x=_("li",{},h,g);if(n&&l.step!==void 0){const w=l.step,I=p("web_learn_step_fmt",w+1,n.steps[w].title),z=_("button",{class:"link-button learn-check-link",title:I,"aria-label":`${p("web_learn_review")}: ${I}`},p("web_learn_review"));z.addEventListener("click",()=>{this.returnTo={lesson:n.id,step:be.lesson(n.id).step,scroll:this.body.scrollTop},this.goToStep(n,w)}),x.append(z)}b(),o.append(x)}),s}renderQuiz(e,t,n){const a=_("div",{class:"learn-quiz"}),s=_("p",{class:"learn-score",role:"status"}),r=()=>n?be.lesson(n.id).quiz??{}:{},o=_("div",{class:"learn-review"}),l=()=>{const u=r(),m=(f,b)=>f.pairs?f.pairs.every((x,v)=>u[`${t}-${b}-${v}`]!==void 0):u[`${t}-${b}`]!==void 0,c=(f,b)=>{var x;return!!(f.pairs?f.pairs.every((v,w)=>mm(f)[u[`${t}-${b}-${w}`]]===f.pairs[w].right):(x=f.options[u[`${t}-${b}`]])!=null&&x.correct)},d=e.filter(m).length,h=e.filter(c).length,g=d===e.length;s.textContent=g?p("web_learn_score_fmt",h,e.length):"",o.replaceChildren(),g&&n&&this.fillChecklistReview(o,n,e,f=>c(e[f],f))};return e.forEach((u,m)=>{const c=`${t}-${m}`,d=_("fieldset",{},tt("legend",{},Ce(u.question))),h=tt("p",{class:"learn-explanation"},Ce(u.explanation??""));if(u.pairs){d.append(this.renderMatch(u,c,r,n,h,l),h),a.append(d);return}const g=f=>{d.querySelectorAll("button").forEach((b,x)=>{b.classList.toggle("right",f!==void 0&&u.options[x].correct),b.classList.toggle("wrong",f===x&&!u.options[x].correct),b.setAttribute("aria-pressed",String(f===x))}),h.hidden=f===void 0||!u.explanation};u.options.forEach((f,b)=>{const x=tt("button",{class:"learn-option"},Ce(f.text));x.addEventListener("click",()=>{n&&be.updateLesson(n.id,{quiz:{...r(),[c]:b}}),g(b),l()}),d.append(x)}),d.append(h),g(r()[c]),a.append(d)}),a.append(s,o),l(),a}fillChecklistReview(e,t,n,a){const s={sun:"☀️",cloud:"⛅",umbrella:"☂️"},r=be.lesson(t.id).checks??{},o=[];let l=0;t.steps.forEach((u,m)=>u.blocks.forEach((c,d)=>{c.kind==="checklist"&&c.items.forEach((h,g)=>{const f=r[`${m}-${d}-${g}`],b=f===!0?"sun":f||void 0,x=h.step===void 0?[]:n.map((k,T)=>k.step===h.step?T:-1).filter(k=>k>=0),v=x.filter(k=>!a(k));let w="";b==="sun"&&v.length?w=p("web_learn_review_overrated_fmt",v.map(k=>k+1).join(", ")):b&&b!=="sun"&&x.length&&!v.length&&(w=p("web_learn_review_underrated")),w&&l++;const I=_("li",{class:w?"learn-review-deviation":""}),z=tt("span",{class:"learn-check-text"},Ce(h.text));if(w&&z.append(_("br",{}),_("em",{},w)),I.append(z,_("span",{class:"learn-review-icon","aria-label":p(b?`web_learn_rating_${b}`:"web_learn_review_unrated")},b?s[b]:"–")),w&&b==="sun"&&h.step!==void 0){const k=h.step,T=_("button",{class:"link-button learn-check-link"},p("web_learn_review"));T.addEventListener("click",()=>{this.returnTo={lesson:t.id,step:be.lesson(t.id).step,scroll:this.body.scrollTop},this.goToStep(t,k)}),I.append(T)}o.push(I)})})),o.length&&e.append(_("p",{class:"learn-review-title"},`📋 ${p("web_learn_review_title")}`),_("p",{},p(l?"web_learn_review_hint":"web_learn_review_match")),_("ul",{class:"learn-checklist"},...o))}renderMatch(e,t,n,a,s,r){const o=e.pairs,l=mm(e),u=_("div",{class:"learn-match"});let m={};const c=()=>a?n():m,d=b=>a?be.updateLesson(a.id,{quiz:b}):m=b,h=b=>c()[`${t}-${b}`],g=o.map(b=>{const x=_("select",{class:"learn-match-select"});x.append(_("option",{value:""},"–")),l.forEach((w,I)=>x.append(_("option",{value:String(I)},w)));const v=tt("label",{class:"learn-match-left"},Ce(b.left));return v.append(x),u.append(v),x}),f=()=>{const b=o.every((x,v)=>h(v)!==void 0);g.forEach((x,v)=>{const w=h(v);x.value=w===void 0?"":String(w),x.classList.toggle("right",b&&l[w]===o[v].right),x.classList.toggle("wrong",b&&l[w]!==o[v].right)}),s.hidden=!b||!e.explanation};return g.forEach((b,x)=>b.addEventListener("change",()=>{const v={...c()};b.value===""?delete v[`${t}-${x}`]:v[`${t}-${x}`]=Number(b.value),d(v),f(),r()})),f(),u}}function mm(i){return(i.pairs??[]).map(e=>e.right).sort((e,t)=>e.localeCompare(t,"de"))}const _Z=""+new URL("visubot-CyGFOI9V.webp",import.meta.url).href,Us="visustruct.visubot";function $s(){try{return localStorage.getItem(Us)}catch{return null}}function ui(){const i=$s();return i==="1"||i==="kurs"?"on":"off"}const dg=()=>$s()==="2";function hg(){try{localStorage.setItem(Us,"2")}catch{}}const gg=()=>$s()==="3";function pg(){try{localStorage.setItem(Us,"3")}catch{}}const jZ=()=>$s()!==null;function Sr(i){try{localStorage.setItem(Us,i==="on"?"1":"0")}catch{}}const AZ=`VisuBot`,Hn=()=>ui()!=="off",cm=i=>i.replace(/[&<>"]/g,e=>({"&":"&","<":"<",">":">",'"':"""})[e]);function Lo(){const i=dg()?"object":gg()?"flow":ui(),e=(n,a)=>``,t={off:"web_visubot_world_visustruct_hint",on:"web_visubot_world_visubot_hint",object:"web_visuobject_world_hint",flow:"web_visuflow_world_hint"}[i];return`
    ${e("off","VisuStruct")}${e("on","🤖 VisuBot")}${e("object","VisuObject")}${e("flow","VisuFlow")}
    - ${cm(p(t))}`}class PZ{constructor(e=Ii){y(this,"element");y(this,"world");y(this,"view");y(this,"loading");y(this,"status");y(this,"stage");y(this,"picker");y(this,"applied",0);y(this,"sent",0);y(this,"liveStatus");y(this,"viewport");y(this,"stopListening");y(this,"realSensors");y(this,"controls",{getBrightness:50,getLoudness:0,getPitch:0,getRoll:0});y(this,"pressTimers",new Map);y(this,"check");y(this,"checking",!1);y(this,"onWorldChange");this.world=new ds(e),this.element=document.createElement("section"),this.element.className="visubot",this.element.innerHTML=`

    ${p("web_visubot_world")}

    ${p("web_visubot_world_in_preview")}

    ${CZ()}${OZ()}`,this.stage=this.element.querySelector(".visubot-stage"),this.picker=this.element.querySelector(".visubot-worlds"),this.status=this.element.querySelector(".visubot-status"),this.liveStatus=this.element.querySelector(".visubot-live"),this.viewport=this.element.querySelector(".visubot-viewport"),this.stopListening=ge.listen(()=>this.updateLive()),this.setupControls(),this.check=this.element.querySelector(".visubot-check"),this.setupCheck(),this.updateLive(),this.updateStatus()}show(){this.loading??(this.loading=K(async()=>{const{Robot3D:e}=await import("./robot3d-I0g91EHr.js");return{Robot3D:e}},[],import.meta.url).then(({Robot3D:e})=>{this.view=new e(this.stage),this.view.setWorld(this.world.setup),this.view.place(this.world.pose,this.world.trail),this.view.setLeds(this.world.leds)}).catch(()=>{this.stage.textContent=p("web_visubot_no_3d")}))}restoreViewport(){this.viewport.parentElement!==this.element&&this.liveStatus.after(this.viewport)}setWorlds(e){this.picker.replaceChildren(),this.picker.hidden=e.length<2,e.forEach((t,n)=>{const a=document.createElement("button");a.textContent=p("web_visubot_world_fmt",n+1),a.addEventListener("click",()=>this.useWorld(t,a)),this.picker.append(a)}),this.useWorld(e[0]??Ii,this.picker.firstElementChild)}useWorld(e,t){var n,a,s,r,o;for(const l of this.picker.children)l.classList.toggle("active",l===t);e!==this.world.setup&&(this.world=new ds(e),this.applied=0,this.sent=0,(n=this.view)==null||n.setWorld(e),(a=this.view)==null||a.place(this.world.pose,this.world.trail),(s=this.view)==null||s.setLed(void 0),(r=this.view)==null||r.setScreen(void 0),this.updateStatus(),(o=this.onWorldChange)==null||o.call(this))}reset(){var e,t,n;this.world.reset(),this.applied=0,this.sent=0,this.realSensors=void 0,(e=this.view)==null||e.place(this.world.pose,this.world.trail),(t=this.view)==null||t.setLed(void 0),(n=this.view)==null||n.setScreen(void 0),this.updateStatus()}prepare(e){e.robotSensors={...this.controls,...this.world.sensors()}}setupControls(){for(const e of this.element.querySelectorAll(".visubot-controls input[type=range]")){const t=e.parentElement.querySelector("output"),n=()=>{this.controls[e.name]=Number(e.value),t.textContent=e.value};e.addEventListener("input",n),n()}for(const e of this.element.querySelectorAll(".visubot-controls button[name]"))e.addEventListener("click",()=>{const t=e.name;this.controls[t]=!0,e.classList.add("pressed"),window.clearTimeout(this.pressTimers.get(t)),this.pressTimers.set(t,window.setTimeout(()=>{this.controls[t]=!1,e.classList.remove("pressed")},1e3))})}setupCheck(){for(const e of this.check.querySelectorAll("button[data-py]"))e.addEventListener("click",()=>{const{after:t,wait:n}=e.dataset;ge.run(e.dataset.py).then(()=>t?new Promise(a=>setTimeout(a,Number(n))).then(()=>ge.run(t)):void 0).catch(a=>this.liveFailed(a))});this.check.addEventListener("toggle",()=>void this.readCheck())}async readCheck(){if(!this.checking){this.checking=!0;try{for(;this.check.open&&ge.connected;){for(const e of this.check.querySelectorAll("[data-sensor]")){if(!this.check.open||!ge.connected)break;const t=e.dataset.sensor,n=await ge.ask(jt[t].python).catch(()=>{});n!==void 0&&(e.textContent=typeof jt[t].simulated=="boolean"?n===!0||typeof n=="number"&&n!==0?"✓":"–":String(typeof n=="number"?Math.round(n*10)/10:n))}await new Promise(e=>setTimeout(e,200))}}finally{this.checking=!1}}}get live(){return ge.connected}async prepareLive(e,t=[]){const n={};for(const a of new Set(["getDistance","getLine",...t])){const s=await ge.ask(jt[a].python);typeof jt[a].simulated=="boolean"?n[a]=s===!0||typeof s=="number"&&s!==0:typeof jt[a].simulated=="string"?n[a]=typeof s=="string"?s:String(jt[a].simulated):n[a]=typeof s=="number"?a==="getDistance"?Math.round(s):s:0}this.realSensors=n,e.robotSensors={...this.controls,...this.world.sensors(),...n}}async drive(e){for(;this.sentsetTimeout(n,t.args[0]))}}liveFailed(e){ge.disconnect(e instanceof Error?e.message:String(e))}updateLive(){this.liveStatus.textContent=bg(),this.liveStatus.classList.toggle("connected",ge.connected),this.check.hidden=!ge.connected,ge.connected||(this.check.open=!1),this.updateStatus()}follow(e,t){var a,s,r,o;for(;this.appliedl!==0);this.world.tick(s0),n&&((o=this.view)==null||o.moveTo(this.world.pose,this.world.trail,t)),this.updateStatus()}dispose(){var e;this.stopListening();for(const t of this.pressTimers.values())window.clearTimeout(t);(e=this.view)==null||e.dispose(),this.view=void 0,this.loading=void 0}updateStatus(){const e=this.world.lineState().toString(2).padStart(4,"0"),t=[`${p("web_visubot_distance")}: ${this.world.distance()} cm`,`${p("web_visubot_line")}: ${e}`];this.world.bumps>0&&t.push(`⚠︎ ${p("web_visubot_bumps")}: ${this.world.bumps}`),this.world.screen!==void 0&&t.push(`📺 ${this.world.screen}`),this.realSensors&&ge.connected&&t.push(`🤖 ${p("web_visubot_distance")}: ${this.realSensors.getDistance} cm · ${p("web_visubot_line")}: ${Number(this.realSensors.getLine).toString(2).padStart(4,"0")}`),this.status.textContent=t.join(" · ")}}let H1;function fg(i,e){try{H1??(H1=new AudioContext);const t=H1.createOscillator(),n=H1.createGain();t.type="square",t.frequency.value=Math.max(20,Math.min(2e4,i)),n.gain.value=.05,t.connect(n).connect(H1.destination);const a=H1.currentTime+Math.min(Math.max(e,0),5e3)/1e3;t.start(),t.stop(a)}catch{}}function CZ(){const i=(t,n,a,s,r)=>``,e=(t,n,a)=>``;return`
    🎛 ${p("web_visubot_controls")} + ${cm(p(t))}`}class PZ{constructor(e=Ii){y(this,"element");y(this,"world");y(this,"view");y(this,"loading");y(this,"status");y(this,"stage");y(this,"picker");y(this,"applied",0);y(this,"sent",0);y(this,"liveStatus");y(this,"viewport");y(this,"stopListening");y(this,"realSensors");y(this,"controls",{getBrightness:50,getLoudness:0,getPitch:0,getRoll:0});y(this,"pressTimers",new Map);y(this,"check");y(this,"checking",!1);y(this,"onWorldChange");this.world=new ds(e),this.element=document.createElement("section"),this.element.className="visubot",this.element.innerHTML=`

    ${p("web_visubot_world")}

    ${p("web_visubot_world_in_preview")}

    ${CZ()}${OZ()}`,this.stage=this.element.querySelector(".visubot-stage"),this.picker=this.element.querySelector(".visubot-worlds"),this.status=this.element.querySelector(".visubot-status"),this.liveStatus=this.element.querySelector(".visubot-live"),this.viewport=this.element.querySelector(".visubot-viewport"),this.stopListening=ge.listen(()=>this.updateLive()),this.setupControls(),this.check=this.element.querySelector(".visubot-check"),this.setupCheck(),this.updateLive(),this.updateStatus()}show(){this.loading??(this.loading=K(async()=>{const{Robot3D:e}=await import("./robot3d-BNw8Z2K3.js");return{Robot3D:e}},[],import.meta.url).then(({Robot3D:e})=>{this.view=new e(this.stage),this.view.setWorld(this.world.setup),this.view.place(this.world.pose,this.world.trail),this.view.setLeds(this.world.leds)}).catch(()=>{this.stage.textContent=p("web_visubot_no_3d")}))}restoreViewport(){this.viewport.parentElement!==this.element&&this.liveStatus.after(this.viewport)}setWorlds(e){this.picker.replaceChildren(),this.picker.hidden=e.length<2,e.forEach((t,n)=>{const a=document.createElement("button");a.textContent=p("web_visubot_world_fmt",n+1),a.addEventListener("click",()=>this.useWorld(t,a)),this.picker.append(a)}),this.useWorld(e[0]??Ii,this.picker.firstElementChild)}useWorld(e,t){var n,a,s,r,o;for(const l of this.picker.children)l.classList.toggle("active",l===t);e!==this.world.setup&&(this.world=new ds(e),this.applied=0,this.sent=0,(n=this.view)==null||n.setWorld(e),(a=this.view)==null||a.place(this.world.pose,this.world.trail),(s=this.view)==null||s.setLed(void 0),(r=this.view)==null||r.setScreen(void 0),this.updateStatus(),(o=this.onWorldChange)==null||o.call(this))}reset(){var e,t,n;this.world.reset(),this.applied=0,this.sent=0,this.realSensors=void 0,(e=this.view)==null||e.place(this.world.pose,this.world.trail),(t=this.view)==null||t.setLed(void 0),(n=this.view)==null||n.setScreen(void 0),this.updateStatus()}prepare(e){e.robotSensors={...this.controls,...this.world.sensors()}}setupControls(){for(const e of this.element.querySelectorAll(".visubot-controls input[type=range]")){const t=e.parentElement.querySelector("output"),n=()=>{this.controls[e.name]=Number(e.value),t.textContent=e.value};e.addEventListener("input",n),n()}for(const e of this.element.querySelectorAll(".visubot-controls button[name]"))e.addEventListener("click",()=>{const t=e.name;this.controls[t]=!0,e.classList.add("pressed"),window.clearTimeout(this.pressTimers.get(t)),this.pressTimers.set(t,window.setTimeout(()=>{this.controls[t]=!1,e.classList.remove("pressed")},1e3))})}setupCheck(){for(const e of this.check.querySelectorAll("button[data-py]"))e.addEventListener("click",()=>{const{after:t,wait:n}=e.dataset;ge.run(e.dataset.py).then(()=>t?new Promise(a=>setTimeout(a,Number(n))).then(()=>ge.run(t)):void 0).catch(a=>this.liveFailed(a))});this.check.addEventListener("toggle",()=>void this.readCheck())}async readCheck(){if(!this.checking){this.checking=!0;try{for(;this.check.open&&ge.connected;){for(const e of this.check.querySelectorAll("[data-sensor]")){if(!this.check.open||!ge.connected)break;const t=e.dataset.sensor,n=await ge.ask(jt[t].python).catch(()=>{});n!==void 0&&(e.textContent=typeof jt[t].simulated=="boolean"?n===!0||typeof n=="number"&&n!==0?"✓":"–":String(typeof n=="number"?Math.round(n*10)/10:n))}await new Promise(e=>setTimeout(e,200))}}finally{this.checking=!1}}}get live(){return ge.connected}async prepareLive(e,t=[]){const n={};for(const a of new Set(["getDistance","getLine",...t])){const s=await ge.ask(jt[a].python);typeof jt[a].simulated=="boolean"?n[a]=s===!0||typeof s=="number"&&s!==0:typeof jt[a].simulated=="string"?n[a]=typeof s=="string"?s:String(jt[a].simulated):n[a]=typeof s=="number"?a==="getDistance"?Math.round(s):s:0}this.realSensors=n,e.robotSensors={...this.controls,...this.world.sensors(),...n}}async drive(e){for(;this.sentsetTimeout(n,t.args[0]))}}liveFailed(e){ge.disconnect(e instanceof Error?e.message:String(e))}updateLive(){this.liveStatus.textContent=bg(),this.liveStatus.classList.toggle("connected",ge.connected),this.check.hidden=!ge.connected,ge.connected||(this.check.open=!1),this.updateStatus()}follow(e,t){var a,s,r,o;for(;this.appliedl!==0);this.world.tick(s0),n&&((o=this.view)==null||o.moveTo(this.world.pose,this.world.trail,t)),this.updateStatus()}dispose(){var e;this.stopListening();for(const t of this.pressTimers.values())window.clearTimeout(t);(e=this.view)==null||e.dispose(),this.view=void 0,this.loading=void 0}updateStatus(){const e=this.world.lineState().toString(2).padStart(4,"0"),t=[`${p("web_visubot_distance")}: ${this.world.distance()} cm`,`${p("web_visubot_line")}: ${e}`];this.world.bumps>0&&t.push(`⚠︎ ${p("web_visubot_bumps")}: ${this.world.bumps}`),this.world.screen!==void 0&&t.push(`📺 ${this.world.screen}`),this.realSensors&&ge.connected&&t.push(`🤖 ${p("web_visubot_distance")}: ${this.realSensors.getDistance} cm · ${p("web_visubot_line")}: ${Number(this.realSensors.getLine).toString(2).padStart(4,"0")}`),this.status.textContent=t.join(" · ")}}let H1;function fg(i,e){try{H1??(H1=new AudioContext);const t=H1.createOscillator(),n=H1.createGain();t.type="square",t.frequency.value=Math.max(20,Math.min(2e4,i)),n.gain.value=.05,t.connect(n).connect(H1.destination);const a=H1.currentTime+Math.min(Math.max(e,0),5e3)/1e3;t.start(),t.stop(a)}catch{}}function CZ(){const i=(t,n,a,s,r)=>``,e=(t,n,a)=>``;return`
    🎛 ${p("web_visubot_controls")}

    ${p("web_visubot_controls_hint")}

    ${i("getBrightness","web_visubot_sensor_brightness",0,100,50)} ${i("getLoudness","web_visubot_sensor_loudness",0,100,0)} @@ -64529,7 +64528,7 @@ ${i}

    ${yn(p("web_visubot_preview_hint"))}

    -

    `;const e=t=>this.element.querySelector(t);this.heightBar=e(".robotpreview-height"),this.stage=e(".robotpreview-stage"),this.status=e(".robotpreview-status"),this.picker=e(".visubot-worlds"),this.playButton=e(".robotpreview-play"),this.stackButton=e(".robotpreview-stack"),this.playButton.addEventListener("click",()=>this.playTimer===void 0?this.play():this.stopPlaying(!0)),this.stackButton.addEventListener("click",()=>this.onToggleStacked()),e(".learn-hide").addEventListener("click",()=>this.onHide()),this.rail=document.createElement("button"),this.rail.className="learn-rail robotpreview-rail",this.setStacked(!1),this.relabel()}hostSimulation(e){var t;e!==this.simulation&&((t=this.simulation)==null||t.remove(),this.simulation=e,this.element.classList.toggle("simulation",!!e),e&&(this.pause(),this.status.after(e)),this.relabel())}relabel(){const e=a=>this.element.querySelector(a),t=!!this.simulation;e("h2").textContent=`🤖 ${p(t?"web_visubot_preview_sim_title":"web_visubot_preview_title")}`,e(".hint").textContent=p(t?"web_visubot_preview_sim_hint":"web_visubot_preview_hint"),this.heightBar.title=p("web_visubot_preview_resize");const n=e(".learn-hide");n.title=p("web_visubot_preview_hide"),n.setAttribute("aria-label",p("web_visubot_preview_hide")),this.rail.title=p("web_visubot_preview_show"),this.rail.innerHTML=`${_t}🤖 ${yn(p("web_visubot_preview_title"))}`,this.setStacked(this.stackButton.textContent==="▥"),this.stopPlaying(!1),this.worldsKey=void 0,this.lastKey=void 0}setStacked(e){const t=e?"web_visubot_preview_side":"web_visubot_preview_stack";this.stackButton.innerHTML=e?"▥":"⬓",this.stackButton.className="icon robotpreview-stack",this.stackButton.dataset.tip=p(t),this.stackButton.setAttribute("aria-label",p(t))}show(){this.loading??(this.loading=K(async()=>{const{Robot3D:e}=await import("./robot3d-I0g91EHr.js");return{Robot3D:e}},[],import.meta.url).then(({Robot3D:e})=>{var t;this.view=new e(this.stage),this.view.setWorld(this.setup),this.showFrame((t=this.result)==null?void 0:t.frames.at(-1))}).catch(()=>{this.stage.textContent=p("web_visubot_no_3d")}))}update(e,t,n,a,s){if(this.simulation)return;this.show(),a!==this.worldsKey&&(this.worldsKey=a,this.setWorlds(n)),this.input={doc:e,resolve:t};const r=JSON.stringify(s)+` +

    `;const e=t=>this.element.querySelector(t);this.heightBar=e(".robotpreview-height"),this.stage=e(".robotpreview-stage"),this.status=e(".robotpreview-status"),this.picker=e(".visubot-worlds"),this.playButton=e(".robotpreview-play"),this.stackButton=e(".robotpreview-stack"),this.playButton.addEventListener("click",()=>this.playTimer===void 0?this.play():this.stopPlaying(!0)),this.stackButton.addEventListener("click",()=>this.onToggleStacked()),e(".learn-hide").addEventListener("click",()=>this.onHide()),this.rail=document.createElement("button"),this.rail.className="learn-rail robotpreview-rail",this.setStacked(!1),this.relabel()}hostSimulation(e){var t;e!==this.simulation&&((t=this.simulation)==null||t.remove(),this.simulation=e,this.element.classList.toggle("simulation",!!e),e&&(this.pause(),this.status.after(e)),this.relabel())}relabel(){const e=a=>this.element.querySelector(a),t=!!this.simulation;e("h2").textContent=`🤖 ${p(t?"web_visubot_preview_sim_title":"web_visubot_preview_title")}`,e(".hint").textContent=p(t?"web_visubot_preview_sim_hint":"web_visubot_preview_hint"),this.heightBar.title=p("web_visubot_preview_resize");const n=e(".learn-hide");n.title=p("web_visubot_preview_hide"),n.setAttribute("aria-label",p("web_visubot_preview_hide")),this.rail.title=p("web_visubot_preview_show"),this.rail.innerHTML=`${_t}🤖 ${yn(p("web_visubot_preview_title"))}`,this.setStacked(this.stackButton.textContent==="▥"),this.stopPlaying(!1),this.worldsKey=void 0,this.lastKey=void 0}setStacked(e){const t=e?"web_visubot_preview_side":"web_visubot_preview_stack";this.stackButton.innerHTML=e?"▥":"⬓",this.stackButton.className="icon robotpreview-stack",this.stackButton.dataset.tip=p(t),this.stackButton.setAttribute("aria-label",p(t))}show(){this.loading??(this.loading=K(async()=>{const{Robot3D:e}=await import("./robot3d-BNw8Z2K3.js");return{Robot3D:e}},[],import.meta.url).then(({Robot3D:e})=>{var t;this.view=new e(this.stage),this.view.setWorld(this.setup),this.showFrame((t=this.result)==null?void 0:t.frames.at(-1))}).catch(()=>{this.stage.textContent=p("web_visubot_no_3d")}))}update(e,t,n,a,s){if(this.simulation)return;this.show(),a!==this.worldsKey&&(this.worldsKey=a,this.setWorlds(n)),this.input={doc:e,resolve:t};const r=JSON.stringify(s)+` `+JSON.stringify(e);r!==this.lastKey&&(this.lastKey=r,window.clearTimeout(this.pending),this.pending=window.setTimeout(()=>this.recompute(),120))}setWorlds(e){this.worlds=e,this.picker.replaceChildren(),this.picker.hidden=e.length<2,e.forEach((t,n)=>{const a=document.createElement("button");a.textContent=p("web_visubot_world_fmt",n+1),a.addEventListener("click",()=>this.useWorld(t)),this.picker.append(a)}),this.useWorld(e[0]??Ii)}useWorld(e){var t;this.worlds.forEach((n,a)=>{var s;return(s=this.picker.children[a])==null?void 0:s.classList.toggle("active",n===e)}),!(e===this.setup&&this.result)&&(this.setup=e,(t=this.view)==null||t.setWorld(e),this.recompute())}recompute(){var e;if(this.pending=void 0,this.stopPlaying(!1),!!this.input){try{this.result=qF(this.input.doc,this.input.resolve,this.setup)}catch{this.result=void 0}this.showFrame((e=this.result)==null?void 0:e.frames.at(-1)),this.updateStatus()}}showFrame(e,t=0){if(!this.view)return;const n=e??{pose:{...this.setup.start},trail:[{x:this.setup.start.x,y:this.setup.start.y}],leds:Array(5).fill(void 0),screen:void 0};t>0?this.view.moveTo(n.pose,n.trail,t):this.view.place(n.pose,n.trail),this.view.setLeds(n.leds),this.view.setScreen(n.screen)}play(){var a;const e=(a=this.result)==null?void 0:a.frames;if(!e||e.length<2||!this.view)return;this.stopPlaying(!1);let t=0;this.showFrame(e[0]),this.playButton.innerHTML=se.stop,this.playButton.dataset.tip=p("web_visubot_preview_stop"),this.playButton.setAttribute("aria-label",p("web_visubot_preview_stop"));const n=()=>{if(t++,t>=e.length){this.stopPlaying(!1);return}const s=e[t];s.tone&&fg(s.tone[0],s.tone[1]),this.showFrame(s,io-30),this.playTimer=window.setTimeout(n,io)};this.playTimer=window.setTimeout(n,io)}stopPlaying(e){var t;this.playTimer!==void 0&&window.clearTimeout(this.playTimer),this.playTimer=void 0,this.playButton.innerHTML=se.play,this.playButton.dataset.tip=p("web_visubot_preview_play"),this.playButton.setAttribute("aria-label",p("web_visubot_preview_play")),e&&this.showFrame((t=this.result)==null?void 0:t.frames.at(-1))}updateStatus(){const e=this.result;if(this.playButton.disabled=!e||e.frames.length<2,!e){this.status.textContent="";return}const t=[p("web_visubot_preview_distance_fmt",e.distance)];e.bumps>0&&t.push(`⚠︎ ${p("web_visubot_bumps")}: ${e.bumps}`),e.stop==="input"?t.push(p("web_visubot_preview_input")):e.stop==="limit"?t.push(p("web_visubot_preview_limit")):e.stop==="error"&&e.notice&&t.push(`⚠︎ ${t1(e.notice)}`),this.status.textContent=t.join(" · ")}pause(){window.clearTimeout(this.pending),this.pending=void 0,this.lastKey=void 0,this.stopPlaying(!1)}}const $F={left:12,top:10},YF=8,Es=8e3,xi=16,ao=12,i2="#fafafa";function a2(i){const e=i.caption.trim();return e===""?p("diagram_title_placeholder"):e}function od(i){let e=i.trim().replace(/\.visustruct$/i,"");if(e==="")return"";for(e=e.replace(/\s/g,"-").replace(/[/:\\*?"<>|]/g,"-");e.includes("--");)e=e.replace(/--/g,"-");return e=e.replace(/^-+|-+$/g,""),e.length>120&&(e=e.slice(0,120).replace(/^-+|-+$/g,"")),e}function ld(i,e){return od(i.caption)||od(e)||"VisuStruct"}function XF(i,e,t){const n=i.split(/\s+/),a=[];let s="";for(const r of n){const o=s?`${s} ${r}`:r;s&&t(o,xi,"bold")>e?(a.push(s),s=r):s=o}if(s&&a.push(s),a.length>2){let r=a.slice(1).join(" ");for(;r.length>1&&t(r+"…",xi,"bold")>e;)r=r.slice(0,-1);return[a[0],r+"…"]}return a}function ud(i,e,t,n=320){const a={...i,elements:i.elements.map(Xa)},s=new Vd(e,t).layout(a,$F),r=Math.min(Es,Math.max(n,s.canvasSize.width)),o=Math.min(Es,Math.max(n,s.canvasSize.height));if(r<=2||o<=2)return;const l=XF(a2(i),r-2*ao,t),u=Math.ceil(xi*1.2),m=Math.min(56,l.length*u+2),c=m+o,d=new $d(e,t).render(s,{width:r,height:o},void 0,YF);d.setAttribute("y",String(m)),d.removeAttribute("class");const h=Se("svg",{xmlns:"http://www.w3.org/2000/svg",width:r,height:c,viewBox:`0 0 ${r} ${c}`});h.append(Se("rect",{x:0,y:0,width:r,height:c,fill:i2}));const g=Se("text",{x:ao,y:0,"font-family":Ns,"font-size":xi,"font-weight":600,fill:"black"});return l.forEach((f,b)=>{const x=Se("tspan",{x:ao,y:b*u+xi});x.textContent=f,g.append(x)}),h.append(g,d),{svg:h,width:r,height:c}}function s2(i){return` `+new XMLSerializer().serializeToString(i.svg)}async function md(i,e){const t=Math.max(1,Math.min(e,Es/i.width,Es/i.height)),n=URL.createObjectURL(new Blob([s2(i)],{type:"image/svg+xml"}));try{const a=new Image;a.src=n,await a.decode();const s=document.createElement("canvas");s.width=Math.round(i.width*t),s.height=Math.round(i.height*t);const r=s.getContext("2d");return r.fillStyle=i2,r.fillRect(0,0,s.width,s.height),r.drawImage(a,0,0,s.width,s.height),s}finally{URL.revokeObjectURL(n)}}function KF(i){return new Promise((e,t)=>i.toBlob(n=>n?e(n):t(new Error("PNG konnte nicht erzeugt werden.")),"image/png"))}function eR(i,e){const a=Math.max(1,i),s=Math.max(1,e),r=f=>{const b=f.width-64,x=f.height-64;return{s:Math.min(b/a,x/s)*.98,cw:b,ch:x}},o={width:595,height:842},l={width:842,height:595},u=r(o),m=r(l),[c,d]=m.s>u.s?[l,m]:[o,u],h=a*d.s,g=s*d.s;return{page:c,draw:{x:32+(d.cw-h)/2,y:32+(d.ch-g)/2,width:h,height:g}}}async function tR(i){const e=new Blob([i]).stream().pipeThrough(new CompressionStream("deflate"));return new Uint8Array(await new Response(e).arrayBuffer())}function cd(i){let e="FEFF";for(let t=0;t`}async function nR(i,e,t,n,a){const{page:s,draw:r}=eR(n.width,n.height),o=await tR(i),l=x=>(Math.round(x*100)/100).toString(),u=`q ${l(r.width)} 0 0 ${l(r.height)} ${l(r.x)} ${l(s.height-r.y-r.height)} cm /Im0 Do Q`,m=new TextEncoder,c=[["<< /Type /Catalog /Pages 2 0 R >>"],["<< /Type /Pages /Kids [3 0 R] /Count 1 >>"],[`<< /Type /Page /Parent 2 0 R /MediaBox [0 0 ${s.width} ${s.height}] /Resources << /XObject << /Im0 4 0 R >> >> /Contents 5 0 R >>`],[`<< /Type /XObject /Subtype /Image /Width ${e} /Height ${t} /ColorSpace /DeviceRGB /BitsPerComponent 8 /Filter /FlateDecode /Length ${o.length} >> stream @@ -64837,4 +64836,4 @@ ${c}

    ${W(p("close_unsaved_title"))}

    ${W(p("web_discard_message_fmt",this.fileName))}

    -
    `,t.addEventListener("click",n=>{const a=n.target.dataset.r;a===void 0&&n.target!==t||(t.remove(),e(a==="1"))}),document.body.append(t),t.querySelector('[data-r="0"]').focus()}):Promise.resolve(!0)}showMessage(e){this.statusLine.textContent=e,this.statusLine.classList.add("message"),setTimeout(()=>{this.statusLine.classList.remove("message"),this.updateStatus()},6e3)}loadXML(e,t,n){let a;try{a=Nl(e)}catch(s){this.showMessage(p("web_err_unreadable_fmt",t,s.message));return}(this.dirty||this.tab.fileName||this.tab.exerciseId)&&this.addTab(),this.doc=a,this.tab.fileName=t.replace(/\.(strk|xml)$/i,".visustruct"),this.fileHandle=n&&/\.visustruct$/i.test(t)?n:void 0,this.resetHistory()}async open(e){const t=window;if(!t.showOpenFilePicker||this.inViewer)return e.click();try{const[n]=await t.showOpenFilePicker({types:pd()}),a=await n.getFile();this.loadXML(await a.text(),a.name,n)}catch{}}async save(){var n,a;if(!this.downloads&&await this.saveToWorkspace())return;const e=new Blob([u1(this.doc)],{type:"application/xml"}),t=window;try{if(this.downloads){const s=this.fileName+".txt";await this.downloads.save({filename:s,data:e}),(n=this.tab).fileName??(n.fileName=this.fileName),this.dirty=!1,this.render(),this.showMessage(p("web_saved_txt_fmt",s));return}if(!this.fileHandle&&t.showSaveFilePicker&&!this.inViewer&&(this.fileHandle=await t.showSaveFilePicker({suggestedName:this.fileName,types:pd()}),this.tab.fileName=this.fileHandle.name),this.fileHandle){const s=await this.fileHandle.createWritable();await s.write(e),await s.close()}else{const s=document.createElement("a");s.href=URL.createObjectURL(e),s.download=this.fileName,s.click(),setTimeout(()=>URL.revokeObjectURL(s.href),1e3)}(a=this.tab).fileName??(a.fileName=this.fileName),this.dirty=!1,this.render()}catch{}}async exportDiagram(e){if(e==="visustruct"){const s=ld(this.doc,un(this.tab));return this.offerDownload(`${s}.visustruct`,new Blob([u1(this.doc)],{type:"application/xml"}))}const t=ud(this.doc,this.metrics,this.measure);if(!t){this.showMessage(p(e==="print"?"err_diagram_too_small_print":"err_diagram_too_small_export"));return}const n=ld(this.doc,un(this.tab)),a=Math.max(2,window.devicePixelRatio||1)*this.zoom;try{switch(e){case"svg":{t.svg.setAttribute("width",String(t.width*this.zoom)),t.svg.setAttribute("height",String(t.height*this.zoom)),await this.offerDownload(`${n}.svg`,new Blob([s2(t)],{type:"image/svg+xml"}));break}case"png":{const s=await md(t,a);await this.offerDownload(`${n}.png`,await KF(s));break}case"pdf":{const s=await md(t,Math.max(a,3)),r=await nR(iR(s),s.width,s.height,t,a2(this.doc));await this.offerDownload(`${n}.pdf`,r);break}case"print":this.printDiagram(t);break}}catch(s){this.showMessage(p("web_export_failed_fmt",s instanceof Error?s.message:String(s)))}}printDiagram(e){const t=document.createElement("div");t.className="print-sheet",e.svg.removeAttribute("width"),e.svg.removeAttribute("height"),t.append(e.svg),document.body.append(t);const n=()=>t.remove();window.addEventListener("afterprint",n,{once:!0});try{window.print()}catch{n(),this.showMessage(`${p("err_print_unavailable")} ${p("web_print_hint")}`);return}setTimeout(n,6e4)}async offerDownload(e,t){try{if(this.downloads){try{await this.downloads.save({filename:e,data:t}),this.showMessage(p("web_saved_fmt",e))}catch{await this.downloads.save({filename:e+".txt",data:t}),this.showMessage(p("web_saved_txt_fmt",e+".txt"))}return}const n=document.createElement("a");n.href=URL.createObjectURL(t),n.download=e,n.click(),setTimeout(()=>URL.revokeObjectURL(n.href),1e3)}catch{this.showMessage(p("err_save_failed_fmt",e))}}setupFileDrop(){window.addEventListener("dragover",e=>{var t;(t=e.dataTransfer)!=null&&t.types.includes("Files")&&(e.preventDefault(),this.root.classList.add("file-drag"))}),window.addEventListener("dragleave",e=>{e.relatedTarget===null&&this.root.classList.remove("file-drag")}),window.addEventListener("drop",async e=>{var n;this.root.classList.remove("file-drag");const t=(n=e.dataTransfer)==null?void 0:n.files[0];t&&(e.preventDefault(),this.loadXML(await t.text(),t.name))})}onKeyDown(e){var a,s;const t=e.metaKey||e.ctrlKey,n=e.target instanceof HTMLTextAreaElement||e.target instanceof HTMLInputElement||((a=e.target)==null?void 0:a.isContentEditable)===!0;if(t&&e.key.toLowerCase()==="s")e.preventDefault(),this.save();else if(t&&e.key.toLowerCase()==="p")e.preventDefault(),this.simulating||this.exportDiagram("print");else if(t&&e.key.toLowerCase()==="o")e.preventDefault(),this.open(this.root.querySelector("input[type=file]"));else{if(n||this.simulating)return;t&&e.key.toLowerCase()==="z"?(e.preventDefault(),e.shiftKey?this.redo():this.undo()):t&&e.key.toLowerCase()==="c"&&!((s=getSelection())!=null&&s.toString())?this.copySelection()&&e.preventDefault():t&&e.key.toLowerCase()==="x"?(e.preventDefault(),this.cutSelection()):t&&e.key.toLowerCase()==="v"?(e.preventDefault(),this.paste()):t&&e.key.toLowerCase()==="y"?(e.preventDefault(),this.redo()):e.key==="Delete"||e.key==="Backspace"?(e.preventDefault(),this.deleteSelection()):e.key==="Escape"&&(this.drag?this.endDrag():(this.selected=void 0,this.render()))}}svgPoint(e,t){if(!this.svg)return;const n=this.svg.getBoundingClientRect(),a=e-n.left,s=t-n.top;if(!(a<0||s<0||a>n.width||s>n.height))return{x:a/this.zoom,y:s/this.zoom}}nodeAt(e,t){for(let n=this.flat.length-1;n>=0;n--){const a=this.flat[n].frame;if(e>=a.x&&e<=a.x+a.width&&t>=a.y&&t<=a.y+a.height)return this.flat[n]}}onCanvasPointerDown(e){if(this.simulating)return;const t=this.svgPoint(e.clientX,e.clientY);if(!t)return;document.activeElement instanceof HTMLElement&&document.activeElement.blur();const n=this.nodeAt(t.x,t.y),a=n&&this.selected&&fo(n.idPath,this.selected);this.selected=n==null?void 0:n.idPath,this.render(),n&&e.pointerType!=="touch"&&!(In(this.doc,n.idPath)&&!a)&&this.beginDrag(e,{kind:"move",path:n.idPath})}beginDrag(e,t){e.button!==0||this.simulating||(e.preventDefault(),this.drag={source:t,pointerId:e.pointerId,startX:e.clientX,startY:e.clientY,active:!1})}onPointerMove(e){const t=this.drag;if(!t||e.pointerId!==t.pointerId)return;if(!t.active){if(Math.hypot(e.clientX-t.startX,e.clientY-t.startY)<5)return;t.active=!0,t.ghost=this.makeGhost(t.source),document.body.append(t.ghost),this.root.classList.add("dragging")}t.ghost.style.transform=`translate(${e.clientX+12}px, ${e.clientY+12}px)`,this.autoScroll(e.clientX,e.clientY);const n=this.svgPoint(e.clientX,e.clientY);t.target=n?this.dropTargetAt(n.x,n.y,t.source):void 0,this.showDropTarget(t.target)}onPointerUp(e){const t=this.drag;!t||e.pointerId!==t.pointerId||(t.active&&t.target?this.applyDrop(t.source,t.target):!t.active&&t.source.kind==="palette"?this.insertNearSelection(t.source.make()):!t.active&&t.source.kind==="sensor"&&this.insertSensor(t.source.text),this.endDrag())}endDrag(){var e,t;(t=(e=this.drag)==null?void 0:e.ghost)==null||t.remove(),this.drag=void 0,this.root.classList.remove("dragging"),this.showDropTarget(void 0)}makeGhost(e){const t=document.createElement("div");if(t.className="drag-ghost",e.kind==="palette"||e.kind==="sensor")t.textContent=e.label;else{const n=Ot(this.doc,e.path);t.textContent=`${so(n.type)}: ${Zl(n)[0]}`}return t}autoScroll(e,t){const n=this.canvasHost.getBoundingClientRect(),a=40,s=12;t>n.bottom-a&&tn.top-a&&(this.canvasHost.scrollTop-=s),e>n.right-a&&en.left-a&&(this.canvasHost.scrollLeft-=s)}dropTargetAt(e,t,n){var l;const a=((l=this.layout)==null?void 0:l.elements)??[],s=this.nodeAt(e,t);if(n.kind==="sensor")return!s||In(this.doc,s.idPath)?void 0:gd.includes(Ot(this.doc,s.idPath).type)?{kind:"condition",path:s.idPath,frame:s.frame}:void 0;if(!s){const u=a[a.length-1];if(!u)return;const m=u.frame.y+u.frame.height;return t>m?n.kind==="move"&&n.path.length===1&&n.path[0]===a.length-1?void 0:{kind:"rootAppend",frame:{x:u.frame.x,y:m,width:u.frame.width,height:0}}:t=n.path.length&&n.path.every((u,m)=>r[m]===u)?void 0:In(this.doc,r)?{kind:"replace",path:r,frame:s.frame}:{kind:t"]/g,e=>({"&":"&","<":"<",">":">",'"':"""})[e])}function Zd(i){if(!i)return[];for(const e of[...Ct.flatMap(t=>t.steps.flatMap(n=>n.blocks)),...An.flatMap(t=>t.blocks)])if(!(e.kind!=="exercise"||e.exercise.id!==i))return e.exercise.tests.flatMap(t=>{const n=t.world?Ja(t.world):void 0;return n?[n]:[]});return[]}let Jt,Ol,Dl;function Bd(i){const e=i.dataset.tip;if(!e)return;Jt??(Jt=Object.assign(document.createElement("div"),{className:"tooltip",role:"tooltip"})),Jt.isConnected||document.body.append(Jt),Jt.textContent=e,Jt.hidden=!1;const t=i.getBoundingClientRect(),n=Jt.offsetWidth,a=Jt.offsetHeight,s=Math.min(Math.max(8,t.left+t.width/2-n/2),window.innerWidth-n-8),r=t.bottom+6+a{if(i.pointerType==="touch")return;const e=i.target.closest("[data-tip]");e!==Dl&&(uo(),e&&(Dl=e,Ol=window.setTimeout(()=>Bd(e),350)))}),document.addEventListener("focusin",i=>{const e=i.target.closest("[data-tip]");uo(),e!=null&&e.matches(":focus-visible")&&Bd(e)});for(const i of["pointerdown","focusout","scroll","keydown"])document.addEventListener(i,uo,!0)}const Ml="visustruct.reloadedAfterError";function u2(){try{const i=Number(sessionStorage.getItem(Ml));if(i&&Date.now()-i<3e4)return!1;sessionStorage.setItem(Ml,String(Date.now()))}catch{return!1}return location.reload(),!0}function SR(i){console.error(i);const e=(navigator.language||"").toLowerCase().startsWith("de"),t=document.createElement("div");t.className="startup-error";const n=document.createElement("h1");n.textContent=e?"VisuStruct konnte nicht starten":"VisuStruct could not start";const a=document.createElement("p");a.textContent=e?"Wahrscheinlich gibt es gerade eine neue Version. Lade die Seite neu. Hilft das nicht, drücke Strg+Umschalt+R (Mac: ⌘⇧R).":"There is probably a new version. Reload the page. If that does not help, press Ctrl+Shift+R (Mac: ⌘⇧R).";const s=document.createElement("button");s.textContent=e?"Neu laden":"Reload",s.addEventListener("click",()=>location.reload());const r=document.createElement("pre");r.textContent=String(i instanceof Error?i.message:i),t.append(n,a,s,r),(document.getElementById("app")??document.body).replaceWith(t)}window.addEventListener("vite:preloadError",i=>{u2()&&i.preventDefault()});const TR=X2();Promise.all([ah(TR,!1),ih($2(),!1)]).then(()=>{l2(),kR();const i=new URLSearchParams(location.search);i.has("visuobject")&&hg(),i.has("visuflow")&&pg();const e=document.getElementById("app"),t=!i.has("visustruct")&&!i.has("visubot");if(dg()&&t)return K(async()=>{const{ObjectApp:n}=await import("./objectApp-exr4obxz.js").then(a=>a.g);return{ObjectApp:n}},[],import.meta.url).then(({ObjectApp:n})=>void new n(e));if(gg()&&t)return K(async()=>{const{FlowApp:n}=await import("./flowApp-4s69NVPv.js");return{FlowApp:n}},[],import.meta.url).then(({FlowApp:n})=>void new n(e));new wR(e)}).then(()=>{try{sessionStorage.removeItem(Ml)}catch{}}).catch(i=>{/dynamically imported module|Importing a module script failed|error loading dynamically/i.test(String(i))&&u2()||SR(i)});export{qn as C,_F as J,Qb as L,K as _,hF as a,BF as b,Yf as c,OR as d,pg as e,Sr as f,vR as g,la as h,se as i,WZ as j,LZ as k,s1 as l,CR as m,hg as n,od as o,CF as p,s2 as q,hm as r,RZ as s,p as t,md as u,KF as v,Lo as w,nR as x,iR as y}; + `,t.addEventListener("click",n=>{const a=n.target.dataset.r;a===void 0&&n.target!==t||(t.remove(),e(a==="1"))}),document.body.append(t),t.querySelector('[data-r="0"]').focus()}):Promise.resolve(!0)}showMessage(e){this.statusLine.textContent=e,this.statusLine.classList.add("message"),setTimeout(()=>{this.statusLine.classList.remove("message"),this.updateStatus()},6e3)}loadXML(e,t,n){let a;try{a=Nl(e)}catch(s){this.showMessage(p("web_err_unreadable_fmt",t,s.message));return}(this.dirty||this.tab.fileName||this.tab.exerciseId)&&this.addTab(),this.doc=a,this.tab.fileName=t.replace(/\.(strk|xml)$/i,".visustruct"),this.fileHandle=n&&/\.visustruct$/i.test(t)?n:void 0,this.resetHistory()}async open(e){const t=window;if(!t.showOpenFilePicker||this.inViewer)return e.click();try{const[n]=await t.showOpenFilePicker({types:pd()}),a=await n.getFile();this.loadXML(await a.text(),a.name,n)}catch{}}async save(){var n,a;if(!this.downloads&&await this.saveToWorkspace())return;const e=new Blob([u1(this.doc)],{type:"application/xml"}),t=window;try{if(this.downloads){const s=this.fileName+".txt";await this.downloads.save({filename:s,data:e}),(n=this.tab).fileName??(n.fileName=this.fileName),this.dirty=!1,this.render(),this.showMessage(p("web_saved_txt_fmt",s));return}if(!this.fileHandle&&t.showSaveFilePicker&&!this.inViewer&&(this.fileHandle=await t.showSaveFilePicker({suggestedName:this.fileName,types:pd()}),this.tab.fileName=this.fileHandle.name),this.fileHandle){const s=await this.fileHandle.createWritable();await s.write(e),await s.close()}else{const s=document.createElement("a");s.href=URL.createObjectURL(e),s.download=this.fileName,s.click(),setTimeout(()=>URL.revokeObjectURL(s.href),1e3)}(a=this.tab).fileName??(a.fileName=this.fileName),this.dirty=!1,this.render()}catch{}}async exportDiagram(e){if(e==="visustruct"){const s=ld(this.doc,un(this.tab));return this.offerDownload(`${s}.visustruct`,new Blob([u1(this.doc)],{type:"application/xml"}))}const t=ud(this.doc,this.metrics,this.measure);if(!t){this.showMessage(p(e==="print"?"err_diagram_too_small_print":"err_diagram_too_small_export"));return}const n=ld(this.doc,un(this.tab)),a=Math.max(2,window.devicePixelRatio||1)*this.zoom;try{switch(e){case"svg":{t.svg.setAttribute("width",String(t.width*this.zoom)),t.svg.setAttribute("height",String(t.height*this.zoom)),await this.offerDownload(`${n}.svg`,new Blob([s2(t)],{type:"image/svg+xml"}));break}case"png":{const s=await md(t,a);await this.offerDownload(`${n}.png`,await KF(s));break}case"pdf":{const s=await md(t,Math.max(a,3)),r=await nR(iR(s),s.width,s.height,t,a2(this.doc));await this.offerDownload(`${n}.pdf`,r);break}case"print":this.printDiagram(t);break}}catch(s){this.showMessage(p("web_export_failed_fmt",s instanceof Error?s.message:String(s)))}}printDiagram(e){const t=document.createElement("div");t.className="print-sheet",e.svg.removeAttribute("width"),e.svg.removeAttribute("height"),t.append(e.svg),document.body.append(t);const n=()=>t.remove();window.addEventListener("afterprint",n,{once:!0});try{window.print()}catch{n(),this.showMessage(`${p("err_print_unavailable")} ${p("web_print_hint")}`);return}setTimeout(n,6e4)}async offerDownload(e,t){try{if(this.downloads){try{await this.downloads.save({filename:e,data:t}),this.showMessage(p("web_saved_fmt",e))}catch{await this.downloads.save({filename:e+".txt",data:t}),this.showMessage(p("web_saved_txt_fmt",e+".txt"))}return}const n=document.createElement("a");n.href=URL.createObjectURL(t),n.download=e,n.click(),setTimeout(()=>URL.revokeObjectURL(n.href),1e3)}catch{this.showMessage(p("err_save_failed_fmt",e))}}setupFileDrop(){window.addEventListener("dragover",e=>{var t;(t=e.dataTransfer)!=null&&t.types.includes("Files")&&(e.preventDefault(),this.root.classList.add("file-drag"))}),window.addEventListener("dragleave",e=>{e.relatedTarget===null&&this.root.classList.remove("file-drag")}),window.addEventListener("drop",async e=>{var n;this.root.classList.remove("file-drag");const t=(n=e.dataTransfer)==null?void 0:n.files[0];t&&(e.preventDefault(),this.loadXML(await t.text(),t.name))})}onKeyDown(e){var a,s;const t=e.metaKey||e.ctrlKey,n=e.target instanceof HTMLTextAreaElement||e.target instanceof HTMLInputElement||((a=e.target)==null?void 0:a.isContentEditable)===!0;if(t&&e.key.toLowerCase()==="s")e.preventDefault(),this.save();else if(t&&e.key.toLowerCase()==="p")e.preventDefault(),this.simulating||this.exportDiagram("print");else if(t&&e.key.toLowerCase()==="o")e.preventDefault(),this.open(this.root.querySelector("input[type=file]"));else{if(n||this.simulating)return;t&&e.key.toLowerCase()==="z"?(e.preventDefault(),e.shiftKey?this.redo():this.undo()):t&&e.key.toLowerCase()==="c"&&!((s=getSelection())!=null&&s.toString())?this.copySelection()&&e.preventDefault():t&&e.key.toLowerCase()==="x"?(e.preventDefault(),this.cutSelection()):t&&e.key.toLowerCase()==="v"?(e.preventDefault(),this.paste()):t&&e.key.toLowerCase()==="y"?(e.preventDefault(),this.redo()):e.key==="Delete"||e.key==="Backspace"?(e.preventDefault(),this.deleteSelection()):e.key==="Escape"&&(this.drag?this.endDrag():(this.selected=void 0,this.render()))}}svgPoint(e,t){if(!this.svg)return;const n=this.svg.getBoundingClientRect(),a=e-n.left,s=t-n.top;if(!(a<0||s<0||a>n.width||s>n.height))return{x:a/this.zoom,y:s/this.zoom}}nodeAt(e,t){for(let n=this.flat.length-1;n>=0;n--){const a=this.flat[n].frame;if(e>=a.x&&e<=a.x+a.width&&t>=a.y&&t<=a.y+a.height)return this.flat[n]}}onCanvasPointerDown(e){if(this.simulating)return;const t=this.svgPoint(e.clientX,e.clientY);if(!t)return;document.activeElement instanceof HTMLElement&&document.activeElement.blur();const n=this.nodeAt(t.x,t.y),a=n&&this.selected&&fo(n.idPath,this.selected);this.selected=n==null?void 0:n.idPath,this.render(),n&&e.pointerType!=="touch"&&!(In(this.doc,n.idPath)&&!a)&&this.beginDrag(e,{kind:"move",path:n.idPath})}beginDrag(e,t){e.button!==0||this.simulating||(e.preventDefault(),this.drag={source:t,pointerId:e.pointerId,startX:e.clientX,startY:e.clientY,active:!1})}onPointerMove(e){const t=this.drag;if(!t||e.pointerId!==t.pointerId)return;if(!t.active){if(Math.hypot(e.clientX-t.startX,e.clientY-t.startY)<5)return;t.active=!0,t.ghost=this.makeGhost(t.source),document.body.append(t.ghost),this.root.classList.add("dragging")}t.ghost.style.transform=`translate(${e.clientX+12}px, ${e.clientY+12}px)`,this.autoScroll(e.clientX,e.clientY);const n=this.svgPoint(e.clientX,e.clientY);t.target=n?this.dropTargetAt(n.x,n.y,t.source):void 0,this.showDropTarget(t.target)}onPointerUp(e){const t=this.drag;!t||e.pointerId!==t.pointerId||(t.active&&t.target?this.applyDrop(t.source,t.target):!t.active&&t.source.kind==="palette"?this.insertNearSelection(t.source.make()):!t.active&&t.source.kind==="sensor"&&this.insertSensor(t.source.text),this.endDrag())}endDrag(){var e,t;(t=(e=this.drag)==null?void 0:e.ghost)==null||t.remove(),this.drag=void 0,this.root.classList.remove("dragging"),this.showDropTarget(void 0)}makeGhost(e){const t=document.createElement("div");if(t.className="drag-ghost",e.kind==="palette"||e.kind==="sensor")t.textContent=e.label;else{const n=Ot(this.doc,e.path);t.textContent=`${so(n.type)}: ${Zl(n)[0]}`}return t}autoScroll(e,t){const n=this.canvasHost.getBoundingClientRect(),a=40,s=12;t>n.bottom-a&&tn.top-a&&(this.canvasHost.scrollTop-=s),e>n.right-a&&en.left-a&&(this.canvasHost.scrollLeft-=s)}dropTargetAt(e,t,n){var l;const a=((l=this.layout)==null?void 0:l.elements)??[],s=this.nodeAt(e,t);if(n.kind==="sensor")return!s||In(this.doc,s.idPath)?void 0:gd.includes(Ot(this.doc,s.idPath).type)?{kind:"condition",path:s.idPath,frame:s.frame}:void 0;if(!s){const u=a[a.length-1];if(!u)return;const m=u.frame.y+u.frame.height;return t>m?n.kind==="move"&&n.path.length===1&&n.path[0]===a.length-1?void 0:{kind:"rootAppend",frame:{x:u.frame.x,y:m,width:u.frame.width,height:0}}:t=n.path.length&&n.path.every((u,m)=>r[m]===u)?void 0:In(this.doc,r)?{kind:"replace",path:r,frame:s.frame}:{kind:t"]/g,e=>({"&":"&","<":"<",">":">",'"':"""})[e])}function Zd(i){if(!i)return[];for(const e of[...Ct.flatMap(t=>t.steps.flatMap(n=>n.blocks)),...An.flatMap(t=>t.blocks)])if(!(e.kind!=="exercise"||e.exercise.id!==i))return e.exercise.tests.flatMap(t=>{const n=t.world?Ja(t.world):void 0;return n?[n]:[]});return[]}let Jt,Ol,Dl;function Bd(i){const e=i.dataset.tip;if(!e)return;Jt??(Jt=Object.assign(document.createElement("div"),{className:"tooltip",role:"tooltip"})),Jt.isConnected||document.body.append(Jt),Jt.textContent=e,Jt.hidden=!1;const t=i.getBoundingClientRect(),n=Jt.offsetWidth,a=Jt.offsetHeight,s=Math.min(Math.max(8,t.left+t.width/2-n/2),window.innerWidth-n-8),r=t.bottom+6+a{if(i.pointerType==="touch")return;const e=i.target.closest("[data-tip]");e!==Dl&&(uo(),e&&(Dl=e,Ol=window.setTimeout(()=>Bd(e),350)))}),document.addEventListener("focusin",i=>{const e=i.target.closest("[data-tip]");uo(),e!=null&&e.matches(":focus-visible")&&Bd(e)});for(const i of["pointerdown","focusout","scroll","keydown"])document.addEventListener(i,uo,!0)}const Ml="visustruct.reloadedAfterError";function u2(){try{const i=Number(sessionStorage.getItem(Ml));if(i&&Date.now()-i<3e4)return!1;sessionStorage.setItem(Ml,String(Date.now()))}catch{return!1}return location.reload(),!0}function SR(i){console.error(i);const e=(navigator.language||"").toLowerCase().startsWith("de"),t=document.createElement("div");t.className="startup-error";const n=document.createElement("h1");n.textContent=e?"VisuStruct konnte nicht starten":"VisuStruct could not start";const a=document.createElement("p");a.textContent=e?"Wahrscheinlich gibt es gerade eine neue Version. Lade die Seite neu. Hilft das nicht, drücke Strg+Umschalt+R (Mac: ⌘⇧R).":"There is probably a new version. Reload the page. If that does not help, press Ctrl+Shift+R (Mac: ⌘⇧R).";const s=document.createElement("button");s.textContent=e?"Neu laden":"Reload",s.addEventListener("click",()=>location.reload());const r=document.createElement("pre");r.textContent=String(i instanceof Error?i.message:i),t.append(n,a,s,r),(document.getElementById("app")??document.body).replaceWith(t)}window.addEventListener("vite:preloadError",i=>{u2()&&i.preventDefault()});const TR=X2();Promise.all([ah(TR,!1),ih($2(),!1)]).then(()=>{l2(),kR();const i=new URLSearchParams(location.search);i.has("visuobject")&&hg(),i.has("visuflow")&&pg();const e=document.getElementById("app"),t=!i.has("visustruct")&&!i.has("visubot");if(dg()&&t)return K(async()=>{const{ObjectApp:n}=await import("./objectApp-Caze4o4v.js").then(a=>a.g);return{ObjectApp:n}},[],import.meta.url).then(({ObjectApp:n})=>void new n(e));if(gg()&&t)return K(async()=>{const{FlowApp:n}=await import("./flowApp-Bn4c4hPI.js");return{FlowApp:n}},[],import.meta.url).then(({FlowApp:n})=>void new n(e));new wR(e)}).then(()=>{try{sessionStorage.removeItem(Ml)}catch{}}).catch(i=>{/dynamically imported module|Importing a module script failed|error loading dynamically/i.test(String(i))&&u2()||SR(i)});export{qn as C,_F as J,Qb as L,K as _,hF as a,BF as b,Yf as c,OR as d,pg as e,Sr as f,vR as g,la as h,se as i,WZ as j,LZ as k,s1 as l,CR as m,hg as n,od as o,CF as p,s2 as q,hm as r,RZ as s,p as t,md as u,KF as v,Lo as w,nR as x,iR as y}; diff --git a/website/app/assets/it-Bsr1AlWk.js b/website/app/assets/it-ClGS2uQV.js similarity index 99% rename from website/app/assets/it-Bsr1AlWk.js rename to website/app/assets/it-ClGS2uQV.js index 86381ac7..436c5511 100644 --- a/website/app/assets/it-Bsr1AlWk.js +++ b/website/app/assets/it-ClGS2uQV.js @@ -135,7 +135,6 @@ const e=`/* Testi presenti solo nella versione web. Tutto il resto proviene dai "web_files_saved_fmt" = "Salvato: %@"; "web_files_create" = "Crea"; "web_learn_ludwig_tip" = "Il consiglio di Ludwig"; -"web_learn_pro" = "Sapere da professionisti con Ludwig"; "web_game_title" = "Gioco: Vero o falso?"; "web_game_intro" = "Ludwig ti mostra dei valori e una condizione. È vera (true) o falsa (false)? Dieci turni, sempre più difficili."; "web_game_start" = "Inizia il gioco"; diff --git a/website/app/assets/ja-L0a84IMq.js b/website/app/assets/ja-JQ8MwNFB.js similarity index 99% rename from website/app/assets/ja-L0a84IMq.js rename to website/app/assets/ja-JQ8MwNFB.js index 18948e97..7c5d2739 100644 --- a/website/app/assets/ja-L0a84IMq.js +++ b/website/app/assets/ja-JQ8MwNFB.js @@ -135,7 +135,6 @@ const e=`/* Web 版にのみ存在するテキスト。その他はすべてア "web_files_saved_fmt" = "保存しました:%@"; "web_files_create" = "作成"; "web_learn_ludwig_tip" = "ルートヴィヒのヒント"; -"web_learn_pro" = "ルートヴィヒのプロ知識"; "web_game_title" = "ゲーム:真か偽か?"; "web_game_intro" = "ルートヴィヒが値と条件を見せます。条件は真(true)?それとも偽(false)?10ラウンド、だんだん難しくなります。"; "web_game_start" = "ゲームを始める"; diff --git a/website/app/assets/ko-U6EDne8i.js b/website/app/assets/ko-tfdKG8Fb.js similarity index 99% rename from website/app/assets/ko-U6EDne8i.js rename to website/app/assets/ko-tfdKG8Fb.js index e74f6754..6753303e 100644 --- a/website/app/assets/ko-U6EDne8i.js +++ b/website/app/assets/ko-tfdKG8Fb.js @@ -135,7 +135,6 @@ const e=`/* 웹 버전에만 있는 텍스트입니다. 나머지는 모두 앱 "web_files_saved_fmt" = "저장됨: %@"; "web_files_create" = "만들기"; "web_learn_ludwig_tip" = "루트비히의 팁"; -"web_learn_pro" = "루트비히의 전문가 지식"; "web_game_title" = "게임: 참일까 거짓일까?"; "web_game_intro" = "루트비히가 값과 조건을 보여 줍니다. 조건이 참(true)일까요, 거짓(false)일까요? 10라운드, 점점 어려워집니다."; "web_game_start" = "게임 시작"; diff --git a/website/app/assets/nb-C9pwk403.js b/website/app/assets/nb-BpibUAkX.js similarity index 99% rename from website/app/assets/nb-C9pwk403.js rename to website/app/assets/nb-BpibUAkX.js index 965bab35..976aa674 100644 --- a/website/app/assets/nb-C9pwk403.js +++ b/website/app/assets/nb-BpibUAkX.js @@ -135,7 +135,6 @@ const e=`/* Tekster som bare finnes i nettversjonen. Alt annet kommer fra appens "web_files_saved_fmt" = "Lagret: %@"; "web_files_create" = "Lag"; "web_learn_ludwig_tip" = "Ludwigs tips"; -"web_learn_pro" = "Proffkunnskap med Ludwig"; "web_game_title" = "Spill: Sant eller usant?"; "web_game_intro" = "Ludwig viser deg verdier og en betingelse. Er betingelsen sann (true) eller usann (false)? Ti runder, stadig vanskeligere."; "web_game_start" = "Start spillet"; diff --git a/website/app/assets/nl-D1JTb8Xr.js b/website/app/assets/nl-HArZjiga.js similarity index 99% rename from website/app/assets/nl-D1JTb8Xr.js rename to website/app/assets/nl-HArZjiga.js index fdccda5e..f64e189c 100644 --- a/website/app/assets/nl-D1JTb8Xr.js +++ b/website/app/assets/nl-HArZjiga.js @@ -135,7 +135,6 @@ const e=`/* Teksten die alleen in de webversie bestaan. Al het andere komt uit d "web_files_saved_fmt" = "Opgeslagen: %@"; "web_files_create" = "Maken"; "web_learn_ludwig_tip" = "Ludwigs tip"; -"web_learn_pro" = "Profkennis met Ludwig"; "web_game_title" = "Spel: Waar of onwaar?"; "web_game_intro" = "Ludwig laat je waarden en een voorwaarde zien. Is de voorwaarde waar (true) of onwaar (false)? Tien rondes, steeds lastiger."; "web_game_start" = "Spel starten"; diff --git a/website/app/assets/objectApp-exr4obxz.js b/website/app/assets/objectApp-Caze4o4v.js similarity index 99% rename from website/app/assets/objectApp-exr4obxz.js rename to website/app/assets/objectApp-Caze4o4v.js index f5d6cf2d..469fdf57 100644 --- a/website/app/assets/objectApp-exr4obxz.js +++ b/website/app/assets/objectApp-Caze4o4v.js @@ -1,5 +1,5 @@ -const __vite__mapDeps=(i,m=__vite__mapDeps,d=(m.f||(m.f=["./projectZip-Dv_LmKlY.js","./index-DqKA7YqL.js","./index-DVwLXYFw.css"])))=>i.map(i=>d[i]); -var Ns=Object.defineProperty;var Os=(a,e,t)=>e in a?Ns(a,e,{enumerable:!0,configurable:!0,writable:!0,value:t}):a[e]=t;var E=(a,e,t)=>Os(a,typeof e!="symbol"?e+"":e,t);import{t as d,i as ie,s as Ps,m as Is,g as Ds,w as Rs,J as Hs,c as Bs,a as Ws,b as Ye,p as zs,d as Vs,e as Us,f as Js,_ as wt,h as $t,j as Ks,r as _t,k as Xs,l as ct}from"./index-DqKA7YqL.js";function Ys(a){const e=[];let t=0;for(;ti.map(i=>d[i]); +var Ns=Object.defineProperty;var Os=(a,e,t)=>e in a?Ns(a,e,{enumerable:!0,configurable:!0,writable:!0,value:t}):a[e]=t;var E=(a,e,t)=>Os(a,typeof e!="symbol"?e+"":e,t);import{t as d,i as ie,s as Ps,m as Is,g as Ds,w as Rs,J as Hs,c as Bs,a as Ws,b as Ye,p as zs,d as Vs,e as Us,f as Js,_ as wt,h as $t,j as Ks,r as _t,k as Xs,l as ct}from"./index-CzgrZgZa.js";function Ys(a){const e=[];let t=0;for(;te.text===","?", ":e.text).join("")}function ms(a){const e=[[]];let t=0;for(const s of a)s.text==="<"||s.text==="("||s.text==="["||s.text==="{"?t++:(s.text===">"||s.text===")"||s.text==="]"||s.text==="}")&&t--,s.text===","&&t===0?e.push([]):e[e.length-1].push(s);return e.filter(s=>s.length>0)}function ft(a){var t,s;const e=[];for(let i=0;i{const t=ft(e).filter(i=>i.text!=="final"),s=t[t.length-1];return{name:s!=null&&s.word?s.text:"",type:lt(t.slice(0,-1))}})}function kt(a,e,t,s){var x,L;const i=ft(a),n=new Set;let o=0;for(;o"));const r=i.slice(o);if(r.length===0||a.length===0)return[];const c=a[0].from,l=r.findIndex(S=>S.text==="("),h=r.findIndex(S=>S.text==="="),u=l>0&&(h<0||lS.text==="="),y=_<0?g:g.slice(0,_);let w=y.length-1;for(;w>0&&!y[w].word;)w--;if(w<1)return[];const $=lt(y.slice(0,w)),p=m.length>1,v=[];return m.forEach((S,k)=>{var C;const j=S.findIndex(F=>F.text==="="),M=j<0?S:S.slice(0,j),A=k===0?y[w]:M.find(F=>F.word);if(!A)return;const R=M.filter(F=>F.from>A.from&&F.text==="[").length;v.push({kind:"field",name:A.text,type:$+"[]".repeat(R),params:[],visibility:xt(n,f),isStatic:n.has("static"),isAbstract:!1,from:c,to:s,headerFrom:c,headerTo:k===0?((C=M[M.length-1])==null?void 0:C.to)??A.to:A.to,shared:p,nameFrom:A.from,nameTo:A.to})}),v}function Zs(a,e,t){var n;let s=[],i=e;for(;ih.text==="="),c=ye(a,i,"{","}");if(r){s.push(...a.slice(i,c)),i=c;continue}const l=s.map(h=>h.text);l.includes("class")||l.includes("interface")||l.includes("enum")||s.length>0&&t.members.push(...kt(s,t.name,t.kind==="interface",((n=a[c-1])==null?void 0:n.to)??o.to)),s=[],i=c;continue}s.push(o),i++}return t.bodyEnd=a.length>0?a[a.length-1].to:0,i}function oe(a){var n,o,r,c;const e=Ys(a),t=[];let s=[],i=0;for(;iw.text==="class"||w.text==="interface"),f=u>=0?h[u+1]:void 0;if(!(f!=null&&f.word)){i=ye(e,i,"{","}"),s=[];continue}let m=u;for(;m>0&&(fs.has(h[m-1].text)||h[m-1].text==="@");)m--;const g={name:f.text,kind:h[u].text==="interface"?"interface":"class",isAbstract:h.slice(m,u).some(w=>w.text==="abstract"),interfaces:[],members:[],from:((n=s[s.indexOf(h[m])])==null?void 0:n.from)??h[m].from,to:0,headerFrom:((o=s[s.indexOf(h[m])])==null?void 0:o.from)??h[m].from,headerTo:h[h.length-1].to,nameFrom:f.from,nameTo:f.to,bodyEnd:0};let _=u+2;((r=h[_])==null?void 0:r.text)==="<"&&(_=ye(h,_,"<",">"));let y="";for(;_")-1:w.word&&y==="extends"&&g.kind==="class"?g.superclass??(g.superclass=w.text):w.word&&y&&g.interfaces.push(w.text)}i=Zs(e,i+1,g),g.to=((c=e[i-1])==null?void 0:c.to)??a.length,t.push(g),s=[]}return t}function Fe(a){const e=/^([\p{L}_$][\p{L}\p{N}_$]*)(\[\])+$/u.exec(a);if(e)return{name:e[1],many:!0};const t=/^(?:ArrayList|LinkedList|List|Set|HashSet|TreeSet|Collection|Queue|Deque|ArrayDeque|Stack|Vector)<([\p{L}_$][\p{L}\p{N}_$]*)>$/u.exec(a);return t?{name:t[1],many:!0}:{name:a,many:!1}}function Qs(a){const e=new Set(a.map(s=>s.name)),t=[];for(const s of a){s.superclass&&e.has(s.superclass)&&t.push({kind:"extends",from:s.name,to:s.superclass});for(const i of s.interfaces)e.has(i)&&t.push({kind:s.kind==="interface"?"extends":"implements",from:s.name,to:i});for(const i of s.members){if(i.kind!=="field")continue;const n=Fe(i.type);e.has(n.name)&&t.push({kind:"association",from:s.name,to:n.name,role:i.name,multiplicity:n.many?"0..*":"1"})}}return t}function Ge(a){const e=a.params.map(t=>`${t.name}: ${t.type}`).join(", ");return a.kind==="field"?`${a.visibility} ${a.name}: ${a.type}`:a.kind==="constructor"?`${a.visibility} ${a.name}(${e})`:`${a.visibility} ${a.name}(${e}): ${a.type}`}const ei=/^[\p{L}_$][\p{L}\p{N}_$]*$/u;function Ve(a){var c;let e=a.trim().replace(/;$/,"").trim();if(!e)return;let t;/^[+\-#~]/.test(e)&&(t=e[0],e=e.slice(1).trim());let s=!1;const i=e.split(/\s+/);for(;["static","public","private","protected"].includes(i[0]);){const l=i.shift();l==="static"?s=!0:t??(t=l==="public"?"+":l==="private"?"-":"#")}e=i.join(" ");const n=e.indexOf("(");if(n>=0){const l=e.lastIndexOf(")");if(lg.trim()).filter(Boolean).map(g=>{const _=/^([\p{L}_$][\p{L}\p{N}_$]*)\s*:\s*(.+)$/u.exec(g);if(_)return{name:_[1],type:_[2].replace(/\s+/g,"")};const y=/^(.+)\s+([\p{L}_$][\p{L}\p{N}_$]*)$/u.exec(g);return y?{name:y[2],type:y[1].replace(/\s+/g,"")}:{name:g,type:"int"}});return{kind:"method",visibility:t,name:h,type:u==null?void 0:u.replace(/\s+/g,""),params:m,isStatic:s}}const o=/^([\p{L}_$][\p{L}\p{N}_$]*)\s*(?::\s*(.+))?$/u.exec(e);if(o)return{kind:"field",visibility:t,name:o[1],type:(c=o[2])==null?void 0:c.replace(/\s+/g,""),params:[],isStatic:s};const r=/^(.+?)\s+([\p{L}_$][\p{L}\p{N}_$]*)$/u.exec(e);if(r)return{kind:"field",visibility:t,name:r[2],type:r[1].replace(/\s+/g,""),params:[],isStatic:s}}const ti={"+":"public ","-":"private ","#":"protected ","~":""};function si(a){return/^(int|long|short|byte)$/.test(a)?"0":/^(double|float)$/.test(a)?"0.0":a==="boolean"?"false":a==="char"?"' '":"null"}function bs(a,e,t){const s=e.kind==="interface",i=s?"":ti[a.visibility??(a.kind==="field"?"-":"+")],n=a.isStatic?"static ":"";if(a.kind==="field")return`${i}${n}${a.type??"int"} ${a.name}`;const o=a.params.map(r=>`${r.type} ${r.name}`).join(", ");return a.name===e.name?`${i}${a.name}(${o})`:`${i}${n}${t&&!s?"abstract ":""}${a.type??"void"} ${a.name}(${o})`}const Ue=(a,e)=>a.lastIndexOf(` `,e-1)+1;function mt(a,e,t){const s=Ue(a,e),i=a.slice(s,e);let n=t;for(;ns.path===e)&&e!==this.active&&this.openFile(e),this.editor.setMarks({placeholders:[],problems:[],current:t},!0)}showDebugState(){const e=this.dbg;if(!e)return;e.frames=e.vm.stack();const t=e.vm.heap(),s=e.frames[e.frame];s&&this.showLine(s.pos.file,s.pos.line);const i=e.values.size===0&&e.vars.size===0,n=new Set,o=new Map;for(const h of t)for(const u of h.fields){const f=`dbg${h.id}.${u.name}`;o.set(f,u.value),!i&&e.values.get(f)!==u.value&&n.add(f)}e.values=o;const r=new Set,c=new Map;e.frames.forEach((h,u)=>{for(const f of h.vars){const m=`${e.frames.length-u}|${h.title}|${f.name}`;c.set(m,f.value),!i&&e.vars.get(m)!==f.value&&r.add(`${h.title}|${f.name}`)}}),e.vars=c;const l={objects:this.liveObjects(t),changed:n,frames:e.frames,frame:e.frame,changedVars:r,onFrame:h=>{e.frame=h,l.frame=h;const u=e.frames[h];u&&this.showLine(u.pos.file,u.pos.line),this.objectDiagram.renderInspector()},move:(h,u)=>e.places.set(h,u)};this.objectDiagram.live=l,this.sequence=e.vm.sequence(),this.diagramMode==="object"&&this.objectDiagram.render(),this.diagramMode==="sequence"&&this.renderSequence()}renderSequence(){var n,o,r;const e=this.shell.querySelector(".vo-seqcanvas"),t=e.querySelector(".vo-seq"),s=e.querySelector(".vo-empty"),i=this.sequence;if(s.hidden=!!i&&i.events.length>0,s.textContent=d(i?"web_visuobject_seq_no_calls":"web_visuobject_seq_empty"),!i||!i.events.length)t.innerHTML="",t.setAttribute("width","0");else{const c=((n=this.dbg)==null?void 0:n.state)==="paused"||((o=this.dbg)==null?void 0:o.state)==="input",{svg:l,width:h,height:u}=Ti(i,c?i.events.length-1:void 0);t.innerHTML=l+(i.truncated?`${b(d("web_visuobject_seq_truncated"))}`:""),t.setAttribute("width",String(h)),t.setAttribute("height",String(u)),c&&((r=t.querySelector(".vo-seq-msg.current"))==null||r.scrollIntoView({block:"nearest",inline:"nearest"}))}this.renderSequenceInspector()}renderSequenceInspector(){if(this.objectDiagram.live)return this.objectDiagram.renderInspector();this.inspector.innerHTML=`

    ${b(d("web_visuobject_seq_hint"))}

    `}liveObjects(e){const t=this.dbg,s=this.project.objects??[],i=c=>40+c.fields.length*20,n=[],o=[],r=[];for(const c of e){const l=`dbg${c.id}`,h=t.places.get(l)??s.find(u=>u.name===c.name&&u.cls===c.cls);if(!h){r.push(c);continue}t.places.set(l,{x:h.x,y:h.y}),n.push({x:h.x,y:h.y,w:260,h:i(c)})}for(const c of r){const l=i(c);let h={x:24,y:24};e:for(let u=24;u<6e3;u+=30)for(let f=24;f<=24+3*320;f+=320)if(n.every(m=>f+260+30<=m.x||m.x+m.w+30<=f||u+l+30<=m.y||m.y+m.h+30<=u)){h={x:f,y:u};break e}t.places.set(`dbg${c.id}`,h),n.push({...h,w:260,h:l})}for(const c of e){const l=`dbg${c.id}`;o.push({id:l,name:c.name,cls:c.cls,...t.places.get(l),values:Object.fromEntries(c.fields.map(h=>[h.name,h.value]))})}return o}stopDebug(e,t=!1){const s=this.dbg;s&&clearTimeout(s.timer),this.dbg=void 0,s&&(this.sequence=s.vm.sequence()),this.objectDiagram.live=void 0,this.consolePane().input.hidden=!0,this.shell.querySelector(".vo-dbg-controls").hidden=!0,this.shell.querySelector("[data-action=stop]").disabled=!0,this.shell.querySelector("[data-action=run]").disabled=!1,t||this.editor.setMarks({placeholders:[],problems:[]},!1),e&&this.debugStatus(d(e),t),this.diagramMode==="object"&&this.objectDiagram.render(),this.diagramMode==="sequence"&&this.renderSequence()}chooseWorld(e){if(e!=="object"){if(e==="flow"){Us(),location.href=`${location.pathname}?visuflow${location.hash}`;return}Js(e),location.href=`${location.pathname}?${e==="on"?"visubot":"visustruct"}${location.hash}`}}get activeFile(){return this.project.files.find(e=>e.path===this.active)}showActive(){const e=this.activeFile;this.editor.setText((e==null?void 0:e.text)??""),this.editor.setBreakpoints(e?this.breakpoints.get(e.path)??[]:[]),this.editor.setReadOnly(!e),e&&!this.openTabs.includes(e.path)&&this.openTabs.push(e.path),this.renderTabs(),J(ot,this.active??"")}renderTabs(){if(this.openTabs=this.openTabs.filter(e=>this.project.files.some(t=>t.path===e)),J(cs,JSON.stringify(this.openTabs)),this.openTabs.length===0){this.tabs.innerHTML=`${b(d("web_visuobject_no_file"))}`;return}this.tabs.innerHTML=this.openTabs.map(e=>{const t=e===this.active,s=this.isDirty(e);return`
    -
    `}).join("")}onTabClick(e){var i;const t=e.target,s=(i=t.closest("[data-tab]"))==null?void 0:i.dataset.tab;if(s){if(t.closest("[data-close]"))return this.closeTab(s);this.treeSelection=`file:${s}`,this.openFile(s)}}closeTab(e){const t=this.openTabs.indexOf(e);t<0||(this.openTabs.splice(t,1),e===this.active?(this.active=this.openTabs[Math.min(t,this.openTabs.length-1)],this.lastTyping=0,this.showActive(),this.refresh()):this.renderTabs())}snapshot(){return JSON.stringify({project:this.project,active:this.active})}remember(){this.history.push(this.snapshot()),this.history.length>kn&&this.history.shift(),this.future=[]}setProject(e,t=this.active){var s;this.remember(),this.lastTyping=0,this.project=e,this.active=e.files.some(i=>i.path===t)?t:(s=e.files[0])==null?void 0:s.path,this.showActive(),this.refresh()}openFile(e){if(e===this.active)return;this.active=e,this.lastTyping=0,this.showActive();const t=D(e);this.currentPackage=t,this.open.set(`pkg:${t}`,!0),this.refresh()}typed(){const e=this.activeFile;if(!e)return;const t=Date.now();t-this.lastTyping>1500&&this.remember(),this.lastTyping=t,this.project=$e(this.project,e.path,this.editor.text),this.saveBreakpoints(),this.dbg&&this.stopDebug("web_visuobject_dbg_code_changed"),this.refresh(),clearTimeout(this.renameTimer),this.renameTimer=window.setTimeout(()=>this.syncFileName(),700)}syncFileName(){var c;const e=this.activeFile;if(!e||this.editing)return;const t=Q(e.path).replace(/\.java$/i,""),s=this.classes.filter(l=>l.path===e.path);if(s.length===0||s.some(l=>l.name===t))return;const i=((c=/\bpublic\s+(?:abstract\s+|final\s+)*(?:class|interface|enum)\s+(\w+)/.exec(e.text))==null?void 0:c[1])??s[0].name;if(!pe.test(i)||s.filter(l=>l.name===i).length!==1)return;const n=le(D(e.path),`${i}.java`);if(this.project.files.some(l=>l.path===n))return;let o=Oe(this.project,e.path,n);const r=this.positions.get(t);r&&!this.positions.has(i)&&this.positions.set(i,r);for(const l of Object.keys(o.uml??{}))l.startsWith(`${t}.`)&&(o={...o,uml:ke(o.uml,l,i+l.slice(t.length))});this.openTabs=this.openTabs.map(l=>l===e.path?n:l),this.treeSelection===`file:${e.path}`&&(this.treeSelection=`file:${n}`),this.isOpen(`file:${e.path}`)&&this.open.set(`file:${n}`,!0),this.project=o,this.active=n,J(ot,n),this.savePositions(),this.refresh()}undo(e){const t=e?this.future:this.history,s=e?this.history:this.future,i=t.pop();if(i===void 0)return;s.push(this.snapshot());const n=JSON.parse(i);this.project=n.project,this.active=n.active,this.lastTyping=0,this.showActive(),this.refresh()}refresh(){J(os,Pe(this.project)),this.renderTabs(),this.classes=Ct(this.project),this.selection&&!this.findClass(this.selection.cls)&&(this.selection=void 0),this.relSelection&&!this.findRelation(this.relSelection)&&!this.findDependency(this.relSelection)&&(this.relSelection=void 0),this.editing||(this.render(),this.renderTree())}ownTypesAt(e){const t=this.activeFile;if(!t)return;const s=this.editor.view.state.doc.toString(),i=X(D(t.path)),n=oe(s).map(l=>({...l,pkg:i})),o=new Set(n.map(l=>l.name)),r=n.find(l=>l.headerFrom<=e&&e<=l.bodyEnd),c=ct()==="de"?"de":ct()==="pt-PT"?"pt":"en";return Ji([...n,...this.classes.filter(l=>l.path!==t.path&&!o.has(l.name))],{cls:r==null?void 0:r.name,pkg:i},c)}findClass(e){return this.classes.find(t=>t.name===e)}caretMoved(){var n,o;const e=this.editor.caret,t=this.classes.find(r=>r.path===this.active&&e>=r.from&&e<=r.to),s=t==null?void 0:t.members.findIndex(r=>e>=r.from&&e<=r.to),i=t?{cls:t.name,member:s!==void 0&&s>=0?s:void 0}:void 0;(i==null?void 0:i.cls)===((n=this.selection)==null?void 0:n.cls)&&(i==null?void 0:i.member)===((o=this.selection)==null?void 0:o.member)||(this.selection=i,this.editing||(this.render(),this.renderTree()))}showInCode(e,t){e.path!==this.active&&(this.active=e.path,this.lastTyping=0,this.showActive());const s=this.editor.view,[i,n]=t?[t.headerFrom,t.headerTo]:[e.nameFrom,e.nameTo],o=Math.min(n,s.state.doc.length);s.dispatch({selection:{anchor:Math.min(i,o),head:o},scrollIntoView:!0})}message(e,t=!1){this.status.textContent=e,this.status.classList.toggle("hint",t)}openFiles(){const e=document.createElement("input");e.type="file",e.multiple=!0,e.accept=".zip,.java,.visuobject,application/zip,text/plain",e.addEventListener("change",()=>void this.readFiles([...e.files??[]])),e.click()}async readFiles(e){var t;if(e.length!==0)try{const s=e.find(r=>/\.zip$/i.test(r.name));if(s){const{projectFromZip:r}=await wt(async()=>{const{projectFromZip:l}=await import("./projectZip-Dv_LmKlY.js");return{projectFromZip:l}},__vite__mapDeps([0,1,2]),import.meta.url),c=r(new Uint8Array(await s.arrayBuffer()),s.name.replace(/\.zip$/i,""));await this.newProject(c);return}const i=e.find(r=>/\.visuobject$/i.test(r.name));if(i){const r=qt(await i.text());if(!r)throw new Error("format");await this.newProject(r);return}const n=At(this.project.name,await Promise.all(e.map(async r=>({name:r.name,text:await r.text()}))));let o=this.project;for(const r of n.files)o=et(o,r.path,r.text);this.setProject(o,(t=n.files[0])==null?void 0:t.path)}catch{this.message(d("web_visuobject_open_failed"))}}async save(){this.workspace?await this.writeCurrent():await this.downloadZip()}async downloadZip(){const{projectToZip:e}=await wt(async()=>{const{projectToZip:s}=await import("./projectZip-Dv_LmKlY.js");return{projectToZip:s}},__vite__mapDeps([0,1,2]),import.meta.url),t=e(this.project);Sn(`${this.project.name||"Projekt"}.zip`,t.slice().buffer,"application/zip")}isDirty(e){var t;return!this.workspace||this.saved===void 0?!1:e===void 0?this.saved!==Pe(this.project):this.savedFiles.get(e)!==((t=this.project.files.find(s=>s.path===e))==null?void 0:t.text)}markSaved(){this.saved=Pe(this.project),this.savedFiles=new Map(this.project.files.map(e=>[e.path,e.text]))}async restoreWorkspace(){if(!$t())return;const e=await Ks(us);if(e!=null&&e.ready){const t=await _t(e.handle);if(t)return this.useWorkspace(t.root,!0)}this.pendingFolder=e==null?void 0:e.handle,this.renderWorkspace()}async useWorkspace(e,t=!1){var s;this.workspace=e,this.pendingFolder=void 0,J(rt,"0");try{this.projects=await is(e);const i=se(We),n=this.project;if(t&&i&&this.projects.includes(i)){const o={active:this.active,tabs:[...this.openTabs],positions:new Map(this.positions)};await this.loadProject(i),this.positions=o.positions,this.savePositions(),Pe(n)!==this.saved&&(this.project=n),this.openTabs=o.tabs.filter(r=>this.project.files.some(c=>c.path===r)),this.active=this.project.files.some(r=>r.path===o.active)?o.active:(s=this.project.files[0])==null?void 0:s.path,this.showActive(),this.refresh()}else!this.projects.some(o=>o.toLowerCase()===ge(n.name).toLowerCase())&&n.files.length?(this.folder=ge(n.name),await this.writeCurrent(!1)):this.projects.length?await this.loadProject(this.projects.includes(i??"")?i:this.projects[0]):(this.folder=ge(n.name),await this.writeCurrent(!1))}catch(i){this.message(d("web_visuobject_ws_failed",String((i==null?void 0:i.message)??i)))}this.renderWorkspace(),this.refresh()}async loadProject(e){var i;const{project:t,positions:s}=await yn(this.workspace,e);this.folder=e,this.project=t,this.markSaved(),this.message(""),this.history=[],this.future=[],this.lastTyping=0,this.selection=void 0,this.relSelection=void 0,this.treeSelection=void 0,this.currentPackage=void 0,this.positions=new Map(Object.entries(s)),this.savePositions(),this.openTabs=[],this.active=(i=t.files[0])==null?void 0:i.path,J(We,e),this.showActive(),this.refresh()}async writeCurrent(e=!0){const t=this.workspace;if(!t)return!1;const s=ge(this.project.name),i=this.folder,n=new Set(this.classes.map(r=>r.name)),o=Object.fromEntries([...this.positions].filter(([r])=>n.has(r)));if(s!==i&&this.projects.some(r=>r!==i&&r.toLowerCase()===s.toLowerCase()))return this.message(d("web_visuobject_ws_taken",this.project.name)),!1;try{return await _n(t,s,this.project,o),i&&i!==s&&this.projects.includes(i)&&await t.remove(i),this.folder=s,this.projects=await is(t),J(We,s),this.markSaved(),e&&this.message(d("web_visuobject_ws_saved",t.name,s),!0),this.refresh(),!0}catch(r){return this.message(d("web_visuobject_ws_failed",String((r==null?void 0:r.message)??r))),!1}}async switchProject(e){if(!(!this.workspace||e===this.folder)&&!(this.isDirty()&&!await this.writeCurrent(!1)))try{await this.loadProject(e)}catch(t){this.message(d("web_visuobject_ws_failed",String((t==null?void 0:t.message)??t)))}}async newProject(e,t,s=!1){var n,o;if(!this.workspace){this.setProject(e,t??((n=e.files[0])==null?void 0:n.path)),e.files.length===0&&!s&&this.editProjectName();return}if(this.isDirty()&&!await this.writeCurrent(!1))return;const i=ns(ge(e.name),this.projects);this.project={...e,name:i},this.folder=i,this.history=[],this.future=[],this.openTabs=[],this.positions.clear(),this.savePositions(),this.active=e.files.some(r=>r.path===t)?t:(o=e.files[0])==null?void 0:o.path,this.showActive(),this.refresh(),await this.writeCurrent(!1)&&(this.message(d("web_visuobject_ws_created",i),!0),e.files.length===0&&!s&&this.editProjectName())}get currentPlace(){const e=this.currentPackage??(this.active?D(this.active):ce(this.project)[0]??"");return{root:U(e),pkg:X(e)}}async newFromWizard(e){var u;const t=this.currentPlace,s=(f,m)=>{let g=f;for(let _=2;m(g);_++)g=f+_;return g},i=await on(e,{roots:ue(this.project),packagesIn:f=>ce(this.project,f).map(X),classes:this.classes,root:t.root,pkg:t.pkg,suggest:f=>f==="project"?ns(d("web_visuobject_project_name"),this.workspace?[...this.projects,this.folder??""]:[]):f==="folder"?s("test",m=>ue(this.project).includes(m)):f==="package"?s(d("web_visuobject_new_package_name"),m=>ce(this.project).includes(re(t.root,m))):this.uniqueClassName(d(f==="class"?"web_visuobject_new_class_name":"web_visuobject_new_interface_name")),check:(f,m,g,_)=>{if(!m)return d("web_visuobject_new_name_missing");if(f==="project")return this.workspace&&this.projects.some(y=>y!==this.folder&&y.toLowerCase()===ge(m).toLowerCase())?d("web_visuobject_ws_taken",m):void 0;if(f==="folder")return!Je(m)||ue(this.project).includes(m)?d("web_visuobject_bad_folder",m):void 0;if(f==="package")return!Mt(m)||ce(this.project).includes(re(g,m))?d("web_visuobject_bad_package",m):void 0;if(!pe.test(m))return d("web_visuobject_bad_name",m);if(this.findClass(m)||this.project.files.some(y=>y.path===le(re(g,_),`${m}.java`)))return d("web_visuobject_new_exists",m);if(m.charAt(0)!==m.charAt(0).toUpperCase())return d("web_visuobject_new_upper")}});if(!i)return;const{name:n,root:o,pkg:r}=i;if(e==="project")return this.newProject({name:n,files:[],packages:[]},void 0,!0);if(this.message(""),e==="folder")return this.currentPackage=re(n,""),this.treeSelection=`root:${n}`,this.open.set(`root:${n}`,!0),this.setProject(bi(this.project,n));if(e==="package"){const f=re(o,n);return this.currentPackage=f,this.treeSelection=`pkg:${f}`,this.open.set(`root:${o}`,!0),this.setProject(fi(this.project,f))}const c=re(o,r),l=le(c,`${n}.java`);this.currentPackage=c,this.selection={cls:n},this.open.set(`root:${o}`,!0),this.open.set(`pkg:${c}`,!0),this.setProject(et(this.project,l,this.sectioned(sn(i.options),n)),l);const h=this.findClass(n);h&&this.showInCode(h),(u=this.canvas.querySelector(`.uml-class[data-class="${CSS.escape(n)}"]`))==null||u.scrollIntoView({block:"nearest",inline:"nearest"})}editProjectName(){this.treeSelection="project",this.renderTree(),this.startEditing(this.tree.querySelector('[data-node="project"] > .vo-row .vo-label'))}renderWorkspace(){const e=this.wsBox;e.hidden=!$t();const t=this.shell.querySelector("[data-action=save]");if(t.dataset.tip=d(this.workspace?"web_visuobject_save_ws_tip":"web_visuobject_save_tip"),e.hidden)return;const s=(i,n,o="text-button",r)=>``;this.workspace?(e.className="vo-ws",e.innerHTML=`${b(this.workspace.name)} + `}).join("")}onTabClick(e){var i;const t=e.target,s=(i=t.closest("[data-tab]"))==null?void 0:i.dataset.tab;if(s){if(t.closest("[data-close]"))return this.closeTab(s);this.treeSelection=`file:${s}`,this.openFile(s)}}closeTab(e){const t=this.openTabs.indexOf(e);t<0||(this.openTabs.splice(t,1),e===this.active?(this.active=this.openTabs[Math.min(t,this.openTabs.length-1)],this.lastTyping=0,this.showActive(),this.refresh()):this.renderTabs())}snapshot(){return JSON.stringify({project:this.project,active:this.active})}remember(){this.history.push(this.snapshot()),this.history.length>kn&&this.history.shift(),this.future=[]}setProject(e,t=this.active){var s;this.remember(),this.lastTyping=0,this.project=e,this.active=e.files.some(i=>i.path===t)?t:(s=e.files[0])==null?void 0:s.path,this.showActive(),this.refresh()}openFile(e){if(e===this.active)return;this.active=e,this.lastTyping=0,this.showActive();const t=D(e);this.currentPackage=t,this.open.set(`pkg:${t}`,!0),this.refresh()}typed(){const e=this.activeFile;if(!e)return;const t=Date.now();t-this.lastTyping>1500&&this.remember(),this.lastTyping=t,this.project=$e(this.project,e.path,this.editor.text),this.saveBreakpoints(),this.dbg&&this.stopDebug("web_visuobject_dbg_code_changed"),this.refresh(),clearTimeout(this.renameTimer),this.renameTimer=window.setTimeout(()=>this.syncFileName(),700)}syncFileName(){var c;const e=this.activeFile;if(!e||this.editing)return;const t=Q(e.path).replace(/\.java$/i,""),s=this.classes.filter(l=>l.path===e.path);if(s.length===0||s.some(l=>l.name===t))return;const i=((c=/\bpublic\s+(?:abstract\s+|final\s+)*(?:class|interface|enum)\s+(\w+)/.exec(e.text))==null?void 0:c[1])??s[0].name;if(!pe.test(i)||s.filter(l=>l.name===i).length!==1)return;const n=le(D(e.path),`${i}.java`);if(this.project.files.some(l=>l.path===n))return;let o=Oe(this.project,e.path,n);const r=this.positions.get(t);r&&!this.positions.has(i)&&this.positions.set(i,r);for(const l of Object.keys(o.uml??{}))l.startsWith(`${t}.`)&&(o={...o,uml:ke(o.uml,l,i+l.slice(t.length))});this.openTabs=this.openTabs.map(l=>l===e.path?n:l),this.treeSelection===`file:${e.path}`&&(this.treeSelection=`file:${n}`),this.isOpen(`file:${e.path}`)&&this.open.set(`file:${n}`,!0),this.project=o,this.active=n,J(ot,n),this.savePositions(),this.refresh()}undo(e){const t=e?this.future:this.history,s=e?this.history:this.future,i=t.pop();if(i===void 0)return;s.push(this.snapshot());const n=JSON.parse(i);this.project=n.project,this.active=n.active,this.lastTyping=0,this.showActive(),this.refresh()}refresh(){J(os,Pe(this.project)),this.renderTabs(),this.classes=Ct(this.project),this.selection&&!this.findClass(this.selection.cls)&&(this.selection=void 0),this.relSelection&&!this.findRelation(this.relSelection)&&!this.findDependency(this.relSelection)&&(this.relSelection=void 0),this.editing||(this.render(),this.renderTree())}ownTypesAt(e){const t=this.activeFile;if(!t)return;const s=this.editor.view.state.doc.toString(),i=X(D(t.path)),n=oe(s).map(l=>({...l,pkg:i})),o=new Set(n.map(l=>l.name)),r=n.find(l=>l.headerFrom<=e&&e<=l.bodyEnd),c=ct()==="de"?"de":ct()==="pt-PT"?"pt":"en";return Ji([...n,...this.classes.filter(l=>l.path!==t.path&&!o.has(l.name))],{cls:r==null?void 0:r.name,pkg:i},c)}findClass(e){return this.classes.find(t=>t.name===e)}caretMoved(){var n,o;const e=this.editor.caret,t=this.classes.find(r=>r.path===this.active&&e>=r.from&&e<=r.to),s=t==null?void 0:t.members.findIndex(r=>e>=r.from&&e<=r.to),i=t?{cls:t.name,member:s!==void 0&&s>=0?s:void 0}:void 0;(i==null?void 0:i.cls)===((n=this.selection)==null?void 0:n.cls)&&(i==null?void 0:i.member)===((o=this.selection)==null?void 0:o.member)||(this.selection=i,this.editing||(this.render(),this.renderTree()))}showInCode(e,t){e.path!==this.active&&(this.active=e.path,this.lastTyping=0,this.showActive());const s=this.editor.view,[i,n]=t?[t.headerFrom,t.headerTo]:[e.nameFrom,e.nameTo],o=Math.min(n,s.state.doc.length);s.dispatch({selection:{anchor:Math.min(i,o),head:o},scrollIntoView:!0})}message(e,t=!1){this.status.textContent=e,this.status.classList.toggle("hint",t)}openFiles(){const e=document.createElement("input");e.type="file",e.multiple=!0,e.accept=".zip,.java,.visuobject,application/zip,text/plain",e.addEventListener("change",()=>void this.readFiles([...e.files??[]])),e.click()}async readFiles(e){var t;if(e.length!==0)try{const s=e.find(r=>/\.zip$/i.test(r.name));if(s){const{projectFromZip:r}=await wt(async()=>{const{projectFromZip:l}=await import("./projectZip-BKS-Blr6.js");return{projectFromZip:l}},__vite__mapDeps([0,1,2]),import.meta.url),c=r(new Uint8Array(await s.arrayBuffer()),s.name.replace(/\.zip$/i,""));await this.newProject(c);return}const i=e.find(r=>/\.visuobject$/i.test(r.name));if(i){const r=qt(await i.text());if(!r)throw new Error("format");await this.newProject(r);return}const n=At(this.project.name,await Promise.all(e.map(async r=>({name:r.name,text:await r.text()}))));let o=this.project;for(const r of n.files)o=et(o,r.path,r.text);this.setProject(o,(t=n.files[0])==null?void 0:t.path)}catch{this.message(d("web_visuobject_open_failed"))}}async save(){this.workspace?await this.writeCurrent():await this.downloadZip()}async downloadZip(){const{projectToZip:e}=await wt(async()=>{const{projectToZip:s}=await import("./projectZip-BKS-Blr6.js");return{projectToZip:s}},__vite__mapDeps([0,1,2]),import.meta.url),t=e(this.project);Sn(`${this.project.name||"Projekt"}.zip`,t.slice().buffer,"application/zip")}isDirty(e){var t;return!this.workspace||this.saved===void 0?!1:e===void 0?this.saved!==Pe(this.project):this.savedFiles.get(e)!==((t=this.project.files.find(s=>s.path===e))==null?void 0:t.text)}markSaved(){this.saved=Pe(this.project),this.savedFiles=new Map(this.project.files.map(e=>[e.path,e.text]))}async restoreWorkspace(){if(!$t())return;const e=await Ks(us);if(e!=null&&e.ready){const t=await _t(e.handle);if(t)return this.useWorkspace(t.root,!0)}this.pendingFolder=e==null?void 0:e.handle,this.renderWorkspace()}async useWorkspace(e,t=!1){var s;this.workspace=e,this.pendingFolder=void 0,J(rt,"0");try{this.projects=await is(e);const i=se(We),n=this.project;if(t&&i&&this.projects.includes(i)){const o={active:this.active,tabs:[...this.openTabs],positions:new Map(this.positions)};await this.loadProject(i),this.positions=o.positions,this.savePositions(),Pe(n)!==this.saved&&(this.project=n),this.openTabs=o.tabs.filter(r=>this.project.files.some(c=>c.path===r)),this.active=this.project.files.some(r=>r.path===o.active)?o.active:(s=this.project.files[0])==null?void 0:s.path,this.showActive(),this.refresh()}else!this.projects.some(o=>o.toLowerCase()===ge(n.name).toLowerCase())&&n.files.length?(this.folder=ge(n.name),await this.writeCurrent(!1)):this.projects.length?await this.loadProject(this.projects.includes(i??"")?i:this.projects[0]):(this.folder=ge(n.name),await this.writeCurrent(!1))}catch(i){this.message(d("web_visuobject_ws_failed",String((i==null?void 0:i.message)??i)))}this.renderWorkspace(),this.refresh()}async loadProject(e){var i;const{project:t,positions:s}=await yn(this.workspace,e);this.folder=e,this.project=t,this.markSaved(),this.message(""),this.history=[],this.future=[],this.lastTyping=0,this.selection=void 0,this.relSelection=void 0,this.treeSelection=void 0,this.currentPackage=void 0,this.positions=new Map(Object.entries(s)),this.savePositions(),this.openTabs=[],this.active=(i=t.files[0])==null?void 0:i.path,J(We,e),this.showActive(),this.refresh()}async writeCurrent(e=!0){const t=this.workspace;if(!t)return!1;const s=ge(this.project.name),i=this.folder,n=new Set(this.classes.map(r=>r.name)),o=Object.fromEntries([...this.positions].filter(([r])=>n.has(r)));if(s!==i&&this.projects.some(r=>r!==i&&r.toLowerCase()===s.toLowerCase()))return this.message(d("web_visuobject_ws_taken",this.project.name)),!1;try{return await _n(t,s,this.project,o),i&&i!==s&&this.projects.includes(i)&&await t.remove(i),this.folder=s,this.projects=await is(t),J(We,s),this.markSaved(),e&&this.message(d("web_visuobject_ws_saved",t.name,s),!0),this.refresh(),!0}catch(r){return this.message(d("web_visuobject_ws_failed",String((r==null?void 0:r.message)??r))),!1}}async switchProject(e){if(!(!this.workspace||e===this.folder)&&!(this.isDirty()&&!await this.writeCurrent(!1)))try{await this.loadProject(e)}catch(t){this.message(d("web_visuobject_ws_failed",String((t==null?void 0:t.message)??t)))}}async newProject(e,t,s=!1){var n,o;if(!this.workspace){this.setProject(e,t??((n=e.files[0])==null?void 0:n.path)),e.files.length===0&&!s&&this.editProjectName();return}if(this.isDirty()&&!await this.writeCurrent(!1))return;const i=ns(ge(e.name),this.projects);this.project={...e,name:i},this.folder=i,this.history=[],this.future=[],this.openTabs=[],this.positions.clear(),this.savePositions(),this.active=e.files.some(r=>r.path===t)?t:(o=e.files[0])==null?void 0:o.path,this.showActive(),this.refresh(),await this.writeCurrent(!1)&&(this.message(d("web_visuobject_ws_created",i),!0),e.files.length===0&&!s&&this.editProjectName())}get currentPlace(){const e=this.currentPackage??(this.active?D(this.active):ce(this.project)[0]??"");return{root:U(e),pkg:X(e)}}async newFromWizard(e){var u;const t=this.currentPlace,s=(f,m)=>{let g=f;for(let _=2;m(g);_++)g=f+_;return g},i=await on(e,{roots:ue(this.project),packagesIn:f=>ce(this.project,f).map(X),classes:this.classes,root:t.root,pkg:t.pkg,suggest:f=>f==="project"?ns(d("web_visuobject_project_name"),this.workspace?[...this.projects,this.folder??""]:[]):f==="folder"?s("test",m=>ue(this.project).includes(m)):f==="package"?s(d("web_visuobject_new_package_name"),m=>ce(this.project).includes(re(t.root,m))):this.uniqueClassName(d(f==="class"?"web_visuobject_new_class_name":"web_visuobject_new_interface_name")),check:(f,m,g,_)=>{if(!m)return d("web_visuobject_new_name_missing");if(f==="project")return this.workspace&&this.projects.some(y=>y!==this.folder&&y.toLowerCase()===ge(m).toLowerCase())?d("web_visuobject_ws_taken",m):void 0;if(f==="folder")return!Je(m)||ue(this.project).includes(m)?d("web_visuobject_bad_folder",m):void 0;if(f==="package")return!Mt(m)||ce(this.project).includes(re(g,m))?d("web_visuobject_bad_package",m):void 0;if(!pe.test(m))return d("web_visuobject_bad_name",m);if(this.findClass(m)||this.project.files.some(y=>y.path===le(re(g,_),`${m}.java`)))return d("web_visuobject_new_exists",m);if(m.charAt(0)!==m.charAt(0).toUpperCase())return d("web_visuobject_new_upper")}});if(!i)return;const{name:n,root:o,pkg:r}=i;if(e==="project")return this.newProject({name:n,files:[],packages:[]},void 0,!0);if(this.message(""),e==="folder")return this.currentPackage=re(n,""),this.treeSelection=`root:${n}`,this.open.set(`root:${n}`,!0),this.setProject(bi(this.project,n));if(e==="package"){const f=re(o,n);return this.currentPackage=f,this.treeSelection=`pkg:${f}`,this.open.set(`root:${o}`,!0),this.setProject(fi(this.project,f))}const c=re(o,r),l=le(c,`${n}.java`);this.currentPackage=c,this.selection={cls:n},this.open.set(`root:${o}`,!0),this.open.set(`pkg:${c}`,!0),this.setProject(et(this.project,l,this.sectioned(sn(i.options),n)),l);const h=this.findClass(n);h&&this.showInCode(h),(u=this.canvas.querySelector(`.uml-class[data-class="${CSS.escape(n)}"]`))==null||u.scrollIntoView({block:"nearest",inline:"nearest"})}editProjectName(){this.treeSelection="project",this.renderTree(),this.startEditing(this.tree.querySelector('[data-node="project"] > .vo-row .vo-label'))}renderWorkspace(){const e=this.wsBox;e.hidden=!$t();const t=this.shell.querySelector("[data-action=save]");if(t.dataset.tip=d(this.workspace?"web_visuobject_save_ws_tip":"web_visuobject_save_tip"),e.hidden)return;const s=(i,n,o="text-button",r)=>``;this.workspace?(e.className="vo-ws",e.innerHTML=`${b(this.workspace.name)} ${s("zip",d("web_visuobject_ws_zip"),"text-button",d("web_visuobject_ws_zip_tip"))} ${s("switch",d("web_visuobject_ws_switch"),"text-button")}`):this.pendingFolder?(e.className="vo-ws",e.innerHTML=`${s("reopen",d("web_visuobject_ws_reopen",this.pendingFolder.name),"text-button primary")}${s("switch",d("web_visuobject_ws_switch"),"text-button")}`):se(rt)==="1"?(e.className="vo-ws",e.innerHTML=s("open",d("web_visuobject_ws_choose"),"text-button",d("web_visuobject_ws_hint"))):(e.className="vo-ws ask",e.innerHTML=`

    ${b(d("web_visuobject_ws_question"))}

    ${b(d("web_visuobject_ws_hint"))}

    diff --git a/website/app/assets/pl-DchXCt_R.js b/website/app/assets/pl-C3HmQqUD.js similarity index 99% rename from website/app/assets/pl-DchXCt_R.js rename to website/app/assets/pl-C3HmQqUD.js index b362f27c..d2d604d6 100644 --- a/website/app/assets/pl-DchXCt_R.js +++ b/website/app/assets/pl-C3HmQqUD.js @@ -135,7 +135,6 @@ const e=`/* Teksty dostępne tylko w wersji webowej. Wszystko inne pochodzi z pl "web_files_saved_fmt" = "Zapisano: %@"; "web_files_create" = "Utwórz"; "web_learn_ludwig_tip" = "Wskazówka Ludwiga"; -"web_learn_pro" = "Wiedza dla profesjonalistów z Ludwigiem"; "web_game_title" = "Gra: Prawda czy fałsz?"; "web_game_intro" = "Ludwig pokazuje wartości i warunek. Czy warunek jest prawdziwy (true), czy fałszywy (false)? Dziesięć rund, coraz trudniejszych."; "web_game_start" = "Zacznij grę"; diff --git a/website/app/assets/projectZip-Dv_LmKlY.js b/website/app/assets/projectZip-BKS-Blr6.js similarity index 99% rename from website/app/assets/projectZip-Dv_LmKlY.js rename to website/app/assets/projectZip-BKS-Blr6.js index 598e25bd..1ccb6803 100644 --- a/website/app/assets/projectZip-Dv_LmKlY.js +++ b/website/app/assets/projectZip-BKS-Blr6.js @@ -1 +1 @@ -import{p as Br,d as Er,a as mr,i as Gr,b as Qr,c as Vr,u as Lr,n as _r,o as pr,e as br,r as dr,f as re,s as ee}from"./objectApp-exr4obxz.js";import"./index-DqKA7YqL.js";var M=Uint8Array,K=Uint16Array,Tr=Int32Array,hr=new M([0,0,0,0,0,0,0,0,1,1,1,1,2,2,2,2,3,3,3,3,4,4,4,4,5,5,5,5,0,0,0,0]),gr=new M([0,0,0,0,1,1,2,2,3,3,4,4,5,5,6,6,7,7,8,8,9,9,10,10,11,11,12,12,13,13,0,0]),Sr=new M([16,17,18,0,8,7,9,6,10,5,11,4,12,3,13,2,14,1,15]),Wr=function(r,e){for(var n=new K(31),a=0;a<31;++a)n[a]=e+=1<>1|(F&21845)<<1;b=(b&52428)>>2|(b&13107)<<2,b=(b&61680)>>4|(b&3855)<<4,Cr[F]=((b&65280)>>8|(b&255)<<8)>>1}var V=(function(r,e,n){for(var a=r.length,f=0,v=new K(e);f>l]=c}else for(s=new K(a),f=0;f>15-r[f]);return s}),d=new M(288);for(var F=0;F<144;++F)d[F]=8;for(var F=144;F<256;++F)d[F]=9;for(var F=256;F<280;++F)d[F]=7;for(var F=280;F<288;++F)d[F]=8;var ir=new M(32);for(var F=0;F<32;++F)ir[F]=5;var ae=V(d,9,0),fe=V(d,9,1),ve=V(ir,5,0),te=V(ir,5,1),xr=function(r){for(var e=r[0],n=1;ne&&(e=r[n]);return e},X=function(r,e,n){var a=e/8|0;return(r[a]|r[a+1]<<8)>>(e&7)&n},yr=function(r,e){var n=e/8|0;return(r[n]|r[n+1]<<8|r[n+2]<<16)>>(e&7)},Ur=function(r){return(r+7)/8|0},lr=function(r,e,n){return(e==null||e<0)&&(e=0),(n==null||n>r.length)&&(n=r.length),new M(r.subarray(e,n))},oe=["unexpected EOF","invalid block type","invalid length/literal","invalid distance","stream finished","no stream handler",,"no callback","invalid UTF-8 data","extra field too long","date not in range 1980-2099","filename too long","stream finishing","invalid zip data"],I=function(r,e,n){var a=new Error(e||oe[r]);if(a.code=r,Error.captureStackTrace&&Error.captureStackTrace(a,I),!n)throw a;return a},ie=function(r,e,n,a){var f=r.length,v=a?a.length:0;if(!f||e.f&&!e.l)return n||new M(0);var i=!n,s=i||e.i!=2,l=e.i;i&&(n=new M(f*3));var c=function(fr){var vr=n.length;if(fr>vr){var nr=new M(Math.max(vr*2,fr));nr.set(n),n=nr}},t=e.f||0,o=e.p||0,u=e.b||0,h=e.l,y=e.d,w=e.m,x=e.n,T=f*8;do{if(!h){t=X(r,o,1);var z=X(r,o+1,3);if(o+=3,z)if(z==1)h=fe,y=te,w=9,x=5;else if(z==2){var U=X(r,o,31)+257,A=X(r,o+10,15)+4,m=U+X(r,o+5,31)+1;o+=14;for(var g=new M(m),B=new M(19),j=0;j>4;if(C<16)g[j++]=C;else{var E=0,k=0;for(C==16?(k=3+X(r,o,3),o+=2,E=g[j-1]):C==17?(k=3+X(r,o,7),o+=3):C==18&&(k=11+X(r,o,127),o+=7);k--;)g[j++]=E}}var W=g.subarray(0,U),J=g.subarray(U);w=xr(W),x=xr(J),h=V(W,w,1),y=V(J,x,1)}else I(1);else{var C=Ur(o)+4,O=r[C-4]|r[C-3]<<8,$=C+O;if($>f){l&&I(0);break}s&&c(u+O),n.set(r.subarray(C,$),u),e.b=u+=O,e.p=o=$*8,e.f=t;continue}if(o>T){l&&I(0);break}}s&&c(u+131072);for(var ar=(1<>4;if(o+=E&15,o>T){l&&I(0);break}if(E||I(2),q<256)n[u++]=q;else if(q==256){L=o,h=null;break}else{var H=q-254;if(q>264){var j=q-257,S=hr[j];H=X(r,o,(1<>4;G||I(3),o+=G&15;var J=ne[rr];if(rr>3){var S=gr[rr];J+=yr(r,o)&(1<T){l&&I(0);break}s&&c(u+131072);var er=u+H;if(u>8},tr=function(r,e,n){n<<=e&7;var a=e/8|0;r[a]|=n,r[a+1]|=n>>8,r[a+2]|=n>>16},Fr=function(r,e){for(var n=[],a=0;au&&(u=v[a].s);var h=new K(u+1),y=Or(n[t-1],h,0);if(y>e){var a=0,w=0,x=y-e,T=1<e)w+=T-(1<>=x;w>0;){var C=v[a].s;h[C]=0&&w;--a){var O=v[a].s;h[O]==e&&(--h[O],++w)}y=e}return{t:new M(h),l:y}},Or=function(r,e,n){return r.s==-1?Math.max(Or(r.l,e,n+1),Or(r.r,e,n+1)):e[r.s]=n},Nr=function(r){for(var e=r.length;e&&!r[--e];);for(var n=new K(++e),a=0,f=r[0],v=1,i=function(l){n[a++]=l},s=1;s<=e;++s)if(r[s]==f&&s!=e)++v;else{if(!f&&v>2){for(;v>138;v-=138)i(32754);v>2&&(i(v>10?v-11<<5|28690:v-3<<5|12305),v=0)}else if(v>3){for(i(f),--v;v>6;v-=6)i(8304);v>2&&(i(v-3<<5|8208),v=0)}for(;v--;)i(f);v=1,f=r[s]}return{c:n.subarray(0,a),n:e}},or=function(r,e){for(var n=0,a=0;a>8,r[f+2]=r[f]^255,r[f+3]=r[f+1]^255;for(var v=0;v4&&!B[Sr[D-1]];--D);var p=c+5<<3,Z=or(f,d)+or(v,ir)+i,P=or(f,u)+or(v,w)+i+14+3*D+or(A,B)+2*A[16]+3*A[17]+7*A[18];if(l>=0&&p<=Z&&p<=P)return Kr(e,t,r.subarray(l,l+c));var E,k,W,J;if(_(e,t,1+(P15&&(_(e,t,q[m]>>5&127),t+=q[m]>>12)}}else E=ae,k=d,W=ve,J=ir;for(var m=0;m255){var H=S>>18&31;tr(e,t,E[H+257]),t+=k[H+257],H>7&&(_(e,t,S>>23&31),t+=hr[H]);var G=S&31;tr(e,t,W[G]),t+=J[G],G>3&&(tr(e,t,S>>5&8191),t+=gr[G])}else tr(e,t,E[S]),t+=k[S]}return tr(e,t,E[256]),t+k[256]},le=new Tr([65540,131080,131088,131104,262176,1048704,1048832,2114560,2117632]),Rr=new M(0),se=function(r,e,n,a,f,v){var i=v.z||r.length,s=new M(a+i+5*(1+Math.ceil(i/7e3))+f),l=s.subarray(a,s.length-f),c=v.l,t=(v.r||0)&7;if(e){t&&(l[0]=v.r>>3);for(var o=le[e-1],u=o>>13,h=o&8191,y=(1<7e3||B>24576)&&(E>423||!c)){t=Dr(r,l,0,O,$,U,m,B,D,g-D,t),B=A=m=0,D=g;for(var k=0;k<286;++k)$[k]=0;for(var k=0;k<30;++k)U[k]=0}var W=2,J=0,ar=h,R=Z-P&32767;if(E>2&&p==C(g-R))for(var L=Math.min(u,E)-1,q=Math.min(32767,g),H=Math.min(258,E);R<=q&&--ar&&Z!=P;){if(r[g+W]==r[g+W-R]){for(var S=0;SW){if(W=S,J=R,S>L)break;for(var G=Math.min(R,S-2),rr=0,k=0;krr&&(rr=ur,P=er)}}}Z=P,P=w[Z],R+=Z-P&32767}if(J){O[B++]=268435456|Mr[W]<<18|Jr[J];var fr=Mr[W]&31,vr=Jr[J]&31;m+=hr[fr]+gr[vr],++$[257+fr],++U[vr],j=g+W,++A}else O[B++]=r[g],++$[r[g]]}}for(g=Math.max(g,j);g=i&&(l[t/8|0]=c,nr=i),t=Kr(l,t+1,r.subarray(g,nr))}v.i=i}return lr(s,0,a+Ur(t)+f)},ue=(function(){for(var r=new Int32Array(256),e=0;e<256;++e){for(var n=e,a=9;--a;)n=(n&1&&-306674912)^n>>>1;r[e]=n}return r})(),ce=function(){var r=-1;return{p:function(e){for(var n=r,a=0;a>>8;r=n},d:function(){return~r}}},he=function(r,e,n,a,f){if(!f&&(f={l:1},e.dictionary)){var v=e.dictionary.subarray(-32768),i=new M(v.length+r.length);i.set(v),i.set(r,v.length),r=i,f.w=v.length}return se(r,e.level==null?6:e.level,e.mem==null?f.l?Math.ceil(Math.max(8,Math.min(13,Math.log(r.length)))*1.5):20:12+e.mem,n,a,f)},Xr=function(r,e){var n={};for(var a in r)n[a]=r[a];for(var a in e)n[a]=e[a];return n},Q=function(r,e){return r[e]|r[e+1]<<8},Y=function(r,e){return(r[e]|r[e+1]<<8|r[e+2]<<16|r[e+3]<<24)>>>0},kr=function(r,e){return Y(r,e)+Y(r,e+4)*4294967296},N=function(r,e,n){for(;n;++e)r[e]=n,n>>>=8};function ge(r,e){return he(r,e||{},0,0)}function we(r,e){return ie(r,{i:2},e&&e.out,e&&e.dictionary)}var Yr=function(r,e,n,a){for(var f in r){var v=r[f],i=e+f,s=a;Array.isArray(v)&&(s=Xr(a,v[1]),v=v[0]),v instanceof M?n[i]=[v,s]:(n[i+="/"]=[new M(0),s],Yr(v,i,n,a))}},Ir=typeof TextEncoder<"u"&&new TextEncoder,Ar=typeof TextDecoder<"u"&&new TextDecoder,me=0;try{Ar.decode(Rr,{stream:!0}),me=1}catch{}var xe=function(r){for(var e="",n=0;;){var a=r[n++],f=(a>127)+(a>223)+(a>239);if(n+f>r.length)return{s:e,r:lr(r,n-1)};f?f==3?(a=((a&15)<<18|(r[n++]&63)<<12|(r[n++]&63)<<6|r[n++]&63)-65536,e+=String.fromCharCode(55296|a>>10,56320|a&1023)):f&1?e+=String.fromCharCode((a&31)<<6|r[n++]&63):e+=String.fromCharCode((a&15)<<12|(r[n++]&63)<<6|r[n++]&63):e+=String.fromCharCode(a)}};function cr(r,e){var n;if(Ir)return Ir.encode(r);for(var a=r.length,f=new M(r.length+(r.length>>1)),v=0,i=function(c){f[v++]=c},n=0;nf.length){var s=new M(v+8+(a-n<<1));s.set(f),f=s}var l=r.charCodeAt(n);l<128||e?i(l):l<2048?(i(192|l>>6),i(128|l&63)):l>55295&&l<57344?(l=65536+(l&1047552)|r.charCodeAt(++n)&1023,i(240|l>>18),i(128|l>>12&63),i(128|l>>6&63),i(128|l&63)):(i(224|l>>12),i(128|l>>6&63),i(128|l&63))}return lr(f,0,v)}function jr(r,e){if(e){for(var n="",a=0;a65535&&I(9),e+=a+4}return e},Pr=function(r,e,n,a,f,v,i,s){var l=a.length,c=n.extra,t=s&&s.length,o=zr(c);N(r,e,i!=null?33639248:67324752),e+=4,i!=null&&(r[e++]=20,r[e++]=n.os),r[e]=20,e+=2,r[e++]=n.flag<<1|(v<0&&8),r[e++]=f&&8,r[e++]=n.compression&255,r[e++]=n.compression>>8;var u=new Date(n.mtime==null?Date.now():n.mtime),h=u.getFullYear()-1980;if((h<0||h>119)&&I(10),N(r,e,h<<25|u.getMonth()+1<<21|u.getDate()<<16|u.getHours()<<11|u.getMinutes()<<5|u.getSeconds()>>1),e+=4,v!=-1&&(N(r,e,n.crc),N(r,e+4,v<0?-v-2:v),N(r,e+8,n.size)),N(r,e+12,l),N(r,e+14,o),e+=16,i!=null&&(N(r,e,t),N(r,e+6,n.attrs),N(r,e+10,i),e+=14),r.set(a,e),e+=l,o)for(var y in c){var w=c[y],x=w.length;N(r,e,+y),N(r,e+2,x),r.set(w,e+4),e+=4+x}return t&&(r.set(s,e),e+=t),e},Se=function(r,e,n,a,f){N(r,e,101010256),N(r,e+8,n),N(r,e+10,n),N(r,e+12,a),N(r,e+16,f)};function Me(r,e){e||(e={});var n={},a=[];Yr(r,"",n,e);var f=0,v=0;for(var i in n){var s=n[i],l=s[0],c=s[1],t=c.level==0?0:8,o=cr(i),u=o.length,h=c.comment,y=h&&cr(h),w=y&&y.length,x=zr(c.extra);u>65535&&I(11);var T=t?ge(l,c):l,z=T.length,C=ce();C.p(l),a.push(Xr(c,{size:l.length,crc:C.d(),c:T,f:o,m:y,u:u!=i.length||y&&h.length!=w,o:f,compression:t})),f+=30+u+x+z,v+=76+2*(u+x)+(w||0)+z}for(var O=new M(v+22),$=f,U=v-f,A=0;A65558)&&I(13);var f=Q(r,a+8);if(!f)return{};var v=Y(r,a+16),i=v==4294967295||f==65535;if(i){var s=Y(r,a-12);i=Y(r,s)==101075792,i&&(f=Y(r,s+32),v=Y(r,s+48))}for(var l=0;l|]/g,"_")||"Projekt",n={};for(const l of r.files)n[`${e}/${br(l.path)}`]=new Uint8Array(cr(l.text));const a=[...r.packages.map(l=>`${e}/${dr(l)}/${re(l).replace(/\./g,"/")}/`),...ee(r).map(l=>`${e}/${l}/`)];for(const l of a)Object.keys(n).some(c=>c.startsWith(l))||(n[l.replace(/\/\/$/,"/")]=new Uint8Array);return(r.uml&&Object.keys(r.uml).length||(f=r.notes)!=null&&f.length||(v=r.objects)!=null&&v.length)&&(n[`${e}/${$r}`]=new Uint8Array(cr(JSON.stringify({format:"visuobject",version:1,uml:r.uml??{},...(i=r.notes)!=null&&i.length?{notes:r.notes}:{},...(s=r.objects)!=null&&s.length?{objects:r.objects}:{}},null,2)))),Me(n,{level:6})}function ze(r,e){var c;const n=Ce(r),a=Object.entries(n).filter(([t])=>/\.java$/i.test(t)&&!t.startsWith("__MACOSX/")).map(([t,o])=>({name:t,text:jr(o)})),f=new Set(Object.keys(n).map(t=>t.split("/")[0])),v=f.size===1&&Object.keys(n).some(t=>t.includes("/"))?[...f][0]:e,i=v!==e,s=Br(v,[]);for(const t of a){const o=Br(v,[{name:t.name.slice(t.name.lastIndexOf("/")+1),text:t.text}]).files[0],u=t.name.split("/").slice(i?1:0,-1),h=Er(o.text).split(".").filter(Boolean),w=u.slice(u.length-h.length).join("/")===h.join("/")?u.slice(0,u.length-h.length).join("/"):"",x=w&&w!==mr&&w.split("/").every(Gr)&&!w.includes(":")?w:mr,T=Qr(Vr(x,Er(o.text)),o.path.slice(o.path.lastIndexOf("/")+1));s.files=[...s.files.filter(z=>z.path!==T),{...o,path:T}],x!==mr&&!((c=s.sourceFolders)!=null&&c.includes(x))&&(s.sourceFolders=[...s.sourceFolders??[],x])}const l=Object.entries(n).find(([t])=>t===$r||t.endsWith(`/${$r}`));if(l)try{const t=JSON.parse(jr(l[1])),o=Lr(t.uml);o&&(s.uml=o);const u=_r(t.notes);u&&(s.notes=u);const h=pr(t.objects);h&&(s.objects=h)}catch{}return s}export{ze as projectFromZip,je as projectToZip}; +import{p as Br,d as Er,a as mr,i as Gr,b as Qr,c as Vr,u as Lr,n as _r,o as pr,e as br,r as dr,f as re,s as ee}from"./objectApp-Caze4o4v.js";import"./index-CzgrZgZa.js";var M=Uint8Array,K=Uint16Array,Tr=Int32Array,hr=new M([0,0,0,0,0,0,0,0,1,1,1,1,2,2,2,2,3,3,3,3,4,4,4,4,5,5,5,5,0,0,0,0]),gr=new M([0,0,0,0,1,1,2,2,3,3,4,4,5,5,6,6,7,7,8,8,9,9,10,10,11,11,12,12,13,13,0,0]),Sr=new M([16,17,18,0,8,7,9,6,10,5,11,4,12,3,13,2,14,1,15]),Wr=function(r,e){for(var n=new K(31),a=0;a<31;++a)n[a]=e+=1<>1|(F&21845)<<1;b=(b&52428)>>2|(b&13107)<<2,b=(b&61680)>>4|(b&3855)<<4,Cr[F]=((b&65280)>>8|(b&255)<<8)>>1}var V=(function(r,e,n){for(var a=r.length,f=0,v=new K(e);f>l]=c}else for(s=new K(a),f=0;f>15-r[f]);return s}),d=new M(288);for(var F=0;F<144;++F)d[F]=8;for(var F=144;F<256;++F)d[F]=9;for(var F=256;F<280;++F)d[F]=7;for(var F=280;F<288;++F)d[F]=8;var ir=new M(32);for(var F=0;F<32;++F)ir[F]=5;var ae=V(d,9,0),fe=V(d,9,1),ve=V(ir,5,0),te=V(ir,5,1),xr=function(r){for(var e=r[0],n=1;ne&&(e=r[n]);return e},X=function(r,e,n){var a=e/8|0;return(r[a]|r[a+1]<<8)>>(e&7)&n},yr=function(r,e){var n=e/8|0;return(r[n]|r[n+1]<<8|r[n+2]<<16)>>(e&7)},Ur=function(r){return(r+7)/8|0},lr=function(r,e,n){return(e==null||e<0)&&(e=0),(n==null||n>r.length)&&(n=r.length),new M(r.subarray(e,n))},oe=["unexpected EOF","invalid block type","invalid length/literal","invalid distance","stream finished","no stream handler",,"no callback","invalid UTF-8 data","extra field too long","date not in range 1980-2099","filename too long","stream finishing","invalid zip data"],I=function(r,e,n){var a=new Error(e||oe[r]);if(a.code=r,Error.captureStackTrace&&Error.captureStackTrace(a,I),!n)throw a;return a},ie=function(r,e,n,a){var f=r.length,v=a?a.length:0;if(!f||e.f&&!e.l)return n||new M(0);var i=!n,s=i||e.i!=2,l=e.i;i&&(n=new M(f*3));var c=function(fr){var vr=n.length;if(fr>vr){var nr=new M(Math.max(vr*2,fr));nr.set(n),n=nr}},t=e.f||0,o=e.p||0,u=e.b||0,h=e.l,y=e.d,w=e.m,x=e.n,T=f*8;do{if(!h){t=X(r,o,1);var z=X(r,o+1,3);if(o+=3,z)if(z==1)h=fe,y=te,w=9,x=5;else if(z==2){var U=X(r,o,31)+257,A=X(r,o+10,15)+4,m=U+X(r,o+5,31)+1;o+=14;for(var g=new M(m),B=new M(19),j=0;j>4;if(C<16)g[j++]=C;else{var E=0,k=0;for(C==16?(k=3+X(r,o,3),o+=2,E=g[j-1]):C==17?(k=3+X(r,o,7),o+=3):C==18&&(k=11+X(r,o,127),o+=7);k--;)g[j++]=E}}var W=g.subarray(0,U),J=g.subarray(U);w=xr(W),x=xr(J),h=V(W,w,1),y=V(J,x,1)}else I(1);else{var C=Ur(o)+4,O=r[C-4]|r[C-3]<<8,$=C+O;if($>f){l&&I(0);break}s&&c(u+O),n.set(r.subarray(C,$),u),e.b=u+=O,e.p=o=$*8,e.f=t;continue}if(o>T){l&&I(0);break}}s&&c(u+131072);for(var ar=(1<>4;if(o+=E&15,o>T){l&&I(0);break}if(E||I(2),q<256)n[u++]=q;else if(q==256){L=o,h=null;break}else{var H=q-254;if(q>264){var j=q-257,S=hr[j];H=X(r,o,(1<>4;G||I(3),o+=G&15;var J=ne[rr];if(rr>3){var S=gr[rr];J+=yr(r,o)&(1<T){l&&I(0);break}s&&c(u+131072);var er=u+H;if(u>8},tr=function(r,e,n){n<<=e&7;var a=e/8|0;r[a]|=n,r[a+1]|=n>>8,r[a+2]|=n>>16},Fr=function(r,e){for(var n=[],a=0;au&&(u=v[a].s);var h=new K(u+1),y=Or(n[t-1],h,0);if(y>e){var a=0,w=0,x=y-e,T=1<e)w+=T-(1<>=x;w>0;){var C=v[a].s;h[C]=0&&w;--a){var O=v[a].s;h[O]==e&&(--h[O],++w)}y=e}return{t:new M(h),l:y}},Or=function(r,e,n){return r.s==-1?Math.max(Or(r.l,e,n+1),Or(r.r,e,n+1)):e[r.s]=n},Nr=function(r){for(var e=r.length;e&&!r[--e];);for(var n=new K(++e),a=0,f=r[0],v=1,i=function(l){n[a++]=l},s=1;s<=e;++s)if(r[s]==f&&s!=e)++v;else{if(!f&&v>2){for(;v>138;v-=138)i(32754);v>2&&(i(v>10?v-11<<5|28690:v-3<<5|12305),v=0)}else if(v>3){for(i(f),--v;v>6;v-=6)i(8304);v>2&&(i(v-3<<5|8208),v=0)}for(;v--;)i(f);v=1,f=r[s]}return{c:n.subarray(0,a),n:e}},or=function(r,e){for(var n=0,a=0;a>8,r[f+2]=r[f]^255,r[f+3]=r[f+1]^255;for(var v=0;v4&&!B[Sr[D-1]];--D);var p=c+5<<3,Z=or(f,d)+or(v,ir)+i,P=or(f,u)+or(v,w)+i+14+3*D+or(A,B)+2*A[16]+3*A[17]+7*A[18];if(l>=0&&p<=Z&&p<=P)return Kr(e,t,r.subarray(l,l+c));var E,k,W,J;if(_(e,t,1+(P15&&(_(e,t,q[m]>>5&127),t+=q[m]>>12)}}else E=ae,k=d,W=ve,J=ir;for(var m=0;m255){var H=S>>18&31;tr(e,t,E[H+257]),t+=k[H+257],H>7&&(_(e,t,S>>23&31),t+=hr[H]);var G=S&31;tr(e,t,W[G]),t+=J[G],G>3&&(tr(e,t,S>>5&8191),t+=gr[G])}else tr(e,t,E[S]),t+=k[S]}return tr(e,t,E[256]),t+k[256]},le=new Tr([65540,131080,131088,131104,262176,1048704,1048832,2114560,2117632]),Rr=new M(0),se=function(r,e,n,a,f,v){var i=v.z||r.length,s=new M(a+i+5*(1+Math.ceil(i/7e3))+f),l=s.subarray(a,s.length-f),c=v.l,t=(v.r||0)&7;if(e){t&&(l[0]=v.r>>3);for(var o=le[e-1],u=o>>13,h=o&8191,y=(1<7e3||B>24576)&&(E>423||!c)){t=Dr(r,l,0,O,$,U,m,B,D,g-D,t),B=A=m=0,D=g;for(var k=0;k<286;++k)$[k]=0;for(var k=0;k<30;++k)U[k]=0}var W=2,J=0,ar=h,R=Z-P&32767;if(E>2&&p==C(g-R))for(var L=Math.min(u,E)-1,q=Math.min(32767,g),H=Math.min(258,E);R<=q&&--ar&&Z!=P;){if(r[g+W]==r[g+W-R]){for(var S=0;SW){if(W=S,J=R,S>L)break;for(var G=Math.min(R,S-2),rr=0,k=0;krr&&(rr=ur,P=er)}}}Z=P,P=w[Z],R+=Z-P&32767}if(J){O[B++]=268435456|Mr[W]<<18|Jr[J];var fr=Mr[W]&31,vr=Jr[J]&31;m+=hr[fr]+gr[vr],++$[257+fr],++U[vr],j=g+W,++A}else O[B++]=r[g],++$[r[g]]}}for(g=Math.max(g,j);g=i&&(l[t/8|0]=c,nr=i),t=Kr(l,t+1,r.subarray(g,nr))}v.i=i}return lr(s,0,a+Ur(t)+f)},ue=(function(){for(var r=new Int32Array(256),e=0;e<256;++e){for(var n=e,a=9;--a;)n=(n&1&&-306674912)^n>>>1;r[e]=n}return r})(),ce=function(){var r=-1;return{p:function(e){for(var n=r,a=0;a>>8;r=n},d:function(){return~r}}},he=function(r,e,n,a,f){if(!f&&(f={l:1},e.dictionary)){var v=e.dictionary.subarray(-32768),i=new M(v.length+r.length);i.set(v),i.set(r,v.length),r=i,f.w=v.length}return se(r,e.level==null?6:e.level,e.mem==null?f.l?Math.ceil(Math.max(8,Math.min(13,Math.log(r.length)))*1.5):20:12+e.mem,n,a,f)},Xr=function(r,e){var n={};for(var a in r)n[a]=r[a];for(var a in e)n[a]=e[a];return n},Q=function(r,e){return r[e]|r[e+1]<<8},Y=function(r,e){return(r[e]|r[e+1]<<8|r[e+2]<<16|r[e+3]<<24)>>>0},kr=function(r,e){return Y(r,e)+Y(r,e+4)*4294967296},N=function(r,e,n){for(;n;++e)r[e]=n,n>>>=8};function ge(r,e){return he(r,e||{},0,0)}function we(r,e){return ie(r,{i:2},e&&e.out,e&&e.dictionary)}var Yr=function(r,e,n,a){for(var f in r){var v=r[f],i=e+f,s=a;Array.isArray(v)&&(s=Xr(a,v[1]),v=v[0]),v instanceof M?n[i]=[v,s]:(n[i+="/"]=[new M(0),s],Yr(v,i,n,a))}},Ir=typeof TextEncoder<"u"&&new TextEncoder,Ar=typeof TextDecoder<"u"&&new TextDecoder,me=0;try{Ar.decode(Rr,{stream:!0}),me=1}catch{}var xe=function(r){for(var e="",n=0;;){var a=r[n++],f=(a>127)+(a>223)+(a>239);if(n+f>r.length)return{s:e,r:lr(r,n-1)};f?f==3?(a=((a&15)<<18|(r[n++]&63)<<12|(r[n++]&63)<<6|r[n++]&63)-65536,e+=String.fromCharCode(55296|a>>10,56320|a&1023)):f&1?e+=String.fromCharCode((a&31)<<6|r[n++]&63):e+=String.fromCharCode((a&15)<<12|(r[n++]&63)<<6|r[n++]&63):e+=String.fromCharCode(a)}};function cr(r,e){var n;if(Ir)return Ir.encode(r);for(var a=r.length,f=new M(r.length+(r.length>>1)),v=0,i=function(c){f[v++]=c},n=0;nf.length){var s=new M(v+8+(a-n<<1));s.set(f),f=s}var l=r.charCodeAt(n);l<128||e?i(l):l<2048?(i(192|l>>6),i(128|l&63)):l>55295&&l<57344?(l=65536+(l&1047552)|r.charCodeAt(++n)&1023,i(240|l>>18),i(128|l>>12&63),i(128|l>>6&63),i(128|l&63)):(i(224|l>>12),i(128|l>>6&63),i(128|l&63))}return lr(f,0,v)}function jr(r,e){if(e){for(var n="",a=0;a65535&&I(9),e+=a+4}return e},Pr=function(r,e,n,a,f,v,i,s){var l=a.length,c=n.extra,t=s&&s.length,o=zr(c);N(r,e,i!=null?33639248:67324752),e+=4,i!=null&&(r[e++]=20,r[e++]=n.os),r[e]=20,e+=2,r[e++]=n.flag<<1|(v<0&&8),r[e++]=f&&8,r[e++]=n.compression&255,r[e++]=n.compression>>8;var u=new Date(n.mtime==null?Date.now():n.mtime),h=u.getFullYear()-1980;if((h<0||h>119)&&I(10),N(r,e,h<<25|u.getMonth()+1<<21|u.getDate()<<16|u.getHours()<<11|u.getMinutes()<<5|u.getSeconds()>>1),e+=4,v!=-1&&(N(r,e,n.crc),N(r,e+4,v<0?-v-2:v),N(r,e+8,n.size)),N(r,e+12,l),N(r,e+14,o),e+=16,i!=null&&(N(r,e,t),N(r,e+6,n.attrs),N(r,e+10,i),e+=14),r.set(a,e),e+=l,o)for(var y in c){var w=c[y],x=w.length;N(r,e,+y),N(r,e+2,x),r.set(w,e+4),e+=4+x}return t&&(r.set(s,e),e+=t),e},Se=function(r,e,n,a,f){N(r,e,101010256),N(r,e+8,n),N(r,e+10,n),N(r,e+12,a),N(r,e+16,f)};function Me(r,e){e||(e={});var n={},a=[];Yr(r,"",n,e);var f=0,v=0;for(var i in n){var s=n[i],l=s[0],c=s[1],t=c.level==0?0:8,o=cr(i),u=o.length,h=c.comment,y=h&&cr(h),w=y&&y.length,x=zr(c.extra);u>65535&&I(11);var T=t?ge(l,c):l,z=T.length,C=ce();C.p(l),a.push(Xr(c,{size:l.length,crc:C.d(),c:T,f:o,m:y,u:u!=i.length||y&&h.length!=w,o:f,compression:t})),f+=30+u+x+z,v+=76+2*(u+x)+(w||0)+z}for(var O=new M(v+22),$=f,U=v-f,A=0;A65558)&&I(13);var f=Q(r,a+8);if(!f)return{};var v=Y(r,a+16),i=v==4294967295||f==65535;if(i){var s=Y(r,a-12);i=Y(r,s)==101075792,i&&(f=Y(r,s+32),v=Y(r,s+48))}for(var l=0;l|]/g,"_")||"Projekt",n={};for(const l of r.files)n[`${e}/${br(l.path)}`]=new Uint8Array(cr(l.text));const a=[...r.packages.map(l=>`${e}/${dr(l)}/${re(l).replace(/\./g,"/")}/`),...ee(r).map(l=>`${e}/${l}/`)];for(const l of a)Object.keys(n).some(c=>c.startsWith(l))||(n[l.replace(/\/\/$/,"/")]=new Uint8Array);return(r.uml&&Object.keys(r.uml).length||(f=r.notes)!=null&&f.length||(v=r.objects)!=null&&v.length)&&(n[`${e}/${$r}`]=new Uint8Array(cr(JSON.stringify({format:"visuobject",version:1,uml:r.uml??{},...(i=r.notes)!=null&&i.length?{notes:r.notes}:{},...(s=r.objects)!=null&&s.length?{objects:r.objects}:{}},null,2)))),Me(n,{level:6})}function ze(r,e){var c;const n=Ce(r),a=Object.entries(n).filter(([t])=>/\.java$/i.test(t)&&!t.startsWith("__MACOSX/")).map(([t,o])=>({name:t,text:jr(o)})),f=new Set(Object.keys(n).map(t=>t.split("/")[0])),v=f.size===1&&Object.keys(n).some(t=>t.includes("/"))?[...f][0]:e,i=v!==e,s=Br(v,[]);for(const t of a){const o=Br(v,[{name:t.name.slice(t.name.lastIndexOf("/")+1),text:t.text}]).files[0],u=t.name.split("/").slice(i?1:0,-1),h=Er(o.text).split(".").filter(Boolean),w=u.slice(u.length-h.length).join("/")===h.join("/")?u.slice(0,u.length-h.length).join("/"):"",x=w&&w!==mr&&w.split("/").every(Gr)&&!w.includes(":")?w:mr,T=Qr(Vr(x,Er(o.text)),o.path.slice(o.path.lastIndexOf("/")+1));s.files=[...s.files.filter(z=>z.path!==T),{...o,path:T}],x!==mr&&!((c=s.sourceFolders)!=null&&c.includes(x))&&(s.sourceFolders=[...s.sourceFolders??[],x])}const l=Object.entries(n).find(([t])=>t===$r||t.endsWith(`/${$r}`));if(l)try{const t=JSON.parse(jr(l[1])),o=Lr(t.uml);o&&(s.uml=o);const u=_r(t.notes);u&&(s.notes=u);const h=pr(t.objects);h&&(s.objects=h)}catch{}return s}export{ze as projectFromZip,je as projectToZip}; diff --git a/website/app/assets/pt-PT-Dq8KVIrs.js b/website/app/assets/pt-PT-2W9Vff48.js similarity index 99% rename from website/app/assets/pt-PT-Dq8KVIrs.js rename to website/app/assets/pt-PT-2W9Vff48.js index 5e3d547b..50b08736 100644 --- a/website/app/assets/pt-PT-Dq8KVIrs.js +++ b/website/app/assets/pt-PT-2W9Vff48.js @@ -219,7 +219,6 @@ const e=`/* Textos que só existem na versão web. Tudo o resto vem dos Localiza "web_files_saved_fmt" = "Guardado: %@"; "web_files_create" = "Criar"; "web_learn_ludwig_tip" = "Dica do Ludwig"; -"web_learn_pro" = "Saber de profissional com o Ludwig"; "web_game_title" = "Jogo: Verdadeiro ou falso?"; "web_game_intro" = "O Ludwig mostra-te valores e uma condição. A condição é verdadeira (true) ou falsa (false)? Dez rondas, cada vez mais difíceis."; "web_game_start" = "Começar o jogo"; diff --git a/website/app/assets/robot3d-I0g91EHr.js b/website/app/assets/robot3d-BNw8Z2K3.js similarity index 99% rename from website/app/assets/robot3d-I0g91EHr.js rename to website/app/assets/robot3d-BNw8Z2K3.js index 242722c8..b367ce72 100644 --- a/website/app/assets/robot3d-I0g91EHr.js +++ b/website/app/assets/robot3d-BNw8Z2K3.js @@ -1,4 +1,4 @@ -var gl=Object.defineProperty;var _l=(i,t,e)=>t in i?gl(i,t,{enumerable:!0,configurable:!0,writable:!0,value:e}):i[t]=e;var le=(i,t,e)=>_l(i,typeof t!="symbol"?t+"":t,e);import{C as rn,L as oo}from"./index-DqKA7YqL.js";/** +var gl=Object.defineProperty;var _l=(i,t,e)=>t in i?gl(i,t,{enumerable:!0,configurable:!0,writable:!0,value:e}):i[t]=e;var le=(i,t,e)=>_l(i,typeof t!="symbol"?t+"":t,e);import{C as rn,L as oo}from"./index-CzgrZgZa.js";/** * @license * Copyright 2010-2025 Three.js Authors * SPDX-License-Identifier: MIT diff --git a/website/app/assets/ru-DGHs_3oc.js b/website/app/assets/ru-B4vTuE57.js similarity index 99% rename from website/app/assets/ru-DGHs_3oc.js rename to website/app/assets/ru-B4vTuE57.js index f5b0dec3..a3d3cb73 100644 --- a/website/app/assets/ru-DGHs_3oc.js +++ b/website/app/assets/ru-B4vTuE57.js @@ -135,7 +135,6 @@ const e=`/* Тексты, которые есть только в веб-вер "web_files_saved_fmt" = "Сохранено: %@"; "web_files_create" = "Создать"; "web_learn_ludwig_tip" = "Совет Людвига"; -"web_learn_pro" = "Профи-знания с Людвигом"; "web_game_title" = "Игра: Истина или ложь?"; "web_game_intro" = "Людвиг показывает значения и условие. Условие истинно (true) или ложно (false)? Десять раундов, всё сложнее."; "web_game_start" = "Начать игру"; diff --git a/website/app/assets/sv-zO9ikvt0.js b/website/app/assets/sv-Dau75zUV.js similarity index 99% rename from website/app/assets/sv-zO9ikvt0.js rename to website/app/assets/sv-Dau75zUV.js index 03af12bd..a13be35d 100644 --- a/website/app/assets/sv-zO9ikvt0.js +++ b/website/app/assets/sv-Dau75zUV.js @@ -135,7 +135,6 @@ const e=`/* Texter som bara finns i webbversionen. Allt annat kommer från appen "web_files_saved_fmt" = "Sparat: %@"; "web_files_create" = "Skapa"; "web_learn_ludwig_tip" = "Ludwigs tips"; -"web_learn_pro" = "Proffskunskap med Ludwig"; "web_game_title" = "Spel: Sant eller falskt?"; "web_game_intro" = "Ludwig visar värden och ett villkor. Är villkoret sant (true) eller falskt (false)? Tio rundor, allt svårare."; "web_game_start" = "Starta spelet"; diff --git a/website/app/assets/tr-zv5TxQHQ.js b/website/app/assets/tr-DrZsTe-O.js similarity index 99% rename from website/app/assets/tr-zv5TxQHQ.js rename to website/app/assets/tr-DrZsTe-O.js index 327f8a97..3cc2459f 100644 --- a/website/app/assets/tr-zv5TxQHQ.js +++ b/website/app/assets/tr-DrZsTe-O.js @@ -135,7 +135,6 @@ const e=`/* Yalnızca web sürümünde bulunan metinler. Geri kalan her şey uyg "web_files_saved_fmt" = "Kaydedildi: %@"; "web_files_create" = "Oluştur"; "web_learn_ludwig_tip" = "Ludwig’in ipucu"; -"web_learn_pro" = "Ludwig ile profesyonel bilgi"; "web_game_title" = "Oyun: Doğru mu yanlış mı?"; "web_game_intro" = "Ludwig sana değerler ve bir koşul gösterir. Koşul doğru (true) mu yanlış (false) mı? On tur, giderek zorlaşır."; "web_game_start" = "Oyunu başlat"; diff --git a/website/app/assets/uk-D5KOtCBD.js b/website/app/assets/uk-DQrOpK2W.js similarity index 99% rename from website/app/assets/uk-D5KOtCBD.js rename to website/app/assets/uk-DQrOpK2W.js index 71210b14..4836970c 100644 --- a/website/app/assets/uk-D5KOtCBD.js +++ b/website/app/assets/uk-DQrOpK2W.js @@ -135,7 +135,6 @@ const e=`/* Тексти, які є лише у веб-версії. Усі ін "web_files_saved_fmt" = "Збережено: %@"; "web_files_create" = "Створити"; "web_learn_ludwig_tip" = "Порада Людвіга"; -"web_learn_pro" = "Знання профі з Людвігом"; "web_game_title" = "Гра: Істина чи хиба?"; "web_game_intro" = "Людвіг показує значення й умову. Умова істинна (true) чи хибна (false)? Десять раундів, щоразу складніше."; "web_game_start" = "Почати гру"; diff --git a/website/app/assets/zh-Hans-C3na1U20.js b/website/app/assets/zh-Hans-CeIYjS3N.js similarity index 99% rename from website/app/assets/zh-Hans-C3na1U20.js rename to website/app/assets/zh-Hans-CeIYjS3N.js index 7e5b6b52..3c763aeb 100644 --- a/website/app/assets/zh-Hans-C3na1U20.js +++ b/website/app/assets/zh-Hans-CeIYjS3N.js @@ -135,7 +135,6 @@ const e=`/* 仅存在于网页版中的文本。其他所有文本均来自应 "web_files_saved_fmt" = "已保存:%@"; "web_files_create" = "新建"; "web_learn_ludwig_tip" = "路德维希的提示"; -"web_learn_pro" = "路德维希的专业知识"; "web_game_title" = "游戏:真还是假?"; "web_game_intro" = "路德维希给你看一些值和一个条件。这个条件是真(true)还是假(false)?共十轮,越来越难。"; "web_game_start" = "开始游戏"; diff --git a/website/app/assets/zh-Hant-BLjr78US.js b/website/app/assets/zh-Hant-7-ScZHAu.js similarity index 99% rename from website/app/assets/zh-Hant-BLjr78US.js rename to website/app/assets/zh-Hant-7-ScZHAu.js index 3afd3e22..cbcbdc06 100644 --- a/website/app/assets/zh-Hant-BLjr78US.js +++ b/website/app/assets/zh-Hant-7-ScZHAu.js @@ -135,7 +135,6 @@ const e=`/* 僅存在於網頁版的文字。其他所有文字皆來自 App 的 "web_files_saved_fmt" = "已儲存:%@"; "web_files_create" = "新增"; "web_learn_ludwig_tip" = "路德維希的提示"; -"web_learn_pro" = "路德維希的專業知識"; "web_game_title" = "遊戲:真還是假?"; "web_game_intro" = "路德維希給你看一些值和一個條件。這個條件是真(true)還是假(false)?共十輪,越來越難。"; "web_game_start" = "開始遊戲"; diff --git a/website/app/index.html b/website/app/index.html index bd9378b3..6fb96b9b 100644 --- a/website/app/index.html +++ b/website/app/index.html @@ -6,7 +6,7 @@ VisuStruct Web - + From 54ff8d7c8c008ca1796e425fbcd6b6a11f397512 Mon Sep 17 00:00:00 2001 From: Claude Date: Fri, 30 Oct 2026 23:45:32 +0000 Subject: [PATCH 3/3] Konsolenbefehle: nach javac zwei Dateien (.java und .class) nennen; Testcache entfernt Co-Authored-By: Claude Opus 5.5 Claude-Session: https://claude.ai/code/session_01Ugz28WToQoMzLJgvHWUb3d --- node_modules/.vite/vitest/CACHEDIR.TAG | 3 - .../results.json | 1 - .../2685641e1680de19f98fa880c880363e3d9a5647 | 164 ----- .../2e7e8c86acce9951f2c7f1e10275b55254f40698 | 27 - .../671ba0efec37747e02cf77c4dec09a7b139242a6 | 136 ---- .../92afb3df989d8c4b3fbf8e596cd079aed22718e6 | 418 ------------- node_modules/.vitest-cache/CACHEDIR.TAG | 3 - node_modules/.vitest-cache/_metadata.json | 3 - .../a24f3c2d2711027964cf8cac3e5bdea117013f42 | 587 ------------------ .../a2bc6900de05952e637aa8c1bf773176a1051346 | 86 --- .../c9e09693ee8175a114f4dbe1e385c70c5582fca5 | 567 ----------------- .../e482c53abeaa5899f7e393b26fde791e2b456b18 | 382 ------------ .../e8414e1454c9436819af0b8d69e3557e442d9777 | 200 ------ .../ead0aad5e88b12ac47bd410f9cc055bc1ed9a667 | 83 --- web/lessons/de/20-java.md | 2 +- web/lessons/en/20-java.md | 2 +- web/lessons/pt/20-java.md | 2 +- ...lowApp-Bn4c4hPI.js => flowApp-B2mFVVBJ.js} | 2 +- .../{index-CzgrZgZa.js => index-Dntu0aWH.js} | 14 +- ...tApp-Caze4o4v.js => objectApp-Thy8-AED.js} | 6 +- ...Zip-BKS-Blr6.js => projectZip-BgHQOrUW.js} | 2 +- ...obot3d-BNw8Z2K3.js => robot3d-SvNK2bGm.js} | 2 +- website/app/index.html | 2 +- 23 files changed, 17 insertions(+), 2677 deletions(-) delete mode 100644 node_modules/.vite/vitest/CACHEDIR.TAG delete mode 100644 node_modules/.vite/vitest/da39a3ee5e6b4b0d3255bfef95601890afd80709/results.json delete mode 100644 node_modules/.vitest-cache/2685641e1680de19f98fa880c880363e3d9a5647 delete mode 100644 node_modules/.vitest-cache/2e7e8c86acce9951f2c7f1e10275b55254f40698 delete mode 100644 node_modules/.vitest-cache/671ba0efec37747e02cf77c4dec09a7b139242a6 delete mode 100644 node_modules/.vitest-cache/92afb3df989d8c4b3fbf8e596cd079aed22718e6 delete mode 100644 node_modules/.vitest-cache/CACHEDIR.TAG delete mode 100644 node_modules/.vitest-cache/_metadata.json delete mode 100644 node_modules/.vitest-cache/a24f3c2d2711027964cf8cac3e5bdea117013f42 delete mode 100644 node_modules/.vitest-cache/a2bc6900de05952e637aa8c1bf773176a1051346 delete mode 100644 node_modules/.vitest-cache/c9e09693ee8175a114f4dbe1e385c70c5582fca5 delete mode 100644 node_modules/.vitest-cache/e482c53abeaa5899f7e393b26fde791e2b456b18 delete mode 100644 node_modules/.vitest-cache/e8414e1454c9436819af0b8d69e3557e442d9777 delete mode 100644 node_modules/.vitest-cache/ead0aad5e88b12ac47bd410f9cc055bc1ed9a667 rename website/app/assets/{flowApp-Bn4c4hPI.js => flowApp-B2mFVVBJ.js} (99%) rename website/app/assets/{index-CzgrZgZa.js => index-Dntu0aWH.js} (99%) rename website/app/assets/{objectApp-Caze4o4v.js => objectApp-Thy8-AED.js} (99%) rename website/app/assets/{projectZip-BKS-Blr6.js => projectZip-BgHQOrUW.js} (99%) rename website/app/assets/{robot3d-BNw8Z2K3.js => robot3d-SvNK2bGm.js} (99%) diff --git a/node_modules/.vite/vitest/CACHEDIR.TAG b/node_modules/.vite/vitest/CACHEDIR.TAG deleted file mode 100644 index 8c1ef4ce..00000000 --- a/node_modules/.vite/vitest/CACHEDIR.TAG +++ /dev/null @@ -1,3 +0,0 @@ -Signature: 8a477f597d28d172789f06886806bc55 -# This file is a cache directory tag created by Vitest. -# For information about cache directory tags see https://bford.info/cachedir/ diff --git a/node_modules/.vite/vitest/da39a3ee5e6b4b0d3255bfef95601890afd80709/results.json b/node_modules/.vite/vitest/da39a3ee5e6b4b0d3255bfef95601890afd80709/results.json deleted file mode 100644 index f75bae95..00000000 --- a/node_modules/.vite/vitest/da39a3ee5e6b4b0d3255bfef95601890afd80709/results.json +++ /dev/null @@ -1 +0,0 @@ -{"version":1,"projects":{"":{"files":{"web/test/zz_tmp.test.ts":{"failed":true,"duration":5.370806999999957,"lastRun":1793403670389}}}}} \ No newline at end of file diff --git a/node_modules/.vitest-cache/2685641e1680de19f98fa880c880363e3d9a5647 b/node_modules/.vitest-cache/2685641e1680de19f98fa880c880363e3d9a5647 deleted file mode 100644 index 2a3493a8..00000000 --- a/node_modules/.vitest-cache/2685641e1680de19f98fa880c880363e3d9a5647 +++ /dev/null @@ -1,164 +0,0 @@ -__vite_ssr_exportName__("RescueGameError", () => { try { return RescueGameError } catch {} }); -__vite_ssr_exportName__("gatePlaceholder", () => { try { return gatePlaceholder } catch {} }); -__vite_ssr_exportName__("crosswordGrid", () => { try { return crosswordGrid } catch {} }); -__vite_ssr_exportName__("parseRescueGame", () => { try { return parseRescueGame } catch {} }); -class RescueGameError extends Error {}; -const gatePlaceholder = "___"; -/** Das Rätsel als Gitter: `grid[zeile][spalte]` ist der Buchstabe oder `''`. */ -function crosswordGrid(game) { - const grid = Array.from({ length: game.rows }, () => Array(game.cols).fill("")); - for (const w of game.words) [...w.word].forEach((c, k) => grid[w.row + (w.across ? 0 : k)][w.col + (w.across ? k : 0)] = c); - return grid; -}; -function parseRescueGame(lines, file) { - const fail = (msg) => { - throw new RescueGameError(`${file}: ${msg}`); - }; - const cell = (text, where) => { - const m = /^(\d+)\s+(\d+)$/.exec(text.trim()); - if (!m || Number(m[1]) < 1 || Number(m[2]) < 1) return fail(`${where}: „${text}“ ist kein Feld (Zeile Spalte, ab 1).`); - return { - row: Number(m[1]) - 1, - col: Number(m[2]) - 1 - }; - }; - let title = ""; - let intro = ""; - let alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"; - let crosswordText = ""; - let gateText = ""; - let gateCode = ""; - let end = ""; - const stations = []; - const raw = []; - let solution = []; - /** Wohin eingerückte Zeilen gehören. */ - let codeTarget; - let section = "start"; - for (const line of lines) { - const text = line.trim(); - if (codeTarget && (/^( {4}|\t)/.test(line) || text === "")) { - const code = line.replace(/^( {4}|\t)/, ""); - if (codeTarget === "station") { - const s = stations[stations.length - 1]; - s.code += (s.code ? "\n" : "") + code; - } else gateCode += (gateCode ? "\n" : "") + code; - continue; - }; - codeTarget = undefined; - if (!text) continue; - const key = /^(titel|intro|alphabet|station|frage|zahl|feld|tipp|kreuzwort|lösung|loesung|tor|ende):\s*(.*)$/.exec(text); - if (key) { - const [, name, value] = key; - if (name === "station") { - stations.push({ - name: value, - code: "", - question: "", - hint: "", - explanation: "" - }); - section = "station"; - codeTarget = "station"; - } else if (name === "kreuzwort") { - crosswordText = value; - section = "crossword"; - } else if (name === "tor") { - gateText = value; - section = "gate"; - codeTarget = "gate"; - } else if (name === "titel") title = value; - else if (name === "intro") intro = value; - else if (name === "alphabet") alphabet = value; - else if (name === "ende") end = value; - else if (name === "lösung" || name === "loesung") { - if (section !== "crossword") fail("„lösung:“ gehört zum Kreuzworträtsel."); - solution = value.split(",").map((c) => cell(c, "lösung")); - } else { - if (section !== "station") fail(`„${name}:“ gehört in eine Station.`); - const s = stations[stations.length - 1]; - if (name === "frage") s.question = value; - else if (name === "tipp") s.hint = value; - else if (name === "zahl") s.answer = /^-?\d+$/.test(value) ? Number(value) : fail(`Station „${s.name}“: „zahl:“ muss eine ganze Zahl sein.`); - else Object.assign(s, cell(value, `Station „${s.name}“`)); - }; - continue; - }; - if (section === "crossword") { - const m = /^-\s+([→↓])\s+(\d+)\s+(\d+)\s+([A-ZÄÖÜ]+):\s*(.+)$/u.exec(text); - if (!m) fail(`Kreuzworträtsel: „${text}“ verstehe ich nicht (z. B. „- → 1 3 STRING: Hinweis“).`); - raw.push({ - across: m[1] === "→", - row: Number(m[2]) - 1, - col: Number(m[3]) - 1, - word: m[4], - clue: m[5] - }); - continue; - }; - if (section === "station" && text.startsWith(">")) { - const s = stations[stations.length - 1]; - s.explanation += (s.explanation ? " " : "") + text.slice(1).trim(); - continue; - }; - fail(`Unbekannte Zeile im Spiel: „${text}“`); - }; - if (!title) fail("Das Spiel braucht eine Zeile „titel:“."); - if (!stations.length) fail("Das Spiel braucht mindestens eine „station:“."); - if (!raw.length) fail("Das Spiel braucht ein „kreuzwort:“ mit Wörtern."); - if (!solution.length) fail("Das Kreuzworträtsel braucht eine Zeile „lösung:“."); - if (!gateCode.includes(gatePlaceholder)) fail(`Der Code bei „tor:“ braucht ${gatePlaceholder} für das Eingabefeld.`); - if (new Set(alphabet).size !== alphabet.length) fail("Im Alphabet kommt ein Zeichen doppelt vor."); - // Wörter ins Gitter legen: Kreuzungen müssen passen. - const rows = Math.max(...raw.map((w) => w.row + (w.across ? 1 : w.word.length))); - const cols = Math.max(...raw.map((w) => w.col + (w.across ? w.word.length : 1))); - const grid = Array.from({ length: rows }, () => Array(cols).fill("")); - for (const w of raw) { - ; - [...w.word].forEach((c, k) => { - const r = w.row + (w.across ? 0 : k); - const col = w.col + (w.across ? k : 0); - if (grid[r][col] && grid[r][col] !== c) fail(`Kreuzworträtsel: ${w.word} passt in Zeile ${r + 1}, Spalte ${col + 1} nicht (dort steht ${grid[r][col]}).`); - grid[r][col] = c; - }); - }; - // Nummern wie in der Zeitung: von oben nach unten, links nach rechts; zwei Wörter im selben Feld teilen sich eine. - const starts = [...new Set(raw.map((w) => w.row * cols + w.col))].sort((a, b) => a - b); - const words = raw.map((w) => ({ - ...w, - number: starts.indexOf(w.row * cols + w.col) + 1 - })); - const letterAt = (r, c) => grid[r]?.[c] ?? ""; - const keyword = solution.map(({ row, col }) => letterAt(row, col) || fail(`lösung: In Zeile ${row + 1}, Spalte ${col + 1} ist kein Feld.`)).join(""); - const checked = stations.map((s) => { - if (!s.code) fail(`Station „${s.name}“: Code fehlt.`); - if (!s.question) fail(`Station „${s.name}“: „frage:“ fehlt.`); - if (s.answer === undefined) fail(`Station „${s.name}“: „zahl:“ fehlt.`); - if (s.row === undefined) fail(`Station „${s.name}“: „feld:“ fehlt.`); - const letter = alphabet.charAt(s.answer); - if (!letter) fail(`Station „${s.name}“: alphabet.charAt(${s.answer}) gibt es nicht.`); - const target = letterAt(s.row, s.col); - if (target !== letter) fail(`Station „${s.name}“: alphabet.charAt(${s.answer}) ist ${letter}, im Feld ${s.row + 1} ${s.col + 1} steht aber „${target}“.`); - s.code = s.code.replace(/\n+$/, ""); - return s; - }); - return { - title, - intro, - alphabet, - stations: checked, - crosswordText, - rows, - cols, - words, - solution, - keyword, - gateText, - gateCode: gateCode.replace(/\n+$/, ""), - end - }; -} -//# sourceMappingSource=vite-generated -//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJtYXBwaW5ncyI6IkFBQUEsQ0FBQTs7OztBQW1FTyxNQUFNLHdCQUF3QixNQUFNLENBQUM7QUFFckMsTUFBTSxrQkFBa0I7O0FBR3hCLFNBQVMsY0FBYyxNQUErRDtDQUMzRixNQUFNLE9BQU8sTUFBTSxLQUFLLEVBQUUsUUFBUSxLQUFLLEtBQUssU0FBUyxNQUFjLEtBQUssSUFBSSxDQUFDLENBQUMsS0FBSyxFQUFFLENBQUM7Q0FDdEYsS0FBSyxNQUFNLEtBQUssS0FBSyxPQUFPLENBQUMsR0FBRyxFQUFFLElBQUksQ0FBQyxDQUFDLFNBQVMsR0FBRyxNQUFPLEtBQUssRUFBRSxPQUFPLEVBQUUsU0FBUyxJQUFJLEdBQUcsQ0FBQyxFQUFFLE9BQU8sRUFBRSxTQUFTLElBQUksTUFBTSxDQUFFO0NBQzVILE9BQU87QUFDVDtBQUVPLFNBQVMsZ0JBQWdCLE9BQWlCLE1BQTBCO0NBQ3pFLE1BQU0sUUFBUSxRQUF1QjtFQUNuQyxNQUFNLElBQUksZ0JBQWdCLEdBQUcsS0FBSyxJQUFJLEtBQUs7Q0FDN0M7Q0FDQSxNQUFNLFFBQVEsTUFBYyxVQUFrQjtFQUM1QyxNQUFNLElBQUksa0JBQWtCLEtBQUssS0FBSyxLQUFLLENBQUM7RUFDNUMsSUFBSSxDQUFDLEtBQUssT0FBTyxFQUFFLEVBQUUsSUFBSSxLQUFLLE9BQU8sRUFBRSxFQUFFLElBQUksR0FBRyxPQUFPLEtBQUssR0FBRyxNQUFNLEtBQUssS0FBSyxzQ0FBc0M7RUFDckgsT0FBTztHQUFFLEtBQUssT0FBTyxFQUFFLEVBQUUsSUFBSTtHQUFHLEtBQUssT0FBTyxFQUFFLEVBQUUsSUFBSTtFQUFFO0NBQ3hEO0NBQ0EsSUFBSSxRQUFRO0NBQ1osSUFBSSxRQUFRO0NBQ1osSUFBSSxXQUFXO0NBQ2YsSUFBSSxnQkFBZ0I7Q0FDcEIsSUFBSSxXQUFXO0NBQ2YsSUFBSSxXQUFXO0NBQ2YsSUFBSSxNQUFNO0NBQ1YsTUFBTSxXQUFnSCxDQUFDO0NBQ3ZILE1BQU0sTUFBbUYsQ0FBQztDQUMxRixJQUFJLFdBQTJDLENBQUM7O0NBRWhELElBQUk7Q0FDSixJQUFJLFVBQXNEO0NBQzFELEtBQUssTUFBTSxRQUFRLE9BQU87RUFDeEIsTUFBTSxPQUFPLEtBQUssS0FBSztFQUN2QixJQUFJLGVBQWUsYUFBYSxLQUFLLElBQUksS0FBSyxTQUFTLEtBQUs7R0FDMUQsTUFBTSxPQUFPLEtBQUssUUFBUSxjQUFjLEVBQUU7R0FDMUMsSUFBSSxlQUFlLFdBQVc7SUFDNUIsTUFBTSxJQUFJLFNBQVMsU0FBUyxTQUFTO0lBQ3JDLEVBQUUsU0FBUyxFQUFFLE9BQU8sT0FBTyxNQUFNO0dBQ25DLE9BQU8sYUFBYSxXQUFXLE9BQU8sTUFBTTtHQUM1QztFQUNGO0VBQ0EsYUFBYTtFQUNiLElBQUksQ0FBQyxNQUFNO0VBQ1gsTUFBTSxNQUFNLGtHQUFrRyxLQUFLLElBQUk7RUFDdkgsSUFBSSxLQUFLO0dBQ1AsTUFBTSxHQUFHLE1BQU0sU0FBUztHQUN4QixJQUFJLFNBQVMsV0FBVztJQUN0QixTQUFTLEtBQUs7S0FBRSxNQUFNO0tBQU8sTUFBTTtLQUFJLFVBQVU7S0FBSSxNQUFNO0tBQUksYUFBYTtJQUFHLENBQUM7SUFDaEYsVUFBVTtJQUNWLGFBQWE7R0FDZixPQUFPLElBQUksU0FBUyxhQUFhO0lBQy9CLGdCQUFnQjtJQUNoQixVQUFVO0dBQ1osT0FBTyxJQUFJLFNBQVMsT0FBTztJQUN6QixXQUFXO0lBQ1gsVUFBVTtJQUNWLGFBQWE7R0FDZixPQUFPLElBQUksU0FBUyxTQUFTLFFBQVE7UUFDaEMsSUFBSSxTQUFTLFNBQVMsUUFBUTtRQUM5QixJQUFJLFNBQVMsWUFBWSxXQUFXO1FBQ3BDLElBQUksU0FBUyxRQUFRLE1BQU07UUFDM0IsSUFBSSxTQUFTLFlBQVksU0FBUyxXQUFXO0lBQ2hELElBQUksWUFBWSxhQUFhLEtBQUssdUNBQXVDO0lBQ3pFLFdBQVcsTUFBTSxNQUFNLEdBQUcsQ0FBQyxDQUFDLEtBQUssTUFBTSxLQUFLLEdBQUcsUUFBUSxDQUFDO0dBQzFELE9BQU87SUFDTCxJQUFJLFlBQVksV0FBVyxLQUFLLElBQUksS0FBSywyQkFBMkI7SUFDcEUsTUFBTSxJQUFJLFNBQVMsU0FBUyxTQUFTO0lBQ3JDLElBQUksU0FBUyxTQUFTLEVBQUUsV0FBVztTQUM5QixJQUFJLFNBQVMsUUFBUSxFQUFFLE9BQU87U0FDOUIsSUFBSSxTQUFTLFFBQVEsRUFBRSxTQUFTLFVBQVUsS0FBSyxLQUFLLElBQUksT0FBTyxLQUFLLElBQUksS0FBSyxZQUFZLEVBQUUsS0FBSyxzQ0FBc0M7U0FDdEksT0FBTyxPQUFPLEdBQUcsS0FBSyxPQUFPLFlBQVksRUFBRSxLQUFLLEVBQUUsQ0FBQztHQUMxRDtHQUNBO0VBQ0Y7RUFDQSxJQUFJLFlBQVksYUFBYTtHQUMzQixNQUFNLElBQUksc0RBQXNELEtBQUssSUFBSTtHQUN6RSxJQUFJLENBQUMsR0FBRyxLQUFLLHFCQUFxQixLQUFLLHdEQUF3RDtHQUMvRixJQUFJLEtBQUs7SUFBRSxRQUFRLEVBQUcsT0FBTztJQUFLLEtBQUssT0FBTyxFQUFHLEVBQUUsSUFBSTtJQUFHLEtBQUssT0FBTyxFQUFHLEVBQUUsSUFBSTtJQUFHLE1BQU0sRUFBRztJQUFJLE1BQU0sRUFBRztHQUFHLENBQUM7R0FDNUc7RUFDRjtFQUNBLElBQUksWUFBWSxhQUFhLEtBQUssV0FBVyxHQUFHLEdBQUc7R0FDakQsTUFBTSxJQUFJLFNBQVMsU0FBUyxTQUFTO0dBQ3JDLEVBQUUsZ0JBQWdCLEVBQUUsY0FBYyxNQUFNLE1BQU0sS0FBSyxNQUFNLENBQUMsQ0FBQyxDQUFDLEtBQUs7R0FDakU7RUFDRjtFQUNBLEtBQUssK0JBQStCLEtBQUssRUFBRTtDQUM3QztDQUVBLElBQUksQ0FBQyxPQUFPLEtBQUssd0NBQXdDO0NBQ3pELElBQUksQ0FBQyxTQUFTLFFBQVEsS0FBSywrQ0FBK0M7Q0FDMUUsSUFBSSxDQUFDLElBQUksUUFBUSxLQUFLLGlEQUFpRDtDQUN2RSxJQUFJLENBQUMsU0FBUyxRQUFRLEtBQUssbURBQW1EO0NBQzlFLElBQUksQ0FBQyxTQUFTLFNBQVMsZUFBZSxHQUFHLEtBQUssK0JBQStCLGdCQUFnQixzQkFBc0I7Q0FDbkgsSUFBSSxJQUFJLElBQUksUUFBUSxDQUFDLENBQUMsU0FBUyxTQUFTLFFBQVEsS0FBSyw0Q0FBNEM7O0NBR2pHLE1BQU0sT0FBTyxLQUFLLElBQUksR0FBRyxJQUFJLEtBQUssTUFBTSxFQUFFLE9BQU8sRUFBRSxTQUFTLElBQUksRUFBRSxLQUFLLE9BQU8sQ0FBQztDQUMvRSxNQUFNLE9BQU8sS0FBSyxJQUFJLEdBQUcsSUFBSSxLQUFLLE1BQU0sRUFBRSxPQUFPLEVBQUUsU0FBUyxFQUFFLEtBQUssU0FBUyxFQUFFLENBQUM7Q0FDL0UsTUFBTSxPQUFPLE1BQU0sS0FBSyxFQUFFLFFBQVEsS0FBSyxTQUFTLE1BQWMsSUFBSSxDQUFDLENBQUMsS0FBSyxFQUFFLENBQUM7Q0FDNUUsS0FBSyxNQUFNLEtBQUssS0FBSztFQUNuQjtFQUFDLENBQUMsR0FBRyxFQUFFLElBQUksQ0FBQyxDQUFDLFNBQVMsR0FBRyxNQUFNO0dBQzdCLE1BQU0sSUFBSSxFQUFFLE9BQU8sRUFBRSxTQUFTLElBQUk7R0FDbEMsTUFBTSxNQUFNLEVBQUUsT0FBTyxFQUFFLFNBQVMsSUFBSTtHQUNwQyxJQUFJLEtBQUssRUFBRSxDQUFDLFFBQVEsS0FBSyxFQUFFLENBQUMsU0FBUyxHQUFHLEtBQUssb0JBQW9CLEVBQUUsS0FBSyxrQkFBa0IsSUFBSSxFQUFFLFdBQVcsTUFBTSxFQUFFLHFCQUFxQixLQUFLLEVBQUUsQ0FBQyxLQUFLLEdBQUc7R0FDeEosS0FBSyxFQUFFLENBQUMsT0FBTztFQUNqQixDQUFDO0NBQ0g7O0NBRUEsTUFBTSxTQUFTLENBQUMsR0FBRyxJQUFJLElBQUksSUFBSSxLQUFLLE1BQU0sRUFBRSxNQUFNLE9BQU8sRUFBRSxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsTUFBTSxHQUFHLE1BQU0sSUFBSSxDQUFDO0NBQ3RGLE1BQU0sUUFBeUIsSUFBSSxLQUFLLE9BQU87RUFBRSxHQUFHO0VBQUcsUUFBUSxPQUFPLFFBQVEsRUFBRSxNQUFNLE9BQU8sRUFBRSxHQUFHLElBQUk7Q0FBRSxFQUFFO0NBQzFHLE1BQU0sWUFBWSxHQUFXLE1BQWMsS0FBSyxFQUFFLEdBQUcsTUFBTTtDQUUzRCxNQUFNLFVBQVUsU0FDYixLQUFLLEVBQUUsS0FBSyxVQUFVLFNBQVMsS0FBSyxHQUFHLEtBQUssS0FBSyxvQkFBb0IsTUFBTSxFQUFFLFdBQVcsTUFBTSxFQUFFLGdCQUFnQixDQUFDLENBQUMsQ0FDbEgsS0FBSyxFQUFFO0NBRVYsTUFBTSxVQUFVLFNBQVMsS0FBSyxNQUFNO0VBQ2xDLElBQUksQ0FBQyxFQUFFLE1BQU0sS0FBSyxZQUFZLEVBQUUsS0FBSyxlQUFlO0VBQ3BELElBQUksQ0FBQyxFQUFFLFVBQVUsS0FBSyxZQUFZLEVBQUUsS0FBSyxtQkFBbUI7RUFDNUQsSUFBSSxFQUFFLFdBQVcsV0FBVyxLQUFLLFlBQVksRUFBRSxLQUFLLGtCQUFrQjtFQUN0RSxJQUFJLEVBQUUsUUFBUSxXQUFXLEtBQUssWUFBWSxFQUFFLEtBQUssa0JBQWtCO0VBQ25FLE1BQU0sU0FBUyxTQUFTLE9BQU8sRUFBRSxNQUFPO0VBQ3hDLElBQUksQ0FBQyxRQUFRLEtBQUssWUFBWSxFQUFFLEtBQUsscUJBQXFCLEVBQUUsT0FBTyxpQkFBaUI7RUFDcEYsTUFBTSxTQUFTLFNBQVMsRUFBRSxLQUFNLEVBQUUsR0FBSTtFQUN0QyxJQUFJLFdBQVcsUUFBUSxLQUFLLFlBQVksRUFBRSxLQUFLLHFCQUFxQixFQUFFLE9BQU8sUUFBUSxPQUFPLFlBQVksRUFBRSxNQUFPLEVBQUUsR0FBRyxFQUFFLE1BQU8sRUFBRSxlQUFlLE9BQU8sR0FBRztFQUMxSixFQUFFLE9BQU8sRUFBRSxLQUFLLFFBQVEsUUFBUSxFQUFFO0VBQ2xDLE9BQU87Q0FDVCxDQUFDO0NBQ0QsT0FBTztFQUFFO0VBQU87RUFBTztFQUFVLFVBQVU7RUFBUztFQUFlO0VBQU07RUFBTTtFQUFPO0VBQVU7RUFBUztFQUFVLFVBQVUsU0FBUyxRQUFRLFFBQVEsRUFBRTtFQUFHO0NBQUk7QUFDaksiLCJuYW1lcyI6W10sImlnbm9yZUxpc3QiOltdLCJzb3VyY2VzIjpbInJlc2N1ZUdhbWUudHMiXSwic291cmNlc0NvbnRlbnQiOlsiLyoqXG4gKiBTcGllbCDigJ5QcmluemVzc2luIHJldHRlbuKAnCAoQmxvY2sgYDo6OiBzcGllbCBwcmluemVzc2luYCk6IEFuIGplZGVyIFN0YXRpb24ga29tbXQgZWluZSBaYWhsIGhlcmF1cyxcbiAqIGBhbHBoYWJldC5jaGFyQXQoemFobClgIG1hY2h0IGRhcmF1cyBlaW5lbiBCdWNoc3RhYmVuLCBkZXIgZWluIEZlbGQgaW0gS3JldXp3b3J0csOkdHNlbCBmw7xsbHQuIERpZSBtYXJraWVydGVuXG4gKiBGZWxkZXIgZGVzIFLDpHRzZWxzIGVyZ2ViZW4gZGFzIGdlaGVpbWUgV29ydCwgZGFzIGFtIEVuZGUgZGFzIFRvciDDtmZmbmV0LlxuICpcbiAqIEZvcm1hdCAoU2NobMO8c3NlbHfDtnJ0ZXIgYXVmIERldXRzY2gsIGF1Y2ggaW4gZGVuIMOcYmVyc2V0enVuZ2VuKTpcbiAqXG4gKiAgICAgdGl0ZWw6IFNwaWVsOiBQcmluemVzc2luIHJldHRlblxuICogICAgIGludHJvOiBEZXIgRnVjaHMgaGF0IOKAplxuICogICAgIGFscGhhYmV0OiBBQkNERUZHSElKS0xNTk9QUVJTVFVWV1hZWiAgICAob2huZSBBbmdhYmUgQSBiaXMgWilcbiAqXG4gKiAgICAgc3RhdGlvbjogQW0gQnVyZ2dyYWJlbiAgICAgICAgICAgICAgICAgICAgKE5hbWUgZGVyIFN0YXRpb24pXG4gKiAgICAgICAgIFN0cmluZyBuYW1lID0gXCIgICBab3JhICAgXCI7ICAgICAgICAgIChDb2RlLCBtaXQgdmllciBMZWVyemVpY2hlbiBlaW5nZXLDvGNrdClcbiAqICAgICBmcmFnZTogV2VsY2hlIFphaGwgc3RlaHQgaW4gYHphaGxgP1xuICogICAgIHphaGw6IDRcbiAqICAgICBmZWxkOiA1IDEgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIChaZWlsZSB1bmQgU3BhbHRlIGltIFLDpHRzZWwsIGFiIDEpXG4gKiAgICAgdGlwcDog4oCmICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIChuYWNoIGVpbmVyIGZhbHNjaGVuIEFudHdvcnQpXG4gKiAgICAgPiBFcmtsw6RydW5nXG4gKlxuICogICAgIGtyZXV6d29ydDogTMO2c2UgZGFzIFLDpHRzZWwg4oCmICAgICAgICAgICAgIChUZXh0IMO8YmVyIGRlbSBSw6R0c2VsKVxuICogICAgIC0g4oaSIDEgMyBCT09MRUFOOiBEYXRlbnR5cCBmw7xyIHdhaHIgb2RlciBmYWxzY2ggICAgICjihpIgd2FhZ3JlY2h0LCDihpMgc2Vua3JlY2h0LCBaZWlsZSwgU3BhbHRlKVxuICogICAgIGzDtnN1bmc6IDEgMywgNCAzICAgICAgICAgICAgICAgICAgICAgICAgIChGZWxkZXIgZGVzIGdlaGVpbWVuIFdvcnRzIGluIHNlaW5lciBSZWloZW5mb2xnZSlcbiAqXG4gKiAgICAgdG9yOiBWb3IgZGlyIGlzdCBkYXMgVG9yIOKApiAgICAgICAgICAgICAgIChUZXh0IHZvciBkZW0gU2NobG9zcylcbiAqICAgICAgICAgaWYgKGVpbmdhYmUuZXF1YWxzKFwiPz8/XCIpKSB7ICAgICAgICAgKENvZGUsIF9fXyB3aXJkIHp1bSBFaW5nYWJlZmVsZClcbiAqICAgICBlbmRlOiBab3JhIGlzdCBmcmVpIVxuICovXG5cbmV4cG9ydCBpbnRlcmZhY2UgUmVzY3VlU3RhdGlvbiB7XG4gIG5hbWU6IHN0cmluZ1xuICBjb2RlOiBzdHJpbmdcbiAgcXVlc3Rpb246IHN0cmluZ1xuICBhbnN3ZXI6IG51bWJlclxuICAvKiogRmVsZCBpbSBSw6R0c2VsIChhYiAwKS4gKi9cbiAgcm93OiBudW1iZXJcbiAgY29sOiBudW1iZXJcbiAgaGludDogc3RyaW5nXG4gIGV4cGxhbmF0aW9uOiBzdHJpbmdcbn1cblxuZXhwb3J0IGludGVyZmFjZSBDcm9zc3dvcmRXb3JkIHtcbiAgLyoqIE51bW1lciBpbSBSw6R0c2VsLCB3aWUgc2llIGltIEZlbGQgc3RlaHQuICovXG4gIG51bWJlcjogbnVtYmVyXG4gIGFjcm9zczogYm9vbGVhblxuICByb3c6IG51bWJlclxuICBjb2w6IG51bWJlclxuICB3b3JkOiBzdHJpbmdcbiAgY2x1ZTogc3RyaW5nXG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgUmVzY3VlR2FtZSB7XG4gIHRpdGxlOiBzdHJpbmdcbiAgaW50cm86IHN0cmluZ1xuICBhbHBoYWJldDogc3RyaW5nXG4gIHN0YXRpb25zOiBSZXNjdWVTdGF0aW9uW11cbiAgY3Jvc3N3b3JkVGV4dDogc3RyaW5nXG4gIHJvd3M6IG51bWJlclxuICBjb2xzOiBudW1iZXJcbiAgd29yZHM6IENyb3Nzd29yZFdvcmRbXVxuICAvKiogRmVsZGVyIGRlcyBnZWhlaW1lbiBXb3J0cyAoYWIgMCkuICovXG4gIHNvbHV0aW9uOiB7IHJvdzogbnVtYmVyOyBjb2w6IG51bWJlciB9W11cbiAga2V5d29yZDogc3RyaW5nXG4gIGdhdGVUZXh0OiBzdHJpbmdcbiAgZ2F0ZUNvZGU6IHN0cmluZ1xuICBlbmQ6IHN0cmluZ1xufVxuXG5leHBvcnQgY2xhc3MgUmVzY3VlR2FtZUVycm9yIGV4dGVuZHMgRXJyb3Ige31cblxuZXhwb3J0IGNvbnN0IGdhdGVQbGFjZWhvbGRlciA9ICdfX18nXG5cbi8qKiBEYXMgUsOkdHNlbCBhbHMgR2l0dGVyOiBgZ3JpZFt6ZWlsZV1bc3BhbHRlXWAgaXN0IGRlciBCdWNoc3RhYmUgb2RlciBgJydgLiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGNyb3Nzd29yZEdyaWQoZ2FtZTogUGljazxSZXNjdWVHYW1lLCAncm93cycgfCAnY29scycgfCAnd29yZHMnPik6IHN0cmluZ1tdW10ge1xuICBjb25zdCBncmlkID0gQXJyYXkuZnJvbSh7IGxlbmd0aDogZ2FtZS5yb3dzIH0sICgpID0+IEFycmF5PHN0cmluZz4oZ2FtZS5jb2xzKS5maWxsKCcnKSlcbiAgZm9yIChjb25zdCB3IG9mIGdhbWUud29yZHMpIFsuLi53LndvcmRdLmZvckVhY2goKGMsIGspID0+IChncmlkW3cucm93ICsgKHcuYWNyb3NzID8gMCA6IGspXVt3LmNvbCArICh3LmFjcm9zcyA/IGsgOiAwKV0gPSBjKSlcbiAgcmV0dXJuIGdyaWRcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIHBhcnNlUmVzY3VlR2FtZShsaW5lczogc3RyaW5nW10sIGZpbGU6IHN0cmluZyk6IFJlc2N1ZUdhbWUge1xuICBjb25zdCBmYWlsID0gKG1zZzogc3RyaW5nKTogbmV2ZXIgPT4ge1xuICAgIHRocm93IG5ldyBSZXNjdWVHYW1lRXJyb3IoYCR7ZmlsZX06ICR7bXNnfWApXG4gIH1cbiAgY29uc3QgY2VsbCA9ICh0ZXh0OiBzdHJpbmcsIHdoZXJlOiBzdHJpbmcpID0+IHtcbiAgICBjb25zdCBtID0gL14oXFxkKylcXHMrKFxcZCspJC8uZXhlYyh0ZXh0LnRyaW0oKSlcbiAgICBpZiAoIW0gfHwgTnVtYmVyKG1bMV0pIDwgMSB8fCBOdW1iZXIobVsyXSkgPCAxKSByZXR1cm4gZmFpbChgJHt3aGVyZX06IOKAniR7dGV4dH3igJwgaXN0IGtlaW4gRmVsZCAoWmVpbGUgU3BhbHRlLCBhYiAxKS5gKVxuICAgIHJldHVybiB7IHJvdzogTnVtYmVyKG1bMV0pIC0gMSwgY29sOiBOdW1iZXIobVsyXSkgLSAxIH1cbiAgfVxuICBsZXQgdGl0bGUgPSAnJ1xuICBsZXQgaW50cm8gPSAnJ1xuICBsZXQgYWxwaGFiZXQgPSAnQUJDREVGR0hJSktMTU5PUFFSU1RVVldYWVonXG4gIGxldCBjcm9zc3dvcmRUZXh0ID0gJydcbiAgbGV0IGdhdGVUZXh0ID0gJydcbiAgbGV0IGdhdGVDb2RlID0gJydcbiAgbGV0IGVuZCA9ICcnXG4gIGNvbnN0IHN0YXRpb25zOiAoT21pdDxSZXNjdWVTdGF0aW9uLCAnYW5zd2VyJyB8ICdyb3cnIHwgJ2NvbCc+ICYgeyBhbnN3ZXI/OiBudW1iZXI7IHJvdz86IG51bWJlcjsgY29sPzogbnVtYmVyIH0pW10gPSBbXVxuICBjb25zdCByYXc6IHsgYWNyb3NzOiBib29sZWFuOyByb3c6IG51bWJlcjsgY29sOiBudW1iZXI7IHdvcmQ6IHN0cmluZzsgY2x1ZTogc3RyaW5nIH1bXSA9IFtdXG4gIGxldCBzb2x1dGlvbjogeyByb3c6IG51bWJlcjsgY29sOiBudW1iZXIgfVtdID0gW11cbiAgLyoqIFdvaGluIGVpbmdlcsO8Y2t0ZSBaZWlsZW4gZ2Vow7ZyZW4uICovXG4gIGxldCBjb2RlVGFyZ2V0OiAnc3RhdGlvbicgfCAnZ2F0ZScgfCB1bmRlZmluZWRcbiAgbGV0IHNlY3Rpb246ICdzdGFydCcgfCAnc3RhdGlvbicgfCAnY3Jvc3N3b3JkJyB8ICdnYXRlJyA9ICdzdGFydCdcbiAgZm9yIChjb25zdCBsaW5lIG9mIGxpbmVzKSB7XG4gICAgY29uc3QgdGV4dCA9IGxpbmUudHJpbSgpXG4gICAgaWYgKGNvZGVUYXJnZXQgJiYgKC9eKCB7NH18XFx0KS8udGVzdChsaW5lKSB8fCB0ZXh0ID09PSAnJykpIHtcbiAgICAgIGNvbnN0IGNvZGUgPSBsaW5lLnJlcGxhY2UoL14oIHs0fXxcXHQpLywgJycpXG4gICAgICBpZiAoY29kZVRhcmdldCA9PT0gJ3N0YXRpb24nKSB7XG4gICAgICAgIGNvbnN0IHMgPSBzdGF0aW9uc1tzdGF0aW9ucy5sZW5ndGggLSAxXVxuICAgICAgICBzLmNvZGUgKz0gKHMuY29kZSA/ICdcXG4nIDogJycpICsgY29kZVxuICAgICAgfSBlbHNlIGdhdGVDb2RlICs9IChnYXRlQ29kZSA/ICdcXG4nIDogJycpICsgY29kZVxuICAgICAgY29udGludWVcbiAgICB9XG4gICAgY29kZVRhcmdldCA9IHVuZGVmaW5lZFxuICAgIGlmICghdGV4dCkgY29udGludWVcbiAgICBjb25zdCBrZXkgPSAvXih0aXRlbHxpbnRyb3xhbHBoYWJldHxzdGF0aW9ufGZyYWdlfHphaGx8ZmVsZHx0aXBwfGtyZXV6d29ydHxsw7ZzdW5nfGxvZXN1bmd8dG9yfGVuZGUpOlxccyooLiopJC8uZXhlYyh0ZXh0KVxuICAgIGlmIChrZXkpIHtcbiAgICAgIGNvbnN0IFssIG5hbWUsIHZhbHVlXSA9IGtleVxuICAgICAgaWYgKG5hbWUgPT09ICdzdGF0aW9uJykge1xuICAgICAgICBzdGF0aW9ucy5wdXNoKHsgbmFtZTogdmFsdWUsIGNvZGU6ICcnLCBxdWVzdGlvbjogJycsIGhpbnQ6ICcnLCBleHBsYW5hdGlvbjogJycgfSlcbiAgICAgICAgc2VjdGlvbiA9ICdzdGF0aW9uJ1xuICAgICAgICBjb2RlVGFyZ2V0ID0gJ3N0YXRpb24nXG4gICAgICB9IGVsc2UgaWYgKG5hbWUgPT09ICdrcmV1endvcnQnKSB7XG4gICAgICAgIGNyb3Nzd29yZFRleHQgPSB2YWx1ZVxuICAgICAgICBzZWN0aW9uID0gJ2Nyb3Nzd29yZCdcbiAgICAgIH0gZWxzZSBpZiAobmFtZSA9PT0gJ3RvcicpIHtcbiAgICAgICAgZ2F0ZVRleHQgPSB2YWx1ZVxuICAgICAgICBzZWN0aW9uID0gJ2dhdGUnXG4gICAgICAgIGNvZGVUYXJnZXQgPSAnZ2F0ZSdcbiAgICAgIH0gZWxzZSBpZiAobmFtZSA9PT0gJ3RpdGVsJykgdGl0bGUgPSB2YWx1ZVxuICAgICAgZWxzZSBpZiAobmFtZSA9PT0gJ2ludHJvJykgaW50cm8gPSB2YWx1ZVxuICAgICAgZWxzZSBpZiAobmFtZSA9PT0gJ2FscGhhYmV0JykgYWxwaGFiZXQgPSB2YWx1ZVxuICAgICAgZWxzZSBpZiAobmFtZSA9PT0gJ2VuZGUnKSBlbmQgPSB2YWx1ZVxuICAgICAgZWxzZSBpZiAobmFtZSA9PT0gJ2zDtnN1bmcnIHx8IG5hbWUgPT09ICdsb2VzdW5nJykge1xuICAgICAgICBpZiAoc2VjdGlvbiAhPT0gJ2Nyb3Nzd29yZCcpIGZhaWwoJ+KAnmzDtnN1bmc64oCcIGdlaMO2cnQgenVtIEtyZXV6d29ydHLDpHRzZWwuJylcbiAgICAgICAgc29sdXRpb24gPSB2YWx1ZS5zcGxpdCgnLCcpLm1hcCgoYykgPT4gY2VsbChjLCAnbMO2c3VuZycpKVxuICAgICAgfSBlbHNlIHtcbiAgICAgICAgaWYgKHNlY3Rpb24gIT09ICdzdGF0aW9uJykgZmFpbChg4oCeJHtuYW1lfTrigJwgZ2Vow7ZydCBpbiBlaW5lIFN0YXRpb24uYClcbiAgICAgICAgY29uc3QgcyA9IHN0YXRpb25zW3N0YXRpb25zLmxlbmd0aCAtIDFdXG4gICAgICAgIGlmIChuYW1lID09PSAnZnJhZ2UnKSBzLnF1ZXN0aW9uID0gdmFsdWVcbiAgICAgICAgZWxzZSBpZiAobmFtZSA9PT0gJ3RpcHAnKSBzLmhpbnQgPSB2YWx1ZVxuICAgICAgICBlbHNlIGlmIChuYW1lID09PSAnemFobCcpIHMuYW5zd2VyID0gL14tP1xcZCskLy50ZXN0KHZhbHVlKSA/IE51bWJlcih2YWx1ZSkgOiBmYWlsKGBTdGF0aW9uIOKAniR7cy5uYW1lfeKAnDog4oCeemFobDrigJwgbXVzcyBlaW5lIGdhbnplIFphaGwgc2Vpbi5gKVxuICAgICAgICBlbHNlIE9iamVjdC5hc3NpZ24ocywgY2VsbCh2YWx1ZSwgYFN0YXRpb24g4oCeJHtzLm5hbWV94oCcYCkpXG4gICAgICB9XG4gICAgICBjb250aW51ZVxuICAgIH1cbiAgICBpZiAoc2VjdGlvbiA9PT0gJ2Nyb3Nzd29yZCcpIHtcbiAgICAgIGNvbnN0IG0gPSAvXi1cXHMrKFvihpLihpNdKVxccysoXFxkKylcXHMrKFxcZCspXFxzKyhbQS1aw4TDlsOcXSspOlxccyooLispJC91LmV4ZWModGV4dClcbiAgICAgIGlmICghbSkgZmFpbChgS3JldXp3b3J0csOkdHNlbDog4oCeJHt0ZXh0feKAnCB2ZXJzdGVoZSBpY2ggbmljaHQgKHouIEIuIOKAni0g4oaSIDEgMyBTVFJJTkc6IEhpbndlaXPigJwpLmApXG4gICAgICByYXcucHVzaCh7IGFjcm9zczogbSFbMV0gPT09ICfihpInLCByb3c6IE51bWJlcihtIVsyXSkgLSAxLCBjb2w6IE51bWJlcihtIVszXSkgLSAxLCB3b3JkOiBtIVs0XSwgY2x1ZTogbSFbNV0gfSlcbiAgICAgIGNvbnRpbnVlXG4gICAgfVxuICAgIGlmIChzZWN0aW9uID09PSAnc3RhdGlvbicgJiYgdGV4dC5zdGFydHNXaXRoKCc+JykpIHtcbiAgICAgIGNvbnN0IHMgPSBzdGF0aW9uc1tzdGF0aW9ucy5sZW5ndGggLSAxXVxuICAgICAgcy5leHBsYW5hdGlvbiArPSAocy5leHBsYW5hdGlvbiA/ICcgJyA6ICcnKSArIHRleHQuc2xpY2UoMSkudHJpbSgpXG4gICAgICBjb250aW51ZVxuICAgIH1cbiAgICBmYWlsKGBVbmJla2FubnRlIFplaWxlIGltIFNwaWVsOiDigJ4ke3RleHR94oCcYClcbiAgfVxuXG4gIGlmICghdGl0bGUpIGZhaWwoJ0RhcyBTcGllbCBicmF1Y2h0IGVpbmUgWmVpbGUg4oCedGl0ZWw64oCcLicpXG4gIGlmICghc3RhdGlvbnMubGVuZ3RoKSBmYWlsKCdEYXMgU3BpZWwgYnJhdWNodCBtaW5kZXN0ZW5zIGVpbmUg4oCec3RhdGlvbjrigJwuJylcbiAgaWYgKCFyYXcubGVuZ3RoKSBmYWlsKCdEYXMgU3BpZWwgYnJhdWNodCBlaW4g4oCea3JldXp3b3J0OuKAnCBtaXQgV8O2cnRlcm4uJylcbiAgaWYgKCFzb2x1dGlvbi5sZW5ndGgpIGZhaWwoJ0RhcyBLcmV1endvcnRyw6R0c2VsIGJyYXVjaHQgZWluZSBaZWlsZSDigJ5sw7ZzdW5nOuKAnC4nKVxuICBpZiAoIWdhdGVDb2RlLmluY2x1ZGVzKGdhdGVQbGFjZWhvbGRlcikpIGZhaWwoYERlciBDb2RlIGJlaSDigJ50b3I64oCcIGJyYXVjaHQgJHtnYXRlUGxhY2Vob2xkZXJ9IGbDvHIgZGFzIEVpbmdhYmVmZWxkLmApXG4gIGlmIChuZXcgU2V0KGFscGhhYmV0KS5zaXplICE9PSBhbHBoYWJldC5sZW5ndGgpIGZhaWwoJ0ltIEFscGhhYmV0IGtvbW10IGVpbiBaZWljaGVuIGRvcHBlbHQgdm9yLicpXG5cbiAgLy8gV8O2cnRlciBpbnMgR2l0dGVyIGxlZ2VuOiBLcmV1enVuZ2VuIG3DvHNzZW4gcGFzc2VuLlxuICBjb25zdCByb3dzID0gTWF0aC5tYXgoLi4ucmF3Lm1hcCgodykgPT4gdy5yb3cgKyAody5hY3Jvc3MgPyAxIDogdy53b3JkLmxlbmd0aCkpKVxuICBjb25zdCBjb2xzID0gTWF0aC5tYXgoLi4ucmF3Lm1hcCgodykgPT4gdy5jb2wgKyAody5hY3Jvc3MgPyB3LndvcmQubGVuZ3RoIDogMSkpKVxuICBjb25zdCBncmlkID0gQXJyYXkuZnJvbSh7IGxlbmd0aDogcm93cyB9LCAoKSA9PiBBcnJheTxzdHJpbmc+KGNvbHMpLmZpbGwoJycpKVxuICBmb3IgKGNvbnN0IHcgb2YgcmF3KSB7XG4gICAgO1suLi53LndvcmRdLmZvckVhY2goKGMsIGspID0+IHtcbiAgICAgIGNvbnN0IHIgPSB3LnJvdyArICh3LmFjcm9zcyA/IDAgOiBrKVxuICAgICAgY29uc3QgY29sID0gdy5jb2wgKyAody5hY3Jvc3MgPyBrIDogMClcbiAgICAgIGlmIChncmlkW3JdW2NvbF0gJiYgZ3JpZFtyXVtjb2xdICE9PSBjKSBmYWlsKGBLcmV1endvcnRyw6R0c2VsOiAke3cud29yZH0gcGFzc3QgaW4gWmVpbGUgJHtyICsgMX0sIFNwYWx0ZSAke2NvbCArIDF9IG5pY2h0IChkb3J0IHN0ZWh0ICR7Z3JpZFtyXVtjb2xdfSkuYClcbiAgICAgIGdyaWRbcl1bY29sXSA9IGNcbiAgICB9KVxuICB9XG4gIC8vIE51bW1lcm4gd2llIGluIGRlciBaZWl0dW5nOiB2b24gb2JlbiBuYWNoIHVudGVuLCBsaW5rcyBuYWNoIHJlY2h0czsgendlaSBXw7ZydGVyIGltIHNlbGJlbiBGZWxkIHRlaWxlbiBzaWNoIGVpbmUuXG4gIGNvbnN0IHN0YXJ0cyA9IFsuLi5uZXcgU2V0KHJhdy5tYXAoKHcpID0+IHcucm93ICogY29scyArIHcuY29sKSldLnNvcnQoKGEsIGIpID0+IGEgLSBiKVxuICBjb25zdCB3b3JkczogQ3Jvc3N3b3JkV29yZFtdID0gcmF3Lm1hcCgodykgPT4gKHsgLi4udywgbnVtYmVyOiBzdGFydHMuaW5kZXhPZih3LnJvdyAqIGNvbHMgKyB3LmNvbCkgKyAxIH0pKVxuICBjb25zdCBsZXR0ZXJBdCA9IChyOiBudW1iZXIsIGM6IG51bWJlcikgPT4gZ3JpZFtyXT8uW2NdID8/ICcnXG5cbiAgY29uc3Qga2V5d29yZCA9IHNvbHV0aW9uXG4gICAgLm1hcCgoeyByb3csIGNvbCB9KSA9PiBsZXR0ZXJBdChyb3csIGNvbCkgfHwgZmFpbChgbMO2c3VuZzogSW4gWmVpbGUgJHtyb3cgKyAxfSwgU3BhbHRlICR7Y29sICsgMX0gaXN0IGtlaW4gRmVsZC5gKSlcbiAgICAuam9pbignJylcblxuICBjb25zdCBjaGVja2VkID0gc3RhdGlvbnMubWFwKChzKSA9PiB7XG4gICAgaWYgKCFzLmNvZGUpIGZhaWwoYFN0YXRpb24g4oCeJHtzLm5hbWV94oCcOiBDb2RlIGZlaGx0LmApXG4gICAgaWYgKCFzLnF1ZXN0aW9uKSBmYWlsKGBTdGF0aW9uIOKAniR7cy5uYW1lfeKAnDog4oCeZnJhZ2U64oCcIGZlaGx0LmApXG4gICAgaWYgKHMuYW5zd2VyID09PSB1bmRlZmluZWQpIGZhaWwoYFN0YXRpb24g4oCeJHtzLm5hbWV94oCcOiDigJ56YWhsOuKAnCBmZWhsdC5gKVxuICAgIGlmIChzLnJvdyA9PT0gdW5kZWZpbmVkKSBmYWlsKGBTdGF0aW9uIOKAniR7cy5uYW1lfeKAnDog4oCeZmVsZDrigJwgZmVobHQuYClcbiAgICBjb25zdCBsZXR0ZXIgPSBhbHBoYWJldC5jaGFyQXQocy5hbnN3ZXIhKVxuICAgIGlmICghbGV0dGVyKSBmYWlsKGBTdGF0aW9uIOKAniR7cy5uYW1lfeKAnDogYWxwaGFiZXQuY2hhckF0KCR7cy5hbnN3ZXJ9KSBnaWJ0IGVzIG5pY2h0LmApXG4gICAgY29uc3QgdGFyZ2V0ID0gbGV0dGVyQXQocy5yb3chLCBzLmNvbCEpXG4gICAgaWYgKHRhcmdldCAhPT0gbGV0dGVyKSBmYWlsKGBTdGF0aW9uIOKAniR7cy5uYW1lfeKAnDogYWxwaGFiZXQuY2hhckF0KCR7cy5hbnN3ZXJ9KSBpc3QgJHtsZXR0ZXJ9LCBpbSBGZWxkICR7cy5yb3chICsgMX0gJHtzLmNvbCEgKyAxfSBzdGVodCBhYmVyIOKAniR7dGFyZ2V0feKAnC5gKVxuICAgIHMuY29kZSA9IHMuY29kZS5yZXBsYWNlKC9cXG4rJC8sICcnKVxuICAgIHJldHVybiBzIGFzIFJlc2N1ZVN0YXRpb25cbiAgfSlcbiAgcmV0dXJuIHsgdGl0bGUsIGludHJvLCBhbHBoYWJldCwgc3RhdGlvbnM6IGNoZWNrZWQsIGNyb3Nzd29yZFRleHQsIHJvd3MsIGNvbHMsIHdvcmRzLCBzb2x1dGlvbiwga2V5d29yZCwgZ2F0ZVRleHQsIGdhdGVDb2RlOiBnYXRlQ29kZS5yZXBsYWNlKC9cXG4rJC8sICcnKSwgZW5kIH1cbn1cbiJdLCJmaWxlIjoiL3dlYi9zcmMvbGVhcm4vcmVzY3VlR2FtZS50cyJ9 - -//# vitestCache=W3siZmlsZSI6IjEiLCJpZCI6IjEiLCJ1cmwiOiIyIiwiaW1wb3J0cyI6IjMiLCJtYXBwaW5ncyI6ZmFsc2UsImRlcHMiOiI0IiwiZHluYW1pY0RlcHMiOiI1Iiwic3RhdGljTW9ja3MiOm51bGx9LCIvaG9tZS91c2VyL3Zpc3VzdHJ1Y3Qtc3dpZnR1aS93ZWIvc3JjL2xlYXJuL3Jlc2N1ZUdhbWUudHMiLCIvd2ViL3NyYy9sZWFybi9yZXNjdWVHYW1lLnRzIix7InVybHMiOiI2IiwiaWRzIjoiNyJ9LFtdLFtdLFtdLHt9XQ== \ No newline at end of file diff --git a/node_modules/.vitest-cache/2e7e8c86acce9951f2c7f1e10275b55254f40698 b/node_modules/.vitest-cache/2e7e8c86acce9951f2c7f1e10275b55254f40698 deleted file mode 100644 index 9edc3f99..00000000 --- a/node_modules/.vitest-cache/2e7e8c86acce9951f2c7f1e10275b55254f40698 +++ /dev/null @@ -1,27 +0,0 @@ -const __vite_ssr_import_0__ = await __vite_ssr_import__("/@fs/root/.npm/_npx/69c381f8ad94b576/node_modules/vitest/dist/index.js", {"importedNames":["test"]}); -const __vite_ssr_import_1__ = await __vite_ssr_import__("fs", {"importedNames":["readFileSync"]}); -const __vite_ssr_import_2__ = await __vite_ssr_import__("/web/src/learn/lessonFormat.ts", {"importedNames":["parseBlocks"]}); -const __vite_ssr_import_3__ = await __vite_ssr_import__("/web/src/learn/markdown.ts", {"importedNames":["markdownToHTML"]}); - - - - -(0,__vite_ssr_import_0__.test)("x", () => { - for (const [l, h] of [ - ["de", "## Wie Java"], - ["en", "## How Java"], - ["pt", "## Como o Java"] - ]) { - const src = (0,__vite_ssr_import_1__.readFileSync)(`lessons/${l}/20-java.md`, "utf8"); - const body = src.split(h)[1].split("\n## ")[0]; - const bs = (0,__vite_ssr_import_2__.parseBlocks)(body, "x"); - console.log(l, bs.map((b) => b.kind + (b.pro ? "(pro)" : "") + (b.caption ? "[" + b.caption.slice(0, 25) + "]" : "")).join(" ")); - if (l === "de") { - for (const b of bs) if (b.pro) console.log((0,__vite_ssr_import_3__.markdownToHTML)(b.text)); - } - } -}); -//# sourceMappingSource=vite-generated -//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJtYXBwaW5ncyI6IkFBQUE7QUFDQTtBQUNBO0FBQ0E7Ozs7O0FBQ0EsK0JBQUssV0FBVztDQUNkLEtBQUssTUFBTSxDQUFDLEdBQUcsTUFBTTtFQUFDLENBQUMsTUFBSyxhQUFhO0VBQUUsQ0FBQyxNQUFLLGFBQWE7RUFBRSxDQUFDLE1BQUssZ0JBQWdCO0NBQUMsR0FBRztFQUMxRixNQUFNLE1BQU0sdUNBQWEsV0FBVyxFQUFFLGNBQWMsTUFBTTtFQUMxRCxNQUFNLE9BQU8sSUFBSSxNQUFNLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxNQUFNLE9BQU8sQ0FBQyxDQUFDO0VBQzVDLE1BQU0sS0FBSyxzQ0FBWSxNQUFNLEdBQUc7RUFDaEMsUUFBUSxJQUFJLEdBQUcsR0FBRyxLQUFJLE1BQUssRUFBRSxRQUFRLEVBQUUsTUFBTSxVQUFVLE9BQU8sRUFBRSxVQUFVLE1BQUksRUFBRSxRQUFRLE1BQU0sR0FBRSxFQUFFLElBQUUsTUFBTSxHQUFHLENBQUMsQ0FBQyxLQUFLLEdBQUcsQ0FBQztFQUN4SCxJQUFJLE1BQU0sTUFBTTtRQUFLLE1BQU0sS0FBSyxJQUFJLElBQUksRUFBRSxLQUFLLFFBQVEsSUFBSSx5Q0FBZSxFQUFFLElBQUksQ0FBQzs7Q0FDakY7QUFDRixDQUFDIiwibmFtZXMiOltdLCJpZ25vcmVMaXN0IjpbXSwic291cmNlcyI6WyJ6el90bXAudGVzdC50cyJdLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyB0ZXN0IH0gZnJvbSAndml0ZXN0J1xuaW1wb3J0IHsgcmVhZEZpbGVTeW5jIH0gZnJvbSAnZnMnXG5pbXBvcnQgeyBwYXJzZUJsb2NrcyB9IGZyb20gJy4uL3NyYy9sZWFybi9sZXNzb25Gb3JtYXQnXG5pbXBvcnQgeyBtYXJrZG93blRvSFRNTCB9IGZyb20gJy4uL3NyYy9sZWFybi9tYXJrZG93bidcbnRlc3QoJ3gnLCAoKSA9PiB7XG4gIGZvciAoY29uc3QgW2wsIGhdIG9mIFtbJ2RlJywnIyMgV2llIEphdmEnXSxbJ2VuJywnIyMgSG93IEphdmEnXSxbJ3B0JywnIyMgQ29tbyBvIEphdmEnXV0pIHtcbiAgY29uc3Qgc3JjID0gcmVhZEZpbGVTeW5jKGBsZXNzb25zLyR7bH0vMjAtamF2YS5tZGAsICd1dGY4JylcbiAgY29uc3QgYm9keSA9IHNyYy5zcGxpdChoKVsxXS5zcGxpdCgnXFxuIyMgJylbMF1cbiAgY29uc3QgYnMgPSBwYXJzZUJsb2Nrcyhib2R5LCAneCcpIGFzIGFueVtdXG4gIGNvbnNvbGUubG9nKGwsIGJzLm1hcChiID0+IGIua2luZCArIChiLnBybyA/ICcocHJvKScgOiAnJykgKyAoYi5jYXB0aW9uID8gJ1snK2IuY2FwdGlvbi5zbGljZSgwLDI1KSsnXScgOiAnJykpLmpvaW4oJyAnKSlcbiAgaWYgKGwgPT09ICdkZScpIGZvciAoY29uc3QgYiBvZiBicykgaWYgKGIucHJvKSBjb25zb2xlLmxvZyhtYXJrZG93blRvSFRNTChiLnRleHQpKVxuICB9XG59KVxuIl0sImZpbGUiOiIvd2ViL3Rlc3QvenpfdG1wLnRlc3QudHMifQ== - -//# vitestCache=W3siZmlsZSI6IjEiLCJpZCI6IjEiLCJ1cmwiOiIyIiwiaW1wb3J0cyI6IjMiLCJtYXBwaW5ncyI6ZmFsc2UsImRlcHMiOiI0IiwiZHluYW1pY0RlcHMiOiI1Iiwic3RhdGljTW9ja3MiOm51bGx9LCIvaG9tZS91c2VyL3Zpc3VzdHJ1Y3Qtc3dpZnR1aS93ZWIvdGVzdC96el90bXAudGVzdC50cyIsIi93ZWIvdGVzdC96el90bXAudGVzdC50cyIseyJ1cmxzIjoiNiIsImlkcyI6IjcifSxbIjgiLCI5IiwiMTAiLCIxMSJdLFtdLFsiOCIsIjEwIiwiMTEiXSx7fSwiL0Bmcy9yb290Ly5ucG0vX25weC82OWMzODFmOGFkOTRiNTc2L25vZGVfbW9kdWxlcy92aXRlc3QvZGlzdC9pbmRleC5qcyIsImZzIiwiL3dlYi9zcmMvbGVhcm4vbGVzc29uRm9ybWF0LnRzIiwiL3dlYi9zcmMvbGVhcm4vbWFya2Rvd24udHMiXQ== \ No newline at end of file diff --git a/node_modules/.vitest-cache/671ba0efec37747e02cf77c4dec09a7b139242a6 b/node_modules/.vitest-cache/671ba0efec37747e02cf77c4dec09a7b139242a6 deleted file mode 100644 index 396b0fd3..00000000 --- a/node_modules/.vitest-cache/671ba0efec37747e02cf77c4dec09a7b139242a6 +++ /dev/null @@ -1,136 +0,0 @@ -__vite_ssr_exportName__("parsePap", () => { try { return parsePap } catch {} }); -__vite_ssr_exportName__("papFits", () => { try { return papFits } catch {} }); -__vite_ssr_exportName__("PAP_WIDTH", () => { try { return PAP_WIDTH } catch {} }); -__vite_ssr_exportName__("papHeight", () => { try { return papHeight } catch {} }); -__vite_ssr_exportName__("papLayout", () => { try { return papLayout } catch {} }); -__vite_ssr_exportName__("papLines", () => { try { return papLines } catch {} }); -const shapeOf = { - start: "oval", - ende: "oval", - anweisung: "rechteck", - eingabe: "parallelogramm", - ausgabe: "parallelogramm", - frage: "raute" -}; -function parsePap(inner, file) { - const pap = { - title: "", - task: "", - nodes: [] - }; - const pending = []; - for (const raw of inner) { - const line = raw.trim(); - if (!line) continue; - const m = /^([a-zäöü]+):\s*(.*)$/i.exec(line); - if (!m) throw new Error(`${file}: Unbekannte Zeile im PAP: „${line}“.`); - const key = m[1].toLowerCase(); - const value = m[2].trim(); - if (key === "titel") pap.title = value; - else if (key === "auftrag") pap.task = value; - else if (key === "erklärung" || key === "erklaerung") pap.explanation = value; - else if (key === "legende") pap.legend = /^(ja|yes|true|sim)$/i.test(value); - else if (key in shapeOf) { - const [text, exit] = value.split(/\s+\|\s+/); - if (!text) throw new Error(`${file}: Leeres Element im PAP: „${line}“.`); - const node = { - shape: shapeOf[key], - text: text.trim() - }; - pap.nodes.push(node); - if (key !== "frage") { - if (exit) throw new Error(`${file}: Nur eine Frage hat einen zweiten Ausgang: „${line}“.`); - continue; - }; - const e = /^(ja|nein)\s*(->|:)\s*(.+)$/i.exec(exit ?? ""); - if (!e) throw new Error(`${file}: Eine Frage braucht „| nein -> Text“ oder „| nein: Text“: „${line}“.`); - node.sideExit = e[1].toLowerCase(); - if (e[2] === ":") { - node.side = pap.nodes.length; - pap.nodes.push({ - shape: "rechteck", - text: e[3].trim(), - isSide: true - }); - } else { - pending.push({ - node: pap.nodes.length - 1, - target: e[3].trim(), - line - }); - } - } else throw new Error(`${file}: Unbekannter Schlüssel „${m[1]}“ im PAP.`); - }; - for (const p of pending) { - const target = pap.nodes.findIndex((n, i) => i < p.node && !n.isSide && n.text === p.target); - if (target < 0) throw new Error(`${file}: Rücksprung zu „${p.target}“: kein Element mit diesem Text weiter oben („${p.line}“).`); - pap.nodes[p.node].backTo = target; - }; - if (!pap.title) throw new Error(`${file}: Ein PAP braucht einen Titel.`); - if (pap.nodes.length < 3) throw new Error(`${file}: PAP „${pap.title}“ braucht mindestens drei Elemente.`); - return pap; -}; -/** Ein Element passt auf einen Platz, wenn Form und Text stimmen (zwei gleiche Elemente sind austauschbar). */ -function papFits(pap, slot, card) { - const a = pap.nodes[slot]; - const b = pap.nodes[card]; - return a.shape === b.shape && a.text === b.text; -}; -const PAP_WIDTH = 400; -const MAIN_X = 140; -const MAIN_W = 180; -const SIDE_X = 327; -const SIDE_W = 130; -const GAP = 20; -function papHeight(shape) { - return shape === "raute" ? 56 : shape === "oval" ? 30 : 36; -}; -/** Plätze der Elemente und Gesamthöhe; Seitenkästen stehen auf Höhe ihrer Raute. */ -function papLayout(pap) { - const boxes = []; - let y = 10; - pap.nodes.forEach((n, i) => { - if (n.isSide) return; - const h = papHeight(n.shape); - // Platz für den Pfeil, der von oben in eine Schleife zurückkommt. - if (pap.nodes.some((o) => o.backTo === i) || n.side !== undefined) y += 12; - boxes[i] = { - x: MAIN_X, - y: y + h / 2, - w: n.shape === "raute" ? 170 : n.shape === "oval" ? 110 : MAIN_W, - h - }; - if (n.side !== undefined) boxes[n.side] = { - x: SIDE_X, - y: y + h / 2, - w: SIDE_W, - h: 40 - }; - y += h + GAP; - }); - return { - boxes, - height: y - GAP + 10 - }; -}; -/** Text auf höchstens zwei Zeilen umbrechen, wenn er bei Schriftgröße 13 nicht in `width` passt. */ -function papLines(text, width) { - const fits = (s) => s.length * 6.6 <= width; - if (fits(text)) return [text]; - const words = text.split(" "); - let best = [text]; - let bestLong = Infinity; - for (let i = 1; i < words.length; i++) { - const lines = [words.slice(0, i).join(" "), words.slice(i).join(" ")]; - const long = Math.max(...lines.map((l) => l.length)); - if (long < bestLong) { - best = lines; - bestLong = long; - } - }; - return best; -} -//# sourceMappingSource=vite-generated -//# sourceMappingURL=data:application/json;base64,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V0FBVztDQUNmLEtBQUssSUFBSSxJQUFJLEdBQUcsSUFBSSxNQUFNLFFBQVEsS0FBSztFQUNyQyxNQUFNLFFBQVEsQ0FBQyxNQUFNLE1BQU0sR0FBRyxDQUFDLENBQUMsQ0FBQyxLQUFLLEdBQUcsR0FBRyxNQUFNLE1BQU0sQ0FBQyxDQUFDLENBQUMsS0FBSyxHQUFHLENBQUM7RUFDcEUsTUFBTSxPQUFPLEtBQUssSUFBSSxHQUFHLE1BQU0sS0FBSyxNQUFNLEVBQUUsTUFBTSxDQUFDO0VBQ25ELElBQUksT0FBTyxVQUFVO0dBQ25CLE9BQU87R0FDUCxXQUFXO0VBQ2I7Q0FDRjtDQUNBLE9BQU87QUFDVCIsIm5hbWVzIjpbXSwiaWdub3JlTGlzdCI6W10sInNvdXJjZXMiOlsicGFwLnRzIl0sInNvdXJjZXNDb250ZW50IjpbIi8qKlxuICogUEFQIGJhdWVuOiBFaW4gUHJvZ3JhbW1hYmxhdWZwbGFuIG1pdCBsZWVyZW4gUGzDpHR6ZW4sIGRpZSBmZXJ0aWdlbiBFbGVtZW50ZSBsZWd0IG1hbiBzZWxic3QgaGluZWluLlxuICpcbiAqICAgICA6OjogcGFwXG4gKiAgICAgdGl0ZWw6IMOcYnVuZzogS3VjaGVuIGJhY2tlbiBhbHMgUEFQXG4gKiAgICAgYXVmdHJhZzogTGVnZSBqZWRlcyBFbGVtZW50IGFuIHNlaW5lbiBQbGF0ei5cbiAqICAgICBzdGFydDogU3RhcnRcbiAqICAgICBhbndlaXN1bmc6IFRlaWcgcsO8aHJlblxuICogICAgIGZyYWdlOiBUZWlnIGdsYXR0PyB8IG5laW4gLT4gVGVpZyByw7xocmVuXG4gKiAgICAgZnJhZ2U6IFN0w6RiY2hlbiBzYXViZXI/IHwgbmVpbjogNSBNaW51dGVuIHdlaXRlcmJhY2tlblxuICogICAgIGF1c2dhYmU6IOKAnkZlcnRpZyHigJxcbiAqICAgICBlbmRlOiBFbmRlXG4gKiAgICAgZXJrbMOkcnVuZzogV2lyZCBnZXplaWd0LCB3ZW5uIGFsbGVzIHN0aW1tdC5cbiAqICAgICBsZWdlbmRlOiBqYVxuICogICAgIDo6OlxuICpcbiAqIERpZSBaZWlsZW4gc3RlaGVuIHZvbiBvYmVuIG5hY2ggdW50ZW4gaW4gZGVyIEhhdXB0c3BhbHRlLiBFaW5lIEZyYWdlIChSYXV0ZSkgaGF0IHp3ZWkgQXVzZ8OkbmdlOiBFaW5lciBnZWh0IG5hY2ggdW50ZW5cbiAqIHdlaXRlciwgZGVyIGFuZGVyZSBzdGVodCBoaW50ZXIgYHxgLiBgbmVpbiAtPiBUZXh0YCBmw7xocnQgbWl0IGVpbmVtIFBmZWlsIHp1csO8Y2sgbmFjaCBvYmVuIHp1IGRlbSBFbGVtZW50IG1pdCBkaWVzZW1cbiAqIFRleHQuIGBuZWluOiBUZXh0YCBmw7xocnQgenUgZWluZXIgQW53ZWlzdW5nIHJlY2h0cyBkYW5lYmVuLCB2b24gZG9ydCBnZWh0IGVpbiBQZmVpbCB6dXLDvGNrIHp1ciBSYXV0ZSAoU2NobGVpZmUgd2llXG4gKiDigJ4xIE1pbnV0ZSB3YXJ0ZW7igJwgaW4gTGVrdGlvbiAxKS4gU3RhdHQgYG5laW5gIGdlaHQgYXVjaCBgamFgOyBkZXIgYW5kZXJlIEF1c2dhbmcgaXN0IGRhbm4gZGVyIG5hY2ggdW50ZW4uXG4gKi9cbmV4cG9ydCB0eXBlIFBhcFNoYXBlID0gJ292YWwnIHwgJ3JlY2h0ZWNrJyB8ICdyYXV0ZScgfCAncGFyYWxsZWxvZ3JhbW0nXG5cbmV4cG9ydCBpbnRlcmZhY2UgUGFwTm9kZSB7XG4gIHNoYXBlOiBQYXBTaGFwZVxuICB0ZXh0OiBzdHJpbmdcbiAgLyoqIE51ciBSYXV0ZTogd2VsY2hlciBBdXNnYW5nIHp1ciBTZWl0ZSBnZWh0LiAqL1xuICBzaWRlRXhpdD86ICdqYScgfCAnbmVpbidcbiAgLyoqIFLDvGNrc3BydW5nIG5hY2ggb2JlbjogSW5kZXggZGVzIFppZWxzIGluIGBub2Rlc2AuICovXG4gIGJhY2tUbz86IG51bWJlclxuICAvKiogQW53ZWlzdW5nIHJlY2h0cyBuZWJlbiBkZXIgUmF1dGUgKFNjaGxlaWZlKSwgSW5kZXggaW4gYG5vZGVzYC4gKi9cbiAgc2lkZT86IG51bWJlclxuICAvKiogU3RlaHQgcmVjaHRzIG5lYmVuIGVpbmVyIFJhdXRlIHN0YXR0IGluIGRlciBIYXVwdHNwYWx0ZS4gKi9cbiAgaXNTaWRlPzogYm9vbGVhblxufVxuXG5leHBvcnQgaW50ZXJmYWNlIFBhcCB7XG4gIHRpdGxlOiBzdHJpbmdcbiAgdGFzazogc3RyaW5nXG4gIG5vZGVzOiBQYXBOb2RlW11cbiAgZXhwbGFuYXRpb24/OiBzdHJpbmdcbiAgLyoqIGBsZWdlbmRlOiBqYWAgemVpZ3QgdW50ZXIgZGVtIFBsYW4sIHdhcyBkaWUgU3ltYm9sZSBiZWRldXRlbi4gKi9cbiAgbGVnZW5kPzogYm9vbGVhblxufVxuXG5jb25zdCBzaGFwZU9mOiBSZWNvcmQ8c3RyaW5nLCBQYXBTaGFwZT4gPSB7XG4gIHN0YXJ0OiAnb3ZhbCcsXG4gIGVuZGU6ICdvdmFsJyxcbiAgYW53ZWlzdW5nOiAncmVjaHRlY2snLFxuICBlaW5nYWJlOiAncGFyYWxsZWxvZ3JhbW0nLFxuICBhdXNnYWJlOiAncGFyYWxsZWxvZ3JhbW0nLFxuICBmcmFnZTogJ3JhdXRlJyxcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIHBhcnNlUGFwKGlubmVyOiBzdHJpbmdbXSwgZmlsZTogc3RyaW5nKTogUGFwIHtcbiAgY29uc3QgcGFwOiBQYXAgPSB7IHRpdGxlOiAnJywgdGFzazogJycsIG5vZGVzOiBbXSB9XG4gIGNvbnN0IHBlbmRpbmc6IHsgbm9kZTogbnVtYmVyOyB0YXJnZXQ6IHN0cmluZzsgbGluZTogc3RyaW5nIH1bXSA9IFtdXG4gIGZvciAoY29uc3QgcmF3IG9mIGlubmVyKSB7XG4gICAgY29uc3QgbGluZSA9IHJhdy50cmltKClcbiAgICBpZiAoIWxpbmUpIGNvbnRpbnVlXG4gICAgY29uc3QgbSA9IC9eKFthLXrDpMO2w7xdKyk6XFxzKiguKikkL2kuZXhlYyhsaW5lKVxuICAgIGlmICghbSkgdGhyb3cgbmV3IEVycm9yKGAke2ZpbGV9OiBVbmJla2FubnRlIFplaWxlIGltIFBBUDog4oCeJHtsaW5lfeKAnC5gKVxuICAgIGNvbnN0IGtleSA9IG1bMV0udG9Mb3dlckNhc2UoKVxuICAgIGNvbnN0IHZhbHVlID0gbVsyXS50cmltKClcbiAgICBpZiAoa2V5ID09PSAndGl0ZWwnKSBwYXAudGl0bGUgPSB2YWx1ZVxuICAgIGVsc2UgaWYgKGtleSA9PT0gJ2F1ZnRyYWcnKSBwYXAudGFzayA9IHZhbHVlXG4gICAgZWxzZSBpZiAoa2V5ID09PSAnZXJrbMOkcnVuZycgfHwga2V5ID09PSAnZXJrbGFlcnVuZycpIHBhcC5leHBsYW5hdGlvbiA9IHZhbHVlXG4gICAgZWxzZSBpZiAoa2V5ID09PSAnbGVnZW5kZScpIHBhcC5sZWdlbmQgPSAvXihqYXx5ZXN8dHJ1ZXxzaW0pJC9pLnRlc3QodmFsdWUpXG4gICAgZWxzZSBpZiAoa2V5IGluIHNoYXBlT2YpIHtcbiAgICAgIGNvbnN0IFt0ZXh0LCBleGl0XSA9IHZhbHVlLnNwbGl0KC9cXHMrXFx8XFxzKy8pXG4gICAgICBpZiAoIXRleHQpIHRocm93IG5ldyBFcnJvcihgJHtmaWxlfTogTGVlcmVzIEVsZW1lbnQgaW0gUEFQOiDigJ4ke2xpbmV94oCcLmApXG4gICAgICBjb25zdCBub2RlOiBQYXBOb2RlID0geyBzaGFwZTogc2hhcGVPZltrZXldLCB0ZXh0OiB0ZXh0LnRyaW0oKSB9XG4gICAgICBwYXAubm9kZXMucHVzaChub2RlKVxuICAgICAgaWYgKGtleSAhPT0gJ2ZyYWdlJykge1xuICAgICAgICBpZiAoZXhpdCkgdGhyb3cgbmV3IEVycm9yKGAke2ZpbGV9OiBOdXIgZWluZSBGcmFnZSBoYXQgZWluZW4gendlaXRlbiBBdXNnYW5nOiDigJ4ke2xpbmV94oCcLmApXG4gICAgICAgIGNvbnRpbnVlXG4gICAgICB9XG4gICAgICBjb25zdCBlID0gL14oamF8bmVpbilcXHMqKC0+fDopXFxzKiguKykkL2kuZXhlYyhleGl0ID8/ICcnKVxuICAgICAgaWYgKCFlKSB0aHJvdyBuZXcgRXJyb3IoYCR7ZmlsZX06IEVpbmUgRnJhZ2UgYnJhdWNodCDigJ58IG5laW4gLT4gVGV4dOKAnCBvZGVyIOKAnnwgbmVpbjogVGV4dOKAnDog4oCeJHtsaW5lfeKAnC5gKVxuICAgICAgbm9kZS5zaWRlRXhpdCA9IGVbMV0udG9Mb3dlckNhc2UoKSBhcyAnamEnIHwgJ25laW4nXG4gICAgICBpZiAoZVsyXSA9PT0gJzonKSB7XG4gICAgICAgIG5vZGUuc2lkZSA9IHBhcC5ub2Rlcy5sZW5ndGhcbiAgICAgICAgcGFwLm5vZGVzLnB1c2goeyBzaGFwZTogJ3JlY2h0ZWNrJywgdGV4dDogZVszXS50cmltKCksIGlzU2lkZTogdHJ1ZSB9KVxuICAgICAgfSBlbHNlIHtcbiAgICAgICAgcGVuZGluZy5wdXNoKHsgbm9kZTogcGFwLm5vZGVzLmxlbmd0aCAtIDEsIHRhcmdldDogZVszXS50cmltKCksIGxpbmUgfSlcbiAgICAgIH1cbiAgICB9IGVsc2UgdGhyb3cgbmV3IEVycm9yKGAke2ZpbGV9OiBVbmJla2FubnRlciBTY2hsw7xzc2VsIOKAniR7bVsxXX3igJwgaW0gUEFQLmApXG4gIH1cbiAgZm9yIChjb25zdCBwIG9mIHBlbmRpbmcpIHtcbiAgICBjb25zdCB0YXJnZXQgPSBwYXAubm9kZXMuZmluZEluZGV4KChuLCBpKSA9PiBpIDwgcC5ub2RlICYmICFuLmlzU2lkZSAmJiBuLnRleHQgPT09IHAudGFyZ2V0KVxuICAgIGlmICh0YXJnZXQgPCAwKSB0aHJvdyBuZXcgRXJyb3IoYCR7ZmlsZX06IFLDvGNrc3BydW5nIHp1IOKAniR7cC50YXJnZXR94oCcOiBrZWluIEVsZW1lbnQgbWl0IGRpZXNlbSBUZXh0IHdlaXRlciBvYmVuICjigJ4ke3AubGluZX3igJwpLmApXG4gICAgcGFwLm5vZGVzW3Aubm9kZV0uYmFja1RvID0gdGFyZ2V0XG4gIH1cbiAgaWYgKCFwYXAudGl0bGUpIHRocm93IG5ldyBFcnJvcihgJHtmaWxlfTogRWluIFBBUCBicmF1Y2h0IGVpbmVuIFRpdGVsLmApXG4gIGlmIChwYXAubm9kZXMubGVuZ3RoIDwgMykgdGhyb3cgbmV3IEVycm9yKGAke2ZpbGV9OiBQQVAg4oCeJHtwYXAudGl0bGV94oCcIGJyYXVjaHQgbWluZGVzdGVucyBkcmVpIEVsZW1lbnRlLmApXG4gIHJldHVybiBwYXBcbn1cblxuLyoqIEVpbiBFbGVtZW50IHBhc3N0IGF1ZiBlaW5lbiBQbGF0eiwgd2VubiBGb3JtIHVuZCBUZXh0IHN0aW1tZW4gKHp3ZWkgZ2xlaWNoZSBFbGVtZW50ZSBzaW5kIGF1c3RhdXNjaGJhcikuICovXG5leHBvcnQgZnVuY3Rpb24gcGFwRml0cyhwYXA6IFBhcCwgc2xvdDogbnVtYmVyLCBjYXJkOiBudW1iZXIpOiBib29sZWFuIHtcbiAgY29uc3QgYSA9IHBhcC5ub2Rlc1tzbG90XVxuICBjb25zdCBiID0gcGFwLm5vZGVzW2NhcmRdXG4gIHJldHVybiBhLnNoYXBlID09PSBiLnNoYXBlICYmIGEudGV4dCA9PT0gYi50ZXh0XG59XG5cbi8qKiBMYWdlIGltIEJpbGQgKHZpZXdCb3ggNDAwIGJyZWl0KTogTWl0dGVscHVua3QsIEJyZWl0ZSwgSMO2aGUuICovXG5leHBvcnQgaW50ZXJmYWNlIFBhcEJveCB7XG4gIHg6IG51bWJlclxuICB5OiBudW1iZXJcbiAgdzogbnVtYmVyXG4gIGg6IG51bWJlclxufVxuXG5leHBvcnQgY29uc3QgUEFQX1dJRFRIID0gNDAwXG5jb25zdCBNQUlOX1ggPSAxNDBcbmNvbnN0IE1BSU5fVyA9IDE4MFxuY29uc3QgU0lERV9YID0gMzI3XG5jb25zdCBTSURFX1cgPSAxMzBcbmNvbnN0IEdBUCA9IDIwXG5cbmV4cG9ydCBmdW5jdGlvbiBwYXBIZWlnaHQoc2hhcGU6IFBhcFNoYXBlKTogbnVtYmVyIHtcbiAgcmV0dXJuIHNoYXBlID09PSAncmF1dGUnID8gNTYgOiBzaGFwZSA9PT0gJ292YWwnID8gMzAgOiAzNlxufVxuXG4vKiogUGzDpHR6ZSBkZXIgRWxlbWVudGUgdW5kIEdlc2FtdGjDtmhlOyBTZWl0ZW5rw6RzdGVuIHN0ZWhlbiBhdWYgSMO2aGUgaWhyZXIgUmF1dGUuICovXG5leHBvcnQgZnVuY3Rpb24gcGFwTGF5b3V0KHBhcDogUGFwKTogeyBib3hlczogUGFwQm94W107IGhlaWdodDogbnVtYmVyIH0ge1xuICBjb25zdCBib3hlczogUGFwQm94W10gPSBbXVxuICBsZXQgeSA9IDEwXG4gIHBhcC5ub2Rlcy5mb3JFYWNoKChuLCBpKSA9PiB7XG4gICAgaWYgKG4uaXNTaWRlKSByZXR1cm5cbiAgICBjb25zdCBoID0gcGFwSGVpZ2h0KG4uc2hhcGUpXG4gICAgLy8gUGxhdHogZsO8ciBkZW4gUGZlaWwsIGRlciB2b24gb2JlbiBpbiBlaW5lIFNjaGxlaWZlIHp1csO8Y2trb21tdC5cbiAgICBpZiAocGFwLm5vZGVzLnNvbWUoKG8pID0+IG8uYmFja1RvID09PSBpKSB8fCBuLnNpZGUgIT09IHVuZGVmaW5lZCkgeSArPSAxMlxuICAgIGJveGVzW2ldID0geyB4OiBNQUlOX1gsIHk6IHkgKyBoIC8gMiwgdzogbi5zaGFwZSA9PT0gJ3JhdXRlJyA/IDE3MCA6IG4uc2hhcGUgPT09ICdvdmFsJyA/IDExMCA6IE1BSU5fVywgaCB9XG4gICAgaWYgKG4uc2lkZSAhPT0gdW5kZWZpbmVkKSBib3hlc1tuLnNpZGVdID0geyB4OiBTSURFX1gsIHk6IHkgKyBoIC8gMiwgdzogU0lERV9XLCBoOiA0MCB9XG4gICAgeSArPSBoICsgR0FQXG4gIH0pXG4gIHJldHVybiB7IGJveGVzLCBoZWlnaHQ6IHkgLSBHQVAgKyAxMCB9XG59XG5cbi8qKiBUZXh0IGF1ZiBow7ZjaHN0ZW5zIHp3ZWkgWmVpbGVuIHVtYnJlY2hlbiwgd2VubiBlciBiZWkgU2NocmlmdGdyw7bDn2UgMTMgbmljaHQgaW4gYHdpZHRoYCBwYXNzdC4gKi9cbmV4cG9ydCBmdW5jdGlvbiBwYXBMaW5lcyh0ZXh0OiBzdHJpbmcsIHdpZHRoOiBudW1iZXIpOiBzdHJpbmdbXSB7XG4gIGNvbnN0IGZpdHMgPSAoczogc3RyaW5nKSA9PiBzLmxlbmd0aCAqIDYuNiA8PSB3aWR0aFxuICBpZiAoZml0cyh0ZXh0KSkgcmV0dXJuIFt0ZXh0XVxuICBjb25zdCB3b3JkcyA9IHRleHQuc3BsaXQoJyAnKVxuICBsZXQgYmVzdDogc3RyaW5nW10gPSBbdGV4dF1cbiAgbGV0IGJlc3RMb25nID0gSW5maW5pdHlcbiAgZm9yIChsZXQgaSA9IDE7IGkgPCB3b3Jkcy5sZW5ndGg7IGkrKykge1xuICAgIGNvbnN0IGxpbmVzID0gW3dvcmRzLnNsaWNlKDAsIGkpLmpvaW4oJyAnKSwgd29yZHMuc2xpY2UoaSkuam9pbignICcpXVxuICAgIGNvbnN0IGxvbmcgPSBNYXRoLm1heCguLi5saW5lcy5tYXAoKGwpID0+IGwubGVuZ3RoKSlcbiAgICBpZiAobG9uZyA8IGJlc3RMb25nKSB7XG4gICAgICBiZXN0ID0gbGluZXNcbiAgICAgIGJlc3RMb25nID0gbG9uZ1xuICAgIH1cbiAgfVxuICByZXR1cm4gYmVzdFxufVxuIl0sImZpbGUiOiIvd2ViL3NyYy9sZWFybi9wYXAudHMifQ== - -//# vitestCache=W3siZmlsZSI6IjEiLCJpZCI6IjEiLCJ1cmwiOiIyIiwiaW1wb3J0cyI6IjMiLCJtYXBwaW5ncyI6ZmFsc2UsImRlcHMiOiI0IiwiZHluYW1pY0RlcHMiOiI1Iiwic3RhdGljTW9ja3MiOm51bGx9LCIvaG9tZS91c2VyL3Zpc3VzdHJ1Y3Qtc3dpZnR1aS93ZWIvc3JjL2xlYXJuL3BhcC50cyIsIi93ZWIvc3JjL2xlYXJuL3BhcC50cyIseyJ1cmxzIjoiNiIsImlkcyI6IjcifSxbXSxbXSxbXSx7fV0= \ No newline at end of file diff --git a/node_modules/.vitest-cache/92afb3df989d8c4b3fbf8e596cd079aed22718e6 b/node_modules/.vitest-cache/92afb3df989d8c4b3fbf8e596cd079aed22718e6 deleted file mode 100644 index f06102c6..00000000 --- a/node_modules/.vitest-cache/92afb3df989d8c4b3fbf8e596cd079aed22718e6 +++ /dev/null @@ -1,418 +0,0 @@ -__vite_ssr_exportName__("RoundGameError", () => { try { return RoundGameError } catch {} }); -__vite_ssr_exportName__("isRoundGameKind", () => { try { return isRoundGameKind } catch {} }); -__vite_ssr_exportName__("parseRoundGame", () => { try { return parseRoundGame } catch {} }); -__vite_ssr_exportName__("parseLayoutPicture", () => { try { return parseLayoutPicture } catch {} }); -__vite_ssr_exportName__("parseSwingWindow", () => { try { return parseSwingWindow } catch {} }); -__vite_ssr_exportName__("startState", () => { try { return startState } catch {} }); -__vite_ssr_exportName__("click", () => { try { return click } catch {} }); -__vite_ssr_exportName__("clickButton", () => { try { return clickButton } catch {} }); -__vite_ssr_exportName__("simulate", () => { try { return simulate } catch {} }); -class RoundGameError extends Error {}; -function isRoundGameKind(arg) { - return arg === "zuhoerer" || arg === "vertrag" || arg === "layout" || arg === "bombe" || arg === "frage" || arg === "reihenfolge"; -}; -function parseRoundGame(kind, lines, file) { - const fail = (msg) => { - throw new RoundGameError(`${file}: ${msg}`); - }; - let title = ""; - let intro = ""; - let question = ""; - let answers = []; - let seconds; - let data; - const rounds = []; - let current; - let inCode = false; - for (const raw of lines) { - const line = raw.trim(); - if (current && inCode && (/^ {4}|^\t/.test(raw) || line === "")) { - current.code += (current.code ? "\n" : "") + raw.replace(/^( {4}|\t)/, ""); - continue; - }; - inCode = false; - if (!line) continue; - const key = /^(titel|intro|antworten|frage|runde|klicks|richtig|zeit|fehler|besser|daten):\s*(.*)$/.exec(line); - if (key) { - const [, name, value] = key; - if (name === "runde") { - current = { - code: "", - question, - options: [], - explanation: "", - clicks: [] - }; - rounds.push(current); - inCode = true; - } else if (!current) { - if (name === "titel") title = value; - else if (name === "intro") intro = value; - else if (name === "antworten") answers = value.split("|").map((a) => a.trim()); - else if (name === "frage") question = value; - else if (name === "zeit") seconds = Number(value); - else if (name === "daten") data = value === "csv" ? value : fail(`„daten:“ kennt nur „csv“.`); - else fail(`„${name}:“ gehört in eine Runde.`); - } else if (name === "frage") current.question = value; - else if (name === "fehler") current.wrongLine = Number(value); - else if (name === "besser") current.fix = value; - else if (name === "klicks") current.clicks = value.split(",").map((c) => c.trim()).filter(Boolean); - else if (name === "richtig") current.rightText = value; - else fail(`„${name}:“ gehört vor die erste Runde.`); - continue; - }; - if (!current) fail(`Unbekannte Zeile vor der ersten Runde: „${line}“`); - const round = current; - const option = /^-\s+(\[x\]\s+)?(.+)$/.exec(line); - if (option) round.options.push({ - text: option[2].trim().replaceAll("\\n", "\n"), - right: !!option[1] - }); - else if (line.startsWith(">")) round.explanation += (round.explanation ? " " : "") + line.slice(1).trim(); - else fail(`Unbekannte Zeile im Spiel: „${line}“`); - }; - if (!title) fail("Das Spiel braucht eine Zeile „titel:“."); - if (!rounds.length) fail("Das Spiel braucht mindestens eine „runde:“."); - rounds.forEach((round, i) => { - round.code = round.code.replace(/\n+$/, ""); - if (kind === "bombe") { - const lines = round.code.split("\n"); - const n = round.wrongLine; - if (!n || !Number.isInteger(n) || n < 1 || n > lines.length || !lines[n - 1].trim()) fail(`Runde ${i + 1}: „fehler:“ muss eine Zeile des Codes sein.`); - if (!round.fix) fail(`Runde ${i + 1}: „besser:“ fehlt.`); - if (round.options.length) fail(`Runde ${i + 1}: Bei „bombe“ gibt es keine Antworten, man tippt auf die Zeile.`); - if (!round.question) fail(`Runde ${i + 1}: keine Frage.`); - return; - }; - if (kind === "reihenfolge") { - if (round.options.length < 3) fail(`Runde ${i + 1}: „reihenfolge“ braucht mindestens drei Schritte.`); - if (round.options.some((o) => o.right)) fail(`Runde ${i + 1}: Bei „reihenfolge“ gibt es kein [x], die Schritte stehen der Reihe nach da.`); - if (new Set(round.options.map((o) => o.text)).size !== round.options.length) fail(`Runde ${i + 1}: zwei Schritte sind gleich.`); - if (!round.question) fail(`Runde ${i + 1}: keine Frage.`); - return; - }; - if (!round.options.length) { - if (!answers.length) fail(`Runde ${i + 1}: keine Antworten.`); - if (!round.rightText || !answers.includes(round.rightText)) fail(`Runde ${i + 1}: „richtig:“ muss eine der Antworten sein.`); - round.options = answers.map((text) => ({ - text, - right: text === round.rightText - })); - }; - if (round.options.filter((o) => o.right).length !== 1) fail(`Runde ${i + 1}: genau eine Antwort muss richtig sein.`); - if (!round.question) fail(`Runde ${i + 1}: keine Frage.`); - if (kind === "layout") round.options.forEach((o) => parseLayoutPicture(o.text, `Runde ${i + 1}`, fail)); - if (kind === "zuhoerer") { - try { - const window = parseSwingWindow(round.code); - for (const c of round.clicks) if (!window.buttons.some((b) => b.caption === c)) fail(`Runde ${i + 1}: Knopf „${c}“ gibt es nicht.`); - simulate(window, round.clicks); - } catch (err) { - if (err instanceof RoundGameError) throw err; - fail(`Runde ${i + 1}: ${err.message}`); - } - }; - delete round.rightText; - }); - if (kind === "bombe" && !(seconds && seconds > 0)) fail("„bombe“ braucht „zeit:“ mit den Sekunden je Runde."); - return { - kind, - title, - intro, - ...kind === "bombe" ? { - seconds, - ...data ? { data } : {} - } : {}, - rounds - }; -}; -/** `grid: A B / C D`, `flow: A B C`, `border: N=A C=B S=C`. */ -function parseLayoutPicture(text, where = "", fail = (m) => { - throw new RoundGameError(m); -}) { - const m = /^(grid|flow|border):\s*(.+)$/.exec(text); - if (!m) return fail(`${where}: Antwort „${text}“ ist kein Fensterbild (grid:, flow: oder border:).`); - if (m[1] === "border") { - const areas = {}; - for (const part of m[2].split(/\s+/)) { - const a = /^([NSWEC])=(.+)$/.exec(part); - if (!a) fail(`${where}: „${part}“ im BorderLayout-Bild verstehe ich nicht (z. B. N=A).`); - areas[a[1]] = a[2]; - }; - return { - kind: "border", - areas - }; - }; - const rows = m[2].split("/").map((r) => r.trim().split(/\s+/).filter(Boolean)); - return { - kind: m[1], - rows - }; -}; -const str = "\"((?:[^\"\\\\]|\\\\.)*)\""; -/** -* Liest Knöpfe, Beschriftungen, int-Variablen und Zuhörer aus einfachem Swing-Code. Ein Zuhörer steht direkt am -* Knopf (`knopf.addActionListener(e -> …)`) oder als Variable (`ActionListener z = e -> …;`), die mit -* `knopf.addActionListener(z);` an mehreren Knöpfen hängen kann. -*/ -function parseSwingWindow(code) { - const lines = code.split("\n"); - const win = { - title: "", - buttons: [], - labels: [], - ints: {}, - listeners: [] - }; - const named = new Map(); - /** Zuhörer ab Zeile i, `rest` ist der Text hinter dem Pfeil; `end` schließt einen Block ab (`});` oder `};`). */ - const lambda = (i, rest, end) => { - if (rest.startsWith("{")) { - let j = i + 1; - const body = []; - while (j < lines.length && lines[j].trim() !== end) body.push(lines[j++].trim()); - if (j >= lines.length) throw new Error(`Dem Zuhörer fehlt „${end}“.`); - return { - from: i, - to: j, - statements: parseStatements(body.join(" ")) - }; - }; - const inner = end === "});" ? rest.replace(/\)\s*;\s*$/, "") : rest.replace(/;\s*$/, ""); - return { - from: i, - to: i, - statements: parseStatements(inner) - }; - }; - const button = (name) => { - if (!win.buttons.some((b) => b.name === name)) throw new Error(`Knopf ${name} ist nicht angelegt.`); - return name; - }; - for (let i = 0; i < lines.length; i++) { - const line = lines[i].trim(); - let m; - if (m = new RegExp(`^JFrame\\s+\\w+\\s*=\\s*new JFrame\\(${str}\\)`).exec(line)) win.title = m[1]; - else if (m = new RegExp(`^JButton\\s+(\\w+)\\s*=\\s*new JButton\\(${str}\\)`).exec(line)) win.buttons.push({ - name: m[1], - caption: m[2] - }); - else if (m = new RegExp(`^JLabel\\s+(\\w+)\\s*=\\s*new JLabel\\(${str}`).exec(line)) win.labels.push({ - name: m[1], - text: m[2] - }); - else if (m = /^(?:static\s+)?int\s+(\w+)\s*=\s*(-?\d+)\s*;/.exec(line)) win.ints[m[1]] = Number(m[2]); - else if (m = /^ActionListener\s+(\w+)\s*=\s*\w+\s*->\s*(.*)$/.exec(line)) { - const listener = lambda(i, m[2], "};"); - named.set(m[1], listener); - i = listener.to; - } else if (m = /^(\w+)\.addActionListener\(\s*(\w+)\s*\)\s*;$/.exec(line)) { - const listener = named.get(m[2]); - if (!listener) throw new Error(`Zuhörer ${m[2]} ist nicht angelegt.`); - win.listeners.push({ - button: button(m[1]), - ...listener - }); - } else if (m = /^(\w+)\.addActionListener\(\s*\w+\s*->\s*(.*)$/.exec(line)) { - const listener = lambda(i, m[2], "});"); - win.listeners.push({ - button: button(m[1]), - ...listener - }); - i = listener.to; - } - }; - return win; -}; -/** Zerlegt den Rumpf eines Zuhörers in Anweisungen, `if`/`else` mit oder ohne geschweifte Klammern. */ -function parseStatements(text) { - const out = []; - let pos = 0; - const skip = () => { - while (pos < text.length && /\s/.test(text[pos])) pos++; - }; - /** Text bis zur passenden schließenden Klammer; `pos` steht auf der öffnenden. */ - const balanced = (open, close) => { - let depth = 0; - let quote = false; - const start = pos + 1; - for (; pos < text.length; pos++) { - const c = text[pos]; - if (quote) { - if (c === "\\") pos++; - else if (c === "\"") quote = false; - } else if (c === "\"") quote = true; - else if (c === open) depth++; - else if (c === close && --depth === 0) return text.slice(start, pos++); - }; - throw new Error(`Es fehlt „${close}“.`); - }; - /** Eine einfache Anweisung bis zum Semikolon außerhalb von Klammern und Text. */ - const simple = () => { - let depth = 0; - let quote = false; - const start = pos; - for (; pos < text.length; pos++) { - const c = text[pos]; - if (quote) { - if (c === "\\") pos++; - else if (c === "\"") quote = false; - } else if (c === "\"") quote = true; - else if (c === "(") depth++; - else if (c === ")") depth--; - else if (c === ";" && depth === 0) return text.slice(start, pos++).trim(); - }; - return text.slice(start).trim(); - }; - const one = () => { - skip(); - if (text[pos] === "{") return parseStatements(balanced("{", "}")); - if (/^if\s*\(/.test(text.slice(pos))) { - pos = text.indexOf("(", pos); - const condition = balanced("(", ")").trim(); - const then = one(); - skip(); - let otherwise = []; - if (/^else\b/.test(text.slice(pos))) { - pos += 4; - otherwise = one(); - }; - return [{ - condition, - then, - otherwise - }]; - }; - const s = simple(); - return s ? [s] : []; - }; - for (skip(); pos < text.length; skip()) out.push(...one()); - return out; -} -function startState(win) { - const texts = {}; - for (const b of win.buttons) texts[b.name] = b.caption; - for (const l of win.labels) texts[l.name] = l.text; - return { - texts, - ints: { ...win.ints } - }; -}; -/** Ein Klick auf den Knopf mit dieser Beschriftung (verändert `state`). */ -function click(win, state, caption) { - const button = win.buttons.find((b) => b.caption === caption) ?? win.buttons.find((b) => state.texts[b.name] === caption); - if (!button) throw new Error(`Knopf „${caption}“ gibt es nicht.`); - return clickButton(win, state, button.name); -}; -/** Klick auf den Knopf mit diesem Variablennamen. */ -function clickButton(win, state, name) { - const listener = win.listeners.find((l) => l.button === name); - const output = []; - // `e.getActionCommand()` ist wie in Java die Beschriftung des Knopfs beim Klick. - const event = { - source: name, - command: state.texts[name] - }; - for (const s of listener?.statements ?? []) run(s, state, output, event); - return { - button: name, - listener, - texts: { ...state.texts }, - console: output - }; -}; -function simulate(win, clicks) { - const state = startState(win); - return clicks.map((c) => click(win, state, c)); -}; -function run(statement, state, output, event) { - if (typeof statement !== "string") { - for (const s of condition(statement.condition, state, event) ? statement.then : statement.otherwise) run(s, state, output, event); - return; - }; - let m; - if (m = /^(\w+)\.setText\((.*)\)$/.exec(statement)) { - if (!(m[1] in state.texts)) throw new Error(`${m[1]} ist keine Beschriftung und kein Knopf.`); - state.texts[m[1]] = String(evaluate(m[2], state, event)); - } else if (m = /^System\.out\.println\((.*)\)$/.exec(statement)) output.push(String(evaluate(m[1], state, event))); - else if (m = /^(\w+)\s*(\+\+|--)$/.exec(statement)) state.ints[intName(m[1], state)] += m[2] === "++" ? 1 : -1; - else if (m = /^(\w+)\s*([+-]?=)\s*(.+)$/.exec(statement)) { - const name = intName(m[1], state); - const value = Number(evaluate(m[3], state, event)); - state.ints[name] = m[2] === "=" ? value : m[2] === "+=" ? state.ints[name] + value : state.ints[name] - value; - } else throw new Error(`Diese Anweisung kann das Spiel nicht nachspielen: „${statement}“`); -} -/** `e.getSource() == knopf`, `text.equals("+")`, `zahl > 3` */ -function condition(text, state, event) { - let m; - if (m = /^e\.getSource\(\)\s*(==|!=)\s*(\w+)$/.exec(text)) { - if (!(m[2] in state.texts)) throw new Error(`${m[2]} ist kein Knopf.`); - return event.source === m[2] === (m[1] === "=="); - }; - if (m = /^(!?)(.+)\.equals\((.+)\)$/.exec(text)) return String(evaluate(m[2], state, event)) === String(evaluate(m[3], state, event)) !== (m[1] === "!"); - if (m = /^(.+?)\s*(==|!=|<=|>=|<|>)\s*(.+)$/.exec(text)) { - const a = Number(evaluate(m[1], state, event)); - const b = Number(evaluate(m[3], state, event)); - return { - "==": a === b, - "!=": a !== b, - "<=": a <= b, - ">=": a >= b, - "<": a < b, - ">": a > b - }[m[2]]; - }; - throw new Error(`Diese Bedingung kann das Spiel nicht nachspielen: „${text}“`); -} -function intName(name, state) { - if (!(name in state.ints)) throw new Error(`Variable ${name} ist nicht angelegt.`); - return name; -} -/** `"Text" + zahl`, `"" + (a + b)`, `zahl * 2`, `e.getActionCommand()`: von links nach rechts wie in Java. */ -function evaluate(expr, state, event) { - const tokens = expr.match(new RegExp(`${str}|\\d+|e\\.getActionCommand\\(\\)|\\w+(?:\\.getText\\(\\))?|[-+*/()]`, "g")) ?? []; - let pos = 0; - const atom = () => { - const tok = tokens[pos++]; - if (tok === undefined) throw new Error(`Unvollständiger Ausdruck „${expr}“`); - if (tok === "(") { - const v = sum(); - pos++; - return v; - }; - if (tok.startsWith("\"")) return JSON.parse(tok); - if (/^\d+$/.test(tok)) return Number(tok); - if (tok === "e.getActionCommand()") { - if (!event) throw new Error("e.getActionCommand() gibt es nur im Zuhörer."); - return event.command; - }; - if (tok.endsWith(".getText()")) return state.texts[tok.slice(0, -10)] ?? ""; - if (tok in state.ints) return state.ints[tok]; - throw new Error(`Unbekannt: „${tok}“`); - }; - const product = () => { - let v = atom(); - while (tokens[pos] === "*" || tokens[pos] === "/") { - const op = tokens[pos++]; - const r = Number(atom()); - v = op === "*" ? Number(v) * r : Math.trunc(Number(v) / r); - }; - return v; - }; - const sum = () => { - let v = product(); - while (tokens[pos] === "+" || tokens[pos] === "-") { - const op = tokens[pos++]; - const r = product(); - if (op === "+") v = typeof v === "string" || typeof r === "string" ? `${v}${r}` : v + r; - else v = Number(v) - Number(r); - }; - return v; - }; - return sum(); -} -//# sourceMappingSource=vite-generated -//# sourceMappingURL=data:application/json;base64,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IjpbXSwic291cmNlcyI6WyJyb3VuZEdhbWUudHMiXSwic291cmNlc0NvbnRlbnQiOlsiLyoqXG4gKiBSdW5kZW5zcGllbGUgenUgU3dpbmcgKEJsb2NrIGA6Ojogc3BpZWwgenVob2VyZXJ8dmVydHJhZ3xsYXlvdXRgKTogSW4gamVkZXIgUnVuZGUgQ29kZSB6ZWlnZW4sIGVpbmVcbiAqIEZyYWdlIG1pdCBBbnR3b3J0ZW4gc3RlbGxlbiB1bmQgZGllIHJpY2h0aWdlIEFudHdvcnQgZXJrbMOkcmVuLlxuICpcbiAqIC0gYHp1aG9lcmVyYCAo4oCeV2VyIGjDtnJ0IHp1P+KAnCk6IEVpbiBuYWNoZ2ViYXV0ZXMgRmVuc3RlciBtaXQgZGVuIEtuw7ZwZmVuIGF1cyBkZW0gQ29kZS4gTmFjaCBkZXIgQW50d29ydFxuICogICB3ZXJkZW4gZGllIEtsaWNrcyBhYmdlc3BpZWx0OiBEYXMgRXJlaWduaXMgbMOkdWZ0IHp1bSBadWjDtnJlciwgZGVzc2VuIFplaWxlbiBsZXVjaHRlbiBhdWYuXG4gKiAtIGB2ZXJ0cmFnYCAo4oCeVmVydHJhZyBlcmbDvGxsdD/igJwpOiBLbGFzc2VuLCBkaWUgZWluIEludGVyZmFjZSBlcmbDvGxsZW4gc29sbGVuLlxuICogLSBgbGF5b3V0YCAo4oCeV28gbGFuZGV0IGRlciBLbm9wZj/igJwpOiBEaWUgQW50d29ydGVuIHNpbmQga2xlaW5lIEZlbnN0ZXIgKGBncmlkOiBBIEIgLyBDIERgLCDigKYpLlxuICogLSBgYm9tYmVgICjigJ5Cb21iZSBlbnRzY2jDpHJmZW7igJwpOiBDb2RlIG1pdCBnZW5hdSBlaW5lciBmYWxzY2hlbiBaZWlsZSB1bmQgZWluIENvdW50ZG93biAoYHplaXQ6YCBTZWt1bmRlbiBqZVxuICogICBSdW5kZSkuIE1hbiB0aXBwdCBhdWYgZGllIFplaWxlOyBgZmVobGVyOmAgaXN0IGlocmUgTnVtbWVyIChhYiAxKSwgYGJlc3NlcjpgIGRpZSByaWNodGlnZSBaZWlsZS4gTWl0IGBkYXRlbjogY3N2YFxuICogICBpc3QgZGVyIOKAnkNvZGXigJwgZWluZSBDU1YtRGF0ZWkgc3RhdHQgSmF2YS5cbiAqIC0gYGZyYWdlYDogQ29kZSAoYXVjaCBsZWVyKSB1bmQgZWluZSBGcmFnZSBtaXQgQW50d29ydGVuLiBgXFxuYCBpbiBlaW5lciBBbnR3b3J0IGJlZ2lubnQgZWluZSBuZXVlIFplaWxlOyBzb2xjaGVcbiAqICAgQW50d29ydGVuIGVyc2NoZWluZW4gYWxzIGtsZWluZSBEYXRlaS5cbiAqIC0gYHJlaWhlbmZvbGdlYCAo4oCeV2VyIGlzdCBkcmFuP+KAnCk6IERpZSBBbnR3b3J0ZW4gc3RlaGVuIGluIGRlciByaWNodGlnZW4gUmVpaGVuZm9sZ2UgZGEgKG9obmUgYFt4XWApLCBkYXMgU3BpZWxcbiAqICAgbWlzY2h0IHNpZS4gTWFuIHRpcHB0IHNpZSBkZXIgUmVpaGUgbmFjaCBhbjsgZWluIGZhbHNjaGVyIFRpcHAgYmVlbmRldCBkaWUgUnVuZGUuXG4gKlxuICogRm9ybWF0IChTY2hsw7xzc2Vsd8O2cnRlciB3aWUgaW4gZGVuIGFuZGVyZW4gQmzDtmNrZW4gYXVmIERldXRzY2gsIGF1Y2ggaW4gZGVuIMOcYmVyc2V0enVuZ2VuKTpcbiAqXG4gKiAgICAgdGl0ZWw6IFNwaWVsOiBWZXJ0cmFnIGVyZsO8bGx0P1xuICogICAgIGludHJvOiBMdWR3aWcgemVpZ3QgZGlyIOKAplxuICogICAgIGFudHdvcnRlbjogZXJmw7xsbHQgfCBuaWNodCBlcmbDvGxsdCAgICAgIChmw7xyIGFsbGUgUnVuZGVuLCBkYW5uIGplIFJ1bmRlIGByaWNodGlnOiDigKZgKVxuICogICAgIGZyYWdlOiDigKYgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoZsO8ciBhbGxlIFJ1bmRlbiwgamUgUnVuZGUgw7xiZXJzY2hyZWliYmFyKVxuICpcbiAqICAgICBydW5kZTpcbiAqICAgICAgICAgQ29kZSwgbWl0IHZpZXIgTGVlcnplaWNoZW4gZWluZ2Vyw7xja3RcbiAqICAgICBrbGlja3M6IEEsIEIgICAgICAgICAgICAgICAgICAgICAgICAgICAgIChudXIgenVob2VyZXI6IEJlc2NocmlmdHVuZ2VuIGRlciBLbsO2cGZlKVxuICogICAgIGZlaGxlcjogMiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKG51ciBib21iZSwgc3RhdHQgQW50d29ydGVuKVxuICogICAgIGJlc3NlcjogU3lzdGVtLm91dC5wcmludGxuKGkpOyAgICAgICAgICAgKG51ciBib21iZSlcbiAqICAgICAtIEFudHdvcnRcbiAqICAgICAtIFt4XSByaWNodGlnZSBBbnR3b3J0XG4gKiAgICAgPiBFcmtsw6RydW5nXG4gKi9cblxuZXhwb3J0IHR5cGUgUm91bmRHYW1lS2luZCA9ICd6dWhvZXJlcicgfCAndmVydHJhZycgfCAnbGF5b3V0JyB8ICdib21iZScgfCAnZnJhZ2UnIHwgJ3JlaWhlbmZvbGdlJ1xuXG5leHBvcnQgaW50ZXJmYWNlIFJvdW5kT3B0aW9uIHtcbiAgdGV4dDogc3RyaW5nXG4gIHJpZ2h0OiBib29sZWFuXG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgUm91bmQge1xuICBjb2RlOiBzdHJpbmdcbiAgcXVlc3Rpb246IHN0cmluZ1xuICBvcHRpb25zOiBSb3VuZE9wdGlvbltdXG4gIGV4cGxhbmF0aW9uOiBzdHJpbmdcbiAgLyoqIEJlc2NocmlmdHVuZ2VuIGRlciBnZWtsaWNrdGVuIEtuw7ZwZmUgKG51ciBgenVob2VyZXJgKS4gKi9cbiAgY2xpY2tzOiBzdHJpbmdbXVxuICAvKiogTnVyIGBib21iZWA6IE51bW1lciBkZXIgZmFsc2NoZW4gWmVpbGUgKGFiIDEpIHVuZCBkaWUgcmljaHRpZ2UgWmVpbGUuICovXG4gIHdyb25nTGluZT86IG51bWJlclxuICBmaXg/OiBzdHJpbmdcbn1cblxuZXhwb3J0IGludGVyZmFjZSBSb3VuZEdhbWUge1xuICBraW5kOiBSb3VuZEdhbWVLaW5kXG4gIHRpdGxlOiBzdHJpbmdcbiAgaW50cm86IHN0cmluZ1xuICAvKiogTnVyIGBib21iZWA6IFNla3VuZGVuIGplIFJ1bmRlLiAqL1xuICBzZWNvbmRzPzogbnVtYmVyXG4gIC8qKiBOdXIgYGJvbWJlYDogV2FzIGluIGRlbiBSdW5kZW4gc3RlaHQsIEphdmEgKFN0YW5kYXJkKSBvZGVyIGVpbmUgQ1NWLURhdGVpLiAqL1xuICBkYXRhPzogJ2NzdidcbiAgcm91bmRzOiBSb3VuZFtdXG59XG5cbmV4cG9ydCBjbGFzcyBSb3VuZEdhbWVFcnJvciBleHRlbmRzIEVycm9yIHt9XG5cbmV4cG9ydCBmdW5jdGlvbiBpc1JvdW5kR2FtZUtpbmQoYXJnOiBzdHJpbmcpOiBhcmcgaXMgUm91bmRHYW1lS2luZCB7XG4gIHJldHVybiBhcmcgPT09ICd6dWhvZXJlcicgfHwgYXJnID09PSAndmVydHJhZycgfHwgYXJnID09PSAnbGF5b3V0JyB8fCBhcmcgPT09ICdib21iZScgfHwgYXJnID09PSAnZnJhZ2UnIHx8IGFyZyA9PT0gJ3JlaWhlbmZvbGdlJ1xufVxuXG5leHBvcnQgZnVuY3Rpb24gcGFyc2VSb3VuZEdhbWUoa2luZDogUm91bmRHYW1lS2luZCwgbGluZXM6IHN0cmluZ1tdLCBmaWxlOiBzdHJpbmcpOiBSb3VuZEdhbWUge1xuICBjb25zdCBmYWlsID0gKG1zZzogc3RyaW5nKTogbmV2ZXIgPT4ge1xuICAgIHRocm93IG5ldyBSb3VuZEdhbWVFcnJvcihgJHtmaWxlfTogJHttc2d9YClcbiAgfVxuICBsZXQgdGl0bGUgPSAnJ1xuICBsZXQgaW50cm8gPSAnJ1xuICBsZXQgcXVlc3Rpb24gPSAnJ1xuICBsZXQgYW5zd2Vyczogc3RyaW5nW10gPSBbXVxuICBsZXQgc2Vjb25kczogbnVtYmVyIHwgdW5kZWZpbmVkXG4gIGxldCBkYXRhOiAnY3N2JyB8IHVuZGVmaW5lZFxuICBjb25zdCByb3VuZHM6IChSb3VuZCAmIHsgcmlnaHRUZXh0Pzogc3RyaW5nIH0pW10gPSBbXVxuICBsZXQgY3VycmVudDogKFJvdW5kICYgeyByaWdodFRleHQ/OiBzdHJpbmcgfSkgfCB1bmRlZmluZWRcbiAgbGV0IGluQ29kZSA9IGZhbHNlXG4gIGZvciAoY29uc3QgcmF3IG9mIGxpbmVzKSB7XG4gICAgY29uc3QgbGluZSA9IHJhdy50cmltKClcbiAgICBpZiAoY3VycmVudCAmJiBpbkNvZGUgJiYgKC9eIHs0fXxeXFx0Ly50ZXN0KHJhdykgfHwgbGluZSA9PT0gJycpKSB7XG4gICAgICBjdXJyZW50LmNvZGUgKz0gKGN1cnJlbnQuY29kZSA/ICdcXG4nIDogJycpICsgcmF3LnJlcGxhY2UoL14oIHs0fXxcXHQpLywgJycpXG4gICAgICBjb250aW51ZVxuICAgIH1cbiAgICBpbkNvZGUgPSBmYWxzZVxuICAgIGlmICghbGluZSkgY29udGludWVcbiAgICBjb25zdCBrZXkgPSAvXih0aXRlbHxpbnRyb3xhbnR3b3J0ZW58ZnJhZ2V8cnVuZGV8a2xpY2tzfHJpY2h0aWd8emVpdHxmZWhsZXJ8YmVzc2VyfGRhdGVuKTpcXHMqKC4qKSQvLmV4ZWMobGluZSlcbiAgICBpZiAoa2V5KSB7XG4gICAgICBjb25zdCBbLCBuYW1lLCB2YWx1ZV0gPSBrZXlcbiAgICAgIGlmIChuYW1lID09PSAncnVuZGUnKSB7XG4gICAgICAgIGN1cnJlbnQgPSB7IGNvZGU6ICcnLCBxdWVzdGlvbiwgb3B0aW9uczogW10sIGV4cGxhbmF0aW9uOiAnJywgY2xpY2tzOiBbXSB9XG4gICAgICAgIHJvdW5kcy5wdXNoKGN1cnJlbnQpXG4gICAgICAgIGluQ29kZSA9IHRydWVcbiAgICAgIH0gZWxzZSBpZiAoIWN1cnJlbnQpIHtcbiAgICAgICAgaWYgKG5hbWUgPT09ICd0aXRlbCcpIHRpdGxlID0gdmFsdWVcbiAgICAgICAgZWxzZSBpZiAobmFtZSA9PT0gJ2ludHJvJykgaW50cm8gPSB2YWx1ZVxuICAgICAgICBlbHNlIGlmIChuYW1lID09PSAnYW50d29ydGVuJykgYW5zd2VycyA9IHZhbHVlLnNwbGl0KCd8JykubWFwKChhKSA9PiBhLnRyaW0oKSlcbiAgICAgICAgZWxzZSBpZiAobmFtZSA9PT0gJ2ZyYWdlJykgcXVlc3Rpb24gPSB2YWx1ZVxuICAgICAgICBlbHNlIGlmIChuYW1lID09PSAnemVpdCcpIHNlY29uZHMgPSBOdW1iZXIodmFsdWUpXG4gICAgICAgIGVsc2UgaWYgKG5hbWUgPT09ICdkYXRlbicpIGRhdGEgPSB2YWx1ZSA9PT0gJ2NzdicgPyB2YWx1ZSA6IGZhaWwoYOKAnmRhdGVuOuKAnCBrZW5udCBudXIg4oCeY3N24oCcLmApXG4gICAgICAgIGVsc2UgZmFpbChg4oCeJHtuYW1lfTrigJwgZ2Vow7ZydCBpbiBlaW5lIFJ1bmRlLmApXG4gICAgICB9IGVsc2UgaWYgKG5hbWUgPT09ICdmcmFnZScpIGN1cnJlbnQucXVlc3Rpb24gPSB2YWx1ZVxuICAgICAgZWxzZSBpZiAobmFtZSA9PT0gJ2ZlaGxlcicpIGN1cnJlbnQud3JvbmdMaW5lID0gTnVtYmVyKHZhbHVlKVxuICAgICAgZWxzZSBpZiAobmFtZSA9PT0gJ2Jlc3NlcicpIGN1cnJlbnQuZml4ID0gdmFsdWVcbiAgICAgIGVsc2UgaWYgKG5hbWUgPT09ICdrbGlja3MnKSBjdXJyZW50LmNsaWNrcyA9IHZhbHVlLnNwbGl0KCcsJykubWFwKChjKSA9PiBjLnRyaW0oKSkuZmlsdGVyKEJvb2xlYW4pXG4gICAgICBlbHNlIGlmIChuYW1lID09PSAncmljaHRpZycpIGN1cnJlbnQucmlnaHRUZXh0ID0gdmFsdWVcbiAgICAgIGVsc2UgZmFpbChg4oCeJHtuYW1lfTrigJwgZ2Vow7ZydCB2b3IgZGllIGVyc3RlIFJ1bmRlLmApXG4gICAgICBjb250aW51ZVxuICAgIH1cbiAgICBpZiAoIWN1cnJlbnQpIGZhaWwoYFVuYmVrYW5udGUgWmVpbGUgdm9yIGRlciBlcnN0ZW4gUnVuZGU6IOKAniR7bGluZX3igJxgKVxuICAgIGNvbnN0IHJvdW5kID0gY3VycmVudCFcbiAgICBjb25zdCBvcHRpb24gPSAvXi1cXHMrKFxcW3hcXF1cXHMrKT8oLispJC8uZXhlYyhsaW5lKVxuICAgIGlmIChvcHRpb24pIHJvdW5kLm9wdGlvbnMucHVzaCh7IHRleHQ6IG9wdGlvblsyXS50cmltKCkucmVwbGFjZUFsbCgnXFxcXG4nLCAnXFxuJyksIHJpZ2h0OiAhIW9wdGlvblsxXSB9KVxuICAgIGVsc2UgaWYgKGxpbmUuc3RhcnRzV2l0aCgnPicpKSByb3VuZC5leHBsYW5hdGlvbiArPSAocm91bmQuZXhwbGFuYXRpb24gPyAnICcgOiAnJykgKyBsaW5lLnNsaWNlKDEpLnRyaW0oKVxuICAgIGVsc2UgZmFpbChgVW5iZWthbm50ZSBaZWlsZSBpbSBTcGllbDog4oCeJHtsaW5lfeKAnGApXG4gIH1cbiAgaWYgKCF0aXRsZSkgZmFpbCgnRGFzIFNwaWVsIGJyYXVjaHQgZWluZSBaZWlsZSDigJ50aXRlbDrigJwuJylcbiAgaWYgKCFyb3VuZHMubGVuZ3RoKSBmYWlsKCdEYXMgU3BpZWwgYnJhdWNodCBtaW5kZXN0ZW5zIGVpbmUg4oCecnVuZGU64oCcLicpXG4gIHJvdW5kcy5mb3JFYWNoKChyb3VuZCwgaSkgPT4ge1xuICAgIHJvdW5kLmNvZGUgPSByb3VuZC5jb2RlLnJlcGxhY2UoL1xcbiskLywgJycpXG4gICAgaWYgKGtpbmQgPT09ICdib21iZScpIHtcbiAgICAgIGNvbnN0IGxpbmVzID0gcm91bmQuY29kZS5zcGxpdCgnXFxuJylcbiAgICAgIGNvbnN0IG4gPSByb3VuZC53cm9uZ0xpbmVcbiAgICAgIGlmICghbiB8fCAhTnVtYmVyLmlzSW50ZWdlcihuKSB8fCBuIDwgMSB8fCBuID4gbGluZXMubGVuZ3RoIHx8ICFsaW5lc1tuIC0gMV0udHJpbSgpKSBmYWlsKGBSdW5kZSAke2kgKyAxfTog4oCeZmVobGVyOuKAnCBtdXNzIGVpbmUgWmVpbGUgZGVzIENvZGVzIHNlaW4uYClcbiAgICAgIGlmICghcm91bmQuZml4KSBmYWlsKGBSdW5kZSAke2kgKyAxfTog4oCeYmVzc2VyOuKAnCBmZWhsdC5gKVxuICAgICAgaWYgKHJvdW5kLm9wdGlvbnMubGVuZ3RoKSBmYWlsKGBSdW5kZSAke2kgKyAxfTogQmVpIOKAnmJvbWJl4oCcIGdpYnQgZXMga2VpbmUgQW50d29ydGVuLCBtYW4gdGlwcHQgYXVmIGRpZSBaZWlsZS5gKVxuICAgICAgaWYgKCFyb3VuZC5xdWVzdGlvbikgZmFpbChgUnVuZGUgJHtpICsgMX06IGtlaW5lIEZyYWdlLmApXG4gICAgICByZXR1cm5cbiAgICB9XG4gICAgaWYgKGtpbmQgPT09ICdyZWloZW5mb2xnZScpIHtcbiAgICAgIGlmIChyb3VuZC5vcHRpb25zLmxlbmd0aCA8IDMpIGZhaWwoYFJ1bmRlICR7aSArIDF9OiDigJ5yZWloZW5mb2xnZeKAnCBicmF1Y2h0IG1pbmRlc3RlbnMgZHJlaSBTY2hyaXR0ZS5gKVxuICAgICAgaWYgKHJvdW5kLm9wdGlvbnMuc29tZSgobykgPT4gby5yaWdodCkpIGZhaWwoYFJ1bmRlICR7aSArIDF9OiBCZWkg4oCecmVpaGVuZm9sZ2XigJwgZ2lidCBlcyBrZWluIFt4XSwgZGllIFNjaHJpdHRlIHN0ZWhlbiBkZXIgUmVpaGUgbmFjaCBkYS5gKVxuICAgICAgaWYgKG5ldyBTZXQocm91bmQub3B0aW9ucy5tYXAoKG8pID0+IG8udGV4dCkpLnNpemUgIT09IHJvdW5kLm9wdGlvbnMubGVuZ3RoKSBmYWlsKGBSdW5kZSAke2kgKyAxfTogendlaSBTY2hyaXR0ZSBzaW5kIGdsZWljaC5gKVxuICAgICAgaWYgKCFyb3VuZC5xdWVzdGlvbikgZmFpbChgUnVuZGUgJHtpICsgMX06IGtlaW5lIEZyYWdlLmApXG4gICAgICByZXR1cm5cbiAgICB9XG4gICAgaWYgKCFyb3VuZC5vcHRpb25zLmxlbmd0aCkge1xuICAgICAgaWYgKCFhbnN3ZXJzLmxlbmd0aCkgZmFpbChgUnVuZGUgJHtpICsgMX06IGtlaW5lIEFudHdvcnRlbi5gKVxuICAgICAgaWYgKCFyb3VuZC5yaWdodFRleHQgfHwgIWFuc3dlcnMuaW5jbHVkZXMocm91bmQucmlnaHRUZXh0KSkgZmFpbChgUnVuZGUgJHtpICsgMX06IOKAnnJpY2h0aWc64oCcIG11c3MgZWluZSBkZXIgQW50d29ydGVuIHNlaW4uYClcbiAgICAgIHJvdW5kLm9wdGlvbnMgPSBhbnN3ZXJzLm1hcCgodGV4dCkgPT4gKHsgdGV4dCwgcmlnaHQ6IHRleHQgPT09IHJvdW5kLnJpZ2h0VGV4dCB9KSlcbiAgICB9XG4gICAgaWYgKHJvdW5kLm9wdGlvbnMuZmlsdGVyKChvKSA9PiBvLnJpZ2h0KS5sZW5ndGggIT09IDEpIGZhaWwoYFJ1bmRlICR7aSArIDF9OiBnZW5hdSBlaW5lIEFudHdvcnQgbXVzcyByaWNodGlnIHNlaW4uYClcbiAgICBpZiAoIXJvdW5kLnF1ZXN0aW9uKSBmYWlsKGBSdW5kZSAke2kgKyAxfToga2VpbmUgRnJhZ2UuYClcbiAgICBpZiAoa2luZCA9PT0gJ2xheW91dCcpIHJvdW5kLm9wdGlvbnMuZm9yRWFjaCgobykgPT4gcGFyc2VMYXlvdXRQaWN0dXJlKG8udGV4dCwgYFJ1bmRlICR7aSArIDF9YCwgZmFpbCkpXG4gICAgaWYgKGtpbmQgPT09ICd6dWhvZXJlcicpIHtcbiAgICAgIHRyeSB7XG4gICAgICAgIGNvbnN0IHdpbmRvdyA9IHBhcnNlU3dpbmdXaW5kb3cocm91bmQuY29kZSlcbiAgICAgICAgZm9yIChjb25zdCBjIG9mIHJvdW5kLmNsaWNrcykgaWYgKCF3aW5kb3cuYnV0dG9ucy5zb21lKChiKSA9PiBiLmNhcHRpb24gPT09IGMpKSBmYWlsKGBSdW5kZSAke2kgKyAxfTogS25vcGYg4oCeJHtjfeKAnCBnaWJ0IGVzIG5pY2h0LmApXG4gICAgICAgIHNpbXVsYXRlKHdpbmRvdywgcm91bmQuY2xpY2tzKVxuICAgICAgfSBjYXRjaCAoZXJyKSB7XG4gICAgICAgIGlmIChlcnIgaW5zdGFuY2VvZiBSb3VuZEdhbWVFcnJvcikgdGhyb3cgZXJyXG4gICAgICAgIGZhaWwoYFJ1bmRlICR7aSArIDF9OiAkeyhlcnIgYXMgRXJyb3IpLm1lc3NhZ2V9YClcbiAgICAgIH1cbiAgICB9XG4gICAgZGVsZXRlIHJvdW5kLnJpZ2h0VGV4dFxuICB9KVxuICBpZiAoa2luZCA9PT0gJ2JvbWJlJyAmJiAhKHNlY29uZHMgJiYgc2Vjb25kcyA+IDApKSBmYWlsKCfigJ5ib21iZeKAnCBicmF1Y2h0IOKAnnplaXQ64oCcIG1pdCBkZW4gU2VrdW5kZW4gamUgUnVuZGUuJylcbiAgcmV0dXJuIHsga2luZCwgdGl0bGUsIGludHJvLCAuLi4oa2luZCA9PT0gJ2JvbWJlJyA/IHsgc2Vjb25kcywgLi4uKGRhdGEgPyB7IGRhdGEgfSA6IHt9KSB9IDoge30pLCByb3VuZHMgfVxufVxuXG4vLyBNQVJLOiAtIExheW91dC1CaWxkZXJcblxuZXhwb3J0IHR5cGUgTGF5b3V0UGljdHVyZSA9XG4gIHwgeyBraW5kOiAnZ3JpZCc7IHJvd3M6IHN0cmluZ1tdW10gfVxuICB8IHsga2luZDogJ2Zsb3cnOyByb3dzOiBzdHJpbmdbXVtdIH1cbiAgfCB7IGtpbmQ6ICdib3JkZXInOyBhcmVhczogUGFydGlhbDxSZWNvcmQ8J04nIHwgJ1MnIHwgJ1cnIHwgJ0UnIHwgJ0MnLCBzdHJpbmc+PiB9XG5cbi8qKiBgZ3JpZDogQSBCIC8gQyBEYCwgYGZsb3c6IEEgQiBDYCwgYGJvcmRlcjogTj1BIEM9QiBTPUNgLiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHBhcnNlTGF5b3V0UGljdHVyZSh0ZXh0OiBzdHJpbmcsIHdoZXJlID0gJycsIGZhaWw6IChtc2c6IHN0cmluZykgPT4gbmV2ZXIgPSAobSkgPT4geyB0aHJvdyBuZXcgUm91bmRHYW1lRXJyb3IobSkgfSk6IExheW91dFBpY3R1cmUge1xuICBjb25zdCBtID0gL14oZ3JpZHxmbG93fGJvcmRlcik6XFxzKiguKykkLy5leGVjKHRleHQpXG4gIGlmICghbSkgcmV0dXJuIGZhaWwoYCR7d2hlcmV9OiBBbnR3b3J0IOKAniR7dGV4dH3igJwgaXN0IGtlaW4gRmVuc3RlcmJpbGQgKGdyaWQ6LCBmbG93OiBvZGVyIGJvcmRlcjopLmApXG4gIGlmIChtWzFdID09PSAnYm9yZGVyJykge1xuICAgIGNvbnN0IGFyZWFzOiBQYXJ0aWFsPFJlY29yZDwnTicgfCAnUycgfCAnVycgfCAnRScgfCAnQycsIHN0cmluZz4+ID0ge31cbiAgICBmb3IgKGNvbnN0IHBhcnQgb2YgbVsyXS5zcGxpdCgvXFxzKy8pKSB7XG4gICAgICBjb25zdCBhID0gL14oW05TV0VDXSk9KC4rKSQvLmV4ZWMocGFydClcbiAgICAgIGlmICghYSkgZmFpbChgJHt3aGVyZX06IOKAniR7cGFydH3igJwgaW0gQm9yZGVyTGF5b3V0LUJpbGQgdmVyc3RlaGUgaWNoIG5pY2h0ICh6LiBCLiBOPUEpLmApXG4gICAgICBhcmVhc1thIVsxXSBhcyAnTiddID0gYSFbMl1cbiAgICB9XG4gICAgcmV0dXJuIHsga2luZDogJ2JvcmRlcicsIGFyZWFzIH1cbiAgfVxuICBjb25zdCByb3dzID0gbVsyXS5zcGxpdCgnLycpLm1hcCgocikgPT4gci50cmltKCkuc3BsaXQoL1xccysvKS5maWx0ZXIoQm9vbGVhbikpXG4gIHJldHVybiB7IGtpbmQ6IG1bMV0gYXMgJ2dyaWQnIHwgJ2Zsb3cnLCByb3dzIH1cbn1cblxuLy8gTUFSSzogLSBOYWNoZ2ViYXV0ZXMgRmVuc3RlciBmw7xyIOKAnldlciBow7ZydCB6dT/igJxcblxuZXhwb3J0IGludGVyZmFjZSBTd2luZ0J1dHRvbiB7XG4gIG5hbWU6IHN0cmluZ1xuICBjYXB0aW9uOiBzdHJpbmdcbn1cblxuZXhwb3J0IGludGVyZmFjZSBTd2luZ0xpc3RlbmVyIHtcbiAgYnV0dG9uOiBzdHJpbmdcbiAgLyoqIFplaWxlbiBkZXMgWnVow7ZyZXJzIGltIENvZGUgKGFiIDAsIGVpbnNjaGxpZcOfbGljaCkuICovXG4gIGZyb206IG51bWJlclxuICB0bzogbnVtYmVyXG4gIHN0YXRlbWVudHM6IFN3aW5nU3RhdGVtZW50W11cbn1cblxuLyoqIEVpbmUgQW53ZWlzdW5nIGltIFp1aMO2cmVyOiBlaW5mYWNoIChgdGV4dC5zZXRUZXh0KOKApilgKSBvZGVyIGBpZiAo4oCmKSB7IOKApiB9IGVsc2UgeyDigKYgfWAuICovXG5leHBvcnQgdHlwZSBTd2luZ1N0YXRlbWVudCA9IHN0cmluZyB8IHsgY29uZGl0aW9uOiBzdHJpbmc7IHRoZW46IFN3aW5nU3RhdGVtZW50W107IG90aGVyd2lzZTogU3dpbmdTdGF0ZW1lbnRbXSB9XG5cbmV4cG9ydCBpbnRlcmZhY2UgU3dpbmdXaW5kb3cge1xuICB0aXRsZTogc3RyaW5nXG4gIGJ1dHRvbnM6IFN3aW5nQnV0dG9uW11cbiAgLyoqIEJlc2NocmlmdHVuZ2VuIChKTGFiZWwpIG1pdCBpaHJlbSBTdGFydHRleHQsIGluIGRlciBSZWloZW5mb2xnZSBpbSBDb2RlLiAqL1xuICBsYWJlbHM6IHsgbmFtZTogc3RyaW5nOyB0ZXh0OiBzdHJpbmcgfVtdXG4gIGludHM6IFJlY29yZDxzdHJpbmcsIG51bWJlcj5cbiAgbGlzdGVuZXJzOiBTd2luZ0xpc3RlbmVyW11cbn1cblxuY29uc3Qgc3RyID0gJ1wiKCg/OlteXCJcXFxcXFxcXF18XFxcXFxcXFwuKSopXCInXG5cbi8qKlxuICogTGllc3QgS27DtnBmZSwgQmVzY2hyaWZ0dW5nZW4sIGludC1WYXJpYWJsZW4gdW5kIFp1aMO2cmVyIGF1cyBlaW5mYWNoZW0gU3dpbmctQ29kZS4gRWluIFp1aMO2cmVyIHN0ZWh0IGRpcmVrdCBhbVxuICogS25vcGYgKGBrbm9wZi5hZGRBY3Rpb25MaXN0ZW5lcihlIC0+IOKApilgKSBvZGVyIGFscyBWYXJpYWJsZSAoYEFjdGlvbkxpc3RlbmVyIHogPSBlIC0+IOKApjtgKSwgZGllIG1pdFxuICogYGtub3BmLmFkZEFjdGlvbkxpc3RlbmVyKHopO2AgYW4gbWVocmVyZW4gS27DtnBmZW4gaMOkbmdlbiBrYW5uLlxuICovXG5leHBvcnQgZnVuY3Rpb24gcGFyc2VTd2luZ1dpbmRvdyhjb2RlOiBzdHJpbmcpOiBTd2luZ1dpbmRvdyB7XG4gIGNvbnN0IGxpbmVzID0gY29kZS5zcGxpdCgnXFxuJylcbiAgY29uc3Qgd2luOiBTd2luZ1dpbmRvdyA9IHsgdGl0bGU6ICcnLCBidXR0b25zOiBbXSwgbGFiZWxzOiBbXSwgaW50czoge30sIGxpc3RlbmVyczogW10gfVxuICBjb25zdCBuYW1lZCA9IG5ldyBNYXA8c3RyaW5nLCBPbWl0PFN3aW5nTGlzdGVuZXIsICdidXR0b24nPj4oKVxuICAvKiogWnVow7ZyZXIgYWIgWmVpbGUgaSwgYHJlc3RgIGlzdCBkZXIgVGV4dCBoaW50ZXIgZGVtIFBmZWlsOyBgZW5kYCBzY2hsaWXDn3QgZWluZW4gQmxvY2sgYWIgKGB9KTtgIG9kZXIgYH07YCkuICovXG4gIGNvbnN0IGxhbWJkYSA9IChpOiBudW1iZXIsIHJlc3Q6IHN0cmluZywgZW5kOiBzdHJpbmcpOiBPbWl0PFN3aW5nTGlzdGVuZXIsICdidXR0b24nPiA9PiB7XG4gICAgaWYgKHJlc3Quc3RhcnRzV2l0aCgneycpKSB7XG4gICAgICBsZXQgaiA9IGkgKyAxXG4gICAgICBjb25zdCBib2R5OiBzdHJpbmdbXSA9IFtdXG4gICAgICB3aGlsZSAoaiA8IGxpbmVzLmxlbmd0aCAmJiBsaW5lc1tqXS50cmltKCkgIT09IGVuZCkgYm9keS5wdXNoKGxpbmVzW2orK10udHJpbSgpKVxuICAgICAgaWYgKGogPj0gbGluZXMubGVuZ3RoKSB0aHJvdyBuZXcgRXJyb3IoYERlbSBadWjDtnJlciBmZWhsdCDigJ4ke2VuZH3igJwuYClcbiAgICAgIHJldHVybiB7IGZyb206IGksIHRvOiBqLCBzdGF0ZW1lbnRzOiBwYXJzZVN0YXRlbWVudHMoYm9keS5qb2luKCcgJykpIH1cbiAgICB9XG4gICAgY29uc3QgaW5uZXIgPSBlbmQgPT09ICd9KTsnID8gcmVzdC5yZXBsYWNlKC9cXClcXHMqO1xccyokLywgJycpIDogcmVzdC5yZXBsYWNlKC87XFxzKiQvLCAnJylcbiAgICByZXR1cm4geyBmcm9tOiBpLCB0bzogaSwgc3RhdGVtZW50czogcGFyc2VTdGF0ZW1lbnRzKGlubmVyKSB9XG4gIH1cbiAgY29uc3QgYnV0dG9uID0gKG5hbWU6IHN0cmluZykgPT4ge1xuICAgIGlmICghd2luLmJ1dHRvbnMuc29tZSgoYikgPT4gYi5uYW1lID09PSBuYW1lKSkgdGhyb3cgbmV3IEVycm9yKGBLbm9wZiAke25hbWV9IGlzdCBuaWNodCBhbmdlbGVndC5gKVxuICAgIHJldHVybiBuYW1lXG4gIH1cbiAgZm9yIChsZXQgaSA9IDA7IGkgPCBsaW5lcy5sZW5ndGg7IGkrKykge1xuICAgIGNvbnN0IGxpbmUgPSBsaW5lc1tpXS50cmltKClcbiAgICBsZXQgbTogUmVnRXhwRXhlY0FycmF5IHwgbnVsbFxuICAgIGlmICgobSA9IG5ldyBSZWdFeHAoYF5KRnJhbWVcXFxccytcXFxcdytcXFxccyo9XFxcXHMqbmV3IEpGcmFtZVxcXFwoJHtzdHJ9XFxcXClgKS5leGVjKGxpbmUpKSkgd2luLnRpdGxlID0gbVsxXVxuICAgIGVsc2UgaWYgKChtID0gbmV3IFJlZ0V4cChgXkpCdXR0b25cXFxccysoXFxcXHcrKVxcXFxzKj1cXFxccypuZXcgSkJ1dHRvblxcXFwoJHtzdHJ9XFxcXClgKS5leGVjKGxpbmUpKSkgd2luLmJ1dHRvbnMucHVzaCh7IG5hbWU6IG1bMV0sIGNhcHRpb246IG1bMl0gfSlcbiAgICBlbHNlIGlmICgobSA9IG5ldyBSZWdFeHAoYF5KTGFiZWxcXFxccysoXFxcXHcrKVxcXFxzKj1cXFxccypuZXcgSkxhYmVsXFxcXCgke3N0cn1gKS5leGVjKGxpbmUpKSkgd2luLmxhYmVscy5wdXNoKHsgbmFtZTogbVsxXSwgdGV4dDogbVsyXSB9KVxuICAgIGVsc2UgaWYgKChtID0gL14oPzpzdGF0aWNcXHMrKT9pbnRcXHMrKFxcdyspXFxzKj1cXHMqKC0/XFxkKylcXHMqOy8uZXhlYyhsaW5lKSkpIHdpbi5pbnRzW21bMV1dID0gTnVtYmVyKG1bMl0pXG4gICAgZWxzZSBpZiAoKG0gPSAvXkFjdGlvbkxpc3RlbmVyXFxzKyhcXHcrKVxccyo9XFxzKlxcdytcXHMqLT5cXHMqKC4qKSQvLmV4ZWMobGluZSkpKSB7XG4gICAgICBjb25zdCBsaXN0ZW5lciA9IGxhbWJkYShpLCBtWzJdLCAnfTsnKVxuICAgICAgbmFtZWQuc2V0KG1bMV0sIGxpc3RlbmVyKVxuICAgICAgaSA9IGxpc3RlbmVyLnRvXG4gICAgfSBlbHNlIGlmICgobSA9IC9eKFxcdyspXFwuYWRkQWN0aW9uTGlzdGVuZXJcXChcXHMqKFxcdyspXFxzKlxcKVxccyo7JC8uZXhlYyhsaW5lKSkpIHtcbiAgICAgIGNvbnN0IGxpc3RlbmVyID0gbmFtZWQuZ2V0KG1bMl0pXG4gICAgICBpZiAoIWxpc3RlbmVyKSB0aHJvdyBuZXcgRXJyb3IoYFp1aMO2cmVyICR7bVsyXX0gaXN0IG5pY2h0IGFuZ2VsZWd0LmApXG4gICAgICB3aW4ubGlzdGVuZXJzLnB1c2goeyBidXR0b246IGJ1dHRvbihtWzFdKSwgLi4ubGlzdGVuZXIgfSlcbiAgICB9IGVsc2UgaWYgKChtID0gL14oXFx3KylcXC5hZGRBY3Rpb25MaXN0ZW5lclxcKFxccypcXHcrXFxzKi0+XFxzKiguKikkLy5leGVjKGxpbmUpKSkge1xuICAgICAgY29uc3QgbGlzdGVuZXIgPSBsYW1iZGEoaSwgbVsyXSwgJ30pOycpXG4gICAgICB3aW4ubGlzdGVuZXJzLnB1c2goeyBidXR0b246IGJ1dHRvbihtWzFdKSwgLi4ubGlzdGVuZXIgfSlcbiAgICAgIGkgPSBsaXN0ZW5lci50b1xuICAgIH1cbiAgfVxuICByZXR1cm4gd2luXG59XG5cbi8qKiBaZXJsZWd0IGRlbiBSdW1wZiBlaW5lcyBadWjDtnJlcnMgaW4gQW53ZWlzdW5nZW4sIGBpZmAvYGVsc2VgIG1pdCBvZGVyIG9obmUgZ2VzY2h3ZWlmdGUgS2xhbW1lcm4uICovXG5mdW5jdGlvbiBwYXJzZVN0YXRlbWVudHModGV4dDogc3RyaW5nKTogU3dpbmdTdGF0ZW1lbnRbXSB7XG4gIGNvbnN0IG91dDogU3dpbmdTdGF0ZW1lbnRbXSA9IFtdXG4gIGxldCBwb3MgPSAwXG4gIGNvbnN0IHNraXAgPSAoKSA9PiB7XG4gICAgd2hpbGUgKHBvcyA8IHRleHQubGVuZ3RoICYmIC9cXHMvLnRlc3QodGV4dFtwb3NdKSkgcG9zKytcbiAgfVxuICAvKiogVGV4dCBiaXMgenVyIHBhc3NlbmRlbiBzY2hsaWXDn2VuZGVuIEtsYW1tZXI7IGBwb3NgIHN0ZWh0IGF1ZiBkZXIgw7ZmZm5lbmRlbi4gKi9cbiAgY29uc3QgYmFsYW5jZWQgPSAob3Blbjogc3RyaW5nLCBjbG9zZTogc3RyaW5nKTogc3RyaW5nID0+IHtcbiAgICBsZXQgZGVwdGggPSAwXG4gICAgbGV0IHF1b3RlID0gZmFsc2VcbiAgICBjb25zdCBzdGFydCA9IHBvcyArIDFcbiAgICBmb3IgKDsgcG9zIDwgdGV4dC5sZW5ndGg7IHBvcysrKSB7XG4gICAgICBjb25zdCBjID0gdGV4dFtwb3NdXG4gICAgICBpZiAocXVvdGUpIHtcbiAgICAgICAgaWYgKGMgPT09ICdcXFxcJykgcG9zKytcbiAgICAgICAgZWxzZSBpZiAoYyA9PT0gJ1wiJykgcXVvdGUgPSBmYWxzZVxuICAgICAgfSBlbHNlIGlmIChjID09PSAnXCInKSBxdW90ZSA9IHRydWVcbiAgICAgIGVsc2UgaWYgKGMgPT09IG9wZW4pIGRlcHRoKytcbiAgICAgIGVsc2UgaWYgKGMgPT09IGNsb3NlICYmIC0tZGVwdGggPT09IDApIHJldHVybiB0ZXh0LnNsaWNlKHN0YXJ0LCBwb3MrKylcbiAgICB9XG4gICAgdGhyb3cgbmV3IEVycm9yKGBFcyBmZWhsdCDigJ4ke2Nsb3NlfeKAnC5gKVxuICB9XG4gIC8qKiBFaW5lIGVpbmZhY2hlIEFud2Vpc3VuZyBiaXMgenVtIFNlbWlrb2xvbiBhdcOfZXJoYWxiIHZvbiBLbGFtbWVybiB1bmQgVGV4dC4gKi9cbiAgY29uc3Qgc2ltcGxlID0gKCk6IHN0cmluZyA9PiB7XG4gICAgbGV0IGRlcHRoID0gMFxuICAgIGxldCBxdW90ZSA9IGZhbHNlXG4gICAgY29uc3Qgc3RhcnQgPSBwb3NcbiAgICBmb3IgKDsgcG9zIDwgdGV4dC5sZW5ndGg7IHBvcysrKSB7XG4gICAgICBjb25zdCBjID0gdGV4dFtwb3NdXG4gICAgICBpZiAocXVvdGUpIHtcbiAgICAgICAgaWYgKGMgPT09ICdcXFxcJykgcG9zKytcbiAgICAgICAgZWxzZSBpZiAoYyA9PT0gJ1wiJykgcXVvdGUgPSBmYWxzZVxuICAgICAgfSBlbHNlIGlmIChjID09PSAnXCInKSBxdW90ZSA9IHRydWVcbiAgICAgIGVsc2UgaWYgKGMgPT09ICcoJykgZGVwdGgrK1xuICAgICAgZWxzZSBpZiAoYyA9PT0gJyknKSBkZXB0aC0tXG4gICAgICBlbHNlIGlmIChjID09PSAnOycgJiYgZGVwdGggPT09IDApIHJldHVybiB0ZXh0LnNsaWNlKHN0YXJ0LCBwb3MrKykudHJpbSgpXG4gICAgfVxuICAgIHJldHVybiB0ZXh0LnNsaWNlKHN0YXJ0KS50cmltKClcbiAgfVxuICBjb25zdCBvbmUgPSAoKTogU3dpbmdTdGF0ZW1lbnRbXSA9PiB7XG4gICAgc2tpcCgpXG4gICAgaWYgKHRleHRbcG9zXSA9PT0gJ3snKSByZXR1cm4gcGFyc2VTdGF0ZW1lbnRzKGJhbGFuY2VkKCd7JywgJ30nKSlcbiAgICBpZiAoL15pZlxccypcXCgvLnRlc3QodGV4dC5zbGljZShwb3MpKSkge1xuICAgICAgcG9zID0gdGV4dC5pbmRleE9mKCcoJywgcG9zKVxuICAgICAgY29uc3QgY29uZGl0aW9uID0gYmFsYW5jZWQoJygnLCAnKScpLnRyaW0oKVxuICAgICAgY29uc3QgdGhlbiA9IG9uZSgpXG4gICAgICBza2lwKClcbiAgICAgIGxldCBvdGhlcndpc2U6IFN3aW5nU3RhdGVtZW50W10gPSBbXVxuICAgICAgaWYgKC9eZWxzZVxcYi8udGVzdCh0ZXh0LnNsaWNlKHBvcykpKSB7XG4gICAgICAgIHBvcyArPSA0XG4gICAgICAgIG90aGVyd2lzZSA9IG9uZSgpXG4gICAgICB9XG4gICAgICByZXR1cm4gW3sgY29uZGl0aW9uLCB0aGVuLCBvdGhlcndpc2UgfV1cbiAgICB9XG4gICAgY29uc3QgcyA9IHNpbXBsZSgpXG4gICAgcmV0dXJuIHMgPyBbc10gOiBbXVxuICB9XG4gIGZvciAoc2tpcCgpOyBwb3MgPCB0ZXh0Lmxlbmd0aDsgc2tpcCgpKSBvdXQucHVzaCguLi5vbmUoKSlcbiAgcmV0dXJuIG91dFxufVxuXG5leHBvcnQgaW50ZXJmYWNlIENsaWNrU3RlcCB7XG4gIGJ1dHRvbjogc3RyaW5nXG4gIC8qKiBadWjDtnJlciwgZGVyIGxpZWY7IGB1bmRlZmluZWRgOiBOaWVtYW5kIGjDtnJ0IHp1LiAqL1xuICBsaXN0ZW5lcj86IFN3aW5nTGlzdGVuZXJcbiAgLyoqIFRleHRlIGFsbGVyIEJlc2NocmlmdHVuZ2VuIHVuZCBLbsO2cGZlIG5hY2ggZGVtIEtsaWNrIChOYW1lIOKGkiBUZXh0KS4gKi9cbiAgdGV4dHM6IFJlY29yZDxzdHJpbmcsIHN0cmluZz5cbiAgY29uc29sZTogc3RyaW5nW11cbn1cblxuZXhwb3J0IGludGVyZmFjZSBTd2luZ1N0YXRlIHtcbiAgdGV4dHM6IFJlY29yZDxzdHJpbmcsIHN0cmluZz5cbiAgaW50czogUmVjb3JkPHN0cmluZywgbnVtYmVyPlxufVxuXG5leHBvcnQgZnVuY3Rpb24gc3RhcnRTdGF0ZSh3aW46IFN3aW5nV2luZG93KTogU3dpbmdTdGF0ZSB7XG4gIGNvbnN0IHRleHRzOiBSZWNvcmQ8c3RyaW5nLCBzdHJpbmc+ID0ge31cbiAgZm9yIChjb25zdCBiIG9mIHdpbi5idXR0b25zKSB0ZXh0c1tiLm5hbWVdID0gYi5jYXB0aW9uXG4gIGZvciAoY29uc3QgbCBvZiB3aW4ubGFiZWxzKSB0ZXh0c1tsLm5hbWVdID0gbC50ZXh0XG4gIHJldHVybiB7IHRleHRzLCBpbnRzOiB7IC4uLndpbi5pbnRzIH0gfVxufVxuXG4vKiogRWluIEtsaWNrIGF1ZiBkZW4gS25vcGYgbWl0IGRpZXNlciBCZXNjaHJpZnR1bmcgKHZlcsOkbmRlcnQgYHN0YXRlYCkuICovXG5leHBvcnQgZnVuY3Rpb24gY2xpY2sod2luOiBTd2luZ1dpbmRvdywgc3RhdGU6IFN3aW5nU3RhdGUsIGNhcHRpb246IHN0cmluZyk6IENsaWNrU3RlcCB7XG4gIGNvbnN0IGJ1dHRvbiA9IHdpbi5idXR0b25zLmZpbmQoKGIpID0+IGIuY2FwdGlvbiA9PT0gY2FwdGlvbikgPz8gd2luLmJ1dHRvbnMuZmluZCgoYikgPT4gc3RhdGUudGV4dHNbYi5uYW1lXSA9PT0gY2FwdGlvbilcbiAgaWYgKCFidXR0b24pIHRocm93IG5ldyBFcnJvcihgS25vcGYg4oCeJHtjYXB0aW9ufeKAnCBnaWJ0IGVzIG5pY2h0LmApXG4gIHJldHVybiBjbGlja0J1dHRvbih3aW4sIHN0YXRlLCBidXR0b24ubmFtZSlcbn1cblxuLyoqIEtsaWNrIGF1ZiBkZW4gS25vcGYgbWl0IGRpZXNlbSBWYXJpYWJsZW5uYW1lbi4gKi9cbmV4cG9ydCBmdW5jdGlvbiBjbGlja0J1dHRvbih3aW46IFN3aW5nV2luZG93LCBzdGF0ZTogU3dpbmdTdGF0ZSwgbmFtZTogc3RyaW5nKTogQ2xpY2tTdGVwIHtcbiAgY29uc3QgbGlzdGVuZXIgPSB3aW4ubGlzdGVuZXJzLmZpbmQoKGwpID0+IGwuYnV0dG9uID09PSBuYW1lKVxuICBjb25zdCBvdXRwdXQ6IHN0cmluZ1tdID0gW11cbiAgLy8gYGUuZ2V0QWN0aW9uQ29tbWFuZCgpYCBpc3Qgd2llIGluIEphdmEgZGllIEJlc2NocmlmdHVuZyBkZXMgS25vcGZzIGJlaW0gS2xpY2suXG4gIGNvbnN0IGV2ZW50OiBTd2luZ0V2ZW50ID0geyBzb3VyY2U6IG5hbWUsIGNvbW1hbmQ6IHN0YXRlLnRleHRzW25hbWVdIH1cbiAgZm9yIChjb25zdCBzIG9mIGxpc3RlbmVyPy5zdGF0ZW1lbnRzID8/IFtdKSBydW4ocywgc3RhdGUsIG91dHB1dCwgZXZlbnQpXG4gIHJldHVybiB7IGJ1dHRvbjogbmFtZSwgbGlzdGVuZXIsIHRleHRzOiB7IC4uLnN0YXRlLnRleHRzIH0sIGNvbnNvbGU6IG91dHB1dCB9XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBzaW11bGF0ZSh3aW46IFN3aW5nV2luZG93LCBjbGlja3M6IHN0cmluZ1tdKTogQ2xpY2tTdGVwW10ge1xuICBjb25zdCBzdGF0ZSA9IHN0YXJ0U3RhdGUod2luKVxuICByZXR1cm4gY2xpY2tzLm1hcCgoYykgPT4gY2xpY2sod2luLCBzdGF0ZSwgYykpXG59XG5cbmludGVyZmFjZSBTd2luZ0V2ZW50IHtcbiAgc291cmNlOiBzdHJpbmdcbiAgY29tbWFuZDogc3RyaW5nXG59XG5cbmZ1bmN0aW9uIHJ1bihzdGF0ZW1lbnQ6IFN3aW5nU3RhdGVtZW50LCBzdGF0ZTogU3dpbmdTdGF0ZSwgb3V0cHV0OiBzdHJpbmdbXSwgZXZlbnQ6IFN3aW5nRXZlbnQpIHtcbiAgaWYgKHR5cGVvZiBzdGF0ZW1lbnQgIT09ICdzdHJpbmcnKSB7XG4gICAgZm9yIChjb25zdCBzIG9mIGNvbmRpdGlvbihzdGF0ZW1lbnQuY29uZGl0aW9uLCBzdGF0ZSwgZXZlbnQpID8gc3RhdGVtZW50LnRoZW4gOiBzdGF0ZW1lbnQub3RoZXJ3aXNlKSBydW4ocywgc3RhdGUsIG91dHB1dCwgZXZlbnQpXG4gICAgcmV0dXJuXG4gIH1cbiAgbGV0IG06IFJlZ0V4cEV4ZWNBcnJheSB8IG51bGxcbiAgaWYgKChtID0gL14oXFx3KylcXC5zZXRUZXh0XFwoKC4qKVxcKSQvLmV4ZWMoc3RhdGVtZW50KSkpIHtcbiAgICBpZiAoIShtWzFdIGluIHN0YXRlLnRleHRzKSkgdGhyb3cgbmV3IEVycm9yKGAke21bMV19IGlzdCBrZWluZSBCZXNjaHJpZnR1bmcgdW5kIGtlaW4gS25vcGYuYClcbiAgICBzdGF0ZS50ZXh0c1ttWzFdXSA9IFN0cmluZyhldmFsdWF0ZShtWzJdLCBzdGF0ZSwgZXZlbnQpKVxuICB9IGVsc2UgaWYgKChtID0gL15TeXN0ZW1cXC5vdXRcXC5wcmludGxuXFwoKC4qKVxcKSQvLmV4ZWMoc3RhdGVtZW50KSkpIG91dHB1dC5wdXNoKFN0cmluZyhldmFsdWF0ZShtWzFdLCBzdGF0ZSwgZXZlbnQpKSlcbiAgZWxzZSBpZiAoKG0gPSAvXihcXHcrKVxccyooXFwrXFwrfC0tKSQvLmV4ZWMoc3RhdGVtZW50KSkpIHN0YXRlLmludHNbaW50TmFtZShtWzFdLCBzdGF0ZSldICs9IG1bMl0gPT09ICcrKycgPyAxIDogLTFcbiAgZWxzZSBpZiAoKG0gPSAvXihcXHcrKVxccyooWystXT89KVxccyooLispJC8uZXhlYyhzdGF0ZW1lbnQpKSkge1xuICAgIGNvbnN0IG5hbWUgPSBpbnROYW1lKG1bMV0sIHN0YXRlKVxuICAgIGNvbnN0IHZhbHVlID0gTnVtYmVyKGV2YWx1YXRlKG1bM10sIHN0YXRlLCBldmVudCkpXG4gICAgc3RhdGUuaW50c1tuYW1lXSA9IG1bMl0gPT09ICc9JyA/IHZhbHVlIDogbVsyXSA9PT0gJys9JyA/IHN0YXRlLmludHNbbmFtZV0gKyB2YWx1ZSA6IHN0YXRlLmludHNbbmFtZV0gLSB2YWx1ZVxuICB9IGVsc2UgdGhyb3cgbmV3IEVycm9yKGBEaWVzZSBBbndlaXN1bmcga2FubiBkYXMgU3BpZWwgbmljaHQgbmFjaHNwaWVsZW46IOKAniR7c3RhdGVtZW50feKAnGApXG59XG5cbi8qKiBgZS5nZXRTb3VyY2UoKSA9PSBrbm9wZmAsIGB0ZXh0LmVxdWFscyhcIitcIilgLCBgemFobCA+IDNgICovXG5mdW5jdGlvbiBjb25kaXRpb24odGV4dDogc3RyaW5nLCBzdGF0ZTogU3dpbmdTdGF0ZSwgZXZlbnQ6IFN3aW5nRXZlbnQpOiBib29sZWFuIHtcbiAgbGV0IG06IFJlZ0V4cEV4ZWNBcnJheSB8IG51bGxcbiAgaWYgKChtID0gL15lXFwuZ2V0U291cmNlXFwoXFwpXFxzKig9PXwhPSlcXHMqKFxcdyspJC8uZXhlYyh0ZXh0KSkpIHtcbiAgICBpZiAoIShtWzJdIGluIHN0YXRlLnRleHRzKSkgdGhyb3cgbmV3IEVycm9yKGAke21bMl19IGlzdCBrZWluIEtub3BmLmApXG4gICAgcmV0dXJuIChldmVudC5zb3VyY2UgPT09IG1bMl0pID09PSAobVsxXSA9PT0gJz09JylcbiAgfVxuICBpZiAoKG0gPSAvXighPykoLispXFwuZXF1YWxzXFwoKC4rKVxcKSQvLmV4ZWModGV4dCkpKSByZXR1cm4gKFN0cmluZyhldmFsdWF0ZShtWzJdLCBzdGF0ZSwgZXZlbnQpKSA9PT0gU3RyaW5nKGV2YWx1YXRlKG1bM10sIHN0YXRlLCBldmVudCkpKSAhPT0gKG1bMV0gPT09ICchJylcbiAgaWYgKChtID0gL14oLis/KVxccyooPT18IT18PD18Pj18PHw+KVxccyooLispJC8uZXhlYyh0ZXh0KSkpIHtcbiAgICBjb25zdCBhID0gTnVtYmVyKGV2YWx1YXRlKG1bMV0sIHN0YXRlLCBldmVudCkpXG4gICAgY29uc3QgYiA9IE51bWJlcihldmFsdWF0ZShtWzNdLCBzdGF0ZSwgZXZlbnQpKVxuICAgIHJldHVybiB7ICc9PSc6IGEgPT09IGIsICchPSc6IGEgIT09IGIsICc8PSc6IGEgPD0gYiwgJz49JzogYSA+PSBiLCAnPCc6IGEgPCBiLCAnPic6IGEgPiBiIH1bbVsyXV0hXG4gIH1cbiAgdGhyb3cgbmV3IEVycm9yKGBEaWVzZSBCZWRpbmd1bmcga2FubiBkYXMgU3BpZWwgbmljaHQgbmFjaHNwaWVsZW46IOKAniR7dGV4dH3igJxgKVxufVxuXG5mdW5jdGlvbiBpbnROYW1lKG5hbWU6IHN0cmluZywgc3RhdGU6IFN3aW5nU3RhdGUpOiBzdHJpbmcge1xuICBpZiAoIShuYW1lIGluIHN0YXRlLmludHMpKSB0aHJvdyBuZXcgRXJyb3IoYFZhcmlhYmxlICR7bmFtZX0gaXN0IG5pY2h0IGFuZ2VsZWd0LmApXG4gIHJldHVybiBuYW1lXG59XG5cbi8qKiBgXCJUZXh0XCIgKyB6YWhsYCwgYFwiXCIgKyAoYSArIGIpYCwgYHphaGwgKiAyYCwgYGUuZ2V0QWN0aW9uQ29tbWFuZCgpYDogdm9uIGxpbmtzIG5hY2ggcmVjaHRzIHdpZSBpbiBKYXZhLiAqL1xuZnVuY3Rpb24gZXZhbHVhdGUoZXhwcjogc3RyaW5nLCBzdGF0ZTogU3dpbmdTdGF0ZSwgZXZlbnQ/OiBTd2luZ0V2ZW50KTogc3RyaW5nIHwgbnVtYmVyIHtcbiAgY29uc3QgdG9rZW5zID0gZXhwci5tYXRjaChuZXcgUmVnRXhwKGAke3N0cn18XFxcXGQrfGVcXFxcLmdldEFjdGlvbkNvbW1hbmRcXFxcKFxcXFwpfFxcXFx3Kyg/OlxcXFwuZ2V0VGV4dFxcXFwoXFxcXCkpP3xbLSsqLygpXWAsICdnJykpID8/IFtdXG4gIGxldCBwb3MgPSAwXG4gIGNvbnN0IGF0b20gPSAoKTogc3RyaW5nIHwgbnVtYmVyID0+IHtcbiAgICBjb25zdCB0b2sgPSB0b2tlbnNbcG9zKytdXG4gICAgaWYgKHRvayA9PT0gdW5kZWZpbmVkKSB0aHJvdyBuZXcgRXJyb3IoYFVudm9sbHN0w6RuZGlnZXIgQXVzZHJ1Y2sg4oCeJHtleHByfeKAnGApXG4gICAgaWYgKHRvayA9PT0gJygnKSB7XG4gICAgICBjb25zdCB2ID0gc3VtKClcbiAgICAgIHBvcysrXG4gICAgICByZXR1cm4gdlxuICAgIH1cbiAgICBpZiAodG9rLnN0YXJ0c1dpdGgoJ1wiJykpIHJldHVybiBKU09OLnBhcnNlKHRvaylcbiAgICBpZiAoL15cXGQrJC8udGVzdCh0b2spKSByZXR1cm4gTnVtYmVyKHRvaylcbiAgICBpZiAodG9rID09PSAnZS5nZXRBY3Rpb25Db21tYW5kKCknKSB7XG4gICAgICBpZiAoIWV2ZW50KSB0aHJvdyBuZXcgRXJyb3IoJ2UuZ2V0QWN0aW9uQ29tbWFuZCgpIGdpYnQgZXMgbnVyIGltIFp1aMO2cmVyLicpXG4gICAgICByZXR1cm4gZXZlbnQuY29tbWFuZFxuICAgIH1cbiAgICBpZiAodG9rLmVuZHNXaXRoKCcuZ2V0VGV4dCgpJykpIHJldHVybiBzdGF0ZS50ZXh0c1t0b2suc2xpY2UoMCwgLTEwKV0gPz8gJydcbiAgICBpZiAodG9rIGluIHN0YXRlLmludHMpIHJldHVybiBzdGF0ZS5pbnRzW3Rva11cbiAgICB0aHJvdyBuZXcgRXJyb3IoYFVuYmVrYW5udDog4oCeJHt0b2t94oCcYClcbiAgfVxuICBjb25zdCBwcm9kdWN0ID0gKCk6IHN0cmluZyB8IG51bWJlciA9PiB7XG4gICAgbGV0IHYgPSBhdG9tKClcbiAgICB3aGlsZSAodG9rZW5zW3Bvc10gPT09ICcqJyB8fCB0b2tlbnNbcG9zXSA9PT0gJy8nKSB7XG4gICAgICBjb25zdCBvcCA9IHRva2Vuc1twb3MrK11cbiAgICAgIGNvbnN0IHIgPSBOdW1iZXIoYXRvbSgpKVxuICAgICAgdiA9IG9wID09PSAnKicgPyBOdW1iZXIodikgKiByIDogTWF0aC50cnVuYyhOdW1iZXIodikgLyByKVxuICAgIH1cbiAgICByZXR1cm4gdlxuICB9XG4gIGNvbnN0IHN1bSA9ICgpOiBzdHJpbmcgfCBudW1iZXIgPT4ge1xuICAgIGxldCB2ID0gcHJvZHVjdCgpXG4gICAgd2hpbGUgKHRva2Vuc1twb3NdID09PSAnKycgfHwgdG9rZW5zW3Bvc10gPT09ICctJykge1xuICAgICAgY29uc3Qgb3AgPSB0b2tlbnNbcG9zKytdXG4gICAgICBjb25zdCByID0gcHJvZHVjdCgpXG4gICAgICBpZiAob3AgPT09ICcrJykgdiA9IHR5cGVvZiB2ID09PSAnc3RyaW5nJyB8fCB0eXBlb2YgciA9PT0gJ3N0cmluZycgPyBgJHt2fSR7cn1gIDogdiArIHJcbiAgICAgIGVsc2UgdiA9IE51bWJlcih2KSAtIE51bWJlcihyKVxuICAgIH1cbiAgICByZXR1cm4gdlxuICB9XG4gIHJldHVybiBzdW0oKVxufVxuIl0sImZpbGUiOiIvd2ViL3NyYy9sZWFybi9yb3VuZEdhbWUudHMifQ== - -//# vitestCache=W3siZmlsZSI6IjEiLCJpZCI6IjEiLCJ1cmwiOiIyIiwiaW1wb3J0cyI6IjMiLCJtYXBwaW5ncyI6ZmFsc2UsImRlcHMiOiI0IiwiZHluYW1pY0RlcHMiOiI1Iiwic3RhdGljTW9ja3MiOm51bGx9LCIvaG9tZS91c2VyL3Zpc3VzdHJ1Y3Qtc3dpZnR1aS93ZWIvc3JjL2xlYXJuL3JvdW5kR2FtZS50cyIsIi93ZWIvc3JjL2xlYXJuL3JvdW5kR2FtZS50cyIseyJ1cmxzIjoiNiIsImlkcyI6IjcifSxbXSxbXSxbXSx7fV0= \ No newline at end of file diff --git a/node_modules/.vitest-cache/CACHEDIR.TAG b/node_modules/.vitest-cache/CACHEDIR.TAG deleted file mode 100644 index 8c1ef4ce..00000000 --- a/node_modules/.vitest-cache/CACHEDIR.TAG +++ /dev/null @@ -1,3 +0,0 @@ -Signature: 8a477f597d28d172789f06886806bc55 -# This file is a cache directory tag created by Vitest. -# For information about cache directory tags see https://bford.info/cachedir/ diff --git a/node_modules/.vitest-cache/_metadata.json b/node_modules/.vitest-cache/_metadata.json deleted file mode 100644 index 9ee9061a..00000000 --- a/node_modules/.vitest-cache/_metadata.json +++ /dev/null @@ -1,3 +0,0 @@ -{ - "lockfileHash": "e3b0c442" -} \ No newline at end of file diff --git a/node_modules/.vitest-cache/a24f3c2d2711027964cf8cac3e5bdea117013f42 b/node_modules/.vitest-cache/a24f3c2d2711027964cf8cac3e5bdea117013f42 deleted file mode 100644 index 83c183a5..00000000 --- a/node_modules/.vitest-cache/a24f3c2d2711027964cf8cac3e5bdea117013f42 +++ /dev/null @@ -1,587 +0,0 @@ -__vite_ssr_exportName__("MBOT_LED_COUNT", () => { try { return MBOT_LED_COUNT } catch {} }); -__vite_ssr_exportName__("MBOT_LED_COLORS", () => { try { return MBOT_LED_COLORS } catch {} }); -__vite_ssr_exportName__("MBOT_EMOTIONS", () => { try { return MBOT_EMOTIONS } catch {} }); -__vite_ssr_exportName__("MBOT_STEP_CM", () => { try { return MBOT_STEP_CM } catch {} }); -__vite_ssr_exportName__("MBOT_COMMANDS", () => { try { return MBOT_COMMANDS } catch {} }); -__vite_ssr_exportName__("MBOT_COLORS", () => { try { return MBOT_COLORS } catch {} }); -__vite_ssr_exportName__("setMBotColorLanguage", () => { try { return setMBotColorLanguage } catch {} }); -__vite_ssr_exportName__("mbotColorLanguage", () => { try { return mbotColorLanguage } catch {} }); -__vite_ssr_exportName__("mbotColorName", () => { try { return mbotColorName } catch {} }); -__vite_ssr_exportName__("MBOT_SENSORS", () => { try { return MBOT_SENSORS } catch {} }); -__vite_ssr_exportName__("usedMBotSensors", () => { try { return usedMBotSensors } catch {} }); -__vite_ssr_exportName__("parseMBotCommand", () => { try { return parseMBotCommand } catch {} }); -__vite_ssr_exportName__("mbotArguments", () => { try { return mbotArguments } catch {} }); -__vite_ssr_exportName__("makeMBotAction", () => { try { return makeMBotAction } catch {} }); -__vite_ssr_exportName__("actionSignature", () => { try { return actionSignature } catch {} }); -__vite_ssr_exportName__("parseActionSpec", () => { try { return parseActionSpec } catch {} }); -__vite_ssr_exportName__("substituteMBotSensors", () => { try { return substituteMBotSensors } catch {} }); -__vite_ssr_exportName__("driveSignature", () => { try { return driveSignature } catch {} }); -__vite_ssr_exportName__("parseDriveSpec", () => { try { return parseDriveSpec } catch {} }); -__vite_ssr_exportName__("compressDrive", () => { try { return compressDrive } catch {} }); -__vite_ssr_exportName__("MBOT_PARTS", () => { try { return MBOT_PARTS } catch {} }); -__vite_ssr_exportName__("isMBotPart", () => { try { return isMBotPart } catch {} }); -const __vite_ssr_import_0__ = await __vite_ssr_import__("/web/src/core/mbotLink.ts", {"importedNames":["showLabel"]}); - -/** Der CyberPi hat fünf LEDs; in Java zählen sie wie Arrays ab 0 (`mbot.led(0)` bis `mbot.led(4)`), die Firmware ab 1. */ -const MBOT_LED_COUNT = 5; -const ledNumber = (nr) => Number.isInteger(nr) && nr >= 0 && nr < MBOT_LED_COUNT; -/** Farben für `mbot.led(i).setColor("grün")`, deutsch und englisch; „aus“ schaltet die LED aus. */ -const MBOT_LED_COLORS = { - rot: [ - 255, - 0, - 0 - ], - red: [ - 255, - 0, - 0 - ], - orange: [ - 255, - 100, - 0 - ], - gelb: [ - 255, - 200, - 0 - ], - yellow: [ - 255, - 200, - 0 - ], - grün: [ - 0, - 255, - 0 - ], - green: [ - 0, - 255, - 0 - ], - türkis: [ - 0, - 200, - 200 - ], - cyan: [ - 0, - 200, - 200 - ], - blau: [ - 0, - 0, - 255 - ], - blue: [ - 0, - 0, - 255 - ], - lila: [ - 160, - 0, - 255 - ], - purple: [ - 160, - 0, - 255 - ], - pink: [ - 255, - 0, - 120 - ], - weiß: [ - 255, - 255, - 255 - ], - white: [ - 255, - 255, - 255 - ], - aus: [ - 0, - 0, - 0 - ], - off: [ - 0, - 0, - 0 - ] -}; -/** -* Vorführungen der Firmware (`cyberpi.emotion.*`): LEDs, Ton und kleine Bewegungen, am echten mBot2 getestet mit `smile`. -* `sprint` fehlt absichtlich, weil der Roboter dabei losfährt. -*/ -const MBOT_EMOTIONS = [ - "smile", - "hello", - "yeah", - "proud", - "wow", - "yummy", - "naughty", - "uh_oh", - "hurt", - "sad", - "angry", - "startle", - "shiver", - "dizzy", - "sleepy", - "zzz", - "wake_up", - "blink", - "yes", - "no", - "look_up", - "look_down", - "look_left", - "look_right", - "look_around" -]; -/** Ein Schritt von `mbot.forward()` ohne Zahl. */ -const MBOT_STEP_CM = 10; -const n = (v) => String(Math.round(v * 100) / 100); -/** Befehle (Anweisungen). Drehen: positiver Winkel bei `mbot2.turn` dreht nach rechts. */ -const MBOT_COMMANDS = { - forward: { - args: 1, - defaults: [MBOT_STEP_CM], - python: ([cm]) => `mbot2.straight(${n(cm)})`, - label: ([cm]) => `${n(cm)} cm vorwärts` - }, - backward: { - args: 1, - defaults: [MBOT_STEP_CM], - python: ([cm]) => `mbot2.straight(${n(-cm)})`, - label: ([cm]) => `${n(cm)} cm rückwärts` - }, - turnLeft: { - args: 1, - defaults: [90], - python: ([deg]) => `mbot2.turn(${n(-deg)})`, - label: ([deg]) => `${n(deg)}° nach links drehen` - }, - turnRight: { - args: 1, - defaults: [90], - python: ([deg]) => `mbot2.turn(${n(deg)})`, - label: ([deg]) => `${n(deg)}° nach rechts drehen` - }, - stop: { - args: 0, - python: () => `mbot2.EM_stop("ALL")`, - label: () => "anhalten" - }, - /** - * Räder einzeln, Leistung in Prozent (−100 … 100); er fährt weiter, bis ein anderer Fahrbefehl oder `stop()` kommt. - * Der rechte Motor ist am mBot2 gespiegelt eingebaut, deshalb das Minus. - */ - drive: { - args: 2, - python: ([l, r]) => `mbot2.drive_power(${n(l)}, ${n(-r)})`, - label: ([l, r]) => `Räder links ${n(l)} %, rechts ${n(r)} %` - }, - setLed: { - args: 3, - python: ([r, g, b]) => `cyberpi.led.on(${n(r)}, ${n(g)}, ${n(b)})`, - label: ([r, g, b]) => `LEDs (${n(r)}, ${n(g)}, ${n(b)})` - }, - ledOff: { - args: 0, - python: () => "cyberpi.led.off()", - label: () => "LEDs aus" - }, - /** `mbot.led(i).setColor("grün")`: eine LED (0–4); aus ist `on(0, 0, 0)`. */ - ledColor: { - args: 1, - text: true, - choices: Object.keys(MBOT_LED_COLORS), - valid: ([nr]) => ledNumber(nr), - python: ([nr], color) => `cyberpi.led.on(${MBOT_LED_COLORS[color].join(", ")}, id=${nr + 1})`, - label: ([nr], color) => `LED ${nr}: ${color}` - }, - playTone: { - args: 2, - python: ([hz, ms]) => `cyberpi.audio.play_tone(${n(hz)}, ${n(ms / 1e3)})`, - label: ([hz, ms]) => `Ton ${n(hz)} Hz, ${n(ms)} ms` - }, - pause: { - args: 1, - label: ([ms]) => `${n(ms)} ms warten` - }, - resetTimer: { - args: 0, - python: () => "cyberpi.timer.reset()", - label: () => "Stoppuhr auf 0" - }, - emotion: { - args: 0, - text: true, - choices: MBOT_EMOTIONS, - python: (_, name) => `cyberpi.emotion.${name}()`, - label: (_, name) => `Gefühl: ${name}` - }, - showText: { - args: 0, - text: true, - python: (_, text) => (0,__vite_ssr_import_0__.showLabel)(text), - label: (_, text) => `Bildschirm: ${text}` - } -}; -/** Farben, die der Quad-RGB-Sensor im Simulator erkennt (Felder `r g b y` in einer Weltkarte). */ -const MBOT_COLORS = [ - "red", - "green", - "blue", - "yellow" -]; -/** Farbnamen von `mbot.getColor()`: wie bei `setColor`, Deutsch oder Englisch je nach Sprache der Lektionen. */ -const COLOR_NAMES = { - red: { - de: "rot", - en: "red" - }, - green: { - de: "grün", - en: "green" - }, - blue: { - de: "blau", - en: "blue" - }, - yellow: { - de: "gelb", - en: "yellow" - }, - cyan: { - de: "türkis", - en: "cyan" - }, - purple: { - de: "lila", - en: "purple" - }, - white: { - de: "weiß", - en: "white" - }, - black: { - de: "schwarz", - en: "black" - } -}; -let colorLanguage = "en"; -/** Sprache der Farbnamen, die `mbot.getColor()` liefert (Deutsch nur bei deutschen Lektionen). */ -function setMBotColorLanguage(language) { - colorLanguage = language === "de" ? "de" : "en"; -}; -const mbotColorLanguage = () => colorLanguage; -/** `red`, `rot` oder eine Antwort des echten Sensors → Farbname in der aktuellen Sprache. */ -function mbotColorName(color) { - const key = color.trim().toLowerCase(); - const entry = COLOR_NAMES[key] ?? Object.values(COLOR_NAMES).find((e) => e.de === key); - return entry ? entry[colorLanguage] : key; -}; -const press = (key) => ({ - python: `cyberpi.controller.is_press('${key}')`, - simulated: false -}); -/** -* Sensoren (Ausdrücke ohne Argumente): Zahlen oder Wahrheitswerte. -* Der Python-Text liest den Wert am echten mBot2 (Modus 1, Antwort `{"ret":…}`). -*/ -const MBOT_SENSORS = { - getDistance: { - python: "mbuild.ultrasonic2.get(1)", - simulated: 100 - }, - getLine: { - python: "mbuild.quad_rgb_sensor.get_line_sta('all', 1)", - simulated: 0 - }, - // die beiden mittleren Fühler (L1, R1) des Liniensensors - isLineLeft: { - python: "mbuild.quad_rgb_sensor.is_line('L1', 1)", - simulated: false - }, - isLineRight: { - python: "mbuild.quad_rgb_sensor.is_line('R1', 1)", - simulated: false - }, - /** Farbe unter dem mBot2 als Text: `mbot.getColor().equals("rot")` */ - getColor: { - python: "mbuild.quad_rgb_sensor.get_color_sta('L1', 1)", - simulated: "white" - }, - isButtonA: press("a"), - isButtonB: press("b"), - isJoystickUp: press("up"), - isJoystickDown: press("down"), - isJoystickLeft: press("left"), - isJoystickRight: press("right"), - getBrightness: { - python: "cyberpi.get_bri()", - simulated: 50 - }, - getLoudness: { - python: "cyberpi.get_loudness('maximum')", - simulated: 0 - }, - getPitch: { - python: "cyberpi.get_pitch()", - simulated: 0 - }, - getRoll: { - python: "cyberpi.get_roll()", - simulated: 0 - }, - isShaken: { - python: "cyberpi.is_shake()", - simulated: false - }, - getBattery: { - python: "cyberpi.get_battery()", - simulated: 100 - }, - /** Sekunden seit dem Start bzw. seit `resetTimer()` */ - getTimer: { - python: "cyberpi.timer.get()", - simulated: 0 - } -}; -/** Welche Sensoren kommen in diesem Text vor (z. B. im ganzen Diagramm)? */ -function usedMBotSensors(text) { - const found = new Set(); - for (const m of text.matchAll(/\bmbot\s*\.\s*([A-Za-z_]\w*)\s*\(\s*\)/gu)) if (m[1] in MBOT_SENSORS) found.add(m[1]); - return [...found]; -}; -/** `mbot.forward(10)` → Name und Argumenttexte; `undefined`, wenn es kein mBot-Befehl ist. */ -function parseMBotCommand(text) { - // `mbot.led(i).setColor("grün")` wird zu `ledColor(i, "grün")` - const led = /^mbot\s*\.\s*led\s*\(([^()]*(?:\([^()]*\)[^()]*)*)\)\s*\.\s*setColor\s*\(([\s\S]*)\)\s*;?$/u.exec(text.trim()); - if (led) return { - method: "ledColor", - args: [led[1].trim(), led[2].trim()] - }; - const m = /^mbot\s*\.\s*([A-Za-z_]\w*)\s*\(([\s\S]*)\)\s*;?$/u.exec(text.trim()); - if (!m) return undefined; - const inner = m[2].trim(); - return { - method: m[1], - args: inner === "" ? [] : splitArgs(inner) - }; -}; -/** Argumente prüfen und leere Klammern mit den Standardwerten füllen; `undefined` bei falscher Anzahl. */ -function mbotArguments(method, args) { - const spec = MBOT_COMMANDS[method]; - if (!spec) return undefined; - const values = args.length === 0 && spec.defaults ? spec.defaults : args; - if (values.length !== spec.args) return undefined; - return !spec.valid || spec.valid(values) ? values : undefined; -}; -function makeMBotAction(method, args, text = "") { - const spec = MBOT_COMMANDS[method]; - return { - method, - args, - python: spec.python?.(args, text), - waitMs: method === "pause" ? Math.max(0, args[0]) : undefined, - label: spec.label(args, text), - ...spec.text ? { text } : {} - }; -}; -/** -* Alle Befehle als Liste wie `setLed 255 0 0`, `pause 500`, `showText "Hallo"` (zum Prüfen von LEDs, Tönen und Bildschirm). -* Anders als `driveSignature` wird nichts zusammengefasst. -*/ -function actionSignature(actions) { - return actions.map((a) => [ - a.method, - ...a.args.map(n), - ...a.text !== undefined ? [JSON.stringify(a.text)] : [] - ].join(" ")); -}; -/** Erwartete Befehle einer Übung, z. B. `befehle: 3 x (setLed 255 0 0, pause 500, ledOff, pause 500)`; Texte in Anführungszeichen. */ -function parseActionSpec(spec) { - let i = 0; - const src = spec.trim(); - const list = () => { - const items = []; - for (;;) { - while (src[i] === " " || src[i] === ",") i++; - if (i >= src.length || src[i] === ")") return items; - const rep = /^(\d+)\s*[x×]\s*\(/u.exec(src.slice(i)); - if (rep) { - i += rep[0].length; - const inner = list(); - if (src[i] !== ")") throw new Error(`„)“ fehlt in „${spec}“`); - i++; - for (let k = 0; k < Number(rep[1]); k++) items.push(...inner); - continue; - }; - const step = /^([A-Za-z]+)((?:\s+-?\d+(?:\.\d+)?)*)(?:\s+("(?:[^"\\]|\\.)*"))?/u.exec(src.slice(i)); - if (!step) throw new Error(`Unbekannt in „${spec}“: ${src.slice(i)}`); - i += step[0].length; - const spec_ = MBOT_COMMANDS[step[1]]; - if (!spec_) throw new Error(`Unbekannter Befehl in „${spec}“: ${step[1]}`); - const nums = step[2].trim() === "" ? [] : step[2].trim().split(/\s+/).map(Number); - const args = mbotArguments(step[1], nums); - if (!args) throw new Error(`Falsche Anzahl Zahlen in „${spec}“: ${step[1]}`); - items.push(actionSignature([{ - method: step[1], - args, - text: spec_.text ? JSON.parse(step[3] ?? "\"\"") : undefined - }])[0]); - } - }; - const items = list(); - if (i < src.length) throw new Error(`Zu viele „)“ in „${spec}“`); - return items; -}; -/** Ersetzt `mbot.getDistance()` usw. durch Zahlen, damit der Rechner sie wie Literale liest. */ -function substituteMBotSensors(expression, read) { - if (!expression.includes("mbot")) return expression; - return expression.replace(/\bmbot\s*\.\s*([A-Za-z_]\w*)\s*\(\s*\)/gu, (all, name) => { - if (!(name in MBOT_SENSORS)) return all; - const value = read(name); - return typeof value === "string" ? JSON.stringify(name === "getColor" ? mbotColorName(value) : value) : String(value); - }); -}; -/** Argumente an Kommas auf oberster Ebene trennen (nicht in Klammern oder Texten). */ -function splitArgs(text) { - const parts = []; - let depth = 0; - let quote = false; - let start = 0; - for (let i = 0; i < text.length; i++) { - const c = text[i]; - if (quote) { - if (c === "\\") i++; - else if (c === "\"") quote = false; - } else if (c === "\"") quote = true; - else if (c === "(" || c === "[") depth++; - else if (c === ")" || c === "]") depth--; - else if (c === "," && depth === 0) { - parts.push(text.slice(start, i).trim()); - start = i + 1; - } - }; - parts.push(text.slice(start).trim()); - return parts; -} -/** -* Gefahrene Strecke als Liste wie `forward 50`, `turnRight 90`: aufeinanderfolgende Fahrten bzw. Drehungen -* zusammengefasst, LEDs und Töne zählen nicht. So ist `5 × forward()` dasselbe wie `forward(50)`. -*/ -function driveSignature(actions) { - const out = []; - for (const a of actions) { - const value = { - forward: a.args[0], - backward: -a.args[0], - turnRight: a.args[0], - turnLeft: -a.args[0] - }[a.method]; - if (value === undefined) continue; - const kind = a.method === "forward" || a.method === "backward" ? "drive" : "turn"; - const last = out[out.length - 1]; - if (last && last.kind === kind) last.value += value; - else out.push({ - kind, - value - }); - }; - return out.flatMap(({ kind, value }) => { - const v = kind === "turn" ? ((value + 180) % 360 + 360) % 360 - 180 : value; - if (Math.abs(v) < 1e-6) return []; - const r = Math.round(Math.abs(v) * 100) / 100; - if (kind === "drive") return [`${v > 0 ? "forward" : "backward"} ${r}`]; - return [v === -180 ? "turnRight 180" : `${v > 0 ? "turnRight" : "turnLeft"} ${r}`]; - }); -}; -/** -* Erwartete Fahrt einer Übung, z. B. `fahrt: 4 x (forward 50, turnRight 90)`. Teile durch Kommas getrennt, -* `n x (…)` wiederholt; ohne Zahl gelten die Werte von `mbot.forward()` bzw. `turnRight()`. -*/ -function parseDriveSpec(spec) { - let i = 0; - const src = spec.trim(); - const list = () => { - const items = []; - for (;;) { - while (src[i] === " " || src[i] === ",") i++; - if (i >= src.length || src[i] === ")") return items; - const rep = /^(\d+)\s*[x×]\s*\(/u.exec(src.slice(i)); - if (rep) { - i += rep[0].length; - const inner = list(); - if (src[i] !== ")") throw new Error(`„)“ fehlt in „${spec}“`); - i++; - for (let k = 0; k < Number(rep[1]); k++) items.push(...inner); - continue; - }; - const step = /^([A-Za-z]+)(?:\s+(-?\d+(?:\.\d+)?))?/u.exec(src.slice(i)); - if (!step) throw new Error(`Unbekannt in „${spec}“: ${src.slice(i)}`); - i += step[0].length; - const args = mbotArguments(step[1], step[2] === undefined ? [] : [Number(step[2])]); - if (!args) throw new Error(`Unbekannter Befehl in „${spec}“: ${step[1]}`); - items.push({ - method: step[1], - args - }); - } - }; - const items = list(); - if (i < src.length) throw new Error(`Zu viele „)“ in „${spec}“`); - return items; -}; -/** Fahrt kurz zum Anzeigen: Wiederholungen als `4 x (forward 50, turnRight 90)`, auch verschachtelt. */ -function compressDrive(drive) { - const n = drive.length; - for (let unit = 1; unit <= n / 2; unit++) { - if (n % unit !== 0) continue; - const times = n / unit; - if (drive.every((s, i) => s === drive[i % unit])) { - const inner = compressDrive(drive.slice(0, unit)); - return `${times} x ${unit === 1 ? inner : `(${inner})`}`; - } - }; - return drive.join(", "); -}; -/** -* Teile des mBot2 im 3D-Modell, z. B. für `fokus:` im Lektionsblock `::: mbot2` und `[Wort]{teil=cyberpi}` im Text. -* Die ersten acht gehören zum CyberPi; `cyberpi` allein ist sein Gehäuse. -*/ -const MBOT_PARTS = [ - "cyberpi", - "screen", - "joystick", - "buttons", - "leds", - "lightSensor", - "microphone", - "shield", - "powerSwitch", - "motors", - "wheels", - "ultrasonic", - "lineSensor", - "caster", - "chassis" -]; -const isMBotPart = (name) => MBOT_PARTS.includes(name); -//# sourceMappingSource=vite-generated -//# sourceMappingURL=data:application/json;base64,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O0NBQ0E7Q0FDQTtDQUNBO0NBQ0E7Q0FDQTtDQUNBO0NBQ0E7Q0FDQTtDQUNBO0FBQ0Y7QUFJTyxNQUFNLGNBQWMsU0FBb0MsV0FBaUMsU0FBUyxJQUFJIiwibmFtZXMiOltdLCJpZ25vcmVMaXN0IjpbXSwic291cmNlcyI6WyJtYm90LnRzIl0sInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IHNob3dMYWJlbCB9IGZyb20gJy4vbWJvdExpbmsnXG5cbi8qKlxuICogbUJvdDIgKE1ha2VibG9jaywgbWl0IEN5YmVyUGkpIGltIFN0cnVrdG9ncmFtbS4gQmVmZWhsZSBzdGVoZW4gYWxzIEFud2Vpc3VuZyBgbWJvdC5mb3J3YXJkKDEwKWAsXG4gKiBTZW5zb3JlbiBhbHMgQXVzZHJ1Y2sgYG1ib3QuZ2V0RGlzdGFuY2UoKWAuIERpZSBTaW11bGF0aW9uIG1lcmt0IHNpY2ggamVkZW4gQmVmZWhsIGFscyBgTUJvdEFjdGlvbmA7XG4gKiBtaXQgYW5nZXNjaGxvc3NlbmVtIFJvYm90ZXIgc2NoaWNrdCBkaWUgT2JlcmZsw6RjaGUgZGVuIFB5dGhvbi1UZXh0IGFuIGRlbiBDeWJlclBpLlxuICovXG5cbmV4cG9ydCBpbnRlcmZhY2UgTUJvdEFjdGlvbiB7XG4gIG1ldGhvZDogc3RyaW5nXG4gIGFyZ3M6IG51bWJlcltdXG4gIC8qKiBaZWlsZSBmw7xyIGRpZSBNYWtlYmxvY2stRmlybXdhcmU7IGB1bmRlZmluZWRgLCB3ZW5uIGRlciBCcm93c2VyIHNlbGJzdCB3YXJ0ZXQgKGBwYXVzZWApLiAqL1xuICBweXRob24/OiBzdHJpbmdcbiAgLyoqIFdhcnRlemVpdCBpbSBCcm93c2VyIGluIE1pbGxpc2VrdW5kZW4gKG51ciBgcGF1c2VgKS4gKi9cbiAgd2FpdE1zPzogbnVtYmVyXG4gIC8qKiBLdXJ6IGbDvHIgZGllIEtvbnNvbGUsIHouIEIuIOKAnjEwIGNtIHZvcnfDpHJ0c+KAnC4gKi9cbiAgbGFiZWw6IHN0cmluZ1xuICAvKiogVGV4dCBmw7xyIGRlbiBCaWxkc2NoaXJtIChgc2hvd1RleHRgKS4gKi9cbiAgdGV4dD86IHN0cmluZ1xufVxuXG5pbnRlcmZhY2UgQ29tbWFuZFNwZWMge1xuICBhcmdzOiBudW1iZXJcbiAgLyoqIFdlcnRlLCB3ZW5uIGRpZSBLbGFtbWVybiBsZWVyIGJsZWliZW46IGBtYm90LmZvcndhcmQoKWAgZsOkaHJ0IGVpbmVuIFNjaHJpdHQgKDEwIGNtKSwgYHR1cm5SaWdodCgpYCBkcmVodCA5MMKwLiAqL1xuICBkZWZhdWx0cz86IG51bWJlcltdXG4gIHB5dGhvbj86IChhOiBudW1iZXJbXSwgdGV4dDogc3RyaW5nKSA9PiBzdHJpbmdcbiAgbGFiZWw6IChhOiBudW1iZXJbXSwgdGV4dDogc3RyaW5nKSA9PiBzdHJpbmdcbiAgLyoqIERhcyBsZXR6dGUgQXJndW1lbnQgaXN0IGVpbiBUZXh0LCB6LiBCLiBgbWJvdC5zaG93VGV4dChcIkhhbGxvXCIpYDsgYGFyZ3NgIHrDpGhsdCBudXIgZGllIFphaGxlbiBkYXZvci4gKi9cbiAgdGV4dD86IGJvb2xlYW5cbiAgLyoqIEVybGF1YnRlIFRleHRlIChzb25zdCBpc3QgZGVyIEJlZmVobCB1bmfDvGx0aWcpLiAqL1xuICBjaG9pY2VzPzogcmVhZG9ubHkgc3RyaW5nW11cbiAgLyoqIFNpbmQgZGllIFphaGxlbiBlcmxhdWJ0PyAoei4gQi4gTEVELU51bW1lciAx4oCTNSkgKi9cbiAgdmFsaWQ/OiAoYTogbnVtYmVyW10pID0+IGJvb2xlYW5cbn1cblxuLyoqIERlciBDeWJlclBpIGhhdCBmw7xuZiBMRURzOyBpbiBKYXZhIHrDpGhsZW4gc2llIHdpZSBBcnJheXMgYWIgMCAoYG1ib3QubGVkKDApYCBiaXMgYG1ib3QubGVkKDQpYCksIGRpZSBGaXJtd2FyZSBhYiAxLiAqL1xuZXhwb3J0IGNvbnN0IE1CT1RfTEVEX0NPVU5UID0gNVxuY29uc3QgbGVkTnVtYmVyID0gKG5yOiBudW1iZXIpID0+IE51bWJlci5pc0ludGVnZXIobnIpICYmIG5yID49IDAgJiYgbnIgPCBNQk9UX0xFRF9DT1VOVFxuXG4vKiogRmFyYmVuIGbDvHIgYG1ib3QubGVkKGkpLnNldENvbG9yKFwiZ3LDvG5cIilgLCBkZXV0c2NoIHVuZCBlbmdsaXNjaDsg4oCeYXVz4oCcIHNjaGFsdGV0IGRpZSBMRUQgYXVzLiAqL1xuZXhwb3J0IGNvbnN0IE1CT1RfTEVEX0NPTE9SUzogUmVjb3JkPHN0cmluZywgW251bWJlciwgbnVtYmVyLCBudW1iZXJdPiA9IHtcbiAgcm90OiBbMjU1LCAwLCAwXSwgcmVkOiBbMjU1LCAwLCAwXSxcbiAgb3JhbmdlOiBbMjU1LCAxMDAsIDBdLFxuICBnZWxiOiBbMjU1LCAyMDAsIDBdLCB5ZWxsb3c6IFsyNTUsIDIwMCwgMF0sXG4gIGdyw7xuOiBbMCwgMjU1LCAwXSwgZ3JlZW46IFswLCAyNTUsIDBdLFxuICB0w7xya2lzOiBbMCwgMjAwLCAyMDBdLCBjeWFuOiBbMCwgMjAwLCAyMDBdLFxuICBibGF1OiBbMCwgMCwgMjU1XSwgYmx1ZTogWzAsIDAsIDI1NV0sXG4gIGxpbGE6IFsxNjAsIDAsIDI1NV0sIHB1cnBsZTogWzE2MCwgMCwgMjU1XSxcbiAgcGluazogWzI1NSwgMCwgMTIwXSxcbiAgd2Vpw586IFsyNTUsIDI1NSwgMjU1XSwgd2hpdGU6IFsyNTUsIDI1NSwgMjU1XSxcbiAgYXVzOiBbMCwgMCwgMF0sIG9mZjogWzAsIDAsIDBdLFxufVxuXG4vKipcbiAqIFZvcmbDvGhydW5nZW4gZGVyIEZpcm13YXJlIChgY3liZXJwaS5lbW90aW9uLipgKTogTEVEcywgVG9uIHVuZCBrbGVpbmUgQmV3ZWd1bmdlbiwgYW0gZWNodGVuIG1Cb3QyIGdldGVzdGV0IG1pdCBgc21pbGVgLlxuICogYHNwcmludGAgZmVobHQgYWJzaWNodGxpY2gsIHdlaWwgZGVyIFJvYm90ZXIgZGFiZWkgbG9zZsOkaHJ0LlxuICovXG5leHBvcnQgY29uc3QgTUJPVF9FTU9USU9OUyA9IFsnc21pbGUnLCAnaGVsbG8nLCAneWVhaCcsICdwcm91ZCcsICd3b3cnLCAneXVtbXknLCAnbmF1Z2h0eScsICd1aF9vaCcsICdodXJ0JywgJ3NhZCcsICdhbmdyeScsICdzdGFydGxlJywgJ3NoaXZlcicsICdkaXp6eScsICdzbGVlcHknLCAnenp6JywgJ3dha2VfdXAnLCAnYmxpbmsnLCAneWVzJywgJ25vJywgJ2xvb2tfdXAnLCAnbG9va19kb3duJywgJ2xvb2tfbGVmdCcsICdsb29rX3JpZ2h0JywgJ2xvb2tfYXJvdW5kJ10gYXMgY29uc3RcblxuLyoqIEVpbiBTY2hyaXR0IHZvbiBgbWJvdC5mb3J3YXJkKClgIG9obmUgWmFobC4gKi9cbmV4cG9ydCBjb25zdCBNQk9UX1NURVBfQ00gPSAxMFxuXG5jb25zdCBuID0gKHY6IG51bWJlcikgPT4gU3RyaW5nKE1hdGgucm91bmQodiAqIDEwMCkgLyAxMDApXG5cbi8qKiBCZWZlaGxlIChBbndlaXN1bmdlbikuIERyZWhlbjogcG9zaXRpdmVyIFdpbmtlbCBiZWkgYG1ib3QyLnR1cm5gIGRyZWh0IG5hY2ggcmVjaHRzLiAqL1xuZXhwb3J0IGNvbnN0IE1CT1RfQ09NTUFORFM6IFJlY29yZDxzdHJpbmcsIENvbW1hbmRTcGVjPiA9IHtcbiAgZm9yd2FyZDogeyBhcmdzOiAxLCBkZWZhdWx0czogW01CT1RfU1RFUF9DTV0sIHB5dGhvbjogKFtjbV0pID0+IGBtYm90Mi5zdHJhaWdodCgke24oY20pfSlgLCBsYWJlbDogKFtjbV0pID0+IGAke24oY20pfSBjbSB2b3J3w6RydHNgIH0sXG4gIGJhY2t3YXJkOiB7IGFyZ3M6IDEsIGRlZmF1bHRzOiBbTUJPVF9TVEVQX0NNXSwgcHl0aG9uOiAoW2NtXSkgPT4gYG1ib3QyLnN0cmFpZ2h0KCR7bigtY20pfSlgLCBsYWJlbDogKFtjbV0pID0+IGAke24oY20pfSBjbSByw7xja3fDpHJ0c2AgfSxcbiAgdHVybkxlZnQ6IHsgYXJnczogMSwgZGVmYXVsdHM6IFs5MF0sIHB5dGhvbjogKFtkZWddKSA9PiBgbWJvdDIudHVybigke24oLWRlZyl9KWAsIGxhYmVsOiAoW2RlZ10pID0+IGAke24oZGVnKX3CsCBuYWNoIGxpbmtzIGRyZWhlbmAgfSxcbiAgdHVyblJpZ2h0OiB7IGFyZ3M6IDEsIGRlZmF1bHRzOiBbOTBdLCBweXRob246IChbZGVnXSkgPT4gYG1ib3QyLnR1cm4oJHtuKGRlZyl9KWAsIGxhYmVsOiAoW2RlZ10pID0+IGAke24oZGVnKX3CsCBuYWNoIHJlY2h0cyBkcmVoZW5gIH0sXG4gIHN0b3A6IHsgYXJnczogMCwgcHl0aG9uOiAoKSA9PiBgbWJvdDIuRU1fc3RvcChcIkFMTFwiKWAsIGxhYmVsOiAoKSA9PiAnYW5oYWx0ZW4nIH0sXG4gIC8qKlxuICAgKiBSw6RkZXIgZWluemVsbiwgTGVpc3R1bmcgaW4gUHJvemVudCAo4oiSMTAwIOKApiAxMDApOyBlciBmw6RocnQgd2VpdGVyLCBiaXMgZWluIGFuZGVyZXIgRmFocmJlZmVobCBvZGVyIGBzdG9wKClgIGtvbW10LlxuICAgKiBEZXIgcmVjaHRlIE1vdG9yIGlzdCBhbSBtQm90MiBnZXNwaWVnZWx0IGVpbmdlYmF1dCwgZGVzaGFsYiBkYXMgTWludXMuXG4gICAqL1xuICBkcml2ZTogeyBhcmdzOiAyLCBweXRob246IChbbCwgcl0pID0+IGBtYm90Mi5kcml2ZV9wb3dlcigke24obCl9LCAke24oLXIpfSlgLCBsYWJlbDogKFtsLCByXSkgPT4gYFLDpGRlciBsaW5rcyAke24obCl9ICUsIHJlY2h0cyAke24ocil9ICVgIH0sXG4gIHNldExlZDogeyBhcmdzOiAzLCBweXRob246IChbciwgZywgYl0pID0+IGBjeWJlcnBpLmxlZC5vbigke24ocil9LCAke24oZyl9LCAke24oYil9KWAsIGxhYmVsOiAoW3IsIGcsIGJdKSA9PiBgTEVEcyAoJHtuKHIpfSwgJHtuKGcpfSwgJHtuKGIpfSlgIH0sXG4gIGxlZE9mZjogeyBhcmdzOiAwLCBweXRob246ICgpID0+ICdjeWJlcnBpLmxlZC5vZmYoKScsIGxhYmVsOiAoKSA9PiAnTEVEcyBhdXMnIH0sXG4gIC8qKiBgbWJvdC5sZWQoaSkuc2V0Q29sb3IoXCJncsO8blwiKWA6IGVpbmUgTEVEICgw4oCTNCk7IGF1cyBpc3QgYG9uKDAsIDAsIDApYC4gKi9cbiAgbGVkQ29sb3I6IHtcbiAgICBhcmdzOiAxLFxuICAgIHRleHQ6IHRydWUsXG4gICAgY2hvaWNlczogT2JqZWN0LmtleXMoTUJPVF9MRURfQ09MT1JTKSxcbiAgICB2YWxpZDogKFtucl0pID0+IGxlZE51bWJlcihuciksXG4gICAgcHl0aG9uOiAoW25yXSwgY29sb3IpID0+IGBjeWJlcnBpLmxlZC5vbigke01CT1RfTEVEX0NPTE9SU1tjb2xvcl0uam9pbignLCAnKX0sIGlkPSR7bnIgKyAxfSlgLFxuICAgIGxhYmVsOiAoW25yXSwgY29sb3IpID0+IGBMRUQgJHtucn06ICR7Y29sb3J9YCxcbiAgfSxcbiAgcGxheVRvbmU6IHsgYXJnczogMiwgcHl0aG9uOiAoW2h6LCBtc10pID0+IGBjeWJlcnBpLmF1ZGlvLnBsYXlfdG9uZSgke24oaHopfSwgJHtuKG1zIC8gMTAwMCl9KWAsIGxhYmVsOiAoW2h6LCBtc10pID0+IGBUb24gJHtuKGh6KX0gSHosICR7bihtcyl9IG1zYCB9LFxuICBwYXVzZTogeyBhcmdzOiAxLCBsYWJlbDogKFttc10pID0+IGAke24obXMpfSBtcyB3YXJ0ZW5gIH0sXG4gIHJlc2V0VGltZXI6IHsgYXJnczogMCwgcHl0aG9uOiAoKSA9PiAnY3liZXJwaS50aW1lci5yZXNldCgpJywgbGFiZWw6ICgpID0+ICdTdG9wcHVociBhdWYgMCcgfSxcbiAgZW1vdGlvbjogeyBhcmdzOiAwLCB0ZXh0OiB0cnVlLCBjaG9pY2VzOiBNQk9UX0VNT1RJT05TLCBweXRob246IChfLCBuYW1lKSA9PiBgY3liZXJwaS5lbW90aW9uLiR7bmFtZX0oKWAsIGxhYmVsOiAoXywgbmFtZSkgPT4gYEdlZsO8aGw6ICR7bmFtZX1gIH0sXG4gIHNob3dUZXh0OiB7IGFyZ3M6IDAsIHRleHQ6IHRydWUsIHB5dGhvbjogKF8sIHRleHQpID0+IHNob3dMYWJlbCh0ZXh0KSwgbGFiZWw6IChfLCB0ZXh0KSA9PiBgQmlsZHNjaGlybTogJHt0ZXh0fWAgfSxcbn1cblxuLyoqIE1lc3N3ZXJ0IGVpbmVzIFNlbnNvcnM6IFphaGwsIHdhaHIvZmFsc2NoIG9kZXIgVGV4dCAoRmFyYm5hbWUgYmVpIGBnZXRDb2xvcigpYCkuICovXG5leHBvcnQgdHlwZSBNQm90U2Vuc29yVmFsdWUgPSBudW1iZXIgfCBib29sZWFuIHwgc3RyaW5nXG5cbmludGVyZmFjZSBTZW5zb3JTcGVjIHtcbiAgcHl0aG9uOiBzdHJpbmdcbiAgLyoqIFdlcnQgaW4gZGVyIFNpbXVsYXRpb24sIHdlbm4gd2VkZXIgV2VsdCBub2NoIFJlZ2xlciBpaG4gbGllZmVybiAqL1xuICBzaW11bGF0ZWQ6IE1Cb3RTZW5zb3JWYWx1ZVxufVxuXG4vKiogRmFyYmVuLCBkaWUgZGVyIFF1YWQtUkdCLVNlbnNvciBpbSBTaW11bGF0b3IgZXJrZW5udCAoRmVsZGVyIGByIGcgYiB5YCBpbiBlaW5lciBXZWx0a2FydGUpLiAqL1xuZXhwb3J0IGNvbnN0IE1CT1RfQ09MT1JTID0gWydyZWQnLCAnZ3JlZW4nLCAnYmx1ZScsICd5ZWxsb3cnXSBhcyBjb25zdFxuZXhwb3J0IHR5cGUgTUJvdENvbG9yID0gKHR5cGVvZiBNQk9UX0NPTE9SUylbbnVtYmVyXVxuXG4vKiogRmFyYm5hbWVuIHZvbiBgbWJvdC5nZXRDb2xvcigpYDogd2llIGJlaSBgc2V0Q29sb3JgLCBEZXV0c2NoIG9kZXIgRW5nbGlzY2ggamUgbmFjaCBTcHJhY2hlIGRlciBMZWt0aW9uZW4uICovXG5jb25zdCBDT0xPUl9OQU1FUzogUmVjb3JkPHN0cmluZywgeyBkZTogc3RyaW5nOyBlbjogc3RyaW5nIH0+ID0ge1xuICByZWQ6IHsgZGU6ICdyb3QnLCBlbjogJ3JlZCcgfSxcbiAgZ3JlZW46IHsgZGU6ICdncsO8bicsIGVuOiAnZ3JlZW4nIH0sXG4gIGJsdWU6IHsgZGU6ICdibGF1JywgZW46ICdibHVlJyB9LFxuICB5ZWxsb3c6IHsgZGU6ICdnZWxiJywgZW46ICd5ZWxsb3cnIH0sXG4gIGN5YW46IHsgZGU6ICd0w7xya2lzJywgZW46ICdjeWFuJyB9LFxuICBwdXJwbGU6IHsgZGU6ICdsaWxhJywgZW46ICdwdXJwbGUnIH0sXG4gIHdoaXRlOiB7IGRlOiAnd2Vpw58nLCBlbjogJ3doaXRlJyB9LFxuICBibGFjazogeyBkZTogJ3NjaHdhcnonLCBlbjogJ2JsYWNrJyB9LFxufVxubGV0IGNvbG9yTGFuZ3VhZ2U6ICdkZScgfCAnZW4nID0gJ2VuJ1xuXG4vKiogU3ByYWNoZSBkZXIgRmFyYm5hbWVuLCBkaWUgYG1ib3QuZ2V0Q29sb3IoKWAgbGllZmVydCAoRGV1dHNjaCBudXIgYmVpIGRldXRzY2hlbiBMZWt0aW9uZW4pLiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHNldE1Cb3RDb2xvckxhbmd1YWdlKGxhbmd1YWdlOiBzdHJpbmcpIHtcbiAgY29sb3JMYW5ndWFnZSA9IGxhbmd1YWdlID09PSAnZGUnID8gJ2RlJyA6ICdlbidcbn1cblxuZXhwb3J0IGNvbnN0IG1ib3RDb2xvckxhbmd1YWdlID0gKCkgPT4gY29sb3JMYW5ndWFnZVxuXG4vKiogYHJlZGAsIGByb3RgIG9kZXIgZWluZSBBbnR3b3J0IGRlcyBlY2h0ZW4gU2Vuc29ycyDihpIgRmFyYm5hbWUgaW4gZGVyIGFrdHVlbGxlbiBTcHJhY2hlLiAqL1xuZXhwb3J0IGZ1bmN0aW9uIG1ib3RDb2xvck5hbWUoY29sb3I6IHN0cmluZyk6IHN0cmluZyB7XG4gIGNvbnN0IGtleSA9IGNvbG9yLnRyaW0oKS50b0xvd2VyQ2FzZSgpXG4gIGNvbnN0IGVudHJ5ID0gQ09MT1JfTkFNRVNba2V5XSA/PyBPYmplY3QudmFsdWVzKENPTE9SX05BTUVTKS5maW5kKChlKSA9PiBlLmRlID09PSBrZXkpXG4gIHJldHVybiBlbnRyeSA/IGVudHJ5W2NvbG9yTGFuZ3VhZ2VdIDoga2V5XG59XG5jb25zdCBwcmVzcyA9IChrZXk6IHN0cmluZyk6IFNlbnNvclNwZWMgPT4gKHsgcHl0aG9uOiBgY3liZXJwaS5jb250cm9sbGVyLmlzX3ByZXNzKCcke2tleX0nKWAsIHNpbXVsYXRlZDogZmFsc2UgfSlcblxuLyoqXG4gKiBTZW5zb3JlbiAoQXVzZHLDvGNrZSBvaG5lIEFyZ3VtZW50ZSk6IFphaGxlbiBvZGVyIFdhaHJoZWl0c3dlcnRlLlxuICogRGVyIFB5dGhvbi1UZXh0IGxpZXN0IGRlbiBXZXJ0IGFtIGVjaHRlbiBtQm90MiAoTW9kdXMgMSwgQW50d29ydCBge1wicmV0XCI64oCmfWApLlxuICovXG5leHBvcnQgY29uc3QgTUJPVF9TRU5TT1JTOiBSZWNvcmQ8c3RyaW5nLCBTZW5zb3JTcGVjPiA9IHtcbiAgZ2V0RGlzdGFuY2U6IHsgcHl0aG9uOiAnbWJ1aWxkLnVsdHJhc29uaWMyLmdldCgxKScsIHNpbXVsYXRlZDogMTAwIH0sXG4gIGdldExpbmU6IHsgcHl0aG9uOiBcIm1idWlsZC5xdWFkX3JnYl9zZW5zb3IuZ2V0X2xpbmVfc3RhKCdhbGwnLCAxKVwiLCBzaW11bGF0ZWQ6IDAgfSxcbiAgLy8gZGllIGJlaWRlbiBtaXR0bGVyZW4gRsO8aGxlciAoTDEsIFIxKSBkZXMgTGluaWVuc2Vuc29yc1xuICBpc0xpbmVMZWZ0OiB7IHB5dGhvbjogXCJtYnVpbGQucXVhZF9yZ2Jfc2Vuc29yLmlzX2xpbmUoJ0wxJywgMSlcIiwgc2ltdWxhdGVkOiBmYWxzZSB9LFxuICBpc0xpbmVSaWdodDogeyBweXRob246IFwibWJ1aWxkLnF1YWRfcmdiX3NlbnNvci5pc19saW5lKCdSMScsIDEpXCIsIHNpbXVsYXRlZDogZmFsc2UgfSxcbiAgLyoqIEZhcmJlIHVudGVyIGRlbSBtQm90MiBhbHMgVGV4dDogYG1ib3QuZ2V0Q29sb3IoKS5lcXVhbHMoXCJyb3RcIilgICovXG4gIGdldENvbG9yOiB7IHB5dGhvbjogXCJtYnVpbGQucXVhZF9yZ2Jfc2Vuc29yLmdldF9jb2xvcl9zdGEoJ0wxJywgMSlcIiwgc2ltdWxhdGVkOiAnd2hpdGUnIH0sXG4gIGlzQnV0dG9uQTogcHJlc3MoJ2EnKSxcbiAgaXNCdXR0b25COiBwcmVzcygnYicpLFxuICBpc0pveXN0aWNrVXA6IHByZXNzKCd1cCcpLFxuICBpc0pveXN0aWNrRG93bjogcHJlc3MoJ2Rvd24nKSxcbiAgaXNKb3lzdGlja0xlZnQ6IHByZXNzKCdsZWZ0JyksXG4gIGlzSm95c3RpY2tSaWdodDogcHJlc3MoJ3JpZ2h0JyksXG4gIGdldEJyaWdodG5lc3M6IHsgcHl0aG9uOiAnY3liZXJwaS5nZXRfYnJpKCknLCBzaW11bGF0ZWQ6IDUwIH0sXG4gIGdldExvdWRuZXNzOiB7IHB5dGhvbjogXCJjeWJlcnBpLmdldF9sb3VkbmVzcygnbWF4aW11bScpXCIsIHNpbXVsYXRlZDogMCB9LFxuICBnZXRQaXRjaDogeyBweXRob246ICdjeWJlcnBpLmdldF9waXRjaCgpJywgc2ltdWxhdGVkOiAwIH0sXG4gIGdldFJvbGw6IHsgcHl0aG9uOiAnY3liZXJwaS5nZXRfcm9sbCgpJywgc2ltdWxhdGVkOiAwIH0sXG4gIGlzU2hha2VuOiB7IHB5dGhvbjogJ2N5YmVycGkuaXNfc2hha2UoKScsIHNpbXVsYXRlZDogZmFsc2UgfSxcbiAgZ2V0QmF0dGVyeTogeyBweXRob246ICdjeWJlcnBpLmdldF9iYXR0ZXJ5KCknLCBzaW11bGF0ZWQ6IDEwMCB9LFxuICAvKiogU2VrdW5kZW4gc2VpdCBkZW0gU3RhcnQgYnp3LiBzZWl0IGByZXNldFRpbWVyKClgICovXG4gIGdldFRpbWVyOiB7IHB5dGhvbjogJ2N5YmVycGkudGltZXIuZ2V0KCknLCBzaW11bGF0ZWQ6IDAgfSxcbn1cblxuLyoqIE1lc3N3ZXJ0ZSBkZXMgUm9ib3RlcnMgbmFjaCBOYW1lbiAoYGdldERpc3RhbmNlYCDihpIgMzgsIGBpc0J1dHRvbkFgIOKGkiB0cnVlKS4gKi9cbmV4cG9ydCB0eXBlIE1Cb3RTZW5zb3JWYWx1ZXMgPSBQYXJ0aWFsPFJlY29yZDxzdHJpbmcsIE1Cb3RTZW5zb3JWYWx1ZT4+XG5cbi8qKiBXZWxjaGUgU2Vuc29yZW4ga29tbWVuIGluIGRpZXNlbSBUZXh0IHZvciAoei4gQi4gaW0gZ2FuemVuIERpYWdyYW1tKT8gKi9cbmV4cG9ydCBmdW5jdGlvbiB1c2VkTUJvdFNlbnNvcnModGV4dDogc3RyaW5nKTogc3RyaW5nW10ge1xuICBjb25zdCBmb3VuZCA9IG5ldyBTZXQ8c3RyaW5nPigpXG4gIGZvciAoY29uc3QgbSBvZiB0ZXh0Lm1hdGNoQWxsKC9cXGJtYm90XFxzKlxcLlxccyooW0EtWmEtel9dXFx3KilcXHMqXFwoXFxzKlxcKS9ndSkpIGlmIChtWzFdIGluIE1CT1RfU0VOU09SUykgZm91bmQuYWRkKG1bMV0pXG4gIHJldHVybiBbLi4uZm91bmRdXG59XG5cbi8qKiBgbWJvdC5mb3J3YXJkKDEwKWAg4oaSIE5hbWUgdW5kIEFyZ3VtZW50dGV4dGU7IGB1bmRlZmluZWRgLCB3ZW5uIGVzIGtlaW4gbUJvdC1CZWZlaGwgaXN0LiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHBhcnNlTUJvdENvbW1hbmQodGV4dDogc3RyaW5nKTogeyBtZXRob2Q6IHN0cmluZzsgYXJnczogc3RyaW5nW10gfSB8IHVuZGVmaW5lZCB7XG4gIC8vIGBtYm90LmxlZChpKS5zZXRDb2xvcihcImdyw7xuXCIpYCB3aXJkIHp1IGBsZWRDb2xvcihpLCBcImdyw7xuXCIpYFxuICBjb25zdCBsZWQgPSAvXm1ib3RcXHMqXFwuXFxzKmxlZFxccypcXCgoW14oKV0qKD86XFwoW14oKV0qXFwpW14oKV0qKSopXFwpXFxzKlxcLlxccypzZXRDb2xvclxccypcXCgoW1xcc1xcU10qKVxcKVxccyo7PyQvdS5leGVjKHRleHQudHJpbSgpKVxuICBpZiAobGVkKSByZXR1cm4geyBtZXRob2Q6ICdsZWRDb2xvcicsIGFyZ3M6IFtsZWRbMV0udHJpbSgpLCBsZWRbMl0udHJpbSgpXSB9XG4gIGNvbnN0IG0gPSAvXm1ib3RcXHMqXFwuXFxzKihbQS1aYS16X11cXHcqKVxccypcXCgoW1xcc1xcU10qKVxcKVxccyo7PyQvdS5leGVjKHRleHQudHJpbSgpKVxuICBpZiAoIW0pIHJldHVybiB1bmRlZmluZWRcbiAgY29uc3QgaW5uZXIgPSBtWzJdLnRyaW0oKVxuICByZXR1cm4geyBtZXRob2Q6IG1bMV0sIGFyZ3M6IGlubmVyID09PSAnJyA/IFtdIDogc3BsaXRBcmdzKGlubmVyKSB9XG59XG5cbi8qKiBBcmd1bWVudGUgcHLDvGZlbiB1bmQgbGVlcmUgS2xhbW1lcm4gbWl0IGRlbiBTdGFuZGFyZHdlcnRlbiBmw7xsbGVuOyBgdW5kZWZpbmVkYCBiZWkgZmFsc2NoZXIgQW56YWhsLiAqL1xuZXhwb3J0IGZ1bmN0aW9uIG1ib3RBcmd1bWVudHMobWV0aG9kOiBzdHJpbmcsIGFyZ3M6IG51bWJlcltdKTogbnVtYmVyW10gfCB1bmRlZmluZWQge1xuICBjb25zdCBzcGVjID0gTUJPVF9DT01NQU5EU1ttZXRob2RdXG4gIGlmICghc3BlYykgcmV0dXJuIHVuZGVmaW5lZFxuICBjb25zdCB2YWx1ZXMgPSBhcmdzLmxlbmd0aCA9PT0gMCAmJiBzcGVjLmRlZmF1bHRzID8gc3BlYy5kZWZhdWx0cyA6IGFyZ3NcbiAgaWYgKHZhbHVlcy5sZW5ndGggIT09IHNwZWMuYXJncykgcmV0dXJuIHVuZGVmaW5lZFxuICByZXR1cm4gIXNwZWMudmFsaWQgfHwgc3BlYy52YWxpZCh2YWx1ZXMpID8gdmFsdWVzIDogdW5kZWZpbmVkXG59XG5cbmV4cG9ydCBmdW5jdGlvbiBtYWtlTUJvdEFjdGlvbihtZXRob2Q6IHN0cmluZywgYXJnczogbnVtYmVyW10sIHRleHQgPSAnJyk6IE1Cb3RBY3Rpb24ge1xuICBjb25zdCBzcGVjID0gTUJPVF9DT01NQU5EU1ttZXRob2RdXG4gIHJldHVybiB7XG4gICAgbWV0aG9kLFxuICAgIGFyZ3MsXG4gICAgcHl0aG9uOiBzcGVjLnB5dGhvbj8uKGFyZ3MsIHRleHQpLFxuICAgIHdhaXRNczogbWV0aG9kID09PSAncGF1c2UnID8gTWF0aC5tYXgoMCwgYXJnc1swXSkgOiB1bmRlZmluZWQsXG4gICAgbGFiZWw6IHNwZWMubGFiZWwoYXJncywgdGV4dCksXG4gICAgLi4uKHNwZWMudGV4dCA/IHsgdGV4dCB9IDoge30pLFxuICB9XG59XG5cbi8qKlxuICogQWxsZSBCZWZlaGxlIGFscyBMaXN0ZSB3aWUgYHNldExlZCAyNTUgMCAwYCwgYHBhdXNlIDUwMGAsIGBzaG93VGV4dCBcIkhhbGxvXCJgICh6dW0gUHLDvGZlbiB2b24gTEVEcywgVMO2bmVuIHVuZCBCaWxkc2NoaXJtKS5cbiAqIEFuZGVycyBhbHMgYGRyaXZlU2lnbmF0dXJlYCB3aXJkIG5pY2h0cyB6dXNhbW1lbmdlZmFzc3QuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBhY3Rpb25TaWduYXR1cmUoYWN0aW9uczogeyBtZXRob2Q6IHN0cmluZzsgYXJnczogbnVtYmVyW107IHRleHQ/OiBzdHJpbmcgfVtdKTogc3RyaW5nW10ge1xuICByZXR1cm4gYWN0aW9ucy5tYXAoKGEpID0+IFthLm1ldGhvZCwgLi4uYS5hcmdzLm1hcChuKSwgLi4uKGEudGV4dCAhPT0gdW5kZWZpbmVkID8gW0pTT04uc3RyaW5naWZ5KGEudGV4dCldIDogW10pXS5qb2luKCcgJykpXG59XG5cbi8qKiBFcndhcnRldGUgQmVmZWhsZSBlaW5lciDDnGJ1bmcsIHouIEIuIGBiZWZlaGxlOiAzIHggKHNldExlZCAyNTUgMCAwLCBwYXVzZSA1MDAsIGxlZE9mZiwgcGF1c2UgNTAwKWA7IFRleHRlIGluIEFuZsO8aHJ1bmdzemVpY2hlbi4gKi9cbmV4cG9ydCBmdW5jdGlvbiBwYXJzZUFjdGlvblNwZWMoc3BlYzogc3RyaW5nKTogc3RyaW5nW10ge1xuICBsZXQgaSA9IDBcbiAgY29uc3Qgc3JjID0gc3BlYy50cmltKClcbiAgY29uc3QgbGlzdCA9ICgpOiBzdHJpbmdbXSA9PiB7XG4gICAgY29uc3QgaXRlbXM6IHN0cmluZ1tdID0gW11cbiAgICBmb3IgKDs7KSB7XG4gICAgICB3aGlsZSAoc3JjW2ldID09PSAnICcgfHwgc3JjW2ldID09PSAnLCcpIGkrK1xuICAgICAgaWYgKGkgPj0gc3JjLmxlbmd0aCB8fCBzcmNbaV0gPT09ICcpJykgcmV0dXJuIGl0ZW1zXG4gICAgICBjb25zdCByZXAgPSAvXihcXGQrKVxccypbeMOXXVxccypcXCgvdS5leGVjKHNyYy5zbGljZShpKSlcbiAgICAgIGlmIChyZXApIHtcbiAgICAgICAgaSArPSByZXBbMF0ubGVuZ3RoXG4gICAgICAgIGNvbnN0IGlubmVyID0gbGlzdCgpXG4gICAgICAgIGlmIChzcmNbaV0gIT09ICcpJykgdGhyb3cgbmV3IEVycm9yKGDigJ4p4oCcIGZlaGx0IGluIOKAniR7c3BlY33igJxgKVxuICAgICAgICBpKytcbiAgICAgICAgZm9yIChsZXQgayA9IDA7IGsgPCBOdW1iZXIocmVwWzFdKTsgaysrKSBpdGVtcy5wdXNoKC4uLmlubmVyKVxuICAgICAgICBjb250aW51ZVxuICAgICAgfVxuICAgICAgY29uc3Qgc3RlcCA9IC9eKFtBLVphLXpdKykoKD86XFxzKy0/XFxkKyg/OlxcLlxcZCspPykqKSg/OlxccysoXCIoPzpbXlwiXFxcXF18XFxcXC4pKlwiKSk/L3UuZXhlYyhzcmMuc2xpY2UoaSkpXG4gICAgICBpZiAoIXN0ZXApIHRocm93IG5ldyBFcnJvcihgVW5iZWthbm50IGluIOKAniR7c3BlY33igJw6ICR7c3JjLnNsaWNlKGkpfWApXG4gICAgICBpICs9IHN0ZXBbMF0ubGVuZ3RoXG4gICAgICBjb25zdCBzcGVjXyA9IE1CT1RfQ09NTUFORFNbc3RlcFsxXV1cbiAgICAgIGlmICghc3BlY18pIHRocm93IG5ldyBFcnJvcihgVW5iZWthbm50ZXIgQmVmZWhsIGluIOKAniR7c3BlY33igJw6ICR7c3RlcFsxXX1gKVxuICAgICAgY29uc3QgbnVtcyA9IHN0ZXBbMl0udHJpbSgpID09PSAnJyA/IFtdIDogc3RlcFsyXS50cmltKCkuc3BsaXQoL1xccysvKS5tYXAoTnVtYmVyKVxuICAgICAgY29uc3QgYXJncyA9IG1ib3RBcmd1bWVudHMoc3RlcFsxXSwgbnVtcylcbiAgICAgIGlmICghYXJncykgdGhyb3cgbmV3IEVycm9yKGBGYWxzY2hlIEFuemFobCBaYWhsZW4gaW4g4oCeJHtzcGVjfeKAnDogJHtzdGVwWzFdfWApXG4gICAgICBpdGVtcy5wdXNoKGFjdGlvblNpZ25hdHVyZShbeyBtZXRob2Q6IHN0ZXBbMV0sIGFyZ3MsIHRleHQ6IHNwZWNfLnRleHQgPyBKU09OLnBhcnNlKHN0ZXBbM10gPz8gJ1wiXCInKSA6IHVuZGVmaW5lZCB9XSlbMF0pXG4gICAgfVxuICB9XG4gIGNvbnN0IGl0ZW1zID0gbGlzdCgpXG4gIGlmIChpIDwgc3JjLmxlbmd0aCkgdGhyb3cgbmV3IEVycm9yKGBadSB2aWVsZSDigJ4p4oCcIGluIOKAniR7c3BlY33igJxgKVxuICByZXR1cm4gaXRlbXNcbn1cblxuLyoqIEVyc2V0enQgYG1ib3QuZ2V0RGlzdGFuY2UoKWAgdXN3LiBkdXJjaCBaYWhsZW4sIGRhbWl0IGRlciBSZWNobmVyIHNpZSB3aWUgTGl0ZXJhbGUgbGllc3QuICovXG5leHBvcnQgZnVuY3Rpb24gc3Vic3RpdHV0ZU1Cb3RTZW5zb3JzKGV4cHJlc3Npb246IHN0cmluZywgcmVhZDogKG5hbWU6IHN0cmluZykgPT4gTUJvdFNlbnNvclZhbHVlKTogc3RyaW5nIHtcbiAgaWYgKCFleHByZXNzaW9uLmluY2x1ZGVzKCdtYm90JykpIHJldHVybiBleHByZXNzaW9uXG4gIHJldHVybiBleHByZXNzaW9uLnJlcGxhY2UoL1xcYm1ib3RcXHMqXFwuXFxzKihbQS1aYS16X11cXHcqKVxccypcXChcXHMqXFwpL2d1LCAoYWxsLCBuYW1lOiBzdHJpbmcpID0+IHtcbiAgICBpZiAoIShuYW1lIGluIE1CT1RfU0VOU09SUykpIHJldHVybiBhbGxcbiAgICBjb25zdCB2YWx1ZSA9IHJlYWQobmFtZSlcbiAgICByZXR1cm4gdHlwZW9mIHZhbHVlID09PSAnc3RyaW5nJyA/IEpTT04uc3RyaW5naWZ5KG5hbWUgPT09ICdnZXRDb2xvcicgPyBtYm90Q29sb3JOYW1lKHZhbHVlKSA6IHZhbHVlKSA6IFN0cmluZyh2YWx1ZSlcbiAgfSlcbn1cblxuLyoqIEFyZ3VtZW50ZSBhbiBLb21tYXMgYXVmIG9iZXJzdGVyIEViZW5lIHRyZW5uZW4gKG5pY2h0IGluIEtsYW1tZXJuIG9kZXIgVGV4dGVuKS4gKi9cbmZ1bmN0aW9uIHNwbGl0QXJncyh0ZXh0OiBzdHJpbmcpOiBzdHJpbmdbXSB7XG4gIGNvbnN0IHBhcnRzOiBzdHJpbmdbXSA9IFtdXG4gIGxldCBkZXB0aCA9IDBcbiAgbGV0IHF1b3RlID0gZmFsc2VcbiAgbGV0IHN0YXJ0ID0gMFxuICBmb3IgKGxldCBpID0gMDsgaSA8IHRleHQubGVuZ3RoOyBpKyspIHtcbiAgICBjb25zdCBjID0gdGV4dFtpXVxuICAgIGlmIChxdW90ZSkge1xuICAgICAgaWYgKGMgPT09ICdcXFxcJykgaSsrXG4gICAgICBlbHNlIGlmIChjID09PSAnXCInKSBxdW90ZSA9IGZhbHNlXG4gICAgfSBlbHNlIGlmIChjID09PSAnXCInKSBxdW90ZSA9IHRydWVcbiAgICBlbHNlIGlmIChjID09PSAnKCcgfHwgYyA9PT0gJ1snKSBkZXB0aCsrXG4gICAgZWxzZSBpZiAoYyA9PT0gJyknIHx8IGMgPT09ICddJykgZGVwdGgtLVxuICAgIGVsc2UgaWYgKGMgPT09ICcsJyAmJiBkZXB0aCA9PT0gMCkge1xuICAgICAgcGFydHMucHVzaCh0ZXh0LnNsaWNlKHN0YXJ0LCBpKS50cmltKCkpXG4gICAgICBzdGFydCA9IGkgKyAxXG4gICAgfVxuICB9XG4gIHBhcnRzLnB1c2godGV4dC5zbGljZShzdGFydCkudHJpbSgpKVxuICByZXR1cm4gcGFydHNcbn1cblxuLyoqXG4gKiBHZWZhaHJlbmUgU3RyZWNrZSBhbHMgTGlzdGUgd2llIGBmb3J3YXJkIDUwYCwgYHR1cm5SaWdodCA5MGA6IGF1ZmVpbmFuZGVyZm9sZ2VuZGUgRmFocnRlbiBiencuIERyZWh1bmdlblxuICogenVzYW1tZW5nZWZhc3N0LCBMRURzIHVuZCBUw7ZuZSB6w6RobGVuIG5pY2h0LiBTbyBpc3QgYDUgw5cgZm9yd2FyZCgpYCBkYXNzZWxiZSB3aWUgYGZvcndhcmQoNTApYC5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGRyaXZlU2lnbmF0dXJlKGFjdGlvbnM6IHsgbWV0aG9kOiBzdHJpbmc7IGFyZ3M6IG51bWJlcltdIH1bXSk6IHN0cmluZ1tdIHtcbiAgY29uc3Qgb3V0OiB7IGtpbmQ6ICdkcml2ZScgfCAndHVybic7IHZhbHVlOiBudW1iZXIgfVtdID0gW11cbiAgZm9yIChjb25zdCBhIG9mIGFjdGlvbnMpIHtcbiAgICBjb25zdCB2YWx1ZSA9IHsgZm9yd2FyZDogYS5hcmdzWzBdLCBiYWNrd2FyZDogLWEuYXJnc1swXSwgdHVyblJpZ2h0OiBhLmFyZ3NbMF0sIHR1cm5MZWZ0OiAtYS5hcmdzWzBdIH1bYS5tZXRob2RdXG4gICAgaWYgKHZhbHVlID09PSB1bmRlZmluZWQpIGNvbnRpbnVlXG4gICAgY29uc3Qga2luZCA9IGEubWV0aG9kID09PSAnZm9yd2FyZCcgfHwgYS5tZXRob2QgPT09ICdiYWNrd2FyZCcgPyAnZHJpdmUnIDogJ3R1cm4nXG4gICAgY29uc3QgbGFzdCA9IG91dFtvdXQubGVuZ3RoIC0gMV1cbiAgICBpZiAobGFzdCAmJiBsYXN0LmtpbmQgPT09IGtpbmQpIGxhc3QudmFsdWUgKz0gdmFsdWVcbiAgICBlbHNlIG91dC5wdXNoKHsga2luZCwgdmFsdWUgfSlcbiAgfVxuICByZXR1cm4gb3V0LmZsYXRNYXAoKHsga2luZCwgdmFsdWUgfSkgPT4ge1xuICAgIGNvbnN0IHYgPSBraW5kID09PSAndHVybicgPyAoKCgodmFsdWUgKyAxODApICUgMzYwKSArIDM2MCkgJSAzNjApIC0gMTgwIDogdmFsdWVcbiAgICBpZiAoTWF0aC5hYnModikgPCAxZS02KSByZXR1cm4gW11cbiAgICBjb25zdCByID0gTWF0aC5yb3VuZChNYXRoLmFicyh2KSAqIDEwMCkgLyAxMDBcbiAgICBpZiAoa2luZCA9PT0gJ2RyaXZlJykgcmV0dXJuIFtgJHt2ID4gMCA/ICdmb3J3YXJkJyA6ICdiYWNrd2FyZCd9ICR7cn1gXVxuICAgIHJldHVybiBbdiA9PT0gLTE4MCA/ICd0dXJuUmlnaHQgMTgwJyA6IGAke3YgPiAwID8gJ3R1cm5SaWdodCcgOiAndHVybkxlZnQnfSAke3J9YF1cbiAgfSlcbn1cblxuLyoqXG4gKiBFcndhcnRldGUgRmFocnQgZWluZXIgw5xidW5nLCB6LiBCLiBgZmFocnQ6IDQgeCAoZm9yd2FyZCA1MCwgdHVyblJpZ2h0IDkwKWAuIFRlaWxlIGR1cmNoIEtvbW1hcyBnZXRyZW5udCxcbiAqIGBuIHggKOKApilgIHdpZWRlcmhvbHQ7IG9obmUgWmFobCBnZWx0ZW4gZGllIFdlcnRlIHZvbiBgbWJvdC5mb3J3YXJkKClgIGJ6dy4gYHR1cm5SaWdodCgpYC5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHBhcnNlRHJpdmVTcGVjKHNwZWM6IHN0cmluZyk6IHsgbWV0aG9kOiBzdHJpbmc7IGFyZ3M6IG51bWJlcltdIH1bXSB7XG4gIGxldCBpID0gMFxuICBjb25zdCBzcmMgPSBzcGVjLnRyaW0oKVxuICBjb25zdCBsaXN0ID0gKCk6IHsgbWV0aG9kOiBzdHJpbmc7IGFyZ3M6IG51bWJlcltdIH1bXSA9PiB7XG4gICAgY29uc3QgaXRlbXM6IHsgbWV0aG9kOiBzdHJpbmc7IGFyZ3M6IG51bWJlcltdIH1bXSA9IFtdXG4gICAgZm9yICg7Oykge1xuICAgICAgd2hpbGUgKHNyY1tpXSA9PT0gJyAnIHx8IHNyY1tpXSA9PT0gJywnKSBpKytcbiAgICAgIGlmIChpID49IHNyYy5sZW5ndGggfHwgc3JjW2ldID09PSAnKScpIHJldHVybiBpdGVtc1xuICAgICAgY29uc3QgcmVwID0gL14oXFxkKylcXHMqW3jDl11cXHMqXFwoL3UuZXhlYyhzcmMuc2xpY2UoaSkpXG4gICAgICBpZiAocmVwKSB7XG4gICAgICAgIGkgKz0gcmVwWzBdLmxlbmd0aFxuICAgICAgICBjb25zdCBpbm5lciA9IGxpc3QoKVxuICAgICAgICBpZiAoc3JjW2ldICE9PSAnKScpIHRocm93IG5ldyBFcnJvcihg4oCeKeKAnCBmZWhsdCBpbiDigJ4ke3NwZWN94oCcYClcbiAgICAgICAgaSsrXG4gICAgICAgIGZvciAobGV0IGsgPSAwOyBrIDwgTnVtYmVyKHJlcFsxXSk7IGsrKykgaXRlbXMucHVzaCguLi5pbm5lcilcbiAgICAgICAgY29udGludWVcbiAgICAgIH1cbiAgICAgIGNvbnN0IHN0ZXAgPSAvXihbQS1aYS16XSspKD86XFxzKygtP1xcZCsoPzpcXC5cXGQrKT8pKT8vdS5leGVjKHNyYy5zbGljZShpKSlcbiAgICAgIGlmICghc3RlcCkgdGhyb3cgbmV3IEVycm9yKGBVbmJla2FubnQgaW4g4oCeJHtzcGVjfeKAnDogJHtzcmMuc2xpY2UoaSl9YClcbiAgICAgIGkgKz0gc3RlcFswXS5sZW5ndGhcbiAgICAgIGNvbnN0IGFyZ3MgPSBtYm90QXJndW1lbnRzKHN0ZXBbMV0sIHN0ZXBbMl0gPT09IHVuZGVmaW5lZCA/IFtdIDogW051bWJlcihzdGVwWzJdKV0pXG4gICAgICBpZiAoIWFyZ3MpIHRocm93IG5ldyBFcnJvcihgVW5iZWthbm50ZXIgQmVmZWhsIGluIOKAniR7c3BlY33igJw6ICR7c3RlcFsxXX1gKVxuICAgICAgaXRlbXMucHVzaCh7IG1ldGhvZDogc3RlcFsxXSwgYXJncyB9KVxuICAgIH1cbiAgfVxuICBjb25zdCBpdGVtcyA9IGxpc3QoKVxuICBpZiAoaSA8IHNyYy5sZW5ndGgpIHRocm93IG5ldyBFcnJvcihgWnUgdmllbGUg4oCeKeKAnCBpbiDigJ4ke3NwZWN94oCcYClcbiAgcmV0dXJuIGl0ZW1zXG59XG5cbi8qKiBGYWhydCBrdXJ6IHp1bSBBbnplaWdlbjogV2llZGVyaG9sdW5nZW4gYWxzIGA0IHggKGZvcndhcmQgNTAsIHR1cm5SaWdodCA5MClgLCBhdWNoIHZlcnNjaGFjaHRlbHQuICovXG5leHBvcnQgZnVuY3Rpb24gY29tcHJlc3NEcml2ZShkcml2ZTogc3RyaW5nW10pOiBzdHJpbmcge1xuICBjb25zdCBuID0gZHJpdmUubGVuZ3RoXG4gIGZvciAobGV0IHVuaXQgPSAxOyB1bml0IDw9IG4gLyAyOyB1bml0KyspIHtcbiAgICBpZiAobiAlIHVuaXQgIT09IDApIGNvbnRpbnVlXG4gICAgY29uc3QgdGltZXMgPSBuIC8gdW5pdFxuICAgIGlmIChkcml2ZS5ldmVyeSgocywgaSkgPT4gcyA9PT0gZHJpdmVbaSAlIHVuaXRdKSkge1xuICAgICAgY29uc3QgaW5uZXIgPSBjb21wcmVzc0RyaXZlKGRyaXZlLnNsaWNlKDAsIHVuaXQpKVxuICAgICAgcmV0dXJuIGAke3RpbWVzfSB4ICR7dW5pdCA9PT0gMSA/IGlubmVyIDogYCgke2lubmVyfSlgfWBcbiAgICB9XG4gIH1cbiAgcmV0dXJuIGRyaXZlLmpvaW4oJywgJylcbn1cblxuLyoqXG4gKiBUZWlsZSBkZXMgbUJvdDIgaW0gM0QtTW9kZWxsLCB6LiBCLiBmw7xyIGBmb2t1czpgIGltIExla3Rpb25zYmxvY2sgYDo6OiBtYm90MmAgdW5kIGBbV29ydF17dGVpbD1jeWJlcnBpfWAgaW0gVGV4dC5cbiAqIERpZSBlcnN0ZW4gYWNodCBnZWjDtnJlbiB6dW0gQ3liZXJQaTsgYGN5YmVycGlgIGFsbGVpbiBpc3Qgc2VpbiBHZWjDpHVzZS5cbiAqL1xuZXhwb3J0IGNvbnN0IE1CT1RfUEFSVFMgPSBbXG4gICdjeWJlcnBpJyxcbiAgJ3NjcmVlbicsXG4gICdqb3lzdGljaycsXG4gICdidXR0b25zJyxcbiAgJ2xlZHMnLFxuICAnbGlnaHRTZW5zb3InLFxuICAnbWljcm9waG9uZScsXG4gICdzaGllbGQnLFxuICAncG93ZXJTd2l0Y2gnLFxuICAnbW90b3JzJyxcbiAgJ3doZWVscycsXG4gICd1bHRyYXNvbmljJyxcbiAgJ2xpbmVTZW5zb3InLFxuICAnY2FzdGVyJyxcbiAgJ2NoYXNzaXMnLFxuXSBhcyBjb25zdFxuXG5leHBvcnQgdHlwZSBNQm90UGFydCA9ICh0eXBlb2YgTUJPVF9QQVJUUylbbnVtYmVyXVxuXG5leHBvcnQgY29uc3QgaXNNQm90UGFydCA9IChuYW1lOiBzdHJpbmcpOiBuYW1lIGlzIE1Cb3RQYXJ0ID0+IChNQk9UX1BBUlRTIGFzIHJlYWRvbmx5IHN0cmluZ1tdKS5pbmNsdWRlcyhuYW1lKVxuIl0sImZpbGUiOiIvd2ViL3NyYy9jb3JlL21ib3QudHMifQ== - -//# vitestCache=W3siZmlsZSI6IjEiLCJpZCI6IjEiLCJ1cmwiOiIyIiwiaW1wb3J0cyI6IjMiLCJtYXBwaW5ncyI6ZmFsc2UsImRlcHMiOiI0IiwiZHluYW1pY0RlcHMiOiI1Iiwic3RhdGljTW9ja3MiOm51bGx9LCIvaG9tZS91c2VyL3Zpc3VzdHJ1Y3Qtc3dpZnR1aS93ZWIvc3JjL2NvcmUvbWJvdC50cyIsIi93ZWIvc3JjL2NvcmUvbWJvdC50cyIseyJ1cmxzIjoiNiIsImlkcyI6IjcifSxbIjgiXSxbXSxbIjgiXSx7fSwiL3dlYi9zcmMvY29yZS9tYm90TGluay50cyJd \ No newline at end of file diff --git a/node_modules/.vitest-cache/a2bc6900de05952e637aa8c1bf773176a1051346 b/node_modules/.vitest-cache/a2bc6900de05952e637aa8c1bf773176a1051346 deleted file mode 100644 index 10e201b1..00000000 --- a/node_modules/.vitest-cache/a2bc6900de05952e637aa8c1bf773176a1051346 +++ /dev/null @@ -1,86 +0,0 @@ -__vite_ssr_exportName__("inline", () => { try { return inline } catch {} }); -__vite_ssr_exportName__("markdownToHTML", () => { try { return markdownToHTML } catch {} }); -/** Kleines Markdown für Lektionstexte: Absätze, ## bis ####, Listen, Zitat als Hinweis, Code, Tabellen, **fett**, *kursiv*, `code`, [Link](url), -* [Wort]{.blau} als farbige Markierung (blau, orange, gruen) passend zu farbigen Kästen, [Wort]{teil=cyberpi} zeigt auf ein Teil des mBot2. */ -const escape = (s) => s.replace(/&/g, "&").replace(//g, ">").replace(/"/g, """); -function inline(text) { - const codes = []; - let s = escape(text).replace(/`([^`]+)`/g, (_, c) => { - codes.push(c); - return `\u0000${codes.length - 1}\u0000`; - }); - s = s.replace(/\*\*(.+?)\*\*/g, "$1").replace(/(^|[^*])\*([^*\s][^*]*?)\*/g, "$1$2").replace(/\[([^\]]+)\]\(([^)\s]+)\)/g, (_, label, url) => { - const safe = /^(https?:|mailto:|#|\.{0,2}\/)/.test(url) ? url : "#"; - const external = /^https?:/.test(safe) ? " target=\"_blank\" rel=\"noopener noreferrer\"" : ""; - return `${label}`; - }).replace(/\[([^\]]+)\]\{\.(blau|orange|gruen|gelb|rosa)\}/g, "$1").replace(/\[([^\]]+)\]\{(?:teil|part)=([\w,]+)\}/g, "$1"); - return s.replace(/\u0000(\d+)\u0000/g, (_, i) => `${codes[Number(i)]}`); -}; -function markdownToHTML(source) { - const out = []; - const lines = source.replace(/\r\n/g, "\n").split("\n"); - let i = 0; - while (i < lines.length) { - const line = lines[i]; - if (line.trim() === "") { - i++; - continue; - }; - if (line.startsWith("```")) { - // ```java editor: Unter dem Beispiel steht „Im Editor öffnen“, dann kann man es in Programmieren ausprobieren. - const [lang, extra] = line.slice(3).trim().split(/\s+/); - const java = lang === "java"; - const open = java && extra === "editor"; - const code = []; - i++; - while (i < lines.length && !lines[i].startsWith("```")) code.push(lines[i++]); - i++; - out.push(`
    ${escape(code.join("\n"))}
    `); - continue; - }; - const heading = /^(#{2,4})\s+(.*)$/.exec(line); - if (heading) { - const level = heading[1].length; - out.push(`${inline(heading[2])}`); - i++; - continue; - }; - if (/^\s*([-*]|\d+\.)\s+/.test(line)) { - const ordered = /^\s*\d+\./.test(line); - const items = []; - while (i < lines.length && /^\s*([-*]|\d+\.)\s+/.test(lines[i])) { - let item = lines[i].replace(/^\s*([-*]|\d+\.)\s+/, ""); - i++; - while (i < lines.length && /^\s{2,}\S/.test(lines[i]) && !/^\s*([-*]|\d+\.)\s+/.test(lines[i])) item += " " + lines[i++].trim(); - items.push(`
  • ${inline(item)}
  • `); - }; - out.push(ordered ? `
      ${items.join("")}
    ` : `
      ${items.join("")}
    `); - continue; - }; - if (line.startsWith("|") && /^\|?[\s:|-]*-{3,}[\s:|-]*$/.test(lines[i + 1] ?? "")) { - const cells = (row) => row.trim().replace(/^\|/, "").replace(/\|$/, "").split("|").map((c) => inline(c.trim())); - const head = cells(line); - i += 2; - const rows = []; - while (i < lines.length && lines[i].startsWith("|")) rows.push(cells(lines[i++])); - out.push(`
    ${head.map((c) => ``).join("")}${rows.map((r) => `${r.map((c) => ``).join("")}`).join("")}
    ${c}
    ${c}
    `); - continue; - }; - if (line.startsWith(">")) { - const quote = []; - while (i < lines.length && lines[i].startsWith(">")) quote.push(lines[i++].replace(/^>\s?/, "")); - out.push(``); - continue; - }; - const para = []; - while (i < lines.length && lines[i].trim() !== "" && !/^(```|#{3,4}\s|>|\||\s*([-*]|\d+\.)\s+)/.test(lines[i])) { - para.push(lines[i++].trim()); - }; - out.push(`

    ${inline(para.join(" "))}

    `); - }; - return out.join("\n"); -} -//# sourceMappingSource=vite-generated -//# sourceMappingURL=data:application/json;base64,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QUFNLFVBQ1YsTUFBTSxFQUFFLENBQUMsS0FBSyxNQUFNLE1BQ3BCLENBQUMsMENBQTBDLEtBQUssTUFBTSxFQUFFLEdBQ3hEO0dBQ0EsS0FBSyxLQUFLLE1BQU0sSUFBSSxDQUFDLEtBQUssQ0FBQztFQUM3QjtFQUNBLElBQUksS0FBSyxNQUFNLE9BQU8sS0FBSyxLQUFLLEdBQUcsQ0FBQyxFQUFFLEtBQUs7Q0FDN0M7Q0FDQSxPQUFPLElBQUksS0FBSyxJQUFJO0FBQ3RCIiwibmFtZXMiOltdLCJpZ25vcmVMaXN0IjpbXSwic291cmNlcyI6WyJtYXJrZG93bi50cyJdLCJzb3VyY2VzQ29udGVudCI6WyIvKiogS2xlaW5lcyBNYXJrZG93biBmw7xyIExla3Rpb25zdGV4dGU6IEFic8OkdHplLCAjIyBiaXMgIyMjIywgTGlzdGVuLCBaaXRhdCBhbHMgSGlud2VpcywgQ29kZSwgVGFiZWxsZW4sICoqZmV0dCoqLCAqa3Vyc2l2KiwgYGNvZGVgLCBbTGlua10odXJsKSxcbiAqIFtXb3J0XXsuYmxhdX0gYWxzIGZhcmJpZ2UgTWFya2llcnVuZyAoYmxhdSwgb3JhbmdlLCBncnVlbikgcGFzc2VuZCB6dSBmYXJiaWdlbiBLw6RzdGVuLCBbV29ydF17dGVpbD1jeWJlcnBpfSB6ZWlndCBhdWYgZWluIFRlaWwgZGVzIG1Cb3QyLiAqL1xuXG5jb25zdCBlc2NhcGUgPSAoczogc3RyaW5nKSA9PiBzLnJlcGxhY2UoLyYvZywgJyZhbXA7JykucmVwbGFjZSgvPC9nLCAnJmx0OycpLnJlcGxhY2UoLz4vZywgJyZndDsnKS5yZXBsYWNlKC9cIi9nLCAnJnF1b3Q7JylcblxuZXhwb3J0IGZ1bmN0aW9uIGlubGluZSh0ZXh0OiBzdHJpbmcpOiBzdHJpbmcge1xuICBjb25zdCBjb2Rlczogc3RyaW5nW10gPSBbXVxuICBsZXQgcyA9IGVzY2FwZSh0ZXh0KS5yZXBsYWNlKC9gKFteYF0rKWAvZywgKF8sIGM6IHN0cmluZykgPT4ge1xuICAgIGNvZGVzLnB1c2goYylcbiAgICByZXR1cm4gYFxcdTAwMDAke2NvZGVzLmxlbmd0aCAtIDF9XFx1MDAwMGBcbiAgfSlcbiAgcyA9IHNcbiAgICAucmVwbGFjZSgvXFwqXFwqKC4rPylcXCpcXCovZywgJzxzdHJvbmc+JDE8L3N0cm9uZz4nKVxuICAgIC5yZXBsYWNlKC8oXnxbXipdKVxcKihbXipcXHNdW14qXSo/KVxcKi9nLCAnJDE8ZW0+JDI8L2VtPicpXG4gICAgLnJlcGxhY2UoL1xcWyhbXlxcXV0rKVxcXVxcKChbXilcXHNdKylcXCkvZywgKF8sIGxhYmVsOiBzdHJpbmcsIHVybDogc3RyaW5nKSA9PiB7XG4gICAgICBjb25zdCBzYWZlID0gL14oaHR0cHM/OnxtYWlsdG86fCN8XFwuezAsMn1cXC8pLy50ZXN0KHVybCkgPyB1cmwgOiAnIydcbiAgICAgIGNvbnN0IGV4dGVybmFsID0gL15odHRwcz86Ly50ZXN0KHNhZmUpID8gJyB0YXJnZXQ9XCJfYmxhbmtcIiByZWw9XCJub29wZW5lciBub3JlZmVycmVyXCInIDogJydcbiAgICAgIHJldHVybiBgPGEgaHJlZj1cIiR7c2FmZX1cIiR7ZXh0ZXJuYWx9PiR7bGFiZWx9PC9hPmBcbiAgICB9KVxuICAgIC5yZXBsYWNlKC9cXFsoW15cXF1dKylcXF1cXHtcXC4oYmxhdXxvcmFuZ2V8Z3J1ZW58Z2VsYnxyb3NhKVxcfS9nLCAnPG1hcmsgY2xhc3M9XCJsZWFybi1tYXJrICQyXCI+JDE8L21hcms+JylcbiAgICAvLyBWaXN1Qm90OiBbVWx0cmFzY2hhbGxzZW5zb3Jde3RlaWw9dWx0cmFzb25pY30gbGV1Y2h0ZXQgaW0gM0QtTW9kZWxsIGF1Ziwgd2VubiBtYW4gZGFyYXVmIHplaWd0LlxuICAgIC5yZXBsYWNlKC9cXFsoW15cXF1dKylcXF1cXHsoPzp0ZWlsfHBhcnQpPShbXFx3LF0rKVxcfS9nLCAnPHNwYW4gY2xhc3M9XCJyb2JvdC1wYXJ0LWxpbmtcIiBkYXRhLXJvYm90LXBhcnQ9XCIkMlwiIHRhYmluZGV4PVwiMFwiPiQxPC9zcGFuPicpXG4gIHJldHVybiBzLnJlcGxhY2UoL1xcdTAwMDAoXFxkKylcXHUwMDAwL2csIChfLCBpOiBzdHJpbmcpID0+IGA8Y29kZT4ke2NvZGVzW051bWJlcihpKV19PC9jb2RlPmApXG59XG5cbmV4cG9ydCBmdW5jdGlvbiBtYXJrZG93blRvSFRNTChzb3VyY2U6IHN0cmluZyk6IHN0cmluZyB7XG4gIGNvbnN0IG91dDogc3RyaW5nW10gPSBbXVxuICBjb25zdCBsaW5lcyA9IHNvdXJjZS5yZXBsYWNlKC9cXHJcXG4vZywgJ1xcbicpLnNwbGl0KCdcXG4nKVxuICBsZXQgaSA9IDBcbiAgd2hpbGUgKGkgPCBsaW5lcy5sZW5ndGgpIHtcbiAgICBjb25zdCBsaW5lID0gbGluZXNbaV1cbiAgICBpZiAobGluZS50cmltKCkgPT09ICcnKSB7XG4gICAgICBpKytcbiAgICAgIGNvbnRpbnVlXG4gICAgfVxuICAgIGlmIChsaW5lLnN0YXJ0c1dpdGgoJ2BgYCcpKSB7XG4gICAgICAvLyBgYGBqYXZhIGVkaXRvcjogVW50ZXIgZGVtIEJlaXNwaWVsIHN0ZWh0IOKAnkltIEVkaXRvciDDtmZmbmVu4oCcLCBkYW5uIGthbm4gbWFuIGVzIGluIFByb2dyYW1taWVyZW4gYXVzcHJvYmllcmVuLlxuICAgICAgY29uc3QgW2xhbmcsIGV4dHJhXSA9IGxpbmUuc2xpY2UoMykudHJpbSgpLnNwbGl0KC9cXHMrLylcbiAgICAgIGNvbnN0IGphdmEgPSBsYW5nID09PSAnamF2YSdcbiAgICAgIGNvbnN0IG9wZW4gPSBqYXZhICYmIGV4dHJhID09PSAnZWRpdG9yJ1xuICAgICAgY29uc3QgY29kZTogc3RyaW5nW10gPSBbXVxuICAgICAgaSsrXG4gICAgICB3aGlsZSAoaSA8IGxpbmVzLmxlbmd0aCAmJiAhbGluZXNbaV0uc3RhcnRzV2l0aCgnYGBgJykpIGNvZGUucHVzaChsaW5lc1tpKytdKVxuICAgICAgaSsrXG4gICAgICBvdXQucHVzaChgPHByZSBjbGFzcz1cImxlc3Nvbi1jb2RlXCIke2phdmEgPyAnIGRhdGEtbGFuZz1cImphdmFcIicgOiAnJ30ke29wZW4gPyAnIGRhdGEtb3Blbj1cImVkaXRvclwiJyA6ICcnfSBkaXI9XCJsdHJcIj48Y29kZT4ke2VzY2FwZShjb2RlLmpvaW4oJ1xcbicpKX08L2NvZGU+PC9wcmU+YClcbiAgICAgIGNvbnRpbnVlXG4gICAgfVxuICAgIGNvbnN0IGhlYWRpbmcgPSAvXigjezIsNH0pXFxzKyguKikkLy5leGVjKGxpbmUpXG4gICAgaWYgKGhlYWRpbmcpIHtcbiAgICAgIGNvbnN0IGxldmVsID0gaGVhZGluZ1sxXS5sZW5ndGhcbiAgICAgIG91dC5wdXNoKGA8aCR7bGV2ZWx9PiR7aW5saW5lKGhlYWRpbmdbMl0pfTwvaCR7bGV2ZWx9PmApXG4gICAgICBpKytcbiAgICAgIGNvbnRpbnVlXG4gICAgfVxuICAgIGlmICgvXlxccyooWy0qXXxcXGQrXFwuKVxccysvLnRlc3QobGluZSkpIHtcbiAgICAgIGNvbnN0IG9yZGVyZWQgPSAvXlxccypcXGQrXFwuLy50ZXN0KGxpbmUpXG4gICAgICBjb25zdCBpdGVtczogc3RyaW5nW10gPSBbXVxuICAgICAgd2hpbGUgKGkgPCBsaW5lcy5sZW5ndGggJiYgL15cXHMqKFstKl18XFxkK1xcLilcXHMrLy50ZXN0KGxpbmVzW2ldKSkge1xuICAgICAgICBsZXQgaXRlbSA9IGxpbmVzW2ldLnJlcGxhY2UoL15cXHMqKFstKl18XFxkK1xcLilcXHMrLywgJycpXG4gICAgICAgIGkrK1xuICAgICAgICB3aGlsZSAoaSA8IGxpbmVzLmxlbmd0aCAmJiAvXlxcc3syLH1cXFMvLnRlc3QobGluZXNbaV0pICYmICEvXlxccyooWy0qXXxcXGQrXFwuKVxccysvLnRlc3QobGluZXNbaV0pKSBpdGVtICs9ICcgJyArIGxpbmVzW2krK10udHJpbSgpXG4gICAgICAgIGl0ZW1zLnB1c2goYDxsaT4ke2lubGluZShpdGVtKX08L2xpPmApXG4gICAgICB9XG4gICAgICBvdXQucHVzaChvcmRlcmVkID8gYDxvbD4ke2l0ZW1zLmpvaW4oJycpfTwvb2w+YCA6IGA8dWw+JHtpdGVtcy5qb2luKCcnKX08L3VsPmApXG4gICAgICBjb250aW51ZVxuICAgIH1cbiAgICBpZiAobGluZS5zdGFydHNXaXRoKCd8JykgJiYgL15cXHw/W1xcczp8LV0qLXszLH1bXFxzOnwtXSokLy50ZXN0KGxpbmVzW2kgKyAxXSA/PyAnJykpIHtcbiAgICAgIGNvbnN0IGNlbGxzID0gKHJvdzogc3RyaW5nKSA9PiByb3cudHJpbSgpLnJlcGxhY2UoL15cXHwvLCAnJykucmVwbGFjZSgvXFx8JC8sICcnKS5zcGxpdCgnfCcpLm1hcCgoYykgPT4gaW5saW5lKGMudHJpbSgpKSlcbiAgICAgIGNvbnN0IGhlYWQgPSBjZWxscyhsaW5lKVxuICAgICAgaSArPSAyXG4gICAgICBjb25zdCByb3dzOiBzdHJpbmdbXVtdID0gW11cbiAgICAgIHdoaWxlIChpIDwgbGluZXMubGVuZ3RoICYmIGxpbmVzW2ldLnN0YXJ0c1dpdGgoJ3wnKSkgcm93cy5wdXNoKGNlbGxzKGxpbmVzW2krK10pKVxuICAgICAgb3V0LnB1c2goXG4gICAgICAgIGA8ZGl2IGNsYXNzPVwibGVzc29uLXRhYmxlXCI+PHRhYmxlPjx0aGVhZD48dHI+JHtoZWFkLm1hcCgoYykgPT4gYDx0aD4ke2N9PC90aD5gKS5qb2luKCcnKX08L3RyPjwvdGhlYWQ+PHRib2R5PiR7cm93c1xuICAgICAgICAgIC5tYXAoKHIpID0+IGA8dHI+JHtyLm1hcCgoYykgPT4gYDx0ZD4ke2N9PC90ZD5gKS5qb2luKCcnKX08L3RyPmApXG4gICAgICAgICAgLmpvaW4oJycpfTwvdGJvZHk+PC90YWJsZT48L2Rpdj5gLFxuICAgICAgKVxuICAgICAgY29udGludWVcbiAgICB9XG4gICAgaWYgKGxpbmUuc3RhcnRzV2l0aCgnPicpKSB7XG4gICAgICBjb25zdCBxdW90ZTogc3RyaW5nW10gPSBbXVxuICAgICAgd2hpbGUgKGkgPCBsaW5lcy5sZW5ndGggJiYgbGluZXNbaV0uc3RhcnRzV2l0aCgnPicpKSBxdW90ZS5wdXNoKGxpbmVzW2krK10ucmVwbGFjZSgvXj5cXHM/LywgJycpKVxuICAgICAgb3V0LnB1c2goYDxhc2lkZSBjbGFzcz1cImxlc3Nvbi1ub3RlXCI+JHttYXJrZG93blRvSFRNTChxdW90ZS5qb2luKCdcXG4nKSl9PC9hc2lkZT5gKVxuICAgICAgY29udGludWVcbiAgICB9XG4gICAgY29uc3QgcGFyYTogc3RyaW5nW10gPSBbXVxuICAgIHdoaWxlIChcbiAgICAgIGkgPCBsaW5lcy5sZW5ndGggJiZcbiAgICAgIGxpbmVzW2ldLnRyaW0oKSAhPT0gJycgJiZcbiAgICAgICEvXihgYGB8I3szLDR9XFxzfD58XFx8fFxccyooWy0qXXxcXGQrXFwuKVxccyspLy50ZXN0KGxpbmVzW2ldKVxuICAgICkge1xuICAgICAgcGFyYS5wdXNoKGxpbmVzW2krK10udHJpbSgpKVxuICAgIH1cbiAgICBvdXQucHVzaChgPHA+JHtpbmxpbmUocGFyYS5qb2luKCcgJykpfTwvcD5gKVxuICB9XG4gIHJldHVybiBvdXQuam9pbignXFxuJylcbn1cbiJdLCJmaWxlIjoiL3dlYi9zcmMvbGVhcm4vbWFya2Rvd24udHMifQ== - -//# vitestCache=W3siZmlsZSI6IjEiLCJpZCI6IjEiLCJ1cmwiOiIyIiwiaW1wb3J0cyI6IjMiLCJtYXBwaW5ncyI6ZmFsc2UsImRlcHMiOiI0IiwiZHluYW1pY0RlcHMiOiI1Iiwic3RhdGljTW9ja3MiOm51bGx9LCIvaG9tZS91c2VyL3Zpc3VzdHJ1Y3Qtc3dpZnR1aS93ZWIvc3JjL2xlYXJuL21hcmtkb3duLnRzIiwiL3dlYi9zcmMvbGVhcm4vbWFya2Rvd24udHMiLHsidXJscyI6IjYiLCJpZHMiOiI3In0sW10sW10sW10se31d \ No newline at end of file diff --git a/node_modules/.vitest-cache/c9e09693ee8175a114f4dbe1e385c70c5582fca5 b/node_modules/.vitest-cache/c9e09693ee8175a114f4dbe1e385c70c5582fca5 deleted file mode 100644 index c4d4930c..00000000 --- a/node_modules/.vitest-cache/c9e09693ee8175a114f4dbe1e385c70c5582fca5 +++ /dev/null @@ -1,567 +0,0 @@ -__vite_ssr_exportName__("FormatError", () => { try { return FormatError } catch {} }); -__vite_ssr_exportName__("parseTest", () => { try { return parseTest } catch {} }); -__vite_ssr_exportName__("parseSensorTest", () => { try { return parseSensorTest } catch {} }); -__vite_ssr_exportName__("parseBlocks", () => { try { return parseBlocks } catch {} }); -__vite_ssr_exportName__("parseLesson", () => { try { return parseLesson } catch {} }); -__vite_ssr_exportName__("parseTask", () => { try { return parseTask } catch {} }); -const __vite_ssr_import_0__ = await __vite_ssr_import__("/web/src/core/mbot.ts", {"importedNames":["driveSignature","isMBotPart","MBOT_PARTS","MBOT_SENSORS","parseActionSpec","parseDriveSpec"]}); -const __vite_ssr_import_1__ = await __vite_ssr_import__("/web/src/learn/boolGame.ts", {"importedNames":["parseBoolGame"]}); -const __vite_ssr_import_2__ = await __vite_ssr_import__("/web/src/learn/roundGame.ts", {"importedNames":["isRoundGameKind","parseRoundGame"]}); -const __vite_ssr_import_3__ = await __vite_ssr_import__("/web/src/learn/rescueGame.ts", {"importedNames":["parseRescueGame"]}); -const __vite_ssr_import_4__ = await __vite_ssr_import__("/web/src/learn/cloze.ts", {"importedNames":["parseCloze"]}); -const __vite_ssr_import_5__ = await __vite_ssr_import__("/web/src/learn/pap.ts", {"importedNames":["parsePap"]}); - - - - - - -class FormatError extends Error {}; -function frontMatter(source, file) { - const m = /^---\n([\s\S]*?)\n---\n?/.exec(source.replace(/\r\n/g, "\n")); - if (!m) throw new FormatError(`${file}: Kopfzeilen (--- … ---) fehlen.`); - const meta = new Map(); - for (const line of m[1].split("\n")) { - const kv = /^([a-zäöüß]+):\s*(.*)$/i.exec(line.trim()); - if (kv) meta.set(kv[1].toLowerCase(), kv[2].trim()); - }; - return { - meta, - body: source.replace(/\r\n/g, "\n").slice(m[0].length) - }; -} -/** `3, 4 -> 7 | 8` = Eingaben 3 und 4, erwartete Ausgabezeilen 7 und 8. */ -function parseTest(spec, file) { - const parts = spec.split(/\s*(?:->|→)\s*/); - if (parts.length !== 2) throw new FormatError(`${file}: Test „${spec}“ braucht genau ein „->“.`); - const list = (s, sep) => s.trim() === "" || s.trim() === "-" ? [] : s.split(sep).map((x) => x.trim()); - return { - inputs: list(parts[0], /\s*,\s*/), - expected: list(parts[1], /\s*\|\s*/) - }; -}; -/** `getLoudness=0/80, isButtonA=true -> forward 30, ledOn` (siehe `messwerte:`). */ -function parseSensorTest(value) { - const arrow = /^(.*?)\s*(?:->|→)\s*(.*)$/.exec(value.trim()); - if (!arrow) throw new Error(`„messwerte: ${value}“ braucht ein „->“.`); - const sensors = {}; - for (const part of arrow[1].split(/\s*,\s*/).filter(Boolean)) { - const m = /^(\w+)\s*=\s*(.+)$/.exec(part); - if (!m || !(m[1] in __vite_ssr_import_0__.MBOT_SENSORS)) throw new Error(`Unbekannter Sensor in „${part}“.`); - sensors[m[1]] = m[2].split("/").map((v) => { - const t = v.trim(); - if (t === "true" || t === "false") return t === "true"; - if (/^-?\d+(\.\d+)?$/.test(t)) return Number(t); - // Text, z. B. eine Farbe: getColor=rot - if (typeof __vite_ssr_import_0__.MBOT_SENSORS[m[1]].simulated === "string") return t; - throw new Error(`Messwert „${t}“ ist keine Zahl und nicht true/false.`); - }); - }; - return robotExpectation({ - inputs: [], - expected: [], - sensors - }, arrow[2]); -}; -/** Rechte Seite von `welt: … ->` und `messwerte: … ->`: Fahrt sowie `ledOn`, `ledOff`, `tone`, `noTone`, `none` (fährt nicht), `drives` (fährt irgendwie), `screen "Text"`. */ -function robotExpectation(test, spec) { - const drive = []; - // `screen "Abstand: 42 cm"`: dieser Text steht am Ende auf dem Bildschirm (darf Kommas enthalten) - spec = spec.replace(/\bscreen\s+("(?:[^"\\]|\\.)*")/u, (_, text) => { - test.screen = JSON.parse(text); - return ""; - }); - for (const token of spec.split(/\s*,\s*/).filter(Boolean)) { - if (token === "ledOn" || token === "ledOff") test.led = token === "ledOn"; - else if (token === "tone" || token === "noTone") test.tone = token === "tone"; - else if (token === "none") test.drive = []; - else if (token === "drives") test.drives = true; - else drive.push(token); - }; - if (drive.length) test.drive = (0,__vite_ssr_import_0__.driveSignature)((0,__vite_ssr_import_0__.parseDriveSpec)(drive.join(", "))); - return test; -} -function parseExercise(id, lines, file) { - const ex = { - id, - title: "", - task: "", - tests: [], - requires: [], - hints: [], - subprograms: [] - }; - let last; - for (const raw of lines) { - const kv = /^(titel|auftrag|start|test|datei|fahrt|befehle|welt|messwerte|schleifentiefe|braucht|tipp|lösung|loesung|unterprogramm|code):\s*(.*)$/i.exec(raw.trim()); - if (kv) { - const [, key, value] = kv; - last = undefined; - switch (key.toLowerCase()) { - case "titel": - ex.title = value; - break; - case "auftrag": - ex.task = value; - last = "task"; - break; - case "start": - ex.start = value; - break; - case "test": - ex.tests.push(parseTest(value, file)); - break; - case "datei": { - // `datei: neu.txt -> Heu | Äpfel`: Diese Datei soll das Programm im letzten Test speichern. - const m = /^([\w.-]+)\s*(?:->|→)\s*(.*)$/.exec(value.trim()); - if (!m || !ex.tests.length) throw new FormatError(`${file}: Übung „${id}“: „datei:“ braucht vorher einen Test und die Form „name.txt -> Zeile | Zeile“.`); - const expected = ex.tests[ex.tests.length - 1]; - expected.files = [...expected.files ?? [], { - name: m[1], - lines: m[2].trim() === "" ? [] : m[2].split(/\s*\|\s*/).map((x) => x.trim()) - }]; - break; - } - case "fahrt": - // VisuBot: `fahrt: 4 x (forward 50, turnRight 90)` – so soll der Roboter fahren (ohne Ausgabe, ohne Eingabe). - try { - ex.tests.push({ - inputs: [], - expected: [], - drive: (0,__vite_ssr_import_0__.driveSignature)((0,__vite_ssr_import_0__.parseDriveSpec)(value)) - }); - } catch (err) { - throw new FormatError(`${file}: Übung „${id}“: ${err.message}`); - }; - break; - case "welt": { - // VisuBot: `welt: wand-nah, wand-weit` – in jeder dieser Welten muss der Roboter ohne Anstoßen ins Ziel. - // `welt: wand-nah -> turnRight` – in dieser Welt soll er genau so fahren (für Verzweigungen mit Sensoren). - const arrow = /^([\w-]+)\s*(?:->|→)\s*(.+)$/.exec(value.trim()); - if (arrow) { - try { - ex.tests.push(robotExpectation({ - inputs: [], - expected: [], - world: arrow[1] - }, arrow[2])); - } catch (err) { - throw new FormatError(`${file}: Übung „${id}“: ${err.message}`); - }; - break; - }; - for (const name of value.split(/\s*,\s*/).filter(Boolean)) { - if (!/^[\w-]+$/.test(name)) throw new FormatError(`${file}: Übung „${id}“: Weltname „${name}“ (nur Buchstaben, Ziffern, -).`); - ex.tests.push({ - inputs: [], - expected: [], - world: name - }); - }; - break; - } - case "befehle": - // VisuBot: `befehle: 3 x (setLed 255 0 0, pause 500, ledOff, pause 500)` – genau diese Befehle für LEDs, Ton und Bildschirm. - try { - ex.tests.push({ - inputs: [], - expected: [], - actions: (0,__vite_ssr_import_0__.parseActionSpec)(value) - }); - } catch (err) { - throw new FormatError(`${file}: Übung „${id}“: ${err.message}`); - }; - break; - case "messwerte": - // VisuBot: `messwerte: getLoudness=0/80, isButtonA=false -> forward, ledOn` – mit diesen Sensorwerten - // (nacheinander, durch / getrennt) soll der Roboter so fahren bzw. leuchten (`ledOn`, `ledOff`, `tone`, `noTone`, `none`). - try { - ex.tests.push(parseSensorTest(value)); - } catch (err) { - throw new FormatError(`${file}: Übung „${id}“: ${err.message}`); - }; - break; - case "schleifentiefe": - ex.loopDepth = Number(value); - if (!Number.isInteger(ex.loopDepth) || ex.loopDepth < 1) throw new FormatError(`${file}: Übung „${id}“: „schleifentiefe:“ braucht eine Zahl ab 1.`); - break; - case "braucht": - ex.requires.push(...value.split(/\s*,\s*/).filter(Boolean)); - break; - case "tipp": - ex.hints.push(value); - last = "hint"; - break; - case "lösung": - case "loesung": - ex.solution = value; - break; - case "unterprogramm": - ex.subprograms.push(...value.split(/\s*,\s*/).filter(Boolean)); - break; - case "code": - if (value.trim().toLowerCase() !== "java") throw new FormatError(`${file}: Übung „${id}“: „code:“ kennt nur „java“.`); - ex.code = "java"; - break; - } - } else if (last && raw.trim() !== "") { - // Fortsetzungszeilen für Auftrag und Tipp - if (last === "task") ex.task += "\n" + raw.trim(); - else ex.hints[ex.hints.length - 1] += "\n" + raw.trim(); - } else if (raw.trim() === "" && last === "task") { - ex.task += "\n"; - } - }; - if (!ex.title) throw new FormatError(`${file}: Übung „${id}“ hat keinen Titel.`); - if (!ex.task.trim()) throw new FormatError(`${file}: Übung „${id}“ hat keinen Auftrag.`); - ex.task = ex.task.trim(); - return ex; -} -function parseQuiz(lines, file) { - const questions = []; - for (const raw of lines) { - const line = raw.trim(); - if (line.startsWith("?")) { - questions.push({ - question: line.slice(1).trim(), - options: [] - }); - } else if (/^- \[[ xX]\]/.test(line)) { - const q = questions.at(-1); - if (!q) throw new FormatError(`${file}: Antwort ohne Frage im Quiz.`); - q.options.push({ - text: line.slice(5).trim(), - correct: line[3].toLowerCase() === "x" - }); - } else if (line.startsWith("= ")) { - const q = questions.at(-1); - const m = /^=\s+(.+?)\s+->\s+(.+)$/.exec(line); - if (!q || !m) throw new FormatError(`${file}: Zuordnung „${line}“ braucht die Form „= links -> rechts“ nach einer Frage.`); - (q.pairs ??= []).push({ - left: m[1].trim(), - right: m[2].trim() - }); - } else if (line.startsWith("→")) { - const q = questions.at(-1); - if (!q) throw new FormatError(`${file}: „→ Schritt“ ohne Frage im Quiz.`); - q.ref = line.slice(1).trim(); - } else if (line.startsWith(">")) { - const q = questions.at(-1); - if (q) q.explanation = ((q.explanation ? q.explanation + " " : "") + line.slice(1).trim()).trim(); - } - }; - for (const q of questions) { - if (q.pairs) { - const rights = new Set(q.pairs.map((p) => p.right)); - if (q.options.length > 0 || q.pairs.length < 2 || rights.size !== q.pairs.length) { - throw new FormatError(`${file}: Zuordnung „${q.question}“ braucht mindestens zwei Paare mit verschiedenen rechten Seiten und keine Antworten.`); - }; - continue; - }; - if (q.options.length < 2 || !q.options.some((o) => o.correct)) { - throw new FormatError(`${file}: Quizfrage „${q.question}“ braucht mindestens zwei Antworten, davon eine richtige.`); - } - }; - return questions; -} -/** Text in Blöcke zerlegen: normales Markdown und `::: art …` bis `:::`. */ -function parseBlocks(body, file) { - const blocks = []; - const lines = body.split("\n"); - let markdown = []; - const flush = () => { - const text = markdown.join("\n").trim(); - if (text) blocks.push({ - kind: "markdown", - text - }); - markdown = []; - }; - for (let i = 0; i < lines.length; i++) { - const open = /^:::\s*([a-zäöüß][a-zäöüß0-9]*)\s*(.*)$/i.exec(lines[i].trim()); - if (!open) { - markdown.push(lines[i]); - continue; - }; - flush(); - const inner = []; - let j = i + 1; - while (j < lines.length && lines[j].trim() !== ":::") inner.push(lines[j++]); - if (j >= lines.length) throw new FormatError(`${file}: Block „::: ${open[1]}“ wird nicht mit „:::“ geschlossen.`); - const kind = open[1].toLowerCase(); - const arg = open[2].trim(); - switch (kind) { - case "diagramm": - if (!arg) throw new FormatError(`${file}: „::: diagramm“ braucht einen Dateinamen.`); - blocks.push({ - kind: "diagram", - file: arg, - caption: inner.join(" ").trim() - }); - break; - case "übung": - case "uebung": - if (!arg) throw new FormatError(`${file}: „::: übung“ braucht eine Kennung.`); - blocks.push({ - kind: "exercise", - exercise: parseExercise(arg, inner, file) - }); - break; - case "checkliste": - blocks.push({ - kind: "checklist", - items: inner.map((l) => l.trim()).filter((l) => l.startsWith("- ")).map((l) => checklistItem(l.slice(2).trim())) - }); - break; - case "kompetenzen": - blocks.push({ - kind: "competences", - items: inner.map((l) => l.trim()).filter((l) => l.startsWith("- ")).map((l) => l.slice(2).trim()) - }); - break; - case "quiz": - blocks.push({ - kind: "quiz", - questions: parseQuiz(inner, file) - }); - break; - case "bild": - if (!arg) throw new FormatError(`${file}: „::: bild“ braucht einen Dateinamen.`); - blocks.push({ - kind: "images", - files: arg.split(/\s+/), - caption: inner.join(" ").trim() - }); - break; - case "grafik": - if (!arg) throw new FormatError(`${file}: „::: grafik“ braucht einen Dateinamen.`); - { - const [graphic, labeled] = arg.split(/\s+/); - blocks.push({ - kind: "graphic", - file: graphic, - ...labeled ? { labeled } : {}, - caption: inner.join(" ").trim() - }); - } - break; - case "angeberwissen": - blocks.push({ - kind: "brag", - text: inner.join("\n").trim() - }); - break; - case "spiel": - try { - if ((0,__vite_ssr_import_2__.isRoundGameKind)(arg)) blocks.push({ - kind: "roundGame", - game: (0,__vite_ssr_import_2__.parseRoundGame)(arg, inner, file) - }); - else if (arg === "prinzessin") blocks.push({ - kind: "rescueGame", - game: (0,__vite_ssr_import_3__.parseRescueGame)(inner, file) - }); - else if (arg) throw new FormatError(`${file}: Unbekanntes Spiel „${arg}“ (zuhoerer, vertrag, layout, bombe, frage, reihenfolge oder prinzessin).`); - else blocks.push({ - kind: "game", - game: (0,__vite_ssr_import_1__.parseBoolGame)(inner, file) - }); - } catch (err) { - throw new FormatError(err.message); - }; - break; - case "lückentext": - case "lueckentext": - try { - blocks.push({ - kind: "cloze", - cloze: (0,__vite_ssr_import_4__.parseCloze)(inner, file) - }); - } catch (err) { - throw new FormatError(err.message); - }; - break; - case "pap": - try { - blocks.push({ - kind: "pap", - pap: (0,__vite_ssr_import_5__.parsePap)(inner, file) - }); - } catch (err) { - throw new FormatError(err.message); - }; - break; - case "profiwissen": - blocks.push({ - kind: "brag", - text: inner.join("\n").trim(), - pro: true - }); - break; - case "ludwig": - blocks.push({ - kind: "brag", - text: inner.join("\n").trim(), - tip: true - }); - break; - case "caesar": { - const key = arg ? Number(arg) : 3; - if (!Number.isInteger(key) || key < 0 || key > 25) throw new FormatError(`${file}: „::: caesar“ braucht einen Schlüssel von 0 bis 25.`); - blocks.push({ - kind: "caesar", - key, - text: inner.join(" ").trim() - }); - break; - } - case "mbot2": { - // `fokus: cyberpi, screen`, `ansicht: unten`, `drehen: ja` - const block = { - kind: "robotModel", - focus: [] - }; - for (const line of inner.filter((l) => l.trim())) { - const m = /^\s*(fokus|focus|ansicht|view|drehen|spin):\s*(.*)$/i.exec(line); - if (!m) throw new FormatError(`${file}: „::: mbot2“ kennt nur Zeilen „fokus:“, „ansicht:“ und „drehen:“.`); - const key = m[1].toLowerCase(); - if (key === "fokus" || key === "focus") block.focus = robotParts(m[2], file); - else if (key === "ansicht" || key === "view") block.view = m[2].trim().toLowerCase(); - else block.spin = /^(ja|yes|true|sim)$/i.test(m[2].trim()); - }; - blocks.push(block); - break; - } - case "mbot2quiz": { - // `- ultrasonic: Wo ist der **Ultraschallsensor**?` und `fertig: Super!` - const block = { - kind: "robotQuiz", - tasks: [] - }; - for (const line of inner.filter((l) => l.trim())) { - const task = /^\s*-\s*(\w+)\s*:\s*(.+)$/.exec(line); - const done = /^\s*(fertig|done):\s*(.+)$/i.exec(line); - if (task) block.tasks.push({ - part: robotParts(task[1], file)[0], - question: task[2].trim() - }); - else if (done) block.done = done[2].trim(); - else throw new FormatError(`${file}: „::: mbot2quiz“ braucht Zeilen „- teil: Frage“ und optional „fertig: Text“.`); - }; - if (!block.tasks.length) throw new FormatError(`${file}: „::: mbot2quiz“ hat keine Fragen.`); - blocks.push(block); - break; - } - case "datei": { - if (!/^[\w.-]+\.(txt|csv|json)$/u.test(arg)) throw new FormatError(`${file}: „::: datei“ braucht einen Dateinamen wie brief.txt, liste.csv oder daten.json.`); - // Der Inhalt bleibt genau so, wie er dasteht, nur ohne Leerzeilen am Anfang und Ende. - while (inner.length && inner[0].trim() === "") inner.shift(); - while (inner.length && inner[inner.length - 1].trim() === "") inner.pop(); - blocks.push({ - kind: "textFile", - name: arg, - content: inner.join("\n") - }); - break; - } - default: throw new FormatError(`${file}: Unbekannter Block „::: ${open[1]}“.`); - }; - i = j; - }; - flush(); - return blocks; -}; -function checklistItem(line) { - const m = /^(.*?)\s+→\s+(.+)$/.exec(line); - return m ? { - text: m[1], - ref: m[2].trim() - } : { text: line }; -} -/** Verweise aus Checklisten auf den erklärenden Schritt auflösen. */ -function resolveChecklistRefs(steps, file) { - const index = new Map(steps.map((s, i) => [s.title.toLowerCase(), i])); - for (const block of steps.flatMap((s) => s.blocks)) { - if (block.kind !== "checklist") continue; - for (const item of block.items) { - if (item.ref === undefined) continue; - item.step = index.get(item.ref.toLowerCase()); - if (item.step === undefined) throw new FormatError(`${file}: Checkliste verweist auf unbekannten Schritt „${item.ref}“.`); - } - }; - const checked = new Set(steps.flatMap((s) => s.blocks).flatMap((b) => b.kind === "checklist" ? b.items.map((i) => i.step) : [])); - for (const block of steps.flatMap((s) => s.blocks)) { - if (block.kind !== "quiz") continue; - for (const q of block.questions) { - if (q.ref === undefined) continue; - q.step = index.get(q.ref.toLowerCase()); - if (q.step === undefined) throw new FormatError(`${file}: Quizfrage „${q.question}“ verweist auf unbekannten Schritt „${q.ref}“.`); - if (!checked.has(q.step)) throw new FormatError(`${file}: Zu „${q.ref}“ (Quizfrage „${q.question}“) gibt es keinen Checklistenpunkt.`); - } - } -} -function parseLesson(source, file) { - const { meta, body } = frontMatter(source, file); - const name = file.replace(/^.*\//, "").replace(/\.md$/, ""); - const number = Number(/^(\d+)/.exec(name)?.[1]); - if (!Number.isFinite(number)) throw new FormatError(`${file}: Dateiname muss mit der Nummer beginnen (z. B. 01-…).`); - const steps = []; - let intro = []; - let current; - const close = () => { - if (current) steps.push({ - title: current.title, - blocks: parseBlocks(current.lines.join("\n"), file) - }); - }; - for (const line of body.split("\n")) { - const h = /^##\s+(.*)$/.exec(line); - if (h) { - close(); - current = { - title: h[1].trim(), - lines: [] - }; - } else if (current) { - current.lines.push(line); - } else { - intro.push(line); - } - }; - close(); - if (steps.length === 0) throw new FormatError(`${file}: Keine Schritte (## Überschrift) gefunden.`); - resolveChecklistRefs(steps, file); - const title = meta.get("titel"); - if (!title) throw new FormatError(`${file}: „titel:“ fehlt.`); - return { - id: name, - number, - title, - section: meta.get("bereich") ?? "", - summary: meta.get("kurz") ?? intro.join(" ").trim(), - steps - }; -}; -function parseTask(source, file) { - const { meta, body } = frontMatter(source, file); - const title = meta.get("titel"); - if (!title) throw new FormatError(`${file}: „titel:“ fehlt.`); - const after = meta.get("nach"); - return { - id: file.replace(/^.*\//, "").replace(/\.md$/, ""), - title, - after: after ? Number(after) : undefined, - level: Number(meta.get("stufe") ?? "1") || 1, - blocks: parseBlocks(body, file) - }; -}; -/** `cyberpi, screen` → geprüfte Teilnamen des mBot2-Modells. */ -function robotParts(list, file) { - const names = list.split(/\s*,\s*/).map((x) => x.trim()).filter(Boolean); - for (const n of names) if (!(0,__vite_ssr_import_0__.isMBotPart)(n)) throw new FormatError(`${file}: Unbekanntes Teil „${n}“. Bekannt: ${__vite_ssr_import_0__.MBOT_PARTS.join(", ")}.`); - return names; -} -//# sourceMappingSource=vite-generated -//# sourceMappingURL=data:application/json;base64,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LEtBQUs7RUFDaEMsU0FBUyxLQUFLLElBQUksTUFBTSxLQUFLLE1BQU0sS0FBSyxHQUFHLENBQUMsQ0FBQyxLQUFLO0VBQ2xEO0NBQ0Y7QUFDRjtBQUVPLFNBQVMsVUFBVSxRQUFnQixNQUFvQjtDQUM1RCxNQUFNLEVBQUUsTUFBTSxTQUFTLFlBQVksUUFBUSxJQUFJO0NBQy9DLE1BQU0sUUFBUSxLQUFLLElBQUksT0FBTztDQUM5QixJQUFJLENBQUMsT0FBTyxNQUFNLElBQUksWUFBWSxHQUFHLEtBQUssa0JBQWtCO0NBQzVELE1BQU0sUUFBUSxLQUFLLElBQUksTUFBTTtDQUM3QixPQUFPO0VBQ0wsSUFBSSxLQUFLLFFBQVEsU0FBUyxFQUFFLENBQUMsQ0FBQyxRQUFRLFNBQVMsRUFBRTtFQUNqRDtFQUNBLE9BQU8sUUFBUSxPQUFPLEtBQUssSUFBSTtFQUMvQixPQUFPLE9BQU8sS0FBSyxJQUFJLE9BQU8sS0FBSyxHQUFHLEtBQUs7RUFDM0MsUUFBUSxZQUFZLE1BQU0sSUFBSTtDQUNoQztBQUNGOztBQUdBLFNBQVMsV0FBVyxNQUFjLE1BQTBCO0NBQzFELE1BQU0sUUFBUSxLQUFLLE1BQU0sU0FBUyxDQUFDLENBQUMsS0FBSyxNQUFNLEVBQUUsS0FBSyxDQUFDLENBQUMsQ0FBQyxPQUFPLE9BQU87Q0FDdkUsS0FBSyxNQUFNLEtBQUssT0FBTyxJQUFJLENBQUMscUNBQVcsQ0FBQyxHQUFHLE1BQU0sSUFBSSxZQUFZLEdBQUcsS0FBSyxzQkFBc0IsRUFBRSxjQUFjLGlDQUFXLEtBQUssSUFBSSxFQUFFLEVBQUU7Q0FDdkksT0FBTztBQUNUIiwibmFtZXMiOltdLCJpZ25vcmVMaXN0IjpbXSwic291cmNlcyI6WyJsZXNzb25Gb3JtYXQudHMiXSwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHR5cGUgeyBFeGVyY2lzZVRlc3QgfSBmcm9tICcuLi9jb3JlL2V4ZXJjaXNlQ2hlY2snXG5pbXBvcnQgeyBkcml2ZVNpZ25hdHVyZSwgaXNNQm90UGFydCwgTUJPVF9QQVJUUywgTUJPVF9TRU5TT1JTLCBwYXJzZUFjdGlvblNwZWMsIHBhcnNlRHJpdmVTcGVjLCB0eXBlIE1Cb3RQYXJ0LCB0eXBlIE1Cb3RTZW5zb3JWYWx1ZSB9IGZyb20gJy4uL2NvcmUvbWJvdCdcbmltcG9ydCB7IHBhcnNlQm9vbEdhbWUsIHR5cGUgQm9vbEdhbWUgfSBmcm9tICcuL2Jvb2xHYW1lJ1xuaW1wb3J0IHsgaXNSb3VuZEdhbWVLaW5kLCBwYXJzZVJvdW5kR2FtZSwgdHlwZSBSb3VuZEdhbWUgfSBmcm9tICcuL3JvdW5kR2FtZSdcbmltcG9ydCB7IHBhcnNlUmVzY3VlR2FtZSwgdHlwZSBSZXNjdWVHYW1lIH0gZnJvbSAnLi9yZXNjdWVHYW1lJ1xuaW1wb3J0IHsgcGFyc2VDbG96ZSwgdHlwZSBDbG96ZSB9IGZyb20gJy4vY2xvemUnXG5pbXBvcnQgeyBwYXJzZVBhcCwgdHlwZSBQYXAgfSBmcm9tICcuL3BhcCdcblxuLyoqXG4gKiBMZWt0aW9uZW4gdW5kIEF1ZmdhYmVuIGFscyBNYXJrZG93biBtaXQgS29wZnplaWxlbiB1bmQgYDo6OmAtQmzDtmNrZW4gKHNpZWhlIGBsZXNzb25zL1JFQURNRS5tZGApLlxuICogSmVkZSBgIyMgw5xiZXJzY2hyaWZ0YCBiZWdpbm50IGVpbmVuIG5ldWVuIFNjaHJpdHQuXG4gKi9cblxuZXhwb3J0IHR5cGUgQmxvY2sgPVxuICB8IHsga2luZDogJ21hcmtkb3duJzsgdGV4dDogc3RyaW5nIH1cbiAgfCB7IGtpbmQ6ICdkaWFncmFtJzsgZmlsZTogc3RyaW5nOyBjYXB0aW9uOiBzdHJpbmcgfVxuICB8IHsga2luZDogJ2V4ZXJjaXNlJzsgZXhlcmNpc2U6IEV4ZXJjaXNlIH1cbiAgfCB7IGtpbmQ6ICdjaGVja2xpc3QnOyBpdGVtczogQ2hlY2tsaXN0SXRlbVtdIH1cbiAgLyoqIEtvbXBldGVuemVuIGFtIEFuZmFuZyBkZXIgTGVrdGlvbiAo4oCeRGllc2UgS29tcGV0ZW56ZW4gZXJ3ZXJiZSBpY2ggamV0enTigJwpLiAqL1xuICB8IHsga2luZDogJ2NvbXBldGVuY2VzJzsgaXRlbXM6IHN0cmluZ1tdIH1cbiAgfCB7IGtpbmQ6ICdxdWl6JzsgcXVlc3Rpb25zOiBRdWl6UXVlc3Rpb25bXSB9XG4gIHwgeyBraW5kOiAnYnJhZyc7IHRleHQ6IHN0cmluZzsgdGlwPzogYm9vbGVhbjsgcHJvPzogYm9vbGVhbiB9XG4gIHwgeyBraW5kOiAnaW1hZ2VzJzsgZmlsZXM6IHN0cmluZ1tdOyBjYXB0aW9uOiBzdHJpbmcgfVxuICAvKiogYGxhYmVsZWRgOiBiZXNjaHJpZnRldGUgRmFzc3VuZywgZGllIGVpbiBLbGljayBhdWYgZGllIEdyYWZpayBlaW4tIHVuZCBhdXNibGVuZGV0LiAqL1xuICB8IHsga2luZDogJ2dyYXBoaWMnOyBmaWxlOiBzdHJpbmc7IGxhYmVsZWQ/OiBzdHJpbmc7IGNhcHRpb246IHN0cmluZyB9XG4gIHwgeyBraW5kOiAnZ2FtZSc7IGdhbWU6IEJvb2xHYW1lIH1cbiAgfCB7IGtpbmQ6ICdyb3VuZEdhbWUnOyBnYW1lOiBSb3VuZEdhbWUgfVxuICB8IHsga2luZDogJ3Jlc2N1ZUdhbWUnOyBnYW1lOiBSZXNjdWVHYW1lIH1cbiAgfCB7IGtpbmQ6ICdjYWVzYXInOyBrZXk6IG51bWJlcjsgdGV4dDogc3RyaW5nIH1cbiAgLyoqIFZpc3VCb3Q6IGRyZWhiYXJlcyAzRC1Nb2RlbGwgZGVzIG1Cb3QyLCBUZWlsZSBhbnRpcHBlbiB6ZWlndCBpaHJlIEVya2zDpHJ1bmcuICovXG4gIC8qKiBWaXN1Qm90OiBkZXIgbUJvdDIgaW4gM0Q7IGRpZSBLYW1lcmEgZsOkaHJ0IHp1IGRlbiBUZWlsZW4gaW4gYGZvY3VzYCAoVG91ciB3aWUgYmVpIEphdmFQaWNvR29hdCkuICovXG4gIHwgeyBraW5kOiAncm9ib3RNb2RlbCc7IGZvY3VzOiBNQm90UGFydFtdOyB2aWV3Pzogc3RyaW5nOyBzcGluPzogYm9vbGVhbiB9XG4gIC8qKiBWaXN1Qm90OiBUZWlsZSBpbSBNb2RlbGwgYW5rbGlja2VuICjigJ5XbyBpc3QgZGVyIFVsdHJhc2NoYWxsc2Vuc29yP+KAnCkuICovXG4gIHwgeyBraW5kOiAncm9ib3RRdWl6JzsgdGFza3M6IHsgcGFydDogTUJvdFBhcnQ7IHF1ZXN0aW9uOiBzdHJpbmcgfVtdOyBkb25lPzogc3RyaW5nIH1cbiAgLyoqIEZlcnRpZ2VyIENvZGUgbWl0IEzDvGNrZW4gZsO8ciBlaW56ZWxuZSBXw7ZydGVyLiAqL1xuICB8IHsga2luZDogJ2Nsb3plJzsgY2xvemU6IENsb3plIH1cbiAgLyoqIFByb2dyYW1tYWJsYXVmcGxhbiBtaXQgbGVlcmVuIFBsw6R0emVuLCBkaWUgZmVydGlnZW4gRWxlbWVudGUgbGVndCBtYW4gaGluZWluLiAqL1xuICB8IHsga2luZDogJ3BhcCc7IHBhcDogUGFwIH1cbiAgLyoqIEVpbmUgVGV4dGRhdGVpIHp1bSBFaW5sZXNlbjogYEZpbGVzLnJlYWRTdHJpbmcoUGF0aC5vZihcIm5hbWVcIikpYCBsaWVmZXJ0IGlocmVuIEluaGFsdC4gKi9cbiAgfCB7IGtpbmQ6ICd0ZXh0RmlsZSc7IG5hbWU6IHN0cmluZzsgY29udGVudDogc3RyaW5nIH1cblxuZXhwb3J0IGludGVyZmFjZSBFeGVyY2lzZSB7XG4gIGlkOiBzdHJpbmdcbiAgdGl0bGU6IHN0cmluZ1xuICB0YXNrOiBzdHJpbmdcbiAgLyoqIFN0YXJ0ZGlhZ3JhbW0gKERhdGVpIGluIGBsZXNzb25zL2RpYWdyYW1tZWApOyBzb25zdCBsZWVyZXMgRGlhZ3JhbW0uICovXG4gIHN0YXJ0Pzogc3RyaW5nXG4gIHRlc3RzOiBFeGVyY2lzZVRlc3RbXVxuICAvKiogRWxlbWVudGFydGVuLCBkaWUgdm9ya29tbWVuIG3DvHNzZW4gKFNjaGzDvHNzZWwgd2llIGluIGRlciBQYWxldHRlLCB6LiBCLiBgdmVyendlaWd1bmdgKS4gKi9cbiAgcmVxdWlyZXM6IHN0cmluZ1tdXG4gIC8qKiBHZXN0dWZ0ZSBUaXBwcyAoZWluZSBgdGlwcDpgLVplaWxlIGplIFRpcHApLCB2b20gYWxsZ2VtZWluZW4genVtIGdlbmF1ZW4uICovXG4gIGhpbnRzOiBzdHJpbmdbXVxuICAvKiogTXVzdGVybMO2c3VuZyAoRGF0ZWkgaW4gYGxlc3NvbnMvZGlhZ3JhbW1lYCksIG51ciBpbSBMZWhyZXJtb2R1cyBzaWNodGJhci4gKi9cbiAgc29sdXRpb24/OiBzdHJpbmdcbiAgLyoqIFVudGVycHJvZ3JhbW1lIHp1ciBNdXN0ZXJsw7ZzdW5nIChEYXRlaWVuIGluIGBsZXNzb25zL2RpYWdyYW1tZWApLCBqZSBlaW5zIHBybyBSZWl0ZXIuICovXG4gIHN1YnByb2dyYW1zOiBzdHJpbmdbXVxuICAvKiogYGNvZGU6IGphdmFgOiBEaWUgw5xidW5nIHdpcmQgaW4gQ29kZSBsaXZlIGF1ZiBKYXZhIGdlbMO2c3Q7IOKAnsOcYnVuZyDDtmZmbmVu4oCcIMO2ZmZuZXQgZGllIFNwYWx0ZSBnbGVpY2ggbWl0LiAqL1xuICBjb2RlPzogJ2phdmEnXG4gIC8qKiBWaXN1Qm90OiBTY2hsZWlmZW4gbcO8c3NlbiBtaW5kZXN0ZW5zIHNvIHRpZWYgaW5laW5hbmRlciBzdGVja2VuIChgc2NobGVpZmVudGllZmU6IDJgKS4gKi9cbiAgbG9vcERlcHRoPzogbnVtYmVyXG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgQ2hlY2tsaXN0SXRlbSB7XG4gIHRleHQ6IHN0cmluZ1xuICAvKiogVGl0ZWwgZGVzIFNjaHJpdHRzLCBpbiBkZW0gZGVyIFB1bmt0IGVya2zDpHJ0IHdpcmQgKGAtIFRleHQg4oaSIFNjaHJpdHRgKS4gKi9cbiAgcmVmPzogc3RyaW5nXG4gIC8qKiBJbmRleCBkaWVzZXMgU2Nocml0dHMgaW4gZGVyIExla3Rpb24sIHZvbiBgcGFyc2VMZXNzb25gIGF1ZmdlbMO2c3QuICovXG4gIHN0ZXA/OiBudW1iZXJcbn1cblxuZXhwb3J0IGludGVyZmFjZSBRdWl6UXVlc3Rpb24ge1xuICBxdWVzdGlvbjogc3RyaW5nXG4gIG9wdGlvbnM6IHsgdGV4dDogc3RyaW5nOyBjb3JyZWN0OiBib29sZWFuIH1bXVxuICAvKiogWnVvcmRudW5nOiBadSBqZWRlbSBsaW5rZW4gQmVncmlmZiB3aXJkIGRlciBwYXNzZW5kZSByZWNodGUgZ2V3w6RobHQuICovXG4gIHBhaXJzPzogeyBsZWZ0OiBzdHJpbmc7IHJpZ2h0OiBzdHJpbmcgfVtdXG4gIGV4cGxhbmF0aW9uPzogc3RyaW5nXG4gIC8qKiBTY2hyaXR0LCBkZW4gZGllIEZyYWdlIHByw7xmdCAoYOKGkiBUaXRlbGApOyB2ZXJiaW5kZXQgc2llIG1pdCBkZW0gQ2hlY2tsaXN0ZW5wdW5rdCB6dSBkaWVzZW0gU2Nocml0dC4gKi9cbiAgcmVmPzogc3RyaW5nXG4gIHN0ZXA/OiBudW1iZXJcbn1cblxuZXhwb3J0IGludGVyZmFjZSBTdGVwIHtcbiAgdGl0bGU6IHN0cmluZ1xuICBibG9ja3M6IEJsb2NrW11cbn1cblxuZXhwb3J0IGludGVyZmFjZSBMZXNzb24ge1xuICBpZDogc3RyaW5nXG4gIG51bWJlcjogbnVtYmVyXG4gIHRpdGxlOiBzdHJpbmdcbiAgc2VjdGlvbjogc3RyaW5nXG4gIHN1bW1hcnk6IHN0cmluZ1xuICBzdGVwczogU3RlcFtdXG4gIC8qKiBWaXN1Qm90LUxla3Rpb24gaW4gZGVyIGR1cmNoZ2VoZW5kZW4gUmVpaGUgZGVyIFZpc3VCb3QtV2VsdCAoYmVrb21tdCBlaW4g8J+kliBpbiBkZXIgTGlzdGUpLiAqL1xuICByb2JvdD86IGJvb2xlYW5cbn1cblxuZXhwb3J0IGludGVyZmFjZSBUYXNrIHtcbiAgaWQ6IHN0cmluZ1xuICB0aXRsZTogc3RyaW5nXG4gIC8qKiBOdW1tZXIgZGVyIExla3Rpb24sIGRpZSBtYW4gdm9yaGVyIGFiZ2VzY2hsb3NzZW4gaGFiZW4gc29sbHRlLiAqL1xuICBhZnRlcj86IG51bWJlclxuICBsZXZlbDogbnVtYmVyXG4gIGJsb2NrczogQmxvY2tbXVxuICAvKiogVmlzdUJvdC1BdWZnYWJlIGluIGRlciBkdXJjaGdlaGVuZGVuIFJlaWhlIGRlciBWaXN1Qm90LVdlbHQuICovXG4gIHJvYm90PzogYm9vbGVhblxufVxuXG5leHBvcnQgY2xhc3MgRm9ybWF0RXJyb3IgZXh0ZW5kcyBFcnJvciB7fVxuXG5mdW5jdGlvbiBmcm9udE1hdHRlcihzb3VyY2U6IHN0cmluZywgZmlsZTogc3RyaW5nKTogeyBtZXRhOiBNYXA8c3RyaW5nLCBzdHJpbmc+OyBib2R5OiBzdHJpbmcgfSB7XG4gIGNvbnN0IG0gPSAvXi0tLVxcbihbXFxzXFxTXSo/KVxcbi0tLVxcbj8vLmV4ZWMoc291cmNlLnJlcGxhY2UoL1xcclxcbi9nLCAnXFxuJykpXG4gIGlmICghbSkgdGhyb3cgbmV3IEZvcm1hdEVycm9yKGAke2ZpbGV9OiBLb3BmemVpbGVuICgtLS0g4oCmIC0tLSkgZmVobGVuLmApXG4gIGNvbnN0IG1ldGEgPSBuZXcgTWFwPHN0cmluZywgc3RyaW5nPigpXG4gIGZvciAoY29uc3QgbGluZSBvZiBtWzFdLnNwbGl0KCdcXG4nKSkge1xuICAgIGNvbnN0IGt2ID0gL14oW2EtesOkw7bDvMOfXSspOlxccyooLiopJC9pLmV4ZWMobGluZS50cmltKCkpXG4gICAgaWYgKGt2KSBtZXRhLnNldChrdlsxXS50b0xvd2VyQ2FzZSgpLCBrdlsyXS50cmltKCkpXG4gIH1cbiAgcmV0dXJuIHsgbWV0YSwgYm9keTogc291cmNlLnJlcGxhY2UoL1xcclxcbi9nLCAnXFxuJykuc2xpY2UobVswXS5sZW5ndGgpIH1cbn1cblxuLyoqIGAzLCA0IC0+IDcgfCA4YCA9IEVpbmdhYmVuIDMgdW5kIDQsIGVyd2FydGV0ZSBBdXNnYWJlemVpbGVuIDcgdW5kIDguICovXG5leHBvcnQgZnVuY3Rpb24gcGFyc2VUZXN0KHNwZWM6IHN0cmluZywgZmlsZTogc3RyaW5nKTogRXhlcmNpc2VUZXN0IHtcbiAgY29uc3QgcGFydHMgPSBzcGVjLnNwbGl0KC9cXHMqKD86LT584oaSKVxccyovKVxuICBpZiAocGFydHMubGVuZ3RoICE9PSAyKSB0aHJvdyBuZXcgRm9ybWF0RXJyb3IoYCR7ZmlsZX06IFRlc3Qg4oCeJHtzcGVjfeKAnCBicmF1Y2h0IGdlbmF1IGVpbiDigJ4tPuKAnC5gKVxuICBjb25zdCBsaXN0ID0gKHM6IHN0cmluZywgc2VwOiBSZWdFeHApID0+IChzLnRyaW0oKSA9PT0gJycgfHwgcy50cmltKCkgPT09ICctJyA/IFtdIDogcy5zcGxpdChzZXApLm1hcCgoeCkgPT4geC50cmltKCkpKVxuICByZXR1cm4geyBpbnB1dHM6IGxpc3QocGFydHNbMF0sIC9cXHMqLFxccyovKSwgZXhwZWN0ZWQ6IGxpc3QocGFydHNbMV0sIC9cXHMqXFx8XFxzKi8pIH1cbn1cblxuLyoqIGBnZXRMb3VkbmVzcz0wLzgwLCBpc0J1dHRvbkE9dHJ1ZSAtPiBmb3J3YXJkIDMwLCBsZWRPbmAgKHNpZWhlIGBtZXNzd2VydGU6YCkuICovXG5leHBvcnQgZnVuY3Rpb24gcGFyc2VTZW5zb3JUZXN0KHZhbHVlOiBzdHJpbmcpOiBFeGVyY2lzZVRlc3Qge1xuICBjb25zdCBhcnJvdyA9IC9eKC4qPylcXHMqKD86LT584oaSKVxccyooLiopJC8uZXhlYyh2YWx1ZS50cmltKCkpXG4gIGlmICghYXJyb3cpIHRocm93IG5ldyBFcnJvcihg4oCebWVzc3dlcnRlOiAke3ZhbHVlfeKAnCBicmF1Y2h0IGVpbiDigJ4tPuKAnC5gKVxuICBjb25zdCBzZW5zb3JzOiBSZWNvcmQ8c3RyaW5nLCBNQm90U2Vuc29yVmFsdWVbXT4gPSB7fVxuICBmb3IgKGNvbnN0IHBhcnQgb2YgYXJyb3dbMV0uc3BsaXQoL1xccyosXFxzKi8pLmZpbHRlcihCb29sZWFuKSkge1xuICAgIGNvbnN0IG0gPSAvXihcXHcrKVxccyo9XFxzKiguKykkLy5leGVjKHBhcnQpXG4gICAgaWYgKCFtIHx8ICEobVsxXSBpbiBNQk9UX1NFTlNPUlMpKSB0aHJvdyBuZXcgRXJyb3IoYFVuYmVrYW5udGVyIFNlbnNvciBpbiDigJ4ke3BhcnR94oCcLmApXG4gICAgc2Vuc29yc1ttWzFdXSA9IG1bMl0uc3BsaXQoJy8nKS5tYXAoKHYpID0+IHtcbiAgICAgIGNvbnN0IHQgPSB2LnRyaW0oKVxuICAgICAgaWYgKHQgPT09ICd0cnVlJyB8fCB0ID09PSAnZmFsc2UnKSByZXR1cm4gdCA9PT0gJ3RydWUnXG4gICAgICBpZiAoL14tP1xcZCsoXFwuXFxkKyk/JC8udGVzdCh0KSkgcmV0dXJuIE51bWJlcih0KVxuICAgICAgLy8gVGV4dCwgei4gQi4gZWluZSBGYXJiZTogZ2V0Q29sb3I9cm90XG4gICAgICBpZiAodHlwZW9mIE1CT1RfU0VOU09SU1ttWzFdXS5zaW11bGF0ZWQgPT09ICdzdHJpbmcnKSByZXR1cm4gdFxuICAgICAgdGhyb3cgbmV3IEVycm9yKGBNZXNzd2VydCDigJ4ke3R94oCcIGlzdCBrZWluZSBaYWhsIHVuZCBuaWNodCB0cnVlL2ZhbHNlLmApXG4gICAgfSlcbiAgfVxuICByZXR1cm4gcm9ib3RFeHBlY3RhdGlvbih7IGlucHV0czogW10sIGV4cGVjdGVkOiBbXSwgc2Vuc29ycyB9LCBhcnJvd1syXSlcbn1cblxuLyoqIFJlY2h0ZSBTZWl0ZSB2b24gYHdlbHQ6IOKApiAtPmAgdW5kIGBtZXNzd2VydGU6IOKApiAtPmA6IEZhaHJ0IHNvd2llIGBsZWRPbmAsIGBsZWRPZmZgLCBgdG9uZWAsIGBub1RvbmVgLCBgbm9uZWAgKGbDpGhydCBuaWNodCksIGBkcml2ZXNgIChmw6RocnQgaXJnZW5kd2llKSwgYHNjcmVlbiBcIlRleHRcImAuICovXG5mdW5jdGlvbiByb2JvdEV4cGVjdGF0aW9uKHRlc3Q6IEV4ZXJjaXNlVGVzdCwgc3BlYzogc3RyaW5nKTogRXhlcmNpc2VUZXN0IHtcbiAgY29uc3QgZHJpdmU6IHN0cmluZ1tdID0gW11cbiAgLy8gYHNjcmVlbiBcIkFic3RhbmQ6IDQyIGNtXCJgOiBkaWVzZXIgVGV4dCBzdGVodCBhbSBFbmRlIGF1ZiBkZW0gQmlsZHNjaGlybSAoZGFyZiBLb21tYXMgZW50aGFsdGVuKVxuICBzcGVjID0gc3BlYy5yZXBsYWNlKC9cXGJzY3JlZW5cXHMrKFwiKD86W15cIlxcXFxdfFxcXFwuKSpcIikvdSwgKF8sIHRleHQ6IHN0cmluZykgPT4ge1xuICAgIHRlc3Quc2NyZWVuID0gSlNPTi5wYXJzZSh0ZXh0KSBhcyBzdHJpbmdcbiAgICByZXR1cm4gJydcbiAgfSlcbiAgZm9yIChjb25zdCB0b2tlbiBvZiBzcGVjLnNwbGl0KC9cXHMqLFxccyovKS5maWx0ZXIoQm9vbGVhbikpIHtcbiAgICBpZiAodG9rZW4gPT09ICdsZWRPbicgfHwgdG9rZW4gPT09ICdsZWRPZmYnKSB0ZXN0LmxlZCA9IHRva2VuID09PSAnbGVkT24nXG4gICAgZWxzZSBpZiAodG9rZW4gPT09ICd0b25lJyB8fCB0b2tlbiA9PT0gJ25vVG9uZScpIHRlc3QudG9uZSA9IHRva2VuID09PSAndG9uZSdcbiAgICBlbHNlIGlmICh0b2tlbiA9PT0gJ25vbmUnKSB0ZXN0LmRyaXZlID0gW11cbiAgICBlbHNlIGlmICh0b2tlbiA9PT0gJ2RyaXZlcycpIHRlc3QuZHJpdmVzID0gdHJ1ZVxuICAgIGVsc2UgZHJpdmUucHVzaCh0b2tlbilcbiAgfVxuICBpZiAoZHJpdmUubGVuZ3RoKSB0ZXN0LmRyaXZlID0gZHJpdmVTaWduYXR1cmUocGFyc2VEcml2ZVNwZWMoZHJpdmUuam9pbignLCAnKSkpXG4gIHJldHVybiB0ZXN0XG59XG5cbmZ1bmN0aW9uIHBhcnNlRXhlcmNpc2UoaWQ6IHN0cmluZywgbGluZXM6IHN0cmluZ1tdLCBmaWxlOiBzdHJpbmcpOiBFeGVyY2lzZSB7XG4gIGNvbnN0IGV4OiBFeGVyY2lzZSA9IHsgaWQsIHRpdGxlOiAnJywgdGFzazogJycsIHRlc3RzOiBbXSwgcmVxdWlyZXM6IFtdLCBoaW50czogW10sIHN1YnByb2dyYW1zOiBbXSB9XG4gIGxldCBsYXN0OiAndGFzaycgfCAnaGludCcgfCB1bmRlZmluZWRcbiAgZm9yIChjb25zdCByYXcgb2YgbGluZXMpIHtcbiAgICBjb25zdCBrdiA9IC9eKHRpdGVsfGF1ZnRyYWd8c3RhcnR8dGVzdHxkYXRlaXxmYWhydHxiZWZlaGxlfHdlbHR8bWVzc3dlcnRlfHNjaGxlaWZlbnRpZWZlfGJyYXVjaHR8dGlwcHxsw7ZzdW5nfGxvZXN1bmd8dW50ZXJwcm9ncmFtbXxjb2RlKTpcXHMqKC4qKSQvaS5leGVjKHJhdy50cmltKCkpXG4gICAgaWYgKGt2KSB7XG4gICAgICBjb25zdCBbLCBrZXksIHZhbHVlXSA9IGt2XG4gICAgICBsYXN0ID0gdW5kZWZpbmVkXG4gICAgICBzd2l0Y2ggKGtleS50b0xvd2VyQ2FzZSgpKSB7XG4gICAgICAgIGNhc2UgJ3RpdGVsJzogZXgudGl0bGUgPSB2YWx1ZTsgYnJlYWtcbiAgICAgICAgY2FzZSAnYXVmdHJhZyc6IGV4LnRhc2sgPSB2YWx1ZTsgbGFzdCA9ICd0YXNrJzsgYnJlYWtcbiAgICAgICAgY2FzZSAnc3RhcnQnOiBleC5zdGFydCA9IHZhbHVlOyBicmVha1xuICAgICAgICBjYXNlICd0ZXN0JzogZXgudGVzdHMucHVzaChwYXJzZVRlc3QodmFsdWUsIGZpbGUpKTsgYnJlYWtcbiAgICAgICAgY2FzZSAnZGF0ZWknOiB7XG4gICAgICAgICAgLy8gYGRhdGVpOiBuZXUudHh0IC0+IEhldSB8IMOEcGZlbGA6IERpZXNlIERhdGVpIHNvbGwgZGFzIFByb2dyYW1tIGltIGxldHp0ZW4gVGVzdCBzcGVpY2hlcm4uXG4gICAgICAgICAgY29uc3QgbSA9IC9eKFtcXHcuLV0rKVxccyooPzotPnzihpIpXFxzKiguKikkLy5leGVjKHZhbHVlLnRyaW0oKSlcbiAgICAgICAgICBpZiAoIW0gfHwgIWV4LnRlc3RzLmxlbmd0aCkgdGhyb3cgbmV3IEZvcm1hdEVycm9yKGAke2ZpbGV9OiDDnGJ1bmcg4oCeJHtpZH3igJw6IOKAnmRhdGVpOuKAnCBicmF1Y2h0IHZvcmhlciBlaW5lbiBUZXN0IHVuZCBkaWUgRm9ybSDigJ5uYW1lLnR4dCAtPiBaZWlsZSB8IFplaWxl4oCcLmApXG4gICAgICAgICAgY29uc3QgZXhwZWN0ZWQgPSBleC50ZXN0c1tleC50ZXN0cy5sZW5ndGggLSAxXVxuICAgICAgICAgIGV4cGVjdGVkLmZpbGVzID0gWy4uLihleHBlY3RlZC5maWxlcyA/PyBbXSksIHsgbmFtZTogbVsxXSwgbGluZXM6IG1bMl0udHJpbSgpID09PSAnJyA/IFtdIDogbVsyXS5zcGxpdCgvXFxzKlxcfFxccyovKS5tYXAoKHgpID0+IHgudHJpbSgpKSB9XVxuICAgICAgICAgIGJyZWFrXG4gICAgICAgIH1cbiAgICAgICAgY2FzZSAnZmFocnQnOlxuICAgICAgICAgIC8vIFZpc3VCb3Q6IGBmYWhydDogNCB4IChmb3J3YXJkIDUwLCB0dXJuUmlnaHQgOTApYCDigJMgc28gc29sbCBkZXIgUm9ib3RlciBmYWhyZW4gKG9obmUgQXVzZ2FiZSwgb2huZSBFaW5nYWJlKS5cbiAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgZXgudGVzdHMucHVzaCh7IGlucHV0czogW10sIGV4cGVjdGVkOiBbXSwgZHJpdmU6IGRyaXZlU2lnbmF0dXJlKHBhcnNlRHJpdmVTcGVjKHZhbHVlKSkgfSlcbiAgICAgICAgICB9IGNhdGNoIChlcnIpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBGb3JtYXRFcnJvcihgJHtmaWxlfTogw5xidW5nIOKAniR7aWR94oCcOiAkeyhlcnIgYXMgRXJyb3IpLm1lc3NhZ2V9YClcbiAgICAgICAgICB9XG4gICAgICAgICAgYnJlYWtcbiAgICAgICAgY2FzZSAnd2VsdCc6IHtcbiAgICAgICAgICAvLyBWaXN1Qm90OiBgd2VsdDogd2FuZC1uYWgsIHdhbmQtd2VpdGAg4oCTIGluIGplZGVyIGRpZXNlciBXZWx0ZW4gbXVzcyBkZXIgUm9ib3RlciBvaG5lIEFuc3Rvw59lbiBpbnMgWmllbC5cbiAgICAgICAgICAvLyBgd2VsdDogd2FuZC1uYWggLT4gdHVyblJpZ2h0YCDigJMgaW4gZGllc2VyIFdlbHQgc29sbCBlciBnZW5hdSBzbyBmYWhyZW4gKGbDvHIgVmVyendlaWd1bmdlbiBtaXQgU2Vuc29yZW4pLlxuICAgICAgICAgIGNvbnN0IGFycm93ID0gL14oW1xcdy1dKylcXHMqKD86LT584oaSKVxccyooLispJC8uZXhlYyh2YWx1ZS50cmltKCkpXG4gICAgICAgICAgaWYgKGFycm93KSB7XG4gICAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgICBleC50ZXN0cy5wdXNoKHJvYm90RXhwZWN0YXRpb24oeyBpbnB1dHM6IFtdLCBleHBlY3RlZDogW10sIHdvcmxkOiBhcnJvd1sxXSB9LCBhcnJvd1syXSkpXG4gICAgICAgICAgICB9IGNhdGNoIChlcnIpIHtcbiAgICAgICAgICAgICAgdGhyb3cgbmV3IEZvcm1hdEVycm9yKGAke2ZpbGV9OiDDnGJ1bmcg4oCeJHtpZH3igJw6ICR7KGVyciBhcyBFcnJvcikubWVzc2FnZX1gKVxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgYnJlYWtcbiAgICAgICAgICB9XG4gICAgICAgICAgZm9yIChjb25zdCBuYW1lIG9mIHZhbHVlLnNwbGl0KC9cXHMqLFxccyovKS5maWx0ZXIoQm9vbGVhbikpIHtcbiAgICAgICAgICAgIGlmICghL15bXFx3LV0rJC8udGVzdChuYW1lKSkgdGhyb3cgbmV3IEZvcm1hdEVycm9yKGAke2ZpbGV9OiDDnGJ1bmcg4oCeJHtpZH3igJw6IFdlbHRuYW1lIOKAniR7bmFtZX3igJwgKG51ciBCdWNoc3RhYmVuLCBaaWZmZXJuLCAtKS5gKVxuICAgICAgICAgICAgZXgudGVzdHMucHVzaCh7IGlucHV0czogW10sIGV4cGVjdGVkOiBbXSwgd29ybGQ6IG5hbWUgfSlcbiAgICAgICAgICB9XG4gICAgICAgICAgYnJlYWtcbiAgICAgICAgfVxuICAgICAgICBjYXNlICdiZWZlaGxlJzpcbiAgICAgICAgICAvLyBWaXN1Qm90OiBgYmVmZWhsZTogMyB4IChzZXRMZWQgMjU1IDAgMCwgcGF1c2UgNTAwLCBsZWRPZmYsIHBhdXNlIDUwMClgIOKAkyBnZW5hdSBkaWVzZSBCZWZlaGxlIGbDvHIgTEVEcywgVG9uIHVuZCBCaWxkc2NoaXJtLlxuICAgICAgICAgIHRyeSB7XG4gICAgICAgICAgICBleC50ZXN0cy5wdXNoKHsgaW5wdXRzOiBbXSwgZXhwZWN0ZWQ6IFtdLCBhY3Rpb25zOiBwYXJzZUFjdGlvblNwZWModmFsdWUpIH0pXG4gICAgICAgICAgfSBjYXRjaCAoZXJyKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgRm9ybWF0RXJyb3IoYCR7ZmlsZX06IMOcYnVuZyDigJ4ke2lkfeKAnDogJHsoZXJyIGFzIEVycm9yKS5tZXNzYWdlfWApXG4gICAgICAgICAgfVxuICAgICAgICAgIGJyZWFrXG4gICAgICAgIGNhc2UgJ21lc3N3ZXJ0ZSc6XG4gICAgICAgICAgLy8gVmlzdUJvdDogYG1lc3N3ZXJ0ZTogZ2V0TG91ZG5lc3M9MC84MCwgaXNCdXR0b25BPWZhbHNlIC0+IGZvcndhcmQsIGxlZE9uYCDigJMgbWl0IGRpZXNlbiBTZW5zb3J3ZXJ0ZW5cbiAgICAgICAgICAvLyAobmFjaGVpbmFuZGVyLCBkdXJjaCAvIGdldHJlbm50KSBzb2xsIGRlciBSb2JvdGVyIHNvIGZhaHJlbiBiencuIGxldWNodGVuIChgbGVkT25gLCBgbGVkT2ZmYCwgYHRvbmVgLCBgbm9Ub25lYCwgYG5vbmVgKS5cbiAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgZXgudGVzdHMucHVzaChwYXJzZVNlbnNvclRlc3QodmFsdWUpKVxuICAgICAgICAgIH0gY2F0Y2ggKGVycikge1xuICAgICAgICAgICAgdGhyb3cgbmV3IEZvcm1hdEVycm9yKGAke2ZpbGV9OiDDnGJ1bmcg4oCeJHtpZH3igJw6ICR7KGVyciBhcyBFcnJvcikubWVzc2FnZX1gKVxuICAgICAgICAgIH1cbiAgICAgICAgICBicmVha1xuICAgICAgICBjYXNlICdzY2hsZWlmZW50aWVmZSc6XG4gICAgICAgICAgZXgubG9vcERlcHRoID0gTnVtYmVyKHZhbHVlKVxuICAgICAgICAgIGlmICghTnVtYmVyLmlzSW50ZWdlcihleC5sb29wRGVwdGgpIHx8IGV4Lmxvb3BEZXB0aCA8IDEpIHRocm93IG5ldyBGb3JtYXRFcnJvcihgJHtmaWxlfTogw5xidW5nIOKAniR7aWR94oCcOiDigJ5zY2hsZWlmZW50aWVmZTrigJwgYnJhdWNodCBlaW5lIFphaGwgYWIgMS5gKVxuICAgICAgICAgIGJyZWFrXG4gICAgICAgIGNhc2UgJ2JyYXVjaHQnOiBleC5yZXF1aXJlcy5wdXNoKC4uLnZhbHVlLnNwbGl0KC9cXHMqLFxccyovKS5maWx0ZXIoQm9vbGVhbikpOyBicmVha1xuICAgICAgICBjYXNlICd0aXBwJzogZXguaGludHMucHVzaCh2YWx1ZSk7IGxhc3QgPSAnaGludCc7IGJyZWFrXG4gICAgICAgIGNhc2UgJ2zDtnN1bmcnOlxuICAgICAgICBjYXNlICdsb2VzdW5nJzogZXguc29sdXRpb24gPSB2YWx1ZTsgYnJlYWtcbiAgICAgICAgY2FzZSAndW50ZXJwcm9ncmFtbSc6IGV4LnN1YnByb2dyYW1zLnB1c2goLi4udmFsdWUuc3BsaXQoL1xccyosXFxzKi8pLmZpbHRlcihCb29sZWFuKSk7IGJyZWFrXG4gICAgICAgIGNhc2UgJ2NvZGUnOlxuICAgICAgICAgIGlmICh2YWx1ZS50cmltKCkudG9Mb3dlckNhc2UoKSAhPT0gJ2phdmEnKSB0aHJvdyBuZXcgRm9ybWF0RXJyb3IoYCR7ZmlsZX06IMOcYnVuZyDigJ4ke2lkfeKAnDog4oCeY29kZTrigJwga2VubnQgbnVyIOKAnmphdmHigJwuYClcbiAgICAgICAgICBleC5jb2RlID0gJ2phdmEnXG4gICAgICAgICAgYnJlYWtcbiAgICAgIH1cbiAgICB9IGVsc2UgaWYgKGxhc3QgJiYgcmF3LnRyaW0oKSAhPT0gJycpIHtcbiAgICAgIC8vIEZvcnRzZXR6dW5nc3plaWxlbiBmw7xyIEF1ZnRyYWcgdW5kIFRpcHBcbiAgICAgIGlmIChsYXN0ID09PSAndGFzaycpIGV4LnRhc2sgKz0gJ1xcbicgKyByYXcudHJpbSgpXG4gICAgICBlbHNlIGV4LmhpbnRzW2V4LmhpbnRzLmxlbmd0aCAtIDFdICs9ICdcXG4nICsgcmF3LnRyaW0oKVxuICAgIH0gZWxzZSBpZiAocmF3LnRyaW0oKSA9PT0gJycgJiYgbGFzdCA9PT0gJ3Rhc2snKSB7XG4gICAgICBleC50YXNrICs9ICdcXG4nXG4gICAgfVxuICB9XG4gIGlmICghZXgudGl0bGUpIHRocm93IG5ldyBGb3JtYXRFcnJvcihgJHtmaWxlfTogw5xidW5nIOKAniR7aWR94oCcIGhhdCBrZWluZW4gVGl0ZWwuYClcbiAgaWYgKCFleC50YXNrLnRyaW0oKSkgdGhyb3cgbmV3IEZvcm1hdEVycm9yKGAke2ZpbGV9OiDDnGJ1bmcg4oCeJHtpZH3igJwgaGF0IGtlaW5lbiBBdWZ0cmFnLmApXG4gIGV4LnRhc2sgPSBleC50YXNrLnRyaW0oKVxuICByZXR1cm4gZXhcbn1cblxuZnVuY3Rpb24gcGFyc2VRdWl6KGxpbmVzOiBzdHJpbmdbXSwgZmlsZTogc3RyaW5nKTogUXVpelF1ZXN0aW9uW10ge1xuICBjb25zdCBxdWVzdGlvbnM6IFF1aXpRdWVzdGlvbltdID0gW11cbiAgZm9yIChjb25zdCByYXcgb2YgbGluZXMpIHtcbiAgICBjb25zdCBsaW5lID0gcmF3LnRyaW0oKVxuICAgIGlmIChsaW5lLnN0YXJ0c1dpdGgoJz8nKSkge1xuICAgICAgcXVlc3Rpb25zLnB1c2goeyBxdWVzdGlvbjogbGluZS5zbGljZSgxKS50cmltKCksIG9wdGlvbnM6IFtdIH0pXG4gICAgfSBlbHNlIGlmICgvXi0gXFxbWyB4WF1cXF0vLnRlc3QobGluZSkpIHtcbiAgICAgIGNvbnN0IHEgPSBxdWVzdGlvbnMuYXQoLTEpXG4gICAgICBpZiAoIXEpIHRocm93IG5ldyBGb3JtYXRFcnJvcihgJHtmaWxlfTogQW50d29ydCBvaG5lIEZyYWdlIGltIFF1aXouYClcbiAgICAgIHEub3B0aW9ucy5wdXNoKHsgdGV4dDogbGluZS5zbGljZSg1KS50cmltKCksIGNvcnJlY3Q6IGxpbmVbM10udG9Mb3dlckNhc2UoKSA9PT0gJ3gnIH0pXG4gICAgfSBlbHNlIGlmIChsaW5lLnN0YXJ0c1dpdGgoJz0gJykpIHtcbiAgICAgIGNvbnN0IHEgPSBxdWVzdGlvbnMuYXQoLTEpXG4gICAgICBjb25zdCBtID0gL149XFxzKyguKz8pXFxzKy0+XFxzKyguKykkLy5leGVjKGxpbmUpXG4gICAgICBpZiAoIXEgfHwgIW0pIHRocm93IG5ldyBGb3JtYXRFcnJvcihgJHtmaWxlfTogWnVvcmRudW5nIOKAniR7bGluZX3igJwgYnJhdWNodCBkaWUgRm9ybSDigJ49IGxpbmtzIC0+IHJlY2h0c+KAnCBuYWNoIGVpbmVyIEZyYWdlLmApXG4gICAgICA7KHEucGFpcnMgPz89IFtdKS5wdXNoKHsgbGVmdDogbVsxXS50cmltKCksIHJpZ2h0OiBtWzJdLnRyaW0oKSB9KVxuICAgIH0gZWxzZSBpZiAobGluZS5zdGFydHNXaXRoKCfihpInKSkge1xuICAgICAgY29uc3QgcSA9IHF1ZXN0aW9ucy5hdCgtMSlcbiAgICAgIGlmICghcSkgdGhyb3cgbmV3IEZvcm1hdEVycm9yKGAke2ZpbGV9OiDigJ7ihpIgU2Nocml0dOKAnCBvaG5lIEZyYWdlIGltIFF1aXouYClcbiAgICAgIHEucmVmID0gbGluZS5zbGljZSgxKS50cmltKClcbiAgICB9IGVsc2UgaWYgKGxpbmUuc3RhcnRzV2l0aCgnPicpKSB7XG4gICAgICBjb25zdCBxID0gcXVlc3Rpb25zLmF0KC0xKVxuICAgICAgaWYgKHEpIHEuZXhwbGFuYXRpb24gPSAoKHEuZXhwbGFuYXRpb24gPyBxLmV4cGxhbmF0aW9uICsgJyAnIDogJycpICsgbGluZS5zbGljZSgxKS50cmltKCkpLnRyaW0oKVxuICAgIH1cbiAgfVxuICBmb3IgKGNvbnN0IHEgb2YgcXVlc3Rpb25zKSB7XG4gICAgaWYgKHEucGFpcnMpIHtcbiAgICAgIGNvbnN0IHJpZ2h0cyA9IG5ldyBTZXQocS5wYWlycy5tYXAoKHApID0+IHAucmlnaHQpKVxuICAgICAgaWYgKHEub3B0aW9ucy5sZW5ndGggPiAwIHx8IHEucGFpcnMubGVuZ3RoIDwgMiB8fCByaWdodHMuc2l6ZSAhPT0gcS5wYWlycy5sZW5ndGgpIHtcbiAgICAgICAgdGhyb3cgbmV3IEZvcm1hdEVycm9yKGAke2ZpbGV9OiBadW9yZG51bmcg4oCeJHtxLnF1ZXN0aW9ufeKAnCBicmF1Y2h0IG1pbmRlc3RlbnMgendlaSBQYWFyZSBtaXQgdmVyc2NoaWVkZW5lbiByZWNodGVuIFNlaXRlbiB1bmQga2VpbmUgQW50d29ydGVuLmApXG4gICAgICB9XG4gICAgICBjb250aW51ZVxuICAgIH1cbiAgICBpZiAocS5vcHRpb25zLmxlbmd0aCA8IDIgfHwgIXEub3B0aW9ucy5zb21lKChvKSA9PiBvLmNvcnJlY3QpKSB7XG4gICAgICB0aHJvdyBuZXcgRm9ybWF0RXJyb3IoYCR7ZmlsZX06IFF1aXpmcmFnZSDigJ4ke3EucXVlc3Rpb2594oCcIGJyYXVjaHQgbWluZGVzdGVucyB6d2VpIEFudHdvcnRlbiwgZGF2b24gZWluZSByaWNodGlnZS5gKVxuICAgIH1cbiAgfVxuICByZXR1cm4gcXVlc3Rpb25zXG59XG5cbi8qKiBUZXh0IGluIEJsw7Zja2UgemVybGVnZW46IG5vcm1hbGVzIE1hcmtkb3duIHVuZCBgOjo6IGFydCDigKZgIGJpcyBgOjo6YC4gKi9cbmV4cG9ydCBmdW5jdGlvbiBwYXJzZUJsb2Nrcyhib2R5OiBzdHJpbmcsIGZpbGU6IHN0cmluZyk6IEJsb2NrW10ge1xuICBjb25zdCBibG9ja3M6IEJsb2NrW10gPSBbXVxuICBjb25zdCBsaW5lcyA9IGJvZHkuc3BsaXQoJ1xcbicpXG4gIGxldCBtYXJrZG93bjogc3RyaW5nW10gPSBbXVxuICBjb25zdCBmbHVzaCA9ICgpID0+IHtcbiAgICBjb25zdCB0ZXh0ID0gbWFya2Rvd24uam9pbignXFxuJykudHJpbSgpXG4gICAgaWYgKHRleHQpIGJsb2Nrcy5wdXNoKHsga2luZDogJ21hcmtkb3duJywgdGV4dCB9KVxuICAgIG1hcmtkb3duID0gW11cbiAgfVxuICBmb3IgKGxldCBpID0gMDsgaSA8IGxpbmVzLmxlbmd0aDsgaSsrKSB7XG4gICAgY29uc3Qgb3BlbiA9IC9eOjo6XFxzKihbYS16w6TDtsO8w59dW2EtesOkw7bDvMOfMC05XSopXFxzKiguKikkL2kuZXhlYyhsaW5lc1tpXS50cmltKCkpXG4gICAgaWYgKCFvcGVuKSB7XG4gICAgICBtYXJrZG93bi5wdXNoKGxpbmVzW2ldKVxuICAgICAgY29udGludWVcbiAgICB9XG4gICAgZmx1c2goKVxuICAgIGNvbnN0IGlubmVyOiBzdHJpbmdbXSA9IFtdXG4gICAgbGV0IGogPSBpICsgMVxuICAgIHdoaWxlIChqIDwgbGluZXMubGVuZ3RoICYmIGxpbmVzW2pdLnRyaW0oKSAhPT0gJzo6OicpIGlubmVyLnB1c2gobGluZXNbaisrXSlcbiAgICBpZiAoaiA+PSBsaW5lcy5sZW5ndGgpIHRocm93IG5ldyBGb3JtYXRFcnJvcihgJHtmaWxlfTogQmxvY2sg4oCeOjo6ICR7b3BlblsxXX3igJwgd2lyZCBuaWNodCBtaXQg4oCeOjo64oCcIGdlc2NobG9zc2VuLmApXG4gICAgY29uc3Qga2luZCA9IG9wZW5bMV0udG9Mb3dlckNhc2UoKVxuICAgIGNvbnN0IGFyZyA9IG9wZW5bMl0udHJpbSgpXG4gICAgc3dpdGNoIChraW5kKSB7XG4gICAgICBjYXNlICdkaWFncmFtbSc6XG4gICAgICAgIGlmICghYXJnKSB0aHJvdyBuZXcgRm9ybWF0RXJyb3IoYCR7ZmlsZX06IOKAnjo6OiBkaWFncmFtbeKAnCBicmF1Y2h0IGVpbmVuIERhdGVpbmFtZW4uYClcbiAgICAgICAgYmxvY2tzLnB1c2goeyBraW5kOiAnZGlhZ3JhbScsIGZpbGU6IGFyZywgY2FwdGlvbjogaW5uZXIuam9pbignICcpLnRyaW0oKSB9KVxuICAgICAgICBicmVha1xuICAgICAgY2FzZSAnw7xidW5nJzpcbiAgICAgIGNhc2UgJ3VlYnVuZyc6XG4gICAgICAgIGlmICghYXJnKSB0aHJvdyBuZXcgRm9ybWF0RXJyb3IoYCR7ZmlsZX06IOKAnjo6OiDDvGJ1bmfigJwgYnJhdWNodCBlaW5lIEtlbm51bmcuYClcbiAgICAgICAgYmxvY2tzLnB1c2goeyBraW5kOiAnZXhlcmNpc2UnLCBleGVyY2lzZTogcGFyc2VFeGVyY2lzZShhcmcsIGlubmVyLCBmaWxlKSB9KVxuICAgICAgICBicmVha1xuICAgICAgY2FzZSAnY2hlY2tsaXN0ZSc6XG4gICAgICAgIGJsb2Nrcy5wdXNoKHsga2luZDogJ2NoZWNrbGlzdCcsIGl0ZW1zOiBpbm5lci5tYXAoKGwpID0+IGwudHJpbSgpKS5maWx0ZXIoKGwpID0+IGwuc3RhcnRzV2l0aCgnLSAnKSkubWFwKChsKSA9PiBjaGVja2xpc3RJdGVtKGwuc2xpY2UoMikudHJpbSgpKSkgfSlcbiAgICAgICAgYnJlYWtcbiAgICAgIGNhc2UgJ2tvbXBldGVuemVuJzpcbiAgICAgICAgYmxvY2tzLnB1c2goeyBraW5kOiAnY29tcGV0ZW5jZXMnLCBpdGVtczogaW5uZXIubWFwKChsKSA9PiBsLnRyaW0oKSkuZmlsdGVyKChsKSA9PiBsLnN0YXJ0c1dpdGgoJy0gJykpLm1hcCgobCkgPT4gbC5zbGljZSgyKS50cmltKCkpIH0pXG4gICAgICAgIGJyZWFrXG4gICAgICBjYXNlICdxdWl6JzpcbiAgICAgICAgYmxvY2tzLnB1c2goeyBraW5kOiAncXVpeicsIHF1ZXN0aW9uczogcGFyc2VRdWl6KGlubmVyLCBmaWxlKSB9KVxuICAgICAgICBicmVha1xuICAgICAgY2FzZSAnYmlsZCc6XG4gICAgICAgIGlmICghYXJnKSB0aHJvdyBuZXcgRm9ybWF0RXJyb3IoYCR7ZmlsZX06IOKAnjo6OiBiaWxk4oCcIGJyYXVjaHQgZWluZW4gRGF0ZWluYW1lbi5gKVxuICAgICAgICBibG9ja3MucHVzaCh7IGtpbmQ6ICdpbWFnZXMnLCBmaWxlczogYXJnLnNwbGl0KC9cXHMrLyksIGNhcHRpb246IGlubmVyLmpvaW4oJyAnKS50cmltKCkgfSlcbiAgICAgICAgYnJlYWtcbiAgICAgIGNhc2UgJ2dyYWZpayc6XG4gICAgICAgIGlmICghYXJnKSB0aHJvdyBuZXcgRm9ybWF0RXJyb3IoYCR7ZmlsZX06IOKAnjo6OiBncmFmaWvigJwgYnJhdWNodCBlaW5lbiBEYXRlaW5hbWVuLmApXG4gICAgICAgIHtcbiAgICAgICAgICBjb25zdCBbZ3JhcGhpYywgbGFiZWxlZF0gPSBhcmcuc3BsaXQoL1xccysvKVxuICAgICAgICAgIGJsb2Nrcy5wdXNoKHsga2luZDogJ2dyYXBoaWMnLCBmaWxlOiBncmFwaGljLCAuLi4obGFiZWxlZCA/IHsgbGFiZWxlZCB9IDoge30pLCBjYXB0aW9uOiBpbm5lci5qb2luKCcgJykudHJpbSgpIH0pXG4gICAgICAgIH1cbiAgICAgICAgYnJlYWtcbiAgICAgIGNhc2UgJ2FuZ2ViZXJ3aXNzZW4nOlxuICAgICAgICBibG9ja3MucHVzaCh7IGtpbmQ6ICdicmFnJywgdGV4dDogaW5uZXIuam9pbignXFxuJykudHJpbSgpIH0pXG4gICAgICAgIGJyZWFrXG4gICAgICBjYXNlICdzcGllbCc6XG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgaWYgKGlzUm91bmRHYW1lS2luZChhcmcpKSBibG9ja3MucHVzaCh7IGtpbmQ6ICdyb3VuZEdhbWUnLCBnYW1lOiBwYXJzZVJvdW5kR2FtZShhcmcsIGlubmVyLCBmaWxlKSB9KVxuICAgICAgICAgIGVsc2UgaWYgKGFyZyA9PT0gJ3ByaW56ZXNzaW4nKSBibG9ja3MucHVzaCh7IGtpbmQ6ICdyZXNjdWVHYW1lJywgZ2FtZTogcGFyc2VSZXNjdWVHYW1lKGlubmVyLCBmaWxlKSB9KVxuICAgICAgICAgIGVsc2UgaWYgKGFyZykgdGhyb3cgbmV3IEZvcm1hdEVycm9yKGAke2ZpbGV9OiBVbmJla2FubnRlcyBTcGllbCDigJ4ke2FyZ33igJwgKHp1aG9lcmVyLCB2ZXJ0cmFnLCBsYXlvdXQsIGJvbWJlLCBmcmFnZSwgcmVpaGVuZm9sZ2Ugb2RlciBwcmluemVzc2luKS5gKVxuICAgICAgICAgIGVsc2UgYmxvY2tzLnB1c2goeyBraW5kOiAnZ2FtZScsIGdhbWU6IHBhcnNlQm9vbEdhbWUoaW5uZXIsIGZpbGUpIH0pXG4gICAgICAgIH0gY2F0Y2ggKGVycikge1xuICAgICAgICAgIHRocm93IG5ldyBGb3JtYXRFcnJvcigoZXJyIGFzIEVycm9yKS5tZXNzYWdlKVxuICAgICAgICB9XG4gICAgICAgIGJyZWFrXG4gICAgICBjYXNlICdsw7xja2VudGV4dCc6XG4gICAgICBjYXNlICdsdWVja2VudGV4dCc6XG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgYmxvY2tzLnB1c2goeyBraW5kOiAnY2xvemUnLCBjbG96ZTogcGFyc2VDbG96ZShpbm5lciwgZmlsZSkgfSlcbiAgICAgICAgfSBjYXRjaCAoZXJyKSB7XG4gICAgICAgICAgdGhyb3cgbmV3IEZvcm1hdEVycm9yKChlcnIgYXMgRXJyb3IpLm1lc3NhZ2UpXG4gICAgICAgIH1cbiAgICAgICAgYnJlYWtcbiAgICAgIGNhc2UgJ3BhcCc6XG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgYmxvY2tzLnB1c2goeyBraW5kOiAncGFwJywgcGFwOiBwYXJzZVBhcChpbm5lciwgZmlsZSkgfSlcbiAgICAgICAgfSBjYXRjaCAoZXJyKSB7XG4gICAgICAgICAgdGhyb3cgbmV3IEZvcm1hdEVycm9yKChlcnIgYXMgRXJyb3IpLm1lc3NhZ2UpXG4gICAgICAgIH1cbiAgICAgICAgYnJlYWtcbiAgICAgIGNhc2UgJ3Byb2Zpd2lzc2VuJzpcbiAgICAgICAgYmxvY2tzLnB1c2goeyBraW5kOiAnYnJhZycsIHRleHQ6IGlubmVyLmpvaW4oJ1xcbicpLnRyaW0oKSwgcHJvOiB0cnVlIH0pXG4gICAgICAgIGJyZWFrXG4gICAgICBjYXNlICdsdWR3aWcnOlxuICAgICAgICBibG9ja3MucHVzaCh7IGtpbmQ6ICdicmFnJywgdGV4dDogaW5uZXIuam9pbignXFxuJykudHJpbSgpLCB0aXA6IHRydWUgfSlcbiAgICAgICAgYnJlYWtcbiAgICAgIGNhc2UgJ2NhZXNhcic6IHtcbiAgICAgICAgY29uc3Qga2V5ID0gYXJnID8gTnVtYmVyKGFyZykgOiAzXG4gICAgICAgIGlmICghTnVtYmVyLmlzSW50ZWdlcihrZXkpIHx8IGtleSA8IDAgfHwga2V5ID4gMjUpIHRocm93IG5ldyBGb3JtYXRFcnJvcihgJHtmaWxlfTog4oCeOjo6IGNhZXNhcuKAnCBicmF1Y2h0IGVpbmVuIFNjaGzDvHNzZWwgdm9uIDAgYmlzIDI1LmApXG4gICAgICAgIGJsb2Nrcy5wdXNoKHsga2luZDogJ2NhZXNhcicsIGtleSwgdGV4dDogaW5uZXIuam9pbignICcpLnRyaW0oKSB9KVxuICAgICAgICBicmVha1xuICAgICAgfVxuICAgICAgY2FzZSAnbWJvdDInOiB7XG4gICAgICAgIC8vIGBmb2t1czogY3liZXJwaSwgc2NyZWVuYCwgYGFuc2ljaHQ6IHVudGVuYCwgYGRyZWhlbjogamFgXG4gICAgICAgIGNvbnN0IGJsb2NrOiBFeHRyYWN0PEJsb2NrLCB7IGtpbmQ6ICdyb2JvdE1vZGVsJyB9PiA9IHsga2luZDogJ3JvYm90TW9kZWwnLCBmb2N1czogW10gfVxuICAgICAgICBmb3IgKGNvbnN0IGxpbmUgb2YgaW5uZXIuZmlsdGVyKChsKSA9PiBsLnRyaW0oKSkpIHtcbiAgICAgICAgICBjb25zdCBtID0gL15cXHMqKGZva3VzfGZvY3VzfGFuc2ljaHR8dmlld3xkcmVoZW58c3Bpbik6XFxzKiguKikkL2kuZXhlYyhsaW5lKVxuICAgICAgICAgIGlmICghbSkgdGhyb3cgbmV3IEZvcm1hdEVycm9yKGAke2ZpbGV9OiDigJ46OjogbWJvdDLigJwga2VubnQgbnVyIFplaWxlbiDigJ5mb2t1czrigJwsIOKAnmFuc2ljaHQ64oCcIHVuZCDigJ5kcmVoZW464oCcLmApXG4gICAgICAgICAgY29uc3Qga2V5ID0gbVsxXS50b0xvd2VyQ2FzZSgpXG4gICAgICAgICAgaWYgKGtleSA9PT0gJ2Zva3VzJyB8fCBrZXkgPT09ICdmb2N1cycpIGJsb2NrLmZvY3VzID0gcm9ib3RQYXJ0cyhtWzJdLCBmaWxlKVxuICAgICAgICAgIGVsc2UgaWYgKGtleSA9PT0gJ2Fuc2ljaHQnIHx8IGtleSA9PT0gJ3ZpZXcnKSBibG9jay52aWV3ID0gbVsyXS50cmltKCkudG9Mb3dlckNhc2UoKVxuICAgICAgICAgIGVsc2UgYmxvY2suc3BpbiA9IC9eKGphfHllc3x0cnVlfHNpbSkkL2kudGVzdChtWzJdLnRyaW0oKSlcbiAgICAgICAgfVxuICAgICAgICBibG9ja3MucHVzaChibG9jaylcbiAgICAgICAgYnJlYWtcbiAgICAgIH1cbiAgICAgIGNhc2UgJ21ib3QycXVpeic6IHtcbiAgICAgICAgLy8gYC0gdWx0cmFzb25pYzogV28gaXN0IGRlciAqKlVsdHJhc2NoYWxsc2Vuc29yKio/YCB1bmQgYGZlcnRpZzogU3VwZXIhYFxuICAgICAgICBjb25zdCBibG9jazogRXh0cmFjdDxCbG9jaywgeyBraW5kOiAncm9ib3RRdWl6JyB9PiA9IHsga2luZDogJ3JvYm90UXVpeicsIHRhc2tzOiBbXSB9XG4gICAgICAgIGZvciAoY29uc3QgbGluZSBvZiBpbm5lci5maWx0ZXIoKGwpID0+IGwudHJpbSgpKSkge1xuICAgICAgICAgIGNvbnN0IHRhc2sgPSAvXlxccyotXFxzKihcXHcrKVxccyo6XFxzKiguKykkLy5leGVjKGxpbmUpXG4gICAgICAgICAgY29uc3QgZG9uZSA9IC9eXFxzKihmZXJ0aWd8ZG9uZSk6XFxzKiguKykkL2kuZXhlYyhsaW5lKVxuICAgICAgICAgIGlmICh0YXNrKSBibG9jay50YXNrcy5wdXNoKHsgcGFydDogcm9ib3RQYXJ0cyh0YXNrWzFdLCBmaWxlKVswXSwgcXVlc3Rpb246IHRhc2tbMl0udHJpbSgpIH0pXG4gICAgICAgICAgZWxzZSBpZiAoZG9uZSkgYmxvY2suZG9uZSA9IGRvbmVbMl0udHJpbSgpXG4gICAgICAgICAgZWxzZSB0aHJvdyBuZXcgRm9ybWF0RXJyb3IoYCR7ZmlsZX06IOKAnjo6OiBtYm90MnF1aXrigJwgYnJhdWNodCBaZWlsZW4g4oCeLSB0ZWlsOiBGcmFnZeKAnCB1bmQgb3B0aW9uYWwg4oCeZmVydGlnOiBUZXh04oCcLmApXG4gICAgICAgIH1cbiAgICAgICAgaWYgKCFibG9jay50YXNrcy5sZW5ndGgpIHRocm93IG5ldyBGb3JtYXRFcnJvcihgJHtmaWxlfTog4oCeOjo6IG1ib3QycXVpeuKAnCBoYXQga2VpbmUgRnJhZ2VuLmApXG4gICAgICAgIGJsb2Nrcy5wdXNoKGJsb2NrKVxuICAgICAgICBicmVha1xuICAgICAgfVxuICAgICAgY2FzZSAnZGF0ZWknOiB7XG4gICAgICAgIGlmICghL15bXFx3Li1dK1xcLih0eHR8Y3N2fGpzb24pJC91LnRlc3QoYXJnKSkgdGhyb3cgbmV3IEZvcm1hdEVycm9yKGAke2ZpbGV9OiDigJ46OjogZGF0ZWnigJwgYnJhdWNodCBlaW5lbiBEYXRlaW5hbWVuIHdpZSBicmllZi50eHQsIGxpc3RlLmNzdiBvZGVyIGRhdGVuLmpzb24uYClcbiAgICAgICAgLy8gRGVyIEluaGFsdCBibGVpYnQgZ2VuYXUgc28sIHdpZSBlciBkYXN0ZWh0LCBudXIgb2huZSBMZWVyemVpbGVuIGFtIEFuZmFuZyB1bmQgRW5kZS5cbiAgICAgICAgd2hpbGUgKGlubmVyLmxlbmd0aCAmJiBpbm5lclswXS50cmltKCkgPT09ICcnKSBpbm5lci5zaGlmdCgpXG4gICAgICAgIHdoaWxlIChpbm5lci5sZW5ndGggJiYgaW5uZXJbaW5uZXIubGVuZ3RoIC0gMV0udHJpbSgpID09PSAnJykgaW5uZXIucG9wKClcbiAgICAgICAgYmxvY2tzLnB1c2goeyBraW5kOiAndGV4dEZpbGUnLCBuYW1lOiBhcmcsIGNvbnRlbnQ6IGlubmVyLmpvaW4oJ1xcbicpIH0pXG4gICAgICAgIGJyZWFrXG4gICAgICB9XG4gICAgICBkZWZhdWx0OlxuICAgICAgICB0aHJvdyBuZXcgRm9ybWF0RXJyb3IoYCR7ZmlsZX06IFVuYmVrYW5udGVyIEJsb2NrIOKAnjo6OiAke29wZW5bMV194oCcLmApXG4gICAgfVxuICAgIGkgPSBqXG4gIH1cbiAgZmx1c2goKVxuICByZXR1cm4gYmxvY2tzXG59XG5cbmZ1bmN0aW9uIGNoZWNrbGlzdEl0ZW0obGluZTogc3RyaW5nKTogQ2hlY2tsaXN0SXRlbSB7XG4gIGNvbnN0IG0gPSAvXiguKj8pXFxzK+KGklxccysoLispJC8uZXhlYyhsaW5lKVxuICByZXR1cm4gbSA/IHsgdGV4dDogbVsxXSwgcmVmOiBtWzJdLnRyaW0oKSB9IDogeyB0ZXh0OiBsaW5lIH1cbn1cblxuLyoqIFZlcndlaXNlIGF1cyBDaGVja2xpc3RlbiBhdWYgZGVuIGVya2zDpHJlbmRlbiBTY2hyaXR0IGF1ZmzDtnNlbi4gKi9cbmZ1bmN0aW9uIHJlc29sdmVDaGVja2xpc3RSZWZzKHN0ZXBzOiBTdGVwW10sIGZpbGU6IHN0cmluZykge1xuICBjb25zdCBpbmRleCA9IG5ldyBNYXAoc3RlcHMubWFwKChzLCBpKSA9PiBbcy50aXRsZS50b0xvd2VyQ2FzZSgpLCBpXSkpXG4gIGZvciAoY29uc3QgYmxvY2sgb2Ygc3RlcHMuZmxhdE1hcCgocykgPT4gcy5ibG9ja3MpKSB7XG4gICAgaWYgKGJsb2NrLmtpbmQgIT09ICdjaGVja2xpc3QnKSBjb250aW51ZVxuICAgIGZvciAoY29uc3QgaXRlbSBvZiBibG9jay5pdGVtcykge1xuICAgICAgaWYgKGl0ZW0ucmVmID09PSB1bmRlZmluZWQpIGNvbnRpbnVlXG4gICAgICBpdGVtLnN0ZXAgPSBpbmRleC5nZXQoaXRlbS5yZWYudG9Mb3dlckNhc2UoKSlcbiAgICAgIGlmIChpdGVtLnN0ZXAgPT09IHVuZGVmaW5lZCkgdGhyb3cgbmV3IEZvcm1hdEVycm9yKGAke2ZpbGV9OiBDaGVja2xpc3RlIHZlcndlaXN0IGF1ZiB1bmJla2FubnRlbiBTY2hyaXR0IOKAniR7aXRlbS5yZWZ94oCcLmApXG4gICAgfVxuICB9XG4gIGNvbnN0IGNoZWNrZWQgPSBuZXcgU2V0KHN0ZXBzLmZsYXRNYXAoKHMpID0+IHMuYmxvY2tzKS5mbGF0TWFwKChiKSA9PiAoYi5raW5kID09PSAnY2hlY2tsaXN0JyA/IGIuaXRlbXMubWFwKChpKSA9PiBpLnN0ZXApIDogW10pKSlcbiAgZm9yIChjb25zdCBibG9jayBvZiBzdGVwcy5mbGF0TWFwKChzKSA9PiBzLmJsb2NrcykpIHtcbiAgICBpZiAoYmxvY2sua2luZCAhPT0gJ3F1aXonKSBjb250aW51ZVxuICAgIGZvciAoY29uc3QgcSBvZiBibG9jay5xdWVzdGlvbnMpIHtcbiAgICAgIGlmIChxLnJlZiA9PT0gdW5kZWZpbmVkKSBjb250aW51ZVxuICAgICAgcS5zdGVwID0gaW5kZXguZ2V0KHEucmVmLnRvTG93ZXJDYXNlKCkpXG4gICAgICBpZiAocS5zdGVwID09PSB1bmRlZmluZWQpIHRocm93IG5ldyBGb3JtYXRFcnJvcihgJHtmaWxlfTogUXVpemZyYWdlIOKAniR7cS5xdWVzdGlvbn3igJwgdmVyd2Vpc3QgYXVmIHVuYmVrYW5udGVuIFNjaHJpdHQg4oCeJHtxLnJlZn3igJwuYClcbiAgICAgIGlmICghY2hlY2tlZC5oYXMocS5zdGVwKSkgdGhyb3cgbmV3IEZvcm1hdEVycm9yKGAke2ZpbGV9OiBadSDigJ4ke3EucmVmfeKAnCAoUXVpemZyYWdlIOKAniR7cS5xdWVzdGlvbn3igJwpIGdpYnQgZXMga2VpbmVuIENoZWNrbGlzdGVucHVua3QuYClcbiAgICB9XG4gIH1cbn1cblxuZXhwb3J0IGZ1bmN0aW9uIHBhcnNlTGVzc29uKHNvdXJjZTogc3RyaW5nLCBmaWxlOiBzdHJpbmcpOiBMZXNzb24ge1xuICBjb25zdCB7IG1ldGEsIGJvZHkgfSA9IGZyb250TWF0dGVyKHNvdXJjZSwgZmlsZSlcbiAgY29uc3QgbmFtZSA9IGZpbGUucmVwbGFjZSgvXi4qXFwvLywgJycpLnJlcGxhY2UoL1xcLm1kJC8sICcnKVxuICBjb25zdCBudW1iZXIgPSBOdW1iZXIoL14oXFxkKykvLmV4ZWMobmFtZSk/LlsxXSlcbiAgaWYgKCFOdW1iZXIuaXNGaW5pdGUobnVtYmVyKSkgdGhyb3cgbmV3IEZvcm1hdEVycm9yKGAke2ZpbGV9OiBEYXRlaW5hbWUgbXVzcyBtaXQgZGVyIE51bW1lciBiZWdpbm5lbiAoei4gQi4gMDEt4oCmKS5gKVxuICBjb25zdCBzdGVwczogU3RlcFtdID0gW11cbiAgbGV0IGludHJvOiBzdHJpbmdbXSA9IFtdXG4gIGxldCBjdXJyZW50OiB7IHRpdGxlOiBzdHJpbmc7IGxpbmVzOiBzdHJpbmdbXSB9IHwgdW5kZWZpbmVkXG4gIGNvbnN0IGNsb3NlID0gKCkgPT4ge1xuICAgIGlmIChjdXJyZW50KSBzdGVwcy5wdXNoKHsgdGl0bGU6IGN1cnJlbnQudGl0bGUsIGJsb2NrczogcGFyc2VCbG9ja3MoY3VycmVudC5saW5lcy5qb2luKCdcXG4nKSwgZmlsZSkgfSlcbiAgfVxuICBmb3IgKGNvbnN0IGxpbmUgb2YgYm9keS5zcGxpdCgnXFxuJykpIHtcbiAgICBjb25zdCBoID0gL14jI1xccysoLiopJC8uZXhlYyhsaW5lKVxuICAgIGlmIChoKSB7XG4gICAgICBjbG9zZSgpXG4gICAgICBjdXJyZW50ID0geyB0aXRsZTogaFsxXS50cmltKCksIGxpbmVzOiBbXSB9XG4gICAgfSBlbHNlIGlmIChjdXJyZW50KSB7XG4gICAgICBjdXJyZW50LmxpbmVzLnB1c2gobGluZSlcbiAgICB9IGVsc2Uge1xuICAgICAgaW50cm8ucHVzaChsaW5lKVxuICAgIH1cbiAgfVxuICBjbG9zZSgpXG4gIGlmIChzdGVwcy5sZW5ndGggPT09IDApIHRocm93IG5ldyBGb3JtYXRFcnJvcihgJHtmaWxlfTogS2VpbmUgU2Nocml0dGUgKCMjIMOcYmVyc2NocmlmdCkgZ2VmdW5kZW4uYClcbiAgcmVzb2x2ZUNoZWNrbGlzdFJlZnMoc3RlcHMsIGZpbGUpXG4gIGNvbnN0IHRpdGxlID0gbWV0YS5nZXQoJ3RpdGVsJylcbiAgaWYgKCF0aXRsZSkgdGhyb3cgbmV3IEZvcm1hdEVycm9yKGAke2ZpbGV9OiDigJ50aXRlbDrigJwgZmVobHQuYClcbiAgcmV0dXJuIHtcbiAgICBpZDogbmFtZSxcbiAgICBudW1iZXIsXG4gICAgdGl0bGUsXG4gICAgc2VjdGlvbjogbWV0YS5nZXQoJ2JlcmVpY2gnKSA/PyAnJyxcbiAgICBzdW1tYXJ5OiBtZXRhLmdldCgna3VyeicpID8/IGludHJvLmpvaW4oJyAnKS50cmltKCksXG4gICAgc3RlcHMsXG4gIH1cbn1cblxuZXhwb3J0IGZ1bmN0aW9uIHBhcnNlVGFzayhzb3VyY2U6IHN0cmluZywgZmlsZTogc3RyaW5nKTogVGFzayB7XG4gIGNvbnN0IHsgbWV0YSwgYm9keSB9ID0gZnJvbnRNYXR0ZXIoc291cmNlLCBmaWxlKVxuICBjb25zdCB0aXRsZSA9IG1ldGEuZ2V0KCd0aXRlbCcpXG4gIGlmICghdGl0bGUpIHRocm93IG5ldyBGb3JtYXRFcnJvcihgJHtmaWxlfTog4oCedGl0ZWw64oCcIGZlaGx0LmApXG4gIGNvbnN0IGFmdGVyID0gbWV0YS5nZXQoJ25hY2gnKVxuICByZXR1cm4ge1xuICAgIGlkOiBmaWxlLnJlcGxhY2UoL14uKlxcLy8sICcnKS5yZXBsYWNlKC9cXC5tZCQvLCAnJyksXG4gICAgdGl0bGUsXG4gICAgYWZ0ZXI6IGFmdGVyID8gTnVtYmVyKGFmdGVyKSA6IHVuZGVmaW5lZCxcbiAgICBsZXZlbDogTnVtYmVyKG1ldGEuZ2V0KCdzdHVmZScpID8/ICcxJykgfHwgMSxcbiAgICBibG9ja3M6IHBhcnNlQmxvY2tzKGJvZHksIGZpbGUpLFxuICB9XG59XG5cbi8qKiBgY3liZXJwaSwgc2NyZWVuYCDihpIgZ2VwcsO8ZnRlIFRlaWxuYW1lbiBkZXMgbUJvdDItTW9kZWxscy4gKi9cbmZ1bmN0aW9uIHJvYm90UGFydHMobGlzdDogc3RyaW5nLCBmaWxlOiBzdHJpbmcpOiBNQm90UGFydFtdIHtcbiAgY29uc3QgbmFtZXMgPSBsaXN0LnNwbGl0KC9cXHMqLFxccyovKS5tYXAoKHgpID0+IHgudHJpbSgpKS5maWx0ZXIoQm9vbGVhbilcbiAgZm9yIChjb25zdCBuIG9mIG5hbWVzKSBpZiAoIWlzTUJvdFBhcnQobikpIHRocm93IG5ldyBGb3JtYXRFcnJvcihgJHtmaWxlfTogVW5iZWthbm50ZXMgVGVpbCDigJ4ke2594oCcLiBCZWthbm50OiAke01CT1RfUEFSVFMuam9pbignLCAnKX0uYClcbiAgcmV0dXJuIG5hbWVzIGFzIE1Cb3RQYXJ0W11cbn1cbiJdLCJmaWxlIjoiL3dlYi9zcmMvbGVhcm4vbGVzc29uRm9ybWF0LnRzIn0= - -//# vitestCache=W3siZmlsZSI6IjEiLCJpZCI6IjEiLCJ1cmwiOiIyIiwiaW1wb3J0cyI6IjMiLCJtYXBwaW5ncyI6ZmFsc2UsImRlcHMiOiI0IiwiZHluYW1pY0RlcHMiOiI1Iiwic3RhdGljTW9ja3MiOm51bGx9LCIvaG9tZS91c2VyL3Zpc3VzdHJ1Y3Qtc3dpZnR1aS93ZWIvc3JjL2xlYXJuL2xlc3NvbkZvcm1hdC50cyIsIi93ZWIvc3JjL2xlYXJuL2xlc3NvbkZvcm1hdC50cyIseyJ1cmxzIjoiNiIsImlkcyI6IjcifSxbIjgiLCI5IiwiMTAiLCIxMSIsIjEyIiwiMTMiXSxbXSxbIjgiLCI5IiwiMTAiLCIxMSIsIjEyIiwiMTMiXSx7fSwiL3dlYi9zcmMvY29yZS9tYm90LnRzIiwiL3dlYi9zcmMvbGVhcm4vYm9vbEdhbWUudHMiLCIvd2ViL3NyYy9sZWFybi9yb3VuZEdhbWUudHMiLCIvd2ViL3NyYy9sZWFybi9yZXNjdWVHYW1lLnRzIiwiL3dlYi9zcmMvbGVhcm4vY2xvemUudHMiLCIvd2ViL3NyYy9sZWFybi9wYXAudHMiXQ== \ No newline at end of file diff --git a/node_modules/.vitest-cache/e482c53abeaa5899f7e393b26fde791e2b456b18 b/node_modules/.vitest-cache/e482c53abeaa5899f7e393b26fde791e2b456b18 deleted file mode 100644 index cfff90bf..00000000 --- a/node_modules/.vitest-cache/e482c53abeaa5899f7e393b26fde791e2b456b18 +++ /dev/null @@ -1,382 +0,0 @@ -__vite_ssr_exportName__("RUN", () => { try { return RUN } catch {} }); -__vite_ssr_exportName__("ASK", () => { try { return ASK } catch {} }); -__vite_ssr_exportName__("frame", () => { try { return frame } catch {} }); -__vite_ssr_exportName__("pythonFrame", () => { try { return pythonFrame } catch {} }); -__vite_ssr_exportName__("readAnswers", () => { try { return readAnswers } catch {} }); -__vite_ssr_exportName__("readFrames", () => { try { return readFrames } catch {} }); -__vite_ssr_exportName__("UPLOAD_PATH", () => { try { return UPLOAD_PATH } catch {} }); -__vite_ssr_exportName__("UPLOAD_PREPARE", () => { try { return UPLOAD_PREPARE } catch {} }); -__vite_ssr_exportName__("fileChecksum", () => { try { return fileChecksum } catch {} }); -__vite_ssr_exportName__("uploadFrames", () => { try { return uploadFrames } catch {} }); -__vite_ssr_exportName__("canConnectMBot", () => { try { return canConnectMBot } catch {} }); -__vite_ssr_exportName__("pyLines", () => { try { return pyLines } catch {} }); -__vite_ssr_exportName__("showLabel", () => { try { return showLabel } catch {} }); -__vite_ssr_exportName__("HELLO", () => { try { return HELLO } catch {} }); -__vite_ssr_exportName__("MBotLink", () => { try { return MBotLink } catch {} }); -__vite_ssr_exportName__("mbotLink", () => { try { return mbotLink } catch {} }); -const HEAD = 243; -const FOOT = 244; -const SCRIPT = 40; -const RUN = 4; -const ASK = 1; -/** Rahmen um einen Inhalt legen. */ -function frame(body) { - const len = body.length; - const head = HEAD + (len & 255) + (len >> 8) & 255; - const sum = body.reduce((a, b) => a + b, 0) & 255; - return Uint8Array.from([ - HEAD, - head, - len & 255, - len >> 8, - ...body, - sum, - FOOT - ]); -}; -/** Python-Zeile als Rahmen mit Modus und Nummer. */ -function pythonFrame(code, mode, idx) { - const text = Array.from(new TextEncoder().encode(code)); - return frame([ - SCRIPT, - mode, - idx & 255, - idx >> 8 & 255, - text.length & 255, - text.length >> 8, - ...text - ]); -}; -/** -* Sucht vollständige Rahmen in `rx` und gibt die Antworten auf Python-Zeilen zurück; verbrauchte Bytes werden entfernt. -* Textausgaben des CyberPi außerhalb von Rahmen (z. B. nach dem Neustart) werden übersprungen. -*/ -function readAnswers(rx) { - return readFrames(rx).flatMap((body) => scriptAnswer(body) ?? []); -}; -/** Inhalt einer Antwort auf eine Python-Zeile, sonst `undefined`. */ -function scriptAnswer(body) { - if (body[0] !== SCRIPT || body.length < 6) return undefined; - const text = new TextDecoder().decode(Uint8Array.from(body.slice(6))); - const m = /"ret"\s*:\s*([^}]*)\}/.exec(text); - return m ? { - idx: body[2] | body[3] << 8, - value: pythonValue(m[1].trim()) - } : undefined; -} -/** Alle vollständigen Rahmen aus `rx` (nur der Inhalt); verbrauchte Bytes werden entfernt. */ -function readFrames(rx) { - const bodies = []; - for (;;) { - const start = rx.indexOf(HEAD); - if (start < 0) { - rx.length = 0; - break; - }; - rx.splice(0, start); - if (rx.length < 4) break; - const len = rx[2] | rx[3] << 8; - // Kein Rahmen, nur ein zufälliges F3 im Text: weitersuchen - if (rx[1] !== (HEAD + rx[2] + rx[3] & 255) || len > 4096) { - rx.splice(0, 1); - continue; - }; - if (rx.length < len + 6) break; - bodies.push(rx.slice(4, 4 + len)); - rx.splice(0, len + 6); - }; - return bodies; -}; -function pythonValue(text) { - if (text === "True") return true; - if (text === "False") return false; - // Text, z. B. ein Farbname: "red" oder 'red' - const quoted = /^["'](.*)["']$/.exec(text); - if (quoted) return quoted[1]; - const n = Number(text); - return text !== "" && Number.isFinite(n) ? n : null; -} -/** -* Programm fest auf dem CyberPi speichern, wie „Hochladen“ in mBlock (Ablauf aus github.com/weare2plus3/cyberpi-uploader, MIT): -* Upload-Modus (`0D 00 00`), REPL aus, Dateikopf mit Größe, XOR-Prüfsumme und Pfad, dann Blöcke zu 80 Byte. -* Die Datei landet in einem Zwischenplatz, den die Firmware beim nächsten Neustart übernimmt. -*/ -const UPLOAD_PATH = "/flash/_xx_main.py"; -const UPLOAD_MODE = [ - 13, - 0, - 0 -]; -const FILE_SERVICE = 94; -const BLOCK = 80; -const UPLOAD_PREPARE = ["try:\n import config\nexcept:\n pass", "try:\n config.write_config(\"repl_enable\", False)\nexcept:\n pass"]; -const le = (value, bytes) => Array.from({ length: bytes }, (_, i) => value >>> 8 * i & 255); -/** XOR der 32-Bit-Wörter (little endian, mit Nullen aufgefüllt), wie mBlock. */ -function fileChecksum(data) { - let x = 0; - for (let i = 0; i < data.length; i += 4) x = (x ^ ((data[i] ?? 0) | (data[i + 1] ?? 0) << 8 | (data[i + 2] ?? 0) << 16 | (data[i + 3] ?? 0) << 24)) >>> 0; - return le(x, 4); -}; -const fileFrame = (cmd, payload) => frame([ - 1, - 0, - FILE_SERVICE, - cmd, - ...le(payload.length, 2), - ...payload -]); -/** Python-Datei in Rahmen: Kopf, dann Blöcke zu 80 Byte und ein letzter Block mit 4 Byte (wie mBlock; mit Zeilenumbrüchen aufgefüllt). */ -function uploadFrames(source, path = UPLOAD_PATH) { - const raw = new TextEncoder().encode(source); - const pad = (4 - raw.length % BLOCK + BLOCK) % BLOCK; - const data = new Uint8Array(raw.length + pad).fill(10); - data.set(raw); - const frames = [fileFrame(1, [ - 0, - ...le(data.length, 4), - ...fileChecksum(data), - ...Array.from(new TextEncoder().encode(path)) - ])]; - const end = data.length - 4; - for (let off = 0; off < end; off += BLOCK) frames.push(fileFrame(2, [...le(off, 4), ...data.subarray(off, Math.min(off + BLOCK, end))])); - frames.push(fileFrame(2, [...le(end, 4), ...data.subarray(end)])); - return frames; -}; -const isModeEcho = (body) => body.length === 3 && body[0] === 13; -const isFileAck = (body) => body.length === 7 || body.some((b, i) => b === FILE_SERVICE && body[i + 1] === 240); -const serial = () => typeof navigator === "undefined" ? undefined : navigator.serial; -/** Kann dieser Browser einen mBot2 über USB ansprechen? */ -const canConnectMBot = () => serial() !== undefined; -/** Mehrere Python-Anweisungen als eine Zeile (der CyberPi nimmt nur eine). JSON-Strings sind auch gültige Python-Strings. */ -const pyLines = (...lines) => `exec(${JSON.stringify(lines.join("; "))})`; -/** -* Bildschirm leeren und Text in der Mitte zeigen. Ohne Pinselfarbe: `display.set_brush` wirkt am CyberPi -* unzuverlässig (Texte kamen rot, lila, grün oder blau statt in der gewählten Farbe, auch mit Pausen). -* Die Schrift hat dann die Farbe, die der CyberPi gerade hat (einfarbig, nicht immer weiß; Holger: in Ordnung). -*/ -const showLabel = (text, size = 24) => pyLines("cyberpi.display.clear()", `cyberpi.display.show_label(${JSON.stringify(text)}, ${size}, 'center')`); -/** -* Logo nach dem Verbinden (und nach „mBot2 testen“ → Text): „VisuBot“ groß, einfarbig. -* Grafik (screen.set_pixel, Sprite) zeigt über USB nichts, Farben gehen nicht zuverlässig. Am echten mBot2 getestet (Oktober 2026). -*/ -const HELLO = showLabel("VisuBot", 32); -class MBotLink { - port; - writer; - reader; - loop; - rx = []; - idx = 1; - frameWaiters = []; - waiting = new Map(); - queue = Promise.resolve(); - listeners = new Set(); - error; - /** Port ist offen, der CyberPi startet noch neu. */ - connecting = false; - /** `fn` bei Verbinden, Trennen und Fehlern rufen; gibt eine Abmeldung zurück. */ - listen(fn) { - this.listeners.add(fn); - return () => this.listeners.delete(fn); - } - changed() { - for (const fn of this.listeners) fn(); - } - get connected() { - return this.writer !== undefined && !this.connecting; - } - /** Fragt nach dem USB-Anschluss, öffnet ihn und wartet den Neustart des CyberPi ab. */ - async connect() { - const s = serial(); - if (!s) throw new Error("Web Serial"); - const port = await s.requestPort(); - await port.open({ baudRate: 115200 }); - this.port = port; - this.writer = port.writable.getWriter(); - this.error = undefined; - this.connecting = true; - this.changed(); - this.loop = this.readLoop(); - // Seite schließen oder neu laden: Anschluss freigeben - window.addEventListener("pagehide", () => void this.disconnect(), { once: true }); - // Das Öffnen setzt den CyberPi zurück - await new Promise((r) => setTimeout(r, 3e3)); - if (!this.writer) return; - // Textausgaben vom Neustart verwerfen - this.rx.length = 0; - this.connecting = false; - this.changed(); - await this.run(HELLO); - } - /** - * Sauber trennen wie beim Auswerfen: Motoren anhalten, LEDs aus, Abschied auf dem Bildschirm, - * dann Leser und Schreiber freigeben und den Anschluss schließen. So lässt er sich ohne Neustart wieder verbinden. - */ - async disconnect(error) { - if (!this.port) { - this.error = error; - return this.changed(); - }; - if (!error && this.writer && !this.connecting) { - for (const code of [ - "mbot2.EM_stop('ALL')", - "cyberpi.led.off()", - showLabel("Bis bald!") - ]) await this.send(code, RUN, 2e3).catch(() => undefined); - }; - const port = this.port; - const writer = this.writer; - const reader = this.reader; - const loop = this.loop; - this.port = this.writer = this.reader = this.loop = undefined; - this.error = error; - this.connecting = false; - for (const w of this.waiting.values()) w.reject(new Error(error ?? "getrennt")); - this.waiting.clear(); - try { - await reader?.cancel(); - await loop; - await writer?.close(); - } catch {}; - try { - writer?.releaseLock(); - await port.close(); - } catch (e) { - console.warn("[mBot2] Schließen", e.message); - }; - this.changed(); - } - /** Python-Zeile ausführen; kehrt zurück, wenn der Roboter fertig ist (Fahren dauert). */ - run(code) { - return this.send(code, RUN, 3e4).then(() => undefined); - } - /** Wert eines Python-Ausdrucks, z. B. eines Sensors. */ - ask(code) { - return this.send(code, ASK, 3e3); - } - /** - * Programm auf den CyberPi übertragen (verbindet vorher, wenn nötig). Danach startet der CyberPi neu und - * das Programm bleibt gespeichert, auch ohne Kabel. `progress` bekommt erledigte und alle Schritte. - */ - async upload(source, progress = () => {}) { - if (!this.port) await this.connect(); - if (!this.writer) throw new Error(this.error ?? "nicht verbunden"); - const files = uploadFrames(source); - const total = 6 + files.length + 3; - let done = 0; - const step = () => progress(++done, total); - const prepare = async () => { - await this.sendFrame(frame(UPLOAD_MODE), isModeEcho); - step(); - for (const code of UPLOAD_PREPARE) { - await this.send(code, RUN, 3e3); - step(); - } - }; - await prepare(); - await prepare(); - for (const f of files) { - await this.sendFrame(f, isFileAck); - step(); - }; - done = total - 3; - await prepare(); - await this.restart(); - } - /** Rahmen schicken und auf die passende Antwort warten (bis zu drei Versuche). */ - sendFrame(data, match) { - const next = this.queue.then(async () => { - for (let attempt = 0; attempt < 3; attempt++) { - if (!this.writer) throw new Error("nicht verbunden"); - let resolve = () => {}; - const answered = new Promise((r) => resolve = r); - const waiter = { - match, - resolve - }; - this.frameWaiters.push(waiter); - await this.writer.write(data); - const ok = await Promise.race([answered.then(() => true), new Promise((r) => setTimeout(() => r(false), 3e3))]); - this.frameWaiters = this.frameWaiters.filter((w) => w !== waiter); - if (ok) return; - }; - throw new Error("keine Antwort"); - }); - this.queue = next.catch(() => undefined); - return next; - } - /** Anschluss schließen und wieder öffnen: das setzt den CyberPi zurück, er übernimmt das neue Programm. */ - async restart() { - const port = this.port; - await this.disconnect("restart"); - this.error = undefined; - await new Promise((r) => setTimeout(r, 300)); - await port.open({ baudRate: 115200 }); - await new Promise((r) => setTimeout(r, 500)); - await port.close(); - this.changed(); - } - send(code, mode, timeoutMs) { - // Immer nur eine Zeile unterwegs: der CyberPi arbeitet sie nacheinander ab. - const next = this.queue.then(() => new Promise((resolve, reject) => { - if (!this.writer) return reject(new Error("nicht verbunden")); - const idx = this.idx; - this.idx = this.idx % 65535 + 1; - const timer = setTimeout(() => { - this.waiting.delete(idx); - reject(new Error("keine Antwort")); - }, timeoutMs); - this.waiting.set(idx, { - resolve: (v) => (clearTimeout(timer), resolve(v)), - reject: (e) => (clearTimeout(timer), reject(e)) - }); - this.writer.write(pythonFrame(code, mode, idx)).catch((e) => { - this.waiting.delete(idx); - reject(e); - }); - })); - this.queue = next.catch(() => undefined); - return next; - } - async readLoop() { - while (this.port?.readable) { - const reader = this.port.readable.getReader(); - this.reader = reader; - try { - for (;;) { - const { value, done } = await reader.read(); - if (done) break; - this.rx.push(...value); - for (const body of readFrames(this.rx)) { - const f = this.frameWaiters.findIndex((w) => w.match(body)); - if (f >= 0) this.frameWaiters.splice(f, 1)[0].resolve(); - const a = scriptAnswer(body); - if (!a) continue; - const w = this.waiting.get(a.idx); - this.waiting.delete(a.idx); - w?.resolve(a.value); - } - } - } catch (e) { - // Störungen auf der Leitung (z. B. beim Neustart des CyberPi) sind harmlos: mit neuem Leser weiter - const harmless = [ - "BufferOverrunError", - "FramingError", - "BreakError", - "ParityError" - ].includes(e.name); - console.warn("[mBot2] Lesefehler", e.name, e.message); - if (!harmless && this.port) void this.disconnect(e.message); - } finally { - reader.releaseLock(); - }; - if (!this.writer) break; - } - } -}; -/** Eine Verbindung für die ganze Seite (bleibt beim Neuaufbau der Oberfläche erhalten). */ -const mbotLink = new MBotLink(); -//# sourceMappingSource=vite-generated -//# sourceMappingURL=data:application/json;base64,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QUssYUFBYSxPQUFPLEdBQUcsQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLFFBQVE7TUFDdEQsTUFBTSxJQUFJLGFBQWEsSUFBSTtNQUMzQixJQUFJLENBQUMsR0FBRztNQUNSLE1BQU0sSUFBSSxLQUFLLFFBQVEsSUFBSSxFQUFFLEdBQUc7TUFDaEMsS0FBSyxRQUFRLE9BQU8sRUFBRSxHQUFHO01BQ3pCLEdBQUcsUUFBUSxFQUFFLEtBQUs7S0FDcEI7SUFDRjtHQUNGLFNBQVMsR0FBRzs7SUFFVixNQUFNLFdBQVc7S0FBQztLQUFzQjtLQUFnQjtLQUFjO0lBQWEsQ0FBQyxDQUFDLFNBQVUsRUFBWSxJQUFJO0lBQy9HLFFBQVEsS0FBSyxzQkFBdUIsRUFBWSxNQUFPLEVBQVksT0FBTztJQUMxRSxJQUFJLENBQUMsWUFBWSxLQUFLLE1BQU0sS0FBSyxLQUFLLFdBQVksRUFBWSxPQUFPO0dBQ3ZFLFVBQVU7SUFDUixPQUFPLFlBQVk7R0FDckI7R0FDQSxJQUFJLENBQUMsS0FBSyxRQUFRO0VBQ3BCO0NBQ0Y7QUFDRjs7QUFHTyxNQUFNLFdBQVcsSUFBSSxTQUFTIiwibmFtZXMiOltdLCJpZ25vcmVMaXN0IjpbXSwic291cmNlcyI6WyJtYm90TGluay50cyJdLCJzb3VyY2VzQ29udGVudCI6WyIvKipcbiAqIFZlcmJpbmR1bmcgenVtIGVjaHRlbiBtQm90MiDDvGJlciBVU0IgKFdlYiBTZXJpYWwsIG51ciBDaHJvbWUvRWRnZSkuIERpZSBNYWtlYmxvY2stRmlybXdhcmUgZGVzIEN5YmVyUGlcbiAqIGbDvGhydCBQeXRob24tWmVpbGVuIGF1cywgZGllIGluIGVpbmVuIFJhaG1lbiB2ZXJwYWNrdCBzaW5kOlxuICogYEYzLCBLb3Bmc3VtbWUsIEzDpG5nZSAoMiBCeXRlKSwgMjgsIE1vZHVzLCBOdW1tZXIgKDIgQnl0ZSksIFRleHRsw6RuZ2UgKDIgQnl0ZSksIFRleHQsIFN1bW1lLCBGNGAuXG4gKiBNb2R1cyA0IGbDvGhydCBudXIgYXVzIChGYWhyYmVmZWhsZSBhbnR3b3J0ZW4gZXJzdCwgd2VubiBzaWUgZmVydGlnIHNpbmQpLCBNb2R1cyAxIGxpZWZlcnQgZGVuIFdlcnQgenVyw7xjay5cbiAqIERpZSBBbnR3b3J0IHRyw6RndCBkaWVzZWxiZSBOdW1tZXIgdW5kIGVudGjDpGx0IGB7XCJyZXRcIjrigKZ9YC4gR2V0ZXN0ZXQgbWl0IEhvbGdlcnMgbUJvdDIgKE9rdG9iZXIgMjAyNikuXG4gKi9cblxuaW1wb3J0IHR5cGUgeyBNQm90U2Vuc29yVmFsdWUgfSBmcm9tICcuL21ib3QnXG5cbmNvbnN0IEhFQUQgPSAweGYzXG5jb25zdCBGT09UID0gMHhmNFxuY29uc3QgU0NSSVBUID0gMHgyOFxuZXhwb3J0IGNvbnN0IFJVTiA9IDRcbmV4cG9ydCBjb25zdCBBU0sgPSAxXG5cbi8qKiBSYWhtZW4gdW0gZWluZW4gSW5oYWx0IGxlZ2VuLiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGZyYW1lKGJvZHk6IG51bWJlcltdKTogVWludDhBcnJheSB7XG4gIGNvbnN0IGxlbiA9IGJvZHkubGVuZ3RoXG4gIGNvbnN0IGhlYWQgPSAoSEVBRCArIChsZW4gJiAweGZmKSArIChsZW4gPj4gOCkpICYgMHhmZlxuICBjb25zdCBzdW0gPSBib2R5LnJlZHVjZSgoYSwgYikgPT4gYSArIGIsIDApICYgMHhmZlxuICByZXR1cm4gVWludDhBcnJheS5mcm9tKFtIRUFELCBoZWFkLCBsZW4gJiAweGZmLCBsZW4gPj4gOCwgLi4uYm9keSwgc3VtLCBGT09UXSlcbn1cblxuLyoqIFB5dGhvbi1aZWlsZSBhbHMgUmFobWVuIG1pdCBNb2R1cyB1bmQgTnVtbWVyLiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHB5dGhvbkZyYW1lKGNvZGU6IHN0cmluZywgbW9kZTogbnVtYmVyLCBpZHg6IG51bWJlcik6IFVpbnQ4QXJyYXkge1xuICBjb25zdCB0ZXh0ID0gQXJyYXkuZnJvbShuZXcgVGV4dEVuY29kZXIoKS5lbmNvZGUoY29kZSkpXG4gIHJldHVybiBmcmFtZShbU0NSSVBULCBtb2RlLCBpZHggJiAweGZmLCAoaWR4ID4+IDgpICYgMHhmZiwgdGV4dC5sZW5ndGggJiAweGZmLCB0ZXh0Lmxlbmd0aCA+PiA4LCAuLi50ZXh0XSlcbn1cblxuZXhwb3J0IGludGVyZmFjZSBTY3JpcHRBbnN3ZXIge1xuICBpZHg6IG51bWJlclxuICAvKiogV2VydCBhdXMgYHtcInJldFwiOuKApn1gOiBaYWhsLCBXYWhyaGVpdHN3ZXJ0LCBUZXh0IG9kZXIgYG51bGxgIChQeXRob24gYE5vbmVgKS4gKi9cbiAgdmFsdWU6IE1Cb3RTZW5zb3JWYWx1ZSB8IG51bGxcbn1cblxuLyoqXG4gKiBTdWNodCB2b2xsc3TDpG5kaWdlIFJhaG1lbiBpbiBgcnhgIHVuZCBnaWJ0IGRpZSBBbnR3b3J0ZW4gYXVmIFB5dGhvbi1aZWlsZW4genVyw7xjazsgdmVyYnJhdWNodGUgQnl0ZXMgd2VyZGVuIGVudGZlcm50LlxuICogVGV4dGF1c2dhYmVuIGRlcyBDeWJlclBpIGF1w59lcmhhbGIgdm9uIFJhaG1lbiAoei4gQi4gbmFjaCBkZW0gTmV1c3RhcnQpIHdlcmRlbiDDvGJlcnNwcnVuZ2VuLlxuICovXG5leHBvcnQgZnVuY3Rpb24gcmVhZEFuc3dlcnMocng6IG51bWJlcltdKTogU2NyaXB0QW5zd2VyW10ge1xuICByZXR1cm4gcmVhZEZyYW1lcyhyeCkuZmxhdE1hcCgoYm9keSkgPT4gc2NyaXB0QW5zd2VyKGJvZHkpID8/IFtdKVxufVxuXG4vKiogSW5oYWx0IGVpbmVyIEFudHdvcnQgYXVmIGVpbmUgUHl0aG9uLVplaWxlLCBzb25zdCBgdW5kZWZpbmVkYC4gKi9cbmZ1bmN0aW9uIHNjcmlwdEFuc3dlcihib2R5OiBudW1iZXJbXSk6IFNjcmlwdEFuc3dlciB8IHVuZGVmaW5lZCB7XG4gIGlmIChib2R5WzBdICE9PSBTQ1JJUFQgfHwgYm9keS5sZW5ndGggPCA2KSByZXR1cm4gdW5kZWZpbmVkXG4gIGNvbnN0IHRleHQgPSBuZXcgVGV4dERlY29kZXIoKS5kZWNvZGUoVWludDhBcnJheS5mcm9tKGJvZHkuc2xpY2UoNikpKVxuICBjb25zdCBtID0gL1wicmV0XCJcXHMqOlxccyooW159XSopXFx9Ly5leGVjKHRleHQpXG4gIHJldHVybiBtID8geyBpZHg6IGJvZHlbMl0gfCAoYm9keVszXSA8PCA4KSwgdmFsdWU6IHB5dGhvblZhbHVlKG1bMV0udHJpbSgpKSB9IDogdW5kZWZpbmVkXG59XG5cbi8qKiBBbGxlIHZvbGxzdMOkbmRpZ2VuIFJhaG1lbiBhdXMgYHJ4YCAobnVyIGRlciBJbmhhbHQpOyB2ZXJicmF1Y2h0ZSBCeXRlcyB3ZXJkZW4gZW50ZmVybnQuICovXG5leHBvcnQgZnVuY3Rpb24gcmVhZEZyYW1lcyhyeDogbnVtYmVyW10pOiBudW1iZXJbXVtdIHtcbiAgY29uc3QgYm9kaWVzOiBudW1iZXJbXVtdID0gW11cbiAgZm9yICg7Oykge1xuICAgIGNvbnN0IHN0YXJ0ID0gcnguaW5kZXhPZihIRUFEKVxuICAgIGlmIChzdGFydCA8IDApIHtcbiAgICAgIHJ4Lmxlbmd0aCA9IDBcbiAgICAgIGJyZWFrXG4gICAgfVxuICAgIHJ4LnNwbGljZSgwLCBzdGFydClcbiAgICBpZiAocngubGVuZ3RoIDwgNCkgYnJlYWtcbiAgICBjb25zdCBsZW4gPSByeFsyXSB8IChyeFszXSA8PCA4KVxuICAgIC8vIEtlaW4gUmFobWVuLCBudXIgZWluIHp1ZsOkbGxpZ2VzIEYzIGltIFRleHQ6IHdlaXRlcnN1Y2hlblxuICAgIGlmIChyeFsxXSAhPT0gKChIRUFEICsgcnhbMl0gKyByeFszXSkgJiAweGZmKSB8fCBsZW4gPiA0MDk2KSB7XG4gICAgICByeC5zcGxpY2UoMCwgMSlcbiAgICAgIGNvbnRpbnVlXG4gICAgfVxuICAgIGlmIChyeC5sZW5ndGggPCBsZW4gKyA2KSBicmVha1xuICAgIGJvZGllcy5wdXNoKHJ4LnNsaWNlKDQsIDQgKyBsZW4pKVxuICAgIHJ4LnNwbGljZSgwLCBsZW4gKyA2KVxuICB9XG4gIHJldHVybiBib2RpZXNcbn1cblxuZnVuY3Rpb24gcHl0aG9uVmFsdWUodGV4dDogc3RyaW5nKTogTUJvdFNlbnNvclZhbHVlIHwgbnVsbCB7XG4gIGlmICh0ZXh0ID09PSAnVHJ1ZScpIHJldHVybiB0cnVlXG4gIGlmICh0ZXh0ID09PSAnRmFsc2UnKSByZXR1cm4gZmFsc2VcbiAgLy8gVGV4dCwgei4gQi4gZWluIEZhcmJuYW1lOiBcInJlZFwiIG9kZXIgJ3JlZCdcbiAgY29uc3QgcXVvdGVkID0gL15bXCInXSguKilbXCInXSQvLmV4ZWModGV4dClcbiAgaWYgKHF1b3RlZCkgcmV0dXJuIHF1b3RlZFsxXVxuICBjb25zdCBuID0gTnVtYmVyKHRleHQpXG4gIHJldHVybiB0ZXh0ICE9PSAnJyAmJiBOdW1iZXIuaXNGaW5pdGUobikgPyBuIDogbnVsbFxufVxuXG4vKipcbiAqIFByb2dyYW1tIGZlc3QgYXVmIGRlbSBDeWJlclBpIHNwZWljaGVybiwgd2llIOKAnkhvY2hsYWRlbuKAnCBpbiBtQmxvY2sgKEFibGF1ZiBhdXMgZ2l0aHViLmNvbS93ZWFyZTJwbHVzMy9jeWJlcnBpLXVwbG9hZGVyLCBNSVQpOlxuICogVXBsb2FkLU1vZHVzIChgMEQgMDAgMDBgKSwgUkVQTCBhdXMsIERhdGVpa29wZiBtaXQgR3LDtsOfZSwgWE9SLVByw7xmc3VtbWUgdW5kIFBmYWQsIGRhbm4gQmzDtmNrZSB6dSA4MCBCeXRlLlxuICogRGllIERhdGVpIGxhbmRldCBpbiBlaW5lbSBad2lzY2hlbnBsYXR6LCBkZW4gZGllIEZpcm13YXJlIGJlaW0gbsOkY2hzdGVuIE5ldXN0YXJ0IMO8YmVybmltbXQuXG4gKi9cbmV4cG9ydCBjb25zdCBVUExPQURfUEFUSCA9ICcvZmxhc2gvX3h4X21haW4ucHknXG5jb25zdCBVUExPQURfTU9ERSA9IFsweDBkLCAweDAwLCAweDAwXVxuY29uc3QgRklMRV9TRVJWSUNFID0gMHg1ZVxuY29uc3QgQkxPQ0sgPSA4MFxuZXhwb3J0IGNvbnN0IFVQTE9BRF9QUkVQQVJFID0gWyd0cnk6XFxuICAgIGltcG9ydCBjb25maWdcXG5leGNlcHQ6XFxuICAgIHBhc3MnLCAndHJ5OlxcbiAgICBjb25maWcud3JpdGVfY29uZmlnKFwicmVwbF9lbmFibGVcIiwgRmFsc2UpXFxuZXhjZXB0OlxcbiAgICBwYXNzJ11cblxuY29uc3QgbGUgPSAodmFsdWU6IG51bWJlciwgYnl0ZXM6IG51bWJlcikgPT4gQXJyYXkuZnJvbSh7IGxlbmd0aDogYnl0ZXMgfSwgKF8sIGkpID0+ICh2YWx1ZSA+Pj4gKDggKiBpKSkgJiAweGZmKVxuXG4vKiogWE9SIGRlciAzMi1CaXQtV8O2cnRlciAobGl0dGxlIGVuZGlhbiwgbWl0IE51bGxlbiBhdWZnZWbDvGxsdCksIHdpZSBtQmxvY2suICovXG5leHBvcnQgZnVuY3Rpb24gZmlsZUNoZWNrc3VtKGRhdGE6IFVpbnQ4QXJyYXkpOiBudW1iZXJbXSB7XG4gIGxldCB4ID0gMFxuICBmb3IgKGxldCBpID0gMDsgaSA8IGRhdGEubGVuZ3RoOyBpICs9IDQpIHggPSAoeCBeICgoZGF0YVtpXSA/PyAwKSB8ICgoZGF0YVtpICsgMV0gPz8gMCkgPDwgOCkgfCAoKGRhdGFbaSArIDJdID8/IDApIDw8IDE2KSB8ICgoZGF0YVtpICsgM10gPz8gMCkgPDwgMjQpKSkgPj4+IDBcbiAgcmV0dXJuIGxlKHgsIDQpXG59XG5cbmNvbnN0IGZpbGVGcmFtZSA9IChjbWQ6IG51bWJlciwgcGF5bG9hZDogbnVtYmVyW10pID0+IGZyYW1lKFsweDAxLCAweDAwLCBGSUxFX1NFUlZJQ0UsIGNtZCwgLi4ubGUocGF5bG9hZC5sZW5ndGgsIDIpLCAuLi5wYXlsb2FkXSlcblxuLyoqIFB5dGhvbi1EYXRlaSBpbiBSYWhtZW46IEtvcGYsIGRhbm4gQmzDtmNrZSB6dSA4MCBCeXRlIHVuZCBlaW4gbGV0enRlciBCbG9jayBtaXQgNCBCeXRlICh3aWUgbUJsb2NrOyBtaXQgWmVpbGVudW1icsO8Y2hlbiBhdWZnZWbDvGxsdCkuICovXG5leHBvcnQgZnVuY3Rpb24gdXBsb2FkRnJhbWVzKHNvdXJjZTogc3RyaW5nLCBwYXRoID0gVVBMT0FEX1BBVEgpOiBVaW50OEFycmF5W10ge1xuICBjb25zdCByYXcgPSBuZXcgVGV4dEVuY29kZXIoKS5lbmNvZGUoc291cmNlKVxuICBjb25zdCBwYWQgPSAoNCAtIChyYXcubGVuZ3RoICUgQkxPQ0spICsgQkxPQ0spICUgQkxPQ0tcbiAgY29uc3QgZGF0YSA9IG5ldyBVaW50OEFycmF5KHJhdy5sZW5ndGggKyBwYWQpLmZpbGwoMHgwYSlcbiAgZGF0YS5zZXQocmF3KVxuICBjb25zdCBmcmFtZXMgPSBbZmlsZUZyYW1lKDB4MDEsIFsweDAwLCAuLi5sZShkYXRhLmxlbmd0aCwgNCksIC4uLmZpbGVDaGVja3N1bShkYXRhKSwgLi4uQXJyYXkuZnJvbShuZXcgVGV4dEVuY29kZXIoKS5lbmNvZGUocGF0aCkpXSldXG4gIGNvbnN0IGVuZCA9IGRhdGEubGVuZ3RoIC0gNFxuICBmb3IgKGxldCBvZmYgPSAwOyBvZmYgPCBlbmQ7IG9mZiArPSBCTE9DSykgZnJhbWVzLnB1c2goZmlsZUZyYW1lKDB4MDIsIFsuLi5sZShvZmYsIDQpLCAuLi5kYXRhLnN1YmFycmF5KG9mZiwgTWF0aC5taW4ob2ZmICsgQkxPQ0ssIGVuZCkpXSkpXG4gIGZyYW1lcy5wdXNoKGZpbGVGcmFtZSgweDAyLCBbLi4ubGUoZW5kLCA0KSwgLi4uZGF0YS5zdWJhcnJheShlbmQpXSkpXG4gIHJldHVybiBmcmFtZXNcbn1cblxuY29uc3QgaXNNb2RlRWNobyA9IChib2R5OiBudW1iZXJbXSkgPT4gYm9keS5sZW5ndGggPT09IDMgJiYgYm9keVswXSA9PT0gMHgwZFxuY29uc3QgaXNGaWxlQWNrID0gKGJvZHk6IG51bWJlcltdKSA9PiBib2R5Lmxlbmd0aCA9PT0gNyB8fCBib2R5LnNvbWUoKGIsIGkpID0+IGIgPT09IEZJTEVfU0VSVklDRSAmJiBib2R5W2kgKyAxXSA9PT0gMHhmMClcblxuLy8gV2ViIFNlcmlhbCBpc3QgbmljaHQgaW4gZGVuIFR5cGVTY3JpcHQtVHlwZW47IG51ciBkYXMgTsO2dGlnc3RlLlxuaW50ZXJmYWNlIFNlcmlhbFBvcnRMaWtlIHtcbiAgb3BlbihvcHRpb25zOiB7IGJhdWRSYXRlOiBudW1iZXIgfSk6IFByb21pc2U8dm9pZD5cbiAgY2xvc2UoKTogUHJvbWlzZTx2b2lkPlxuICByZWFkYWJsZTogUmVhZGFibGVTdHJlYW08VWludDhBcnJheT4gfCBudWxsXG4gIHdyaXRhYmxlOiBXcml0YWJsZVN0cmVhbTxVaW50OEFycmF5PiB8IG51bGxcbn1cbmludGVyZmFjZSBTZXJpYWxMaWtlIHtcbiAgcmVxdWVzdFBvcnQoKTogUHJvbWlzZTxTZXJpYWxQb3J0TGlrZT5cbn1cblxuY29uc3Qgc2VyaWFsID0gKCk6IFNlcmlhbExpa2UgfCB1bmRlZmluZWQgPT4gKHR5cGVvZiBuYXZpZ2F0b3IgPT09ICd1bmRlZmluZWQnID8gdW5kZWZpbmVkIDogKG5hdmlnYXRvciBhcyB1bmtub3duIGFzIHsgc2VyaWFsPzogU2VyaWFsTGlrZSB9KS5zZXJpYWwpXG5cbi8qKiBLYW5uIGRpZXNlciBCcm93c2VyIGVpbmVuIG1Cb3QyIMO8YmVyIFVTQiBhbnNwcmVjaGVuPyAqL1xuZXhwb3J0IGNvbnN0IGNhbkNvbm5lY3RNQm90ID0gKCkgPT4gc2VyaWFsKCkgIT09IHVuZGVmaW5lZFxuXG4vKiogTWVocmVyZSBQeXRob24tQW53ZWlzdW5nZW4gYWxzIGVpbmUgWmVpbGUgKGRlciBDeWJlclBpIG5pbW10IG51ciBlaW5lKS4gSlNPTi1TdHJpbmdzIHNpbmQgYXVjaCBnw7xsdGlnZSBQeXRob24tU3RyaW5ncy4gKi9cbmV4cG9ydCBjb25zdCBweUxpbmVzID0gKC4uLmxpbmVzOiBzdHJpbmdbXSkgPT4gYGV4ZWMoJHtKU09OLnN0cmluZ2lmeShsaW5lcy5qb2luKCc7ICcpKX0pYFxuXG4vKipcbiAqIEJpbGRzY2hpcm0gbGVlcmVuIHVuZCBUZXh0IGluIGRlciBNaXR0ZSB6ZWlnZW4uIE9obmUgUGluc2VsZmFyYmU6IGBkaXNwbGF5LnNldF9icnVzaGAgd2lya3QgYW0gQ3liZXJQaVxuICogdW56dXZlcmzDpHNzaWcgKFRleHRlIGthbWVuIHJvdCwgbGlsYSwgZ3LDvG4gb2RlciBibGF1IHN0YXR0IGluIGRlciBnZXfDpGhsdGVuIEZhcmJlLCBhdWNoIG1pdCBQYXVzZW4pLlxuICogRGllIFNjaHJpZnQgaGF0IGRhbm4gZGllIEZhcmJlLCBkaWUgZGVyIEN5YmVyUGkgZ2VyYWRlIGhhdCAoZWluZmFyYmlnLCBuaWNodCBpbW1lciB3ZWnDnzsgSG9sZ2VyOiBpbiBPcmRudW5nKS5cbiAqL1xuZXhwb3J0IGNvbnN0IHNob3dMYWJlbCA9ICh0ZXh0OiBzdHJpbmcsIHNpemUgPSAyNCkgPT4gcHlMaW5lcygnY3liZXJwaS5kaXNwbGF5LmNsZWFyKCknLCBgY3liZXJwaS5kaXNwbGF5LnNob3dfbGFiZWwoJHtKU09OLnN0cmluZ2lmeSh0ZXh0KX0sICR7c2l6ZX0sICdjZW50ZXInKWApXG5cbi8qKlxuICogTG9nbyBuYWNoIGRlbSBWZXJiaW5kZW4gKHVuZCBuYWNoIOKAnm1Cb3QyIHRlc3RlbuKAnCDihpIgVGV4dCk6IOKAnlZpc3VCb3TigJwgZ3Jvw58sIGVpbmZhcmJpZy5cbiAqIEdyYWZpayAoc2NyZWVuLnNldF9waXhlbCwgU3ByaXRlKSB6ZWlndCDDvGJlciBVU0IgbmljaHRzLCBGYXJiZW4gZ2VoZW4gbmljaHQgenV2ZXJsw6Rzc2lnLiBBbSBlY2h0ZW4gbUJvdDIgZ2V0ZXN0ZXQgKE9rdG9iZXIgMjAyNikuXG4gKi9cbmV4cG9ydCBjb25zdCBIRUxMTyA9IHNob3dMYWJlbCgnVmlzdUJvdCcsIDMyKVxuXG5leHBvcnQgY2xhc3MgTUJvdExpbmsge1xuICBwcml2YXRlIHBvcnQ/OiBTZXJpYWxQb3J0TGlrZVxuICBwcml2YXRlIHdyaXRlcj86IFdyaXRhYmxlU3RyZWFtRGVmYXVsdFdyaXRlcjxVaW50OEFycmF5PlxuICBwcml2YXRlIHJlYWRlcj86IFJlYWRhYmxlU3RyZWFtRGVmYXVsdFJlYWRlcjxVaW50OEFycmF5PlxuICBwcml2YXRlIGxvb3A/OiBQcm9taXNlPHZvaWQ+XG4gIHByaXZhdGUgcng6IG51bWJlcltdID0gW11cbiAgcHJpdmF0ZSBpZHggPSAxXG4gIHByaXZhdGUgZnJhbWVXYWl0ZXJzOiB7IG1hdGNoOiAoYm9keTogbnVtYmVyW10pID0+IGJvb2xlYW47IHJlc29sdmU6ICgpID0+IHZvaWQgfVtdID0gW11cbiAgcHJpdmF0ZSB3YWl0aW5nID0gbmV3IE1hcDxudW1iZXIsIHsgcmVzb2x2ZTogKHY6IE1Cb3RTZW5zb3JWYWx1ZSB8IG51bGwpID0+IHZvaWQ7IHJlamVjdDogKGU6IEVycm9yKSA9PiB2b2lkIH0+KClcbiAgcHJpdmF0ZSBxdWV1ZTogUHJvbWlzZTx1bmtub3duPiA9IFByb21pc2UucmVzb2x2ZSgpXG4gIHByaXZhdGUgbGlzdGVuZXJzID0gbmV3IFNldDwoKSA9PiB2b2lkPigpXG4gIGVycm9yPzogc3RyaW5nXG4gIC8qKiBQb3J0IGlzdCBvZmZlbiwgZGVyIEN5YmVyUGkgc3RhcnRldCBub2NoIG5ldS4gKi9cbiAgY29ubmVjdGluZyA9IGZhbHNlXG5cbiAgLyoqIGBmbmAgYmVpIFZlcmJpbmRlbiwgVHJlbm5lbiB1bmQgRmVobGVybiBydWZlbjsgZ2lidCBlaW5lIEFibWVsZHVuZyB6dXLDvGNrLiAqL1xuICBsaXN0ZW4oZm46ICgpID0+IHZvaWQpOiAoKSA9PiB2b2lkIHtcbiAgICB0aGlzLmxpc3RlbmVycy5hZGQoZm4pXG4gICAgcmV0dXJuICgpID0+IHRoaXMubGlzdGVuZXJzLmRlbGV0ZShmbilcbiAgfVxuXG4gIHByaXZhdGUgY2hhbmdlZCgpIHtcbiAgICBmb3IgKGNvbnN0IGZuIG9mIHRoaXMubGlzdGVuZXJzKSBmbigpXG4gIH1cblxuICBnZXQgY29ubmVjdGVkKCkge1xuICAgIHJldHVybiB0aGlzLndyaXRlciAhPT0gdW5kZWZpbmVkICYmICF0aGlzLmNvbm5lY3RpbmdcbiAgfVxuXG4gIC8qKiBGcmFndCBuYWNoIGRlbSBVU0ItQW5zY2hsdXNzLCDDtmZmbmV0IGlobiB1bmQgd2FydGV0IGRlbiBOZXVzdGFydCBkZXMgQ3liZXJQaSBhYi4gKi9cbiAgYXN5bmMgY29ubmVjdCgpIHtcbiAgICBjb25zdCBzID0gc2VyaWFsKClcbiAgICBpZiAoIXMpIHRocm93IG5ldyBFcnJvcignV2ViIFNlcmlhbCcpXG4gICAgY29uc3QgcG9ydCA9IGF3YWl0IHMucmVxdWVzdFBvcnQoKVxuICAgIGF3YWl0IHBvcnQub3Blbih7IGJhdWRSYXRlOiAxMTUyMDAgfSlcbiAgICB0aGlzLnBvcnQgPSBwb3J0XG4gICAgdGhpcy53cml0ZXIgPSBwb3J0LndyaXRhYmxlIS5nZXRXcml0ZXIoKVxuICAgIHRoaXMuZXJyb3IgPSB1bmRlZmluZWRcbiAgICB0aGlzLmNvbm5lY3RpbmcgPSB0cnVlXG4gICAgdGhpcy5jaGFuZ2VkKClcbiAgICB0aGlzLmxvb3AgPSB0aGlzLnJlYWRMb29wKClcbiAgICAvLyBTZWl0ZSBzY2hsaWXDn2VuIG9kZXIgbmV1IGxhZGVuOiBBbnNjaGx1c3MgZnJlaWdlYmVuXG4gICAgd2luZG93LmFkZEV2ZW50TGlzdGVuZXIoJ3BhZ2VoaWRlJywgKCkgPT4gdm9pZCB0aGlzLmRpc2Nvbm5lY3QoKSwgeyBvbmNlOiB0cnVlIH0pXG4gICAgLy8gRGFzIMOWZmZuZW4gc2V0enQgZGVuIEN5YmVyUGkgenVyw7xja1xuICAgIGF3YWl0IG5ldyBQcm9taXNlKChyKSA9PiBzZXRUaW1lb3V0KHIsIDMwMDApKVxuICAgIGlmICghdGhpcy53cml0ZXIpIHJldHVyblxuICAgIC8vIFRleHRhdXNnYWJlbiB2b20gTmV1c3RhcnQgdmVyd2VyZmVuXG4gICAgdGhpcy5yeC5sZW5ndGggPSAwXG4gICAgdGhpcy5jb25uZWN0aW5nID0gZmFsc2VcbiAgICB0aGlzLmNoYW5nZWQoKVxuICAgIGF3YWl0IHRoaXMucnVuKEhFTExPKVxuICB9XG5cbiAgLyoqXG4gICAqIFNhdWJlciB0cmVubmVuIHdpZSBiZWltIEF1c3dlcmZlbjogTW90b3JlbiBhbmhhbHRlbiwgTEVEcyBhdXMsIEFic2NoaWVkIGF1ZiBkZW0gQmlsZHNjaGlybSxcbiAgICogZGFubiBMZXNlciB1bmQgU2NocmVpYmVyIGZyZWlnZWJlbiB1bmQgZGVuIEFuc2NobHVzcyBzY2hsaWXDn2VuLiBTbyBsw6Rzc3QgZXIgc2ljaCBvaG5lIE5ldXN0YXJ0IHdpZWRlciB2ZXJiaW5kZW4uXG4gICAqL1xuICBhc3luYyBkaXNjb25uZWN0KGVycm9yPzogc3RyaW5nKSB7XG4gICAgaWYgKCF0aGlzLnBvcnQpIHtcbiAgICAgIHRoaXMuZXJyb3IgPSBlcnJvclxuICAgICAgcmV0dXJuIHRoaXMuY2hhbmdlZCgpXG4gICAgfVxuICAgIGlmICghZXJyb3IgJiYgdGhpcy53cml0ZXIgJiYgIXRoaXMuY29ubmVjdGluZykge1xuICAgICAgZm9yIChjb25zdCBjb2RlIG9mIFtcIm1ib3QyLkVNX3N0b3AoJ0FMTCcpXCIsICdjeWJlcnBpLmxlZC5vZmYoKScsIHNob3dMYWJlbCgnQmlzIGJhbGQhJyldKVxuICAgICAgICBhd2FpdCB0aGlzLnNlbmQoY29kZSwgUlVOLCAyMDAwKS5jYXRjaCgoKSA9PiB1bmRlZmluZWQpXG4gICAgfVxuICAgIGNvbnN0IHBvcnQgPSB0aGlzLnBvcnRcbiAgICBjb25zdCB3cml0ZXIgPSB0aGlzLndyaXRlclxuICAgIGNvbnN0IHJlYWRlciA9IHRoaXMucmVhZGVyXG4gICAgY29uc3QgbG9vcCA9IHRoaXMubG9vcFxuICAgIHRoaXMucG9ydCA9IHRoaXMud3JpdGVyID0gdGhpcy5yZWFkZXIgPSB0aGlzLmxvb3AgPSB1bmRlZmluZWRcbiAgICB0aGlzLmVycm9yID0gZXJyb3JcbiAgICB0aGlzLmNvbm5lY3RpbmcgPSBmYWxzZVxuICAgIGZvciAoY29uc3QgdyBvZiB0aGlzLndhaXRpbmcudmFsdWVzKCkpIHcucmVqZWN0KG5ldyBFcnJvcihlcnJvciA/PyAnZ2V0cmVubnQnKSlcbiAgICB0aGlzLndhaXRpbmcuY2xlYXIoKVxuICAgIHRyeSB7XG4gICAgICBhd2FpdCByZWFkZXI/LmNhbmNlbCgpXG4gICAgICBhd2FpdCBsb29wXG4gICAgICBhd2FpdCB3cml0ZXI/LmNsb3NlKClcbiAgICB9IGNhdGNoIHtcbiAgICAgIC8qIExlaXR1bmcgc2Nob24gd2VnICovXG4gICAgfVxuICAgIHRyeSB7XG4gICAgICB3cml0ZXI/LnJlbGVhc2VMb2NrKClcbiAgICAgIGF3YWl0IHBvcnQuY2xvc2UoKVxuICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgIGNvbnNvbGUud2FybignW21Cb3QyXSBTY2hsaWXDn2VuJywgKGUgYXMgRXJyb3IpLm1lc3NhZ2UpXG4gICAgfVxuICAgIHRoaXMuY2hhbmdlZCgpXG4gIH1cblxuICAvKiogUHl0aG9uLVplaWxlIGF1c2bDvGhyZW47IGtlaHJ0IHp1csO8Y2ssIHdlbm4gZGVyIFJvYm90ZXIgZmVydGlnIGlzdCAoRmFocmVuIGRhdWVydCkuICovXG4gIHJ1bihjb2RlOiBzdHJpbmcpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICByZXR1cm4gdGhpcy5zZW5kKGNvZGUsIFJVTiwgMzAwMDApLnRoZW4oKCkgPT4gdW5kZWZpbmVkKVxuICB9XG5cbiAgLyoqIFdlcnQgZWluZXMgUHl0aG9uLUF1c2RydWNrcywgei4gQi4gZWluZXMgU2Vuc29ycy4gKi9cbiAgYXNrKGNvZGU6IHN0cmluZyk6IFByb21pc2U8TUJvdFNlbnNvclZhbHVlIHwgbnVsbD4ge1xuICAgIHJldHVybiB0aGlzLnNlbmQoY29kZSwgQVNLLCAzMDAwKVxuICB9XG5cbiAgLyoqXG4gICAqIFByb2dyYW1tIGF1ZiBkZW4gQ3liZXJQaSDDvGJlcnRyYWdlbiAodmVyYmluZGV0IHZvcmhlciwgd2VubiBuw7Z0aWcpLiBEYW5hY2ggc3RhcnRldCBkZXIgQ3liZXJQaSBuZXUgdW5kXG4gICAqIGRhcyBQcm9ncmFtbSBibGVpYnQgZ2VzcGVpY2hlcnQsIGF1Y2ggb2huZSBLYWJlbC4gYHByb2dyZXNzYCBiZWtvbW10IGVybGVkaWd0ZSB1bmQgYWxsZSBTY2hyaXR0ZS5cbiAgICovXG4gIGFzeW5jIHVwbG9hZChzb3VyY2U6IHN0cmluZywgcHJvZ3Jlc3M6IChkb25lOiBudW1iZXIsIHRvdGFsOiBudW1iZXIpID0+IHZvaWQgPSAoKSA9PiB7fSkge1xuICAgIGlmICghdGhpcy5wb3J0KSBhd2FpdCB0aGlzLmNvbm5lY3QoKVxuICAgIGlmICghdGhpcy53cml0ZXIpIHRocm93IG5ldyBFcnJvcih0aGlzLmVycm9yID8/ICduaWNodCB2ZXJidW5kZW4nKVxuICAgIGNvbnN0IGZpbGVzID0gdXBsb2FkRnJhbWVzKHNvdXJjZSlcbiAgICBjb25zdCB0b3RhbCA9IDYgKyBmaWxlcy5sZW5ndGggKyAzXG4gICAgbGV0IGRvbmUgPSAwXG4gICAgY29uc3Qgc3RlcCA9ICgpID0+IHByb2dyZXNzKCsrZG9uZSwgdG90YWwpXG4gICAgY29uc3QgcHJlcGFyZSA9IGFzeW5jICgpID0+IHtcbiAgICAgIGF3YWl0IHRoaXMuc2VuZEZyYW1lKGZyYW1lKFVQTE9BRF9NT0RFKSwgaXNNb2RlRWNobylcbiAgICAgIHN0ZXAoKVxuICAgICAgZm9yIChjb25zdCBjb2RlIG9mIFVQTE9BRF9QUkVQQVJFKSB7XG4gICAgICAgIGF3YWl0IHRoaXMuc2VuZChjb2RlLCBSVU4sIDMwMDApXG4gICAgICAgIHN0ZXAoKVxuICAgICAgfVxuICAgIH1cbiAgICBhd2FpdCBwcmVwYXJlKClcbiAgICBhd2FpdCBwcmVwYXJlKClcbiAgICBmb3IgKGNvbnN0IGYgb2YgZmlsZXMpIHtcbiAgICAgIGF3YWl0IHRoaXMuc2VuZEZyYW1lKGYsIGlzRmlsZUFjaylcbiAgICAgIHN0ZXAoKVxuICAgIH1cbiAgICBkb25lID0gdG90YWwgLSAzXG4gICAgYXdhaXQgcHJlcGFyZSgpXG4gICAgYXdhaXQgdGhpcy5yZXN0YXJ0KClcbiAgfVxuXG4gIC8qKiBSYWhtZW4gc2NoaWNrZW4gdW5kIGF1ZiBkaWUgcGFzc2VuZGUgQW50d29ydCB3YXJ0ZW4gKGJpcyB6dSBkcmVpIFZlcnN1Y2hlKS4gKi9cbiAgcHJpdmF0ZSBzZW5kRnJhbWUoZGF0YTogVWludDhBcnJheSwgbWF0Y2g6IChib2R5OiBudW1iZXJbXSkgPT4gYm9vbGVhbik6IFByb21pc2U8dm9pZD4ge1xuICAgIGNvbnN0IG5leHQgPSB0aGlzLnF1ZXVlLnRoZW4oYXN5bmMgKCkgPT4ge1xuICAgICAgZm9yIChsZXQgYXR0ZW1wdCA9IDA7IGF0dGVtcHQgPCAzOyBhdHRlbXB0KyspIHtcbiAgICAgICAgaWYgKCF0aGlzLndyaXRlcikgdGhyb3cgbmV3IEVycm9yKCduaWNodCB2ZXJidW5kZW4nKVxuICAgICAgICBsZXQgcmVzb2x2ZSA9ICgpID0+IHt9XG4gICAgICAgIGNvbnN0IGFuc3dlcmVkID0gbmV3IFByb21pc2U8dm9pZD4oKHIpID0+IChyZXNvbHZlID0gcikpXG4gICAgICAgIGNvbnN0IHdhaXRlciA9IHsgbWF0Y2gsIHJlc29sdmUgfVxuICAgICAgICB0aGlzLmZyYW1lV2FpdGVycy5wdXNoKHdhaXRlcilcbiAgICAgICAgYXdhaXQgdGhpcy53cml0ZXIud3JpdGUoZGF0YSlcbiAgICAgICAgY29uc3Qgb2sgPSBhd2FpdCBQcm9taXNlLnJhY2UoW2Fuc3dlcmVkLnRoZW4oKCkgPT4gdHJ1ZSksIG5ldyBQcm9taXNlPGJvb2xlYW4+KChyKSA9PiBzZXRUaW1lb3V0KCgpID0+IHIoZmFsc2UpLCAzMDAwKSldKVxuICAgICAgICB0aGlzLmZyYW1lV2FpdGVycyA9IHRoaXMuZnJhbWVXYWl0ZXJzLmZpbHRlcigodykgPT4gdyAhPT0gd2FpdGVyKVxuICAgICAgICBpZiAob2spIHJldHVyblxuICAgICAgfVxuICAgICAgdGhyb3cgbmV3IEVycm9yKCdrZWluZSBBbnR3b3J0JylcbiAgICB9KVxuICAgIHRoaXMucXVldWUgPSBuZXh0LmNhdGNoKCgpID0+IHVuZGVmaW5lZClcbiAgICByZXR1cm4gbmV4dFxuICB9XG5cbiAgLyoqIEFuc2NobHVzcyBzY2hsaWXDn2VuIHVuZCB3aWVkZXIgw7ZmZm5lbjogZGFzIHNldHp0IGRlbiBDeWJlclBpIHp1csO8Y2ssIGVyIMO8YmVybmltbXQgZGFzIG5ldWUgUHJvZ3JhbW0uICovXG4gIHByaXZhdGUgYXN5bmMgcmVzdGFydCgpIHtcbiAgICBjb25zdCBwb3J0ID0gdGhpcy5wb3J0IVxuICAgIGF3YWl0IHRoaXMuZGlzY29ubmVjdCgncmVzdGFydCcpXG4gICAgdGhpcy5lcnJvciA9IHVuZGVmaW5lZFxuICAgIGF3YWl0IG5ldyBQcm9taXNlKChyKSA9PiBzZXRUaW1lb3V0KHIsIDMwMCkpXG4gICAgYXdhaXQgcG9ydC5vcGVuKHsgYmF1ZFJhdGU6IDExNTIwMCB9KVxuICAgIGF3YWl0IG5ldyBQcm9taXNlKChyKSA9PiBzZXRUaW1lb3V0KHIsIDUwMCkpXG4gICAgYXdhaXQgcG9ydC5jbG9zZSgpXG4gICAgdGhpcy5jaGFuZ2VkKClcbiAgfVxuXG4gIHByaXZhdGUgc2VuZChjb2RlOiBzdHJpbmcsIG1vZGU6IG51bWJlciwgdGltZW91dE1zOiBudW1iZXIpOiBQcm9taXNlPE1Cb3RTZW5zb3JWYWx1ZSB8IG51bGw+IHtcbiAgICAvLyBJbW1lciBudXIgZWluZSBaZWlsZSB1bnRlcndlZ3M6IGRlciBDeWJlclBpIGFyYmVpdGV0IHNpZSBuYWNoZWluYW5kZXIgYWIuXG4gICAgY29uc3QgbmV4dCA9IHRoaXMucXVldWUudGhlbihcbiAgICAgICgpID0+XG4gICAgICAgIG5ldyBQcm9taXNlPE1Cb3RTZW5zb3JWYWx1ZSB8IG51bGw+KChyZXNvbHZlLCByZWplY3QpID0+IHtcbiAgICAgICAgICBpZiAoIXRoaXMud3JpdGVyKSByZXR1cm4gcmVqZWN0KG5ldyBFcnJvcignbmljaHQgdmVyYnVuZGVuJykpXG4gICAgICAgICAgY29uc3QgaWR4ID0gdGhpcy5pZHhcbiAgICAgICAgICB0aGlzLmlkeCA9ICh0aGlzLmlkeCAlIDB4ZmZmZikgKyAxXG4gICAgICAgICAgY29uc3QgdGltZXIgPSBzZXRUaW1lb3V0KCgpID0+IHtcbiAgICAgICAgICAgIHRoaXMud2FpdGluZy5kZWxldGUoaWR4KVxuICAgICAgICAgICAgcmVqZWN0KG5ldyBFcnJvcigna2VpbmUgQW50d29ydCcpKVxuICAgICAgICAgIH0sIHRpbWVvdXRNcylcbiAgICAgICAgICB0aGlzLndhaXRpbmcuc2V0KGlkeCwge1xuICAgICAgICAgICAgcmVzb2x2ZTogKHYpID0+IChjbGVhclRpbWVvdXQodGltZXIpLCByZXNvbHZlKHYpKSxcbiAgICAgICAgICAgIHJlamVjdDogKGUpID0+IChjbGVhclRpbWVvdXQodGltZXIpLCByZWplY3QoZSkpLFxuICAgICAgICAgIH0pXG4gICAgICAgICAgdGhpcy53cml0ZXIud3JpdGUocHl0aG9uRnJhbWUoY29kZSwgbW9kZSwgaWR4KSkuY2F0Y2goKGU6IEVycm9yKSA9PiB7XG4gICAgICAgICAgICB0aGlzLndhaXRpbmcuZGVsZXRlKGlkeClcbiAgICAgICAgICAgIHJlamVjdChlKVxuICAgICAgICAgIH0pXG4gICAgICAgIH0pLFxuICAgIClcbiAgICB0aGlzLnF1ZXVlID0gbmV4dC5jYXRjaCgoKSA9PiB1bmRlZmluZWQpXG4gICAgcmV0dXJuIG5leHRcbiAgfVxuXG4gIHByaXZhdGUgYXN5bmMgcmVhZExvb3AoKSB7XG4gICAgd2hpbGUgKHRoaXMucG9ydD8ucmVhZGFibGUpIHtcbiAgICAgIGNvbnN0IHJlYWRlciA9IHRoaXMucG9ydC5yZWFkYWJsZS5nZXRSZWFkZXIoKVxuICAgICAgdGhpcy5yZWFkZXIgPSByZWFkZXJcbiAgICAgIHRyeSB7XG4gICAgICAgIGZvciAoOzspIHtcbiAgICAgICAgICBjb25zdCB7IHZhbHVlLCBkb25lIH0gPSBhd2FpdCByZWFkZXIucmVhZCgpXG4gICAgICAgICAgaWYgKGRvbmUpIGJyZWFrXG4gICAgICAgICAgdGhpcy5yeC5wdXNoKC4uLnZhbHVlKVxuICAgICAgICAgIGZvciAoY29uc3QgYm9keSBvZiByZWFkRnJhbWVzKHRoaXMucngpKSB7XG4gICAgICAgICAgICBjb25zdCBmID0gdGhpcy5mcmFtZVdhaXRlcnMuZmluZEluZGV4KCh3KSA9PiB3Lm1hdGNoKGJvZHkpKVxuICAgICAgICAgICAgaWYgKGYgPj0gMCkgdGhpcy5mcmFtZVdhaXRlcnMuc3BsaWNlKGYsIDEpWzBdLnJlc29sdmUoKVxuICAgICAgICAgICAgY29uc3QgYSA9IHNjcmlwdEFuc3dlcihib2R5KVxuICAgICAgICAgICAgaWYgKCFhKSBjb250aW51ZVxuICAgICAgICAgICAgY29uc3QgdyA9IHRoaXMud2FpdGluZy5nZXQoYS5pZHgpXG4gICAgICAgICAgICB0aGlzLndhaXRpbmcuZGVsZXRlKGEuaWR4KVxuICAgICAgICAgICAgdz8ucmVzb2x2ZShhLnZhbHVlKVxuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgfSBjYXRjaCAoZSkge1xuICAgICAgICAvLyBTdMO2cnVuZ2VuIGF1ZiBkZXIgTGVpdHVuZyAoei4gQi4gYmVpbSBOZXVzdGFydCBkZXMgQ3liZXJQaSkgc2luZCBoYXJtbG9zOiBtaXQgbmV1ZW0gTGVzZXIgd2VpdGVyXG4gICAgICAgIGNvbnN0IGhhcm1sZXNzID0gWydCdWZmZXJPdmVycnVuRXJyb3InLCAnRnJhbWluZ0Vycm9yJywgJ0JyZWFrRXJyb3InLCAnUGFyaXR5RXJyb3InXS5pbmNsdWRlcygoZSBhcyBFcnJvcikubmFtZSlcbiAgICAgICAgY29uc29sZS53YXJuKCdbbUJvdDJdIExlc2VmZWhsZXInLCAoZSBhcyBFcnJvcikubmFtZSwgKGUgYXMgRXJyb3IpLm1lc3NhZ2UpXG4gICAgICAgIGlmICghaGFybWxlc3MgJiYgdGhpcy5wb3J0KSB2b2lkIHRoaXMuZGlzY29ubmVjdCgoZSBhcyBFcnJvcikubWVzc2FnZSlcbiAgICAgIH0gZmluYWxseSB7XG4gICAgICAgIHJlYWRlci5yZWxlYXNlTG9jaygpXG4gICAgICB9XG4gICAgICBpZiAoIXRoaXMud3JpdGVyKSBicmVha1xuICAgIH1cbiAgfVxufVxuXG4vKiogRWluZSBWZXJiaW5kdW5nIGbDvHIgZGllIGdhbnplIFNlaXRlIChibGVpYnQgYmVpbSBOZXVhdWZiYXUgZGVyIE9iZXJmbMOkY2hlIGVyaGFsdGVuKS4gKi9cbmV4cG9ydCBjb25zdCBtYm90TGluayA9IG5ldyBNQm90TGluaygpXG4iXSwiZmlsZSI6Ii93ZWIvc3JjL2NvcmUvbWJvdExpbmsudHMifQ== - -//# vitestCache=W3siZmlsZSI6IjEiLCJpZCI6IjEiLCJ1cmwiOiIyIiwiaW1wb3J0cyI6IjMiLCJtYXBwaW5ncyI6ZmFsc2UsImRlcHMiOiI0IiwiZHluYW1pY0RlcHMiOiI1Iiwic3RhdGljTW9ja3MiOm51bGx9LCIvaG9tZS91c2VyL3Zpc3VzdHJ1Y3Qtc3dpZnR1aS93ZWIvc3JjL2NvcmUvbWJvdExpbmsudHMiLCIvd2ViL3NyYy9jb3JlL21ib3RMaW5rLnRzIix7InVybHMiOiI2IiwiaWRzIjoiNyJ9LFtdLFtdLFtdLHt9XQ== \ No newline at end of file diff --git a/node_modules/.vitest-cache/e8414e1454c9436819af0b8d69e3557e442d9777 b/node_modules/.vitest-cache/e8414e1454c9436819af0b8d69e3557e442d9777 deleted file mode 100644 index 14ff0247..00000000 --- a/node_modules/.vitest-cache/e8414e1454c9436819af0b8d69e3557e442d9777 +++ /dev/null @@ -1,200 +0,0 @@ -__vite_ssr_exportName__("GameFormatError", () => { try { return GameFormatError } catch {} }); -__vite_ssr_exportName__("parseBoolGame", () => { try { return parseBoolGame } catch {} }); -__vite_ssr_exportName__("evaluate", () => { try { return evaluate } catch {} }); -__vite_ssr_exportName__("explain", () => { try { return explain } catch {} }); -__vite_ssr_exportName__("makeRound", () => { try { return makeRound } catch {} }); -__vite_ssr_exportName__("usedValues", () => { try { return usedValues } catch {} }); -class GameFormatError extends Error {}; -/** Zeilen `alter: 8..20`, `schueler: boolean` und `? bedingung`. */ -function parseBoolGame(lines, file) { - const vars = []; - const conditions = []; - for (const raw of lines) { - const line = raw.trim(); - if (!line) continue; - if (line.startsWith("?")) { - const condition = line.slice(1).trim(); - evaluate(condition, sampleValues(vars)); - conditions.push(condition); - continue; - }; - const m = /^([A-Za-z_]\w*)\s*:\s*(?:(-?\d+)\s*\.\.\s*(-?\d+)|(boolean))$/.exec(line); - if (!m) throw new GameFormatError(`${file}: Unbekannte Zeile im Spiel: „${line}“`); - vars.push(m[4] ? { - name: m[1], - kind: "boolean" - } : { - name: m[1], - kind: "int", - min: Number(m[2]), - max: Number(m[3]) - }); - }; - if (!conditions.length) throw new GameFormatError(`${file}: Das Spiel braucht mindestens eine Zeile „? bedingung“.`); - return { - vars, - conditions - }; -}; -function sampleValues(vars) { - return Object.fromEntries(vars.map((v) => [v.name, v.kind === "boolean" ? true : v.min])); -} -function tokenize(text) { - const out = []; - const re = /\s*(?:(\d+)|(true|false)\b|([A-Za-z_]\w*)|(&&|\|\||==|!=|<=|>=|<|>|!|\(|\)))/y; - let pos = 0; - while (pos < text.length) { - if (/^\s*$/.test(text.slice(pos))) break; - re.lastIndex = pos; - const m = re.exec(text); - if (!m) throw new GameFormatError(`Unerwartetes Zeichen in „${text}“ bei „${text.slice(pos)}“`); - pos = re.lastIndex; - if (m[1] !== undefined) out.push({ - kind: "num", - value: Number(m[1]) - }); - else if (m[2] !== undefined) out.push({ - kind: "bool", - value: m[2] === "true" - }); - else if (m[3] !== undefined) out.push({ - kind: "name", - value: m[3] - }); - else out.push({ - kind: "op", - value: m[4] - }); - }; - return out; -} -/** Bedingung mit diesen Werten auswerten (nur ganze Zahlen, Wahrheitswerte, Vergleiche, !, && und ||). */ -function evaluate(text, values) { - const tokens = tokenize(text); - let i = 0; - const peek = () => tokens[i]; - const isOp = (v) => peek()?.kind === "op" && peek().value === v; - const fail = () => { - throw new GameFormatError(`Bedingung nicht lesbar: „${text}“`); - }; - const primary = () => { - const tok = tokens[i++] ?? fail(); - if (tok.kind === "num" || tok.kind === "bool") return tok.value; - if (tok.kind === "name") { - if (!(tok.value in values)) throw new GameFormatError(`Unbekannte Variable „${tok.value}“ in „${text}“`); - return values[tok.value]; - }; - if (tok.value === "(") { - const v = or(); - if (!isOp(")")) fail(); - i++; - return v; - }; - if (tok.value === "!") { - const v = primary(); - if (typeof v !== "boolean") fail(); - return !v; - }; - return fail(); - }; - const comparison = () => { - const left = primary(); - const op = peek(); - if (op?.kind === "op" && [ - "==", - "!=", - "<", - "<=", - ">", - ">=" - ].includes(op.value)) { - i++; - const right = primary(); - switch (op.value) { - case "==": return left === right; - case "!=": return left !== right; - }; - if (typeof left !== "number" || typeof right !== "number") fail(); - const [a, b] = [left, right]; - return op.value === "<" ? a < b : op.value === "<=" ? a <= b : op.value === ">" ? a > b : a >= b; - }; - return left; - }; - const and = () => { - let v = comparison(); - while (isOp("&&")) { - i++; - const r = comparison(); - v = v && r; - }; - return v; - }; - const or = () => { - let v = and(); - while (isOp("||")) { - i++; - const r = and(); - v = v || r; - }; - return v; - }; - const result = or(); - if (i !== tokens.length || typeof result !== "boolean") return fail(); - return result; -}; -// MARK: - Erklären -/** -* Auswertung in Zwischenschritten, z. B. `alter >= 12 && alter < 18` → -* `15 >= 12 && 15 < 18` → `true && true` → `true`. -*/ -function explain(text, values) { - const steps = [text]; - const substituted = text.replace(/\b[A-Za-z_]\w*\b/g, (name) => name in values ? String(values[name]) : name); - if (substituted !== text) steps.push(substituted); - // Jeden Vergleich durch sein Ergebnis ersetzen. - const compared = substituted.replace(/(-?\d+|true|false)\s*(==|!=|<=|>=|<|>)\s*(-?\d+|true|false)/g, (m) => String(evaluate(m, {}))); - if (compared !== steps[steps.length - 1]) steps.push(compared); - const result = String(evaluate(text, values)); - if (result !== steps[steps.length - 1]) steps.push(result); - return steps; -}; -// MARK: - Runden -/** Zahlen, mit denen in der Bedingung verglichen wird: dort und knapp daneben sind die spannenden Fälle. */ -function edgeValues(condition, name) { - const out = []; - const re = new RegExp(`\\b${name}\\s*(?:==|!=|<=|>=|<|>)\\s*(-?\\d+)|(-?\\d+)\\s*(?:==|!=|<=|>=|<|>)\\s*${name}\\b`, "g"); - for (const m of condition.matchAll(re)) { - const c = Number(m[1] ?? m[2]); - out.push(c - 1, c, c + 1); - }; - return out; -} -/** Runde `index` von `count`: je später, desto schwerer die Bedingung. */ -function makeRound(game, index, count, random = Math.random) { - const n = game.conditions.length; - const base = Math.floor(index * n / count); - const pick = Math.min(n - 1, base + (random() < .5 ? 0 : 1)); - const condition = game.conditions[pick]; - const values = {}; - for (const v of game.vars) { - if (v.kind === "boolean") { - values[v.name] = random() < .5; - continue; - }; - const edges = edgeValues(condition, v.name).filter((x) => x >= v.min && x <= v.max); - values[v.name] = edges.length && random() < .6 ? edges[Math.floor(random() * edges.length)] : v.min + Math.floor(random() * (v.max - v.min + 1)); - }; - return { - condition, - values, - answer: evaluate(condition, values) - }; -}; -/** Nur die Variablen, die in der Bedingung vorkommen. */ -function usedValues(round) { - return Object.entries(round.values).filter(([name]) => new RegExp(`\\b${name}\\b`).test(round.condition)); -} -//# sourceMappingSource=vite-generated -//# sourceMappingURL=data:application/json;base64,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LEtBQUssTUFBTyxRQUFRLElBQUssS0FBSztDQUMzQyxNQUFNLE9BQU8sS0FBSyxJQUFJLElBQUksR0FBRyxRQUFRLE9BQU8sSUFBSSxLQUFNLElBQUksRUFBRTtDQUM1RCxNQUFNLFlBQVksS0FBSyxXQUFXO0NBQ2xDLE1BQU0sU0FBaUIsQ0FBQztDQUN4QixLQUFLLE1BQU0sS0FBSyxLQUFLLE1BQU07RUFDekIsSUFBSSxFQUFFLFNBQVMsV0FBVztHQUN4QixPQUFPLEVBQUUsUUFBUSxPQUFPLElBQUk7R0FDNUI7RUFDRjtFQUNBLE1BQU0sUUFBUSxXQUFXLFdBQVcsRUFBRSxJQUFJLENBQUMsQ0FBQyxRQUFRLE1BQU0sS0FBSyxFQUFFLE9BQU8sS0FBSyxFQUFFLEdBQUc7RUFDbEYsT0FBTyxFQUFFLFFBQVEsTUFBTSxVQUFVLE9BQU8sSUFBSSxLQUFNLE1BQU0sS0FBSyxNQUFNLE9BQU8sSUFBSSxNQUFNLE1BQU0sS0FBSyxFQUFFLE1BQU0sS0FBSyxNQUFNLE9BQU8sS0FBSyxFQUFFLE1BQU0sRUFBRSxNQUFNLEVBQUU7Q0FDbEo7Q0FDQSxPQUFPO0VBQUU7RUFBVztFQUFRLFFBQVEsU0FBUyxXQUFXLE1BQU07Q0FBRTtBQUNsRTs7QUFHTyxTQUFTLFdBQVcsT0FBNEM7Q0FDckUsT0FBTyxPQUFPLFFBQVEsTUFBTSxNQUFNLENBQUMsQ0FBQyxRQUFRLENBQUMsVUFBVSxJQUFJLE9BQU8sTUFBTSxLQUFLLElBQUksQ0FBQyxDQUFDLEtBQUssTUFBTSxTQUFTLENBQUM7QUFDMUciLCJuYW1lcyI6W10sImlnbm9yZUxpc3QiOltdLCJzb3VyY2VzIjpbImJvb2xHYW1lLnRzIl0sInNvdXJjZXNDb250ZW50IjpbIi8qKlxuICogU3BpZWwg4oCeV2FociBvZGVyIGZhbHNjaD/igJwgKEJsb2NrIGA6Ojogc3BpZWxgIGltIExlcm5iZXJlaWNoKTogV2VydGUgdW5kIGVpbmUgQmVkaW5ndW5nIHplaWdlbixcbiAqIGRpZSBBbnR3b3J0IHByw7xmZW4gdW5kIGRpZSBBdXN3ZXJ0dW5nIFNjaHJpdHQgZsO8ciBTY2hyaXR0IGVya2zDpHJlbi5cbiAqL1xuXG5leHBvcnQgdHlwZSBHYW1lVmFyID0geyBuYW1lOiBzdHJpbmc7IGtpbmQ6ICdpbnQnOyBtaW46IG51bWJlcjsgbWF4OiBudW1iZXIgfSB8IHsgbmFtZTogc3RyaW5nOyBraW5kOiAnYm9vbGVhbicgfVxuXG5leHBvcnQgaW50ZXJmYWNlIEJvb2xHYW1lIHtcbiAgdmFyczogR2FtZVZhcltdXG4gIC8qKiBCZWRpbmd1bmdlbiB2b20gbGVpY2h0ZW4genVtIHNjaHdlcmVuLiAqL1xuICBjb25kaXRpb25zOiBzdHJpbmdbXVxufVxuXG5leHBvcnQgdHlwZSBWYWx1ZXMgPSBSZWNvcmQ8c3RyaW5nLCBudW1iZXIgfCBib29sZWFuPlxuXG5leHBvcnQgY2xhc3MgR2FtZUZvcm1hdEVycm9yIGV4dGVuZHMgRXJyb3Ige31cblxuLyoqIFplaWxlbiBgYWx0ZXI6IDguLjIwYCwgYHNjaHVlbGVyOiBib29sZWFuYCB1bmQgYD8gYmVkaW5ndW5nYC4gKi9cbmV4cG9ydCBmdW5jdGlvbiBwYXJzZUJvb2xHYW1lKGxpbmVzOiBzdHJpbmdbXSwgZmlsZTogc3RyaW5nKTogQm9vbEdhbWUge1xuICBjb25zdCB2YXJzOiBHYW1lVmFyW10gPSBbXVxuICBjb25zdCBjb25kaXRpb25zOiBzdHJpbmdbXSA9IFtdXG4gIGZvciAoY29uc3QgcmF3IG9mIGxpbmVzKSB7XG4gICAgY29uc3QgbGluZSA9IHJhdy50cmltKClcbiAgICBpZiAoIWxpbmUpIGNvbnRpbnVlXG4gICAgaWYgKGxpbmUuc3RhcnRzV2l0aCgnPycpKSB7XG4gICAgICBjb25zdCBjb25kaXRpb24gPSBsaW5lLnNsaWNlKDEpLnRyaW0oKVxuICAgICAgZXZhbHVhdGUoY29uZGl0aW9uLCBzYW1wbGVWYWx1ZXModmFycykpIC8vIEZlaGxlciBmcsO8aCBtZWxkZW5cbiAgICAgIGNvbmRpdGlvbnMucHVzaChjb25kaXRpb24pXG4gICAgICBjb250aW51ZVxuICAgIH1cbiAgICBjb25zdCBtID0gL14oW0EtWmEtel9dXFx3KilcXHMqOlxccyooPzooLT9cXGQrKVxccypcXC5cXC5cXHMqKC0/XFxkKyl8KGJvb2xlYW4pKSQvLmV4ZWMobGluZSlcbiAgICBpZiAoIW0pIHRocm93IG5ldyBHYW1lRm9ybWF0RXJyb3IoYCR7ZmlsZX06IFVuYmVrYW5udGUgWmVpbGUgaW0gU3BpZWw6IOKAniR7bGluZX3igJxgKVxuICAgIHZhcnMucHVzaChtWzRdID8geyBuYW1lOiBtWzFdLCBraW5kOiAnYm9vbGVhbicgfSA6IHsgbmFtZTogbVsxXSwga2luZDogJ2ludCcsIG1pbjogTnVtYmVyKG1bMl0pLCBtYXg6IE51bWJlcihtWzNdKSB9KVxuICB9XG4gIGlmICghY29uZGl0aW9ucy5sZW5ndGgpIHRocm93IG5ldyBHYW1lRm9ybWF0RXJyb3IoYCR7ZmlsZX06IERhcyBTcGllbCBicmF1Y2h0IG1pbmRlc3RlbnMgZWluZSBaZWlsZSDigJ4/IGJlZGluZ3VuZ+KAnC5gKVxuICByZXR1cm4geyB2YXJzLCBjb25kaXRpb25zIH1cbn1cblxuZnVuY3Rpb24gc2FtcGxlVmFsdWVzKHZhcnM6IEdhbWVWYXJbXSk6IFZhbHVlcyB7XG4gIHJldHVybiBPYmplY3QuZnJvbUVudHJpZXModmFycy5tYXAoKHYpID0+IFt2Lm5hbWUsIHYua2luZCA9PT0gJ2Jvb2xlYW4nID8gdHJ1ZSA6IHYubWluXSkpXG59XG5cbi8vIE1BUks6IC0gQXVzd2VydGVuXG5cbnR5cGUgVG9rZW4gPSB7IGtpbmQ6ICdudW0nOyB2YWx1ZTogbnVtYmVyIH0gfCB7IGtpbmQ6ICdib29sJzsgdmFsdWU6IGJvb2xlYW4gfSB8IHsga2luZDogJ25hbWUnOyB2YWx1ZTogc3RyaW5nIH0gfCB7IGtpbmQ6ICdvcCc7IHZhbHVlOiBzdHJpbmcgfVxuXG5mdW5jdGlvbiB0b2tlbml6ZSh0ZXh0OiBzdHJpbmcpOiBUb2tlbltdIHtcbiAgY29uc3Qgb3V0OiBUb2tlbltdID0gW11cbiAgY29uc3QgcmUgPSAvXFxzKig/OihcXGQrKXwodHJ1ZXxmYWxzZSlcXGJ8KFtBLVphLXpfXVxcdyopfCgmJnxcXHxcXHx8PT18IT18PD18Pj18PHw+fCF8XFwofFxcKSkpL3lcbiAgbGV0IHBvcyA9IDBcbiAgd2hpbGUgKHBvcyA8IHRleHQubGVuZ3RoKSB7XG4gICAgaWYgKC9eXFxzKiQvLnRlc3QodGV4dC5zbGljZShwb3MpKSkgYnJlYWtcbiAgICByZS5sYXN0SW5kZXggPSBwb3NcbiAgICBjb25zdCBtID0gcmUuZXhlYyh0ZXh0KVxuICAgIGlmICghbSkgdGhyb3cgbmV3IEdhbWVGb3JtYXRFcnJvcihgVW5lcndhcnRldGVzIFplaWNoZW4gaW4g4oCeJHt0ZXh0feKAnCBiZWkg4oCeJHt0ZXh0LnNsaWNlKHBvcyl94oCcYClcbiAgICBwb3MgPSByZS5sYXN0SW5kZXhcbiAgICBpZiAobVsxXSAhPT0gdW5kZWZpbmVkKSBvdXQucHVzaCh7IGtpbmQ6ICdudW0nLCB2YWx1ZTogTnVtYmVyKG1bMV0pIH0pXG4gICAgZWxzZSBpZiAobVsyXSAhPT0gdW5kZWZpbmVkKSBvdXQucHVzaCh7IGtpbmQ6ICdib29sJywgdmFsdWU6IG1bMl0gPT09ICd0cnVlJyB9KVxuICAgIGVsc2UgaWYgKG1bM10gIT09IHVuZGVmaW5lZCkgb3V0LnB1c2goeyBraW5kOiAnbmFtZScsIHZhbHVlOiBtWzNdIH0pXG4gICAgZWxzZSBvdXQucHVzaCh7IGtpbmQ6ICdvcCcsIHZhbHVlOiBtWzRdIH0pXG4gIH1cbiAgcmV0dXJuIG91dFxufVxuXG4vKiogQmVkaW5ndW5nIG1pdCBkaWVzZW4gV2VydGVuIGF1c3dlcnRlbiAobnVyIGdhbnplIFphaGxlbiwgV2FocmhlaXRzd2VydGUsIFZlcmdsZWljaGUsICEsICYmIHVuZCB8fCkuICovXG5leHBvcnQgZnVuY3Rpb24gZXZhbHVhdGUodGV4dDogc3RyaW5nLCB2YWx1ZXM6IFZhbHVlcyk6IGJvb2xlYW4ge1xuICBjb25zdCB0b2tlbnMgPSB0b2tlbml6ZSh0ZXh0KVxuICBsZXQgaSA9IDBcbiAgY29uc3QgcGVlayA9ICgpID0+IHRva2Vuc1tpXVxuICBjb25zdCBpc09wID0gKHY6IHN0cmluZykgPT4gcGVlaygpPy5raW5kID09PSAnb3AnICYmIHBlZWsoKSEudmFsdWUgPT09IHZcbiAgY29uc3QgZmFpbCA9ICgpOiBuZXZlciA9PiB7XG4gICAgdGhyb3cgbmV3IEdhbWVGb3JtYXRFcnJvcihgQmVkaW5ndW5nIG5pY2h0IGxlc2Jhcjog4oCeJHt0ZXh0feKAnGApXG4gIH1cblxuICBjb25zdCBwcmltYXJ5ID0gKCk6IG51bWJlciB8IGJvb2xlYW4gPT4ge1xuICAgIGNvbnN0IHRvayA9IHRva2Vuc1tpKytdID8/IGZhaWwoKVxuICAgIGlmICh0b2sua2luZCA9PT0gJ251bScgfHwgdG9rLmtpbmQgPT09ICdib29sJykgcmV0dXJuIHRvay52YWx1ZVxuICAgIGlmICh0b2sua2luZCA9PT0gJ25hbWUnKSB7XG4gICAgICBpZiAoISh0b2sudmFsdWUgaW4gdmFsdWVzKSkgdGhyb3cgbmV3IEdhbWVGb3JtYXRFcnJvcihgVW5iZWthbm50ZSBWYXJpYWJsZSDigJ4ke3Rvay52YWx1ZX3igJwgaW4g4oCeJHt0ZXh0feKAnGApXG4gICAgICByZXR1cm4gdmFsdWVzW3Rvay52YWx1ZV1cbiAgICB9XG4gICAgaWYgKHRvay52YWx1ZSA9PT0gJygnKSB7XG4gICAgICBjb25zdCB2ID0gb3IoKVxuICAgICAgaWYgKCFpc09wKCcpJykpIGZhaWwoKVxuICAgICAgaSsrXG4gICAgICByZXR1cm4gdlxuICAgIH1cbiAgICBpZiAodG9rLnZhbHVlID09PSAnIScpIHtcbiAgICAgIGNvbnN0IHYgPSBwcmltYXJ5KClcbiAgICAgIGlmICh0eXBlb2YgdiAhPT0gJ2Jvb2xlYW4nKSBmYWlsKClcbiAgICAgIHJldHVybiAhdlxuICAgIH1cbiAgICByZXR1cm4gZmFpbCgpXG4gIH1cbiAgY29uc3QgY29tcGFyaXNvbiA9ICgpOiBudW1iZXIgfCBib29sZWFuID0+IHtcbiAgICBjb25zdCBsZWZ0ID0gcHJpbWFyeSgpXG4gICAgY29uc3Qgb3AgPSBwZWVrKClcbiAgICBpZiAob3A/LmtpbmQgPT09ICdvcCcgJiYgWyc9PScsICchPScsICc8JywgJzw9JywgJz4nLCAnPj0nXS5pbmNsdWRlcyhvcC52YWx1ZSkpIHtcbiAgICAgIGkrK1xuICAgICAgY29uc3QgcmlnaHQgPSBwcmltYXJ5KClcbiAgICAgIHN3aXRjaCAob3AudmFsdWUpIHtcbiAgICAgICAgY2FzZSAnPT0nOlxuICAgICAgICAgIHJldHVybiBsZWZ0ID09PSByaWdodFxuICAgICAgICBjYXNlICchPSc6XG4gICAgICAgICAgcmV0dXJuIGxlZnQgIT09IHJpZ2h0XG4gICAgICB9XG4gICAgICBpZiAodHlwZW9mIGxlZnQgIT09ICdudW1iZXInIHx8IHR5cGVvZiByaWdodCAhPT0gJ251bWJlcicpIGZhaWwoKVxuICAgICAgY29uc3QgW2EsIGJdID0gW2xlZnQgYXMgbnVtYmVyLCByaWdodCBhcyBudW1iZXJdXG4gICAgICByZXR1cm4gb3AudmFsdWUgPT09ICc8JyA/IGEgPCBiIDogb3AudmFsdWUgPT09ICc8PScgPyBhIDw9IGIgOiBvcC52YWx1ZSA9PT0gJz4nID8gYSA+IGIgOiBhID49IGJcbiAgICB9XG4gICAgcmV0dXJuIGxlZnRcbiAgfVxuICBjb25zdCBhbmQgPSAoKTogbnVtYmVyIHwgYm9vbGVhbiA9PiB7XG4gICAgbGV0IHYgPSBjb21wYXJpc29uKClcbiAgICB3aGlsZSAoaXNPcCgnJiYnKSkge1xuICAgICAgaSsrXG4gICAgICBjb25zdCByID0gY29tcGFyaXNvbigpXG4gICAgICB2ID0gKHYgYXMgYm9vbGVhbikgJiYgKHIgYXMgYm9vbGVhbilcbiAgICB9XG4gICAgcmV0dXJuIHZcbiAgfVxuICBjb25zdCBvciA9ICgpOiBudW1iZXIgfCBib29sZWFuID0+IHtcbiAgICBsZXQgdiA9IGFuZCgpXG4gICAgd2hpbGUgKGlzT3AoJ3x8JykpIHtcbiAgICAgIGkrK1xuICAgICAgY29uc3QgciA9IGFuZCgpXG4gICAgICB2ID0gKHYgYXMgYm9vbGVhbikgfHwgKHIgYXMgYm9vbGVhbilcbiAgICB9XG4gICAgcmV0dXJuIHZcbiAgfVxuICBjb25zdCByZXN1bHQgPSBvcigpXG4gIGlmIChpICE9PSB0b2tlbnMubGVuZ3RoIHx8IHR5cGVvZiByZXN1bHQgIT09ICdib29sZWFuJykgcmV0dXJuIGZhaWwoKVxuICByZXR1cm4gcmVzdWx0XG59XG5cbi8vIE1BUks6IC0gRXJrbMOkcmVuXG5cbi8qKlxuICogQXVzd2VydHVuZyBpbiBad2lzY2hlbnNjaHJpdHRlbiwgei4gQi4gYGFsdGVyID49IDEyICYmIGFsdGVyIDwgMThgIOKGklxuICogYDE1ID49IDEyICYmIDE1IDwgMThgIOKGkiBgdHJ1ZSAmJiB0cnVlYCDihpIgYHRydWVgLlxuICovXG5leHBvcnQgZnVuY3Rpb24gZXhwbGFpbih0ZXh0OiBzdHJpbmcsIHZhbHVlczogVmFsdWVzKTogc3RyaW5nW10ge1xuICBjb25zdCBzdGVwcyA9IFt0ZXh0XVxuICBjb25zdCBzdWJzdGl0dXRlZCA9IHRleHQucmVwbGFjZSgvXFxiW0EtWmEtel9dXFx3KlxcYi9nLCAobmFtZSkgPT4gKG5hbWUgaW4gdmFsdWVzID8gU3RyaW5nKHZhbHVlc1tuYW1lXSkgOiBuYW1lKSlcbiAgaWYgKHN1YnN0aXR1dGVkICE9PSB0ZXh0KSBzdGVwcy5wdXNoKHN1YnN0aXR1dGVkKVxuICAvLyBKZWRlbiBWZXJnbGVpY2ggZHVyY2ggc2VpbiBFcmdlYm5pcyBlcnNldHplbi5cbiAgY29uc3QgY29tcGFyZWQgPSBzdWJzdGl0dXRlZC5yZXBsYWNlKC8oLT9cXGQrfHRydWV8ZmFsc2UpXFxzKig9PXwhPXw8PXw+PXw8fD4pXFxzKigtP1xcZCt8dHJ1ZXxmYWxzZSkvZywgKG0pID0+IFN0cmluZyhldmFsdWF0ZShtLCB7fSkpKVxuICBpZiAoY29tcGFyZWQgIT09IHN0ZXBzW3N0ZXBzLmxlbmd0aCAtIDFdKSBzdGVwcy5wdXNoKGNvbXBhcmVkKVxuICBjb25zdCByZXN1bHQgPSBTdHJpbmcoZXZhbHVhdGUodGV4dCwgdmFsdWVzKSlcbiAgaWYgKHJlc3VsdCAhPT0gc3RlcHNbc3RlcHMubGVuZ3RoIC0gMV0pIHN0ZXBzLnB1c2gocmVzdWx0KVxuICByZXR1cm4gc3RlcHNcbn1cblxuLy8gTUFSSzogLSBSdW5kZW5cblxuLyoqIFphaGxlbiwgbWl0IGRlbmVuIGluIGRlciBCZWRpbmd1bmcgdmVyZ2xpY2hlbiB3aXJkOiBkb3J0IHVuZCBrbmFwcCBkYW5lYmVuIHNpbmQgZGllIHNwYW5uZW5kZW4gRsOkbGxlLiAqL1xuZnVuY3Rpb24gZWRnZVZhbHVlcyhjb25kaXRpb246IHN0cmluZywgbmFtZTogc3RyaW5nKTogbnVtYmVyW10ge1xuICBjb25zdCBvdXQ6IG51bWJlcltdID0gW11cbiAgY29uc3QgcmUgPSBuZXcgUmVnRXhwKGBcXFxcYiR7bmFtZX1cXFxccyooPzo9PXwhPXw8PXw+PXw8fD4pXFxcXHMqKC0/XFxcXGQrKXwoLT9cXFxcZCspXFxcXHMqKD86PT18IT18PD18Pj18PHw+KVxcXFxzKiR7bmFtZX1cXFxcYmAsICdnJylcbiAgZm9yIChjb25zdCBtIG9mIGNvbmRpdGlvbi5tYXRjaEFsbChyZSkpIHtcbiAgICBjb25zdCBjID0gTnVtYmVyKG1bMV0gPz8gbVsyXSlcbiAgICBvdXQucHVzaChjIC0gMSwgYywgYyArIDEpXG4gIH1cbiAgcmV0dXJuIG91dFxufVxuXG5leHBvcnQgaW50ZXJmYWNlIFJvdW5kIHtcbiAgY29uZGl0aW9uOiBzdHJpbmdcbiAgdmFsdWVzOiBWYWx1ZXNcbiAgYW5zd2VyOiBib29sZWFuXG59XG5cbi8qKiBSdW5kZSBgaW5kZXhgIHZvbiBgY291bnRgOiBqZSBzcMOkdGVyLCBkZXN0byBzY2h3ZXJlciBkaWUgQmVkaW5ndW5nLiAqL1xuZXhwb3J0IGZ1bmN0aW9uIG1ha2VSb3VuZChnYW1lOiBCb29sR2FtZSwgaW5kZXg6IG51bWJlciwgY291bnQ6IG51bWJlciwgcmFuZG9tOiAoKSA9PiBudW1iZXIgPSBNYXRoLnJhbmRvbSk6IFJvdW5kIHtcbiAgY29uc3QgbiA9IGdhbWUuY29uZGl0aW9ucy5sZW5ndGhcbiAgY29uc3QgYmFzZSA9IE1hdGguZmxvb3IoKGluZGV4ICogbikgLyBjb3VudClcbiAgY29uc3QgcGljayA9IE1hdGgubWluKG4gLSAxLCBiYXNlICsgKHJhbmRvbSgpIDwgMC41ID8gMCA6IDEpKVxuICBjb25zdCBjb25kaXRpb24gPSBnYW1lLmNvbmRpdGlvbnNbcGlja11cbiAgY29uc3QgdmFsdWVzOiBWYWx1ZXMgPSB7fVxuICBmb3IgKGNvbnN0IHYgb2YgZ2FtZS52YXJzKSB7XG4gICAgaWYgKHYua2luZCA9PT0gJ2Jvb2xlYW4nKSB7XG4gICAgICB2YWx1ZXNbdi5uYW1lXSA9IHJhbmRvbSgpIDwgMC41XG4gICAgICBjb250aW51ZVxuICAgIH1cbiAgICBjb25zdCBlZGdlcyA9IGVkZ2VWYWx1ZXMoY29uZGl0aW9uLCB2Lm5hbWUpLmZpbHRlcigoeCkgPT4geCA+PSB2Lm1pbiAmJiB4IDw9IHYubWF4KVxuICAgIHZhbHVlc1t2Lm5hbWVdID0gZWRnZXMubGVuZ3RoICYmIHJhbmRvbSgpIDwgMC42ID8gZWRnZXNbTWF0aC5mbG9vcihyYW5kb20oKSAqIGVkZ2VzLmxlbmd0aCldIDogdi5taW4gKyBNYXRoLmZsb29yKHJhbmRvbSgpICogKHYubWF4IC0gdi5taW4gKyAxKSlcbiAgfVxuICByZXR1cm4geyBjb25kaXRpb24sIHZhbHVlcywgYW5zd2VyOiBldmFsdWF0ZShjb25kaXRpb24sIHZhbHVlcykgfVxufVxuXG4vKiogTnVyIGRpZSBWYXJpYWJsZW4sIGRpZSBpbiBkZXIgQmVkaW5ndW5nIHZvcmtvbW1lbi4gKi9cbmV4cG9ydCBmdW5jdGlvbiB1c2VkVmFsdWVzKHJvdW5kOiBSb3VuZCk6IFtzdHJpbmcsIG51bWJlciB8IGJvb2xlYW5dW10ge1xuICByZXR1cm4gT2JqZWN0LmVudHJpZXMocm91bmQudmFsdWVzKS5maWx0ZXIoKFtuYW1lXSkgPT4gbmV3IFJlZ0V4cChgXFxcXGIke25hbWV9XFxcXGJgKS50ZXN0KHJvdW5kLmNvbmRpdGlvbikpXG59XG4iXSwiZmlsZSI6Ii93ZWIvc3JjL2xlYXJuL2Jvb2xHYW1lLnRzIn0= - -//# vitestCache=W3siZmlsZSI6IjEiLCJpZCI6IjEiLCJ1cmwiOiIyIiwiaW1wb3J0cyI6IjMiLCJtYXBwaW5ncyI6ZmFsc2UsImRlcHMiOiI0IiwiZHluYW1pY0RlcHMiOiI1Iiwic3RhdGljTW9ja3MiOm51bGx9LCIvaG9tZS91c2VyL3Zpc3VzdHJ1Y3Qtc3dpZnR1aS93ZWIvc3JjL2xlYXJuL2Jvb2xHYW1lLnRzIiwiL3dlYi9zcmMvbGVhcm4vYm9vbEdhbWUudHMiLHsidXJscyI6IjYiLCJpZHMiOiI3In0sW10sW10sW10se31d \ No newline at end of file diff --git a/node_modules/.vitest-cache/ead0aad5e88b12ac47bd410f9cc055bc1ed9a667 b/node_modules/.vitest-cache/ead0aad5e88b12ac47bd410f9cc055bc1ed9a667 deleted file mode 100644 index 8d536e21..00000000 --- a/node_modules/.vitest-cache/ead0aad5e88b12ac47bd410f9cc055bc1ed9a667 +++ /dev/null @@ -1,83 +0,0 @@ -__vite_ssr_exportName__("parseCloze", () => { try { return parseCloze } catch {} }); -__vite_ssr_exportName__("clozeGaps", () => { try { return clozeGaps } catch {} }); -__vite_ssr_exportName__("clozeAnswerRight", () => { try { return clozeAnswerRight } catch {} }); -const gapPattern = /\[\[(.+?)\]\]/g; -function parseCloze(inner, file) { - const cloze = { - title: "", - task: "", - blocks: [] - }; - const codes = []; - let inCode = false; - for (const raw of inner) { - if (/^\s*```/.test(raw)) { - if (!inCode) codes.push([]); - inCode = !inCode; - continue; - }; - if (inCode) { - codes[codes.length - 1].push(raw.replace(/\s+$/, "")); - continue; - }; - const line = raw.trim(); - if (!line) continue; - const m = /^([a-zäöü]+):\s*(.*)$/i.exec(line); - if (!m) throw new Error(`${file}: Unbekannte Zeile im Lückentext: „${line}“.`); - const value = m[2].trim(); - switch (m[1].toLowerCase()) { - case "titel": - cloze.title = value; - break; - case "auftrag": - cloze.task = value; - break; - case "erklärung": - case "erklaerung": - cloze.explanation = value; - break; - default: throw new Error(`${file}: Unbekannter Schlüssel „${m[1]}“ im Lückentext.`); - } - }; - if (inCode) throw new Error(`${file}: Der Codeblock im Lückentext wird nicht mit \`\`\` geschlossen.`); - if (!cloze.title) throw new Error(`${file}: Ein Lückentext braucht einen Titel.`); - if (!codes.some((c) => c.some((l) => l.trim()))) throw new Error(`${file}: Lückentext „${cloze.title}“ braucht einen Codeblock.`); - cloze.blocks = codes.map((code) => { - // Gemeinsame Einrückung entfernen, damit der Code links beginnt. - const indent = Math.min(...code.filter((l) => l.trim()).map((l) => /^ */.exec(l)[0].length)); - return code.map((l) => splitGaps(l.slice(indent), file, cloze.title)); - }); - if (!clozeGaps(cloze).length) { - throw new Error(`${file}: Lückentext „${cloze.title}“ braucht mindestens eine Lücke [[…]].`); - }; - return cloze; -}; -function splitGaps(line, file, title) { - const parts = []; - let at = 0; - for (const m of line.matchAll(gapPattern)) { - if (m.index > at) parts.push(line.slice(at, m.index)); - const answers = m[1].split(/\s+\|\s+/).map((a) => a.trim()).filter(Boolean); - if (!answers.length) throw new Error(`${file}: Leere Lücke im Lückentext „${title}“.`); - parts.push({ answers }); - at = m.index + m[0].length; - }; - if (at < line.length) parts.push(line.slice(at)); - if (parts.some((p) => typeof p === "string" && (p.includes("[[") || p.includes("]]")))) { - throw new Error(`${file}: Unvollständige Lücke im Lückentext „${title}“: „${line}“.`); - }; - return parts; -} -/** Alle Lücken in Reihenfolge. */ -function clozeGaps(cloze) { - return cloze.blocks.flat().flatMap((l) => l.flatMap((p) => typeof p === "string" ? [] : [p.answers])); -}; -/** Leerzeichen zählen nicht: `i = i + 1` und `i=i+1` sind gleich. Groß/klein zählt (wie in Java). */ -function clozeAnswerRight(answers, input) { - const norm = (s) => s.replace(/\s+/g, ""); - return norm(input) !== "" && answers.some((a) => norm(a) === norm(input)); -} -//# sourceMappingSource=vite-generated -//# sourceMappingURL=data:application/json;base64,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QUssTUFBTSxFQUFFLENBQUM7Q0FDL0MsSUFBSSxNQUFNLE1BQU0sTUFBTSxPQUFPLE1BQU0sYUFBYSxFQUFFLFNBQVMsSUFBSSxLQUFLLEVBQUUsU0FBUyxJQUFJLEVBQUUsR0FBRztFQUN0RixNQUFNLElBQUksTUFBTSxHQUFHLEtBQUssd0NBQXdDLE1BQU0sTUFBTSxLQUFLLEdBQUc7Q0FDdEY7Q0FDQSxPQUFPO0FBQ1Q7O0FBR08sU0FBUyxVQUFVLE9BQTBCO0NBQ2xELE9BQU8sTUFBTSxPQUFPLEtBQUssQ0FBQyxDQUFDLFNBQVMsTUFBTSxFQUFFLFNBQVMsTUFBTyxPQUFPLE1BQU0sV0FBVyxDQUFDLElBQUksQ0FBQyxFQUFFLE9BQU8sQ0FBRSxDQUFDO0FBQ3hHOztBQUdPLFNBQVMsaUJBQWlCLFNBQW1CLE9BQXdCO0NBQzFFLE1BQU0sUUFBUSxNQUFjLEVBQUUsUUFBUSxRQUFRLEVBQUU7Q0FDaEQsT0FBTyxLQUFLLEtBQUssTUFBTSxNQUFNLFFBQVEsTUFBTSxNQUFNLEtBQUssQ0FBQyxNQUFNLEtBQUssS0FBSyxDQUFDO0FBQzFFIiwibmFtZXMiOltdLCJpZ25vcmVMaXN0IjpbXSwic291cmNlcyI6WyJjbG96ZS50cyJdLCJzb3VyY2VzQ29udGVudCI6WyIvKipcbiAqIEzDvGNrZW50ZXh0OiBmZXJ0aWdlciBDb2RlLCBpbiBkZW0gZWluemVsbmUgV8O2cnRlciBmZWhsZW4uXG4gKlxuICogICAgIDo6OiBsw7xja2VudGV4dFxuICogICAgIHRpdGVsOiBMw7xja2VudGV4dDogWsOkaGxzY2hsZWlmZVxuICogICAgIGF1ZnRyYWc6IEVyZ8OkbnplIGRpZSBmZWhsZW5kZW4gV8O2cnRlci5cbiAqICAgICBgYGBqYXZhXG4gKiAgICAgZm9yIChbW2ludF1dIGkgPSAxOyBpIFtbPD1dXSAxMDsgW1tpKysgfCBpICs9IDEgfCBpID0gaSArIDFdXSkge1xuICogICAgIGBgYFxuICogICAgIGVya2zDpHJ1bmc6IFdpcmQgZ2V6ZWlndCwgd2VubiBhbGxlIEzDvGNrZW4gc3RpbW1lbi5cbiAqICAgICA6OjpcbiAqXG4gKiBNZWhyZXJlIENvZGVibMO2Y2tlIHN0ZWhlbiB1bnRlcmVpbmFuZGVyLCB6LiBCLiBlaW5lIE1ldGhvZGUgdW5kIGRhcyBIYXVwdHByb2dyYW1tLlxuICogYFtbYV1dYCBpc3QgZWluZSBMw7xja2UuIFdlaXRlcmUgcmljaHRpZ2UgQW50d29ydGVuIHN0ZWhlbiBtaXQgYCB8IGAgKExlZXJ6ZWljaGVuIGRhdm9yIHVuZCBkYW5hY2gpXG4gKiBkYWhpbnRlciwgZGFtaXQgYHx8YCB1bmQgYHxgIHNlbGJzdCBhbHMgQW50d29ydCBnZWhlbjogYFtbaSsrIHwgaSArPSAxXV1gLlxuICovXG5leHBvcnQgaW50ZXJmYWNlIENsb3plIHtcbiAgdGl0bGU6IHN0cmluZ1xuICB0YXNrOiBzdHJpbmdcbiAgLyoqIENvZGVibMO2Y2tlICh6LiBCLiBNZXRob2RlIHVuZCBIYXVwdHByb2dyYW1tIHdpZSBpbiBlaWdlbmVuIFJlaXRlcm4pLCBkYXJpbiBaZWlsZW4gYXVzIFRleHQgdW5kIEzDvGNrZW4uICovXG4gIGJsb2NrczogQ2xvemVQYXJ0W11bXVtdXG4gIGV4cGxhbmF0aW9uPzogc3RyaW5nXG59XG5cbmV4cG9ydCB0eXBlIENsb3plUGFydCA9IHN0cmluZyB8IHsgYW5zd2Vyczogc3RyaW5nW10gfVxuXG5jb25zdCBnYXBQYXR0ZXJuID0gL1xcW1xcWyguKz8pXFxdXFxdL2dcblxuZXhwb3J0IGZ1bmN0aW9uIHBhcnNlQ2xvemUoaW5uZXI6IHN0cmluZ1tdLCBmaWxlOiBzdHJpbmcpOiBDbG96ZSB7XG4gIGNvbnN0IGNsb3plOiBDbG96ZSA9IHsgdGl0bGU6ICcnLCB0YXNrOiAnJywgYmxvY2tzOiBbXSB9XG4gIGNvbnN0IGNvZGVzOiBzdHJpbmdbXVtdID0gW11cbiAgbGV0IGluQ29kZSA9IGZhbHNlXG4gIGZvciAoY29uc3QgcmF3IG9mIGlubmVyKSB7XG4gICAgaWYgKC9eXFxzKmBgYC8udGVzdChyYXcpKSB7XG4gICAgICBpZiAoIWluQ29kZSkgY29kZXMucHVzaChbXSlcbiAgICAgIGluQ29kZSA9ICFpbkNvZGVcbiAgICAgIGNvbnRpbnVlXG4gICAgfVxuICAgIGlmIChpbkNvZGUpIHtcbiAgICAgIGNvZGVzW2NvZGVzLmxlbmd0aCAtIDFdLnB1c2gocmF3LnJlcGxhY2UoL1xccyskLywgJycpKVxuICAgICAgY29udGludWVcbiAgICB9XG4gICAgY29uc3QgbGluZSA9IHJhdy50cmltKClcbiAgICBpZiAoIWxpbmUpIGNvbnRpbnVlXG4gICAgY29uc3QgbSA9IC9eKFthLXrDpMO2w7xdKyk6XFxzKiguKikkL2kuZXhlYyhsaW5lKVxuICAgIGlmICghbSkgdGhyb3cgbmV3IEVycm9yKGAke2ZpbGV9OiBVbmJla2FubnRlIFplaWxlIGltIEzDvGNrZW50ZXh0OiDigJ4ke2xpbmV94oCcLmApXG4gICAgY29uc3QgdmFsdWUgPSBtWzJdLnRyaW0oKVxuICAgIHN3aXRjaCAobVsxXS50b0xvd2VyQ2FzZSgpKSB7XG4gICAgICBjYXNlICd0aXRlbCc6IGNsb3plLnRpdGxlID0gdmFsdWU7IGJyZWFrXG4gICAgICBjYXNlICdhdWZ0cmFnJzogY2xvemUudGFzayA9IHZhbHVlOyBicmVha1xuICAgICAgY2FzZSAnZXJrbMOkcnVuZyc6XG4gICAgICBjYXNlICdlcmtsYWVydW5nJzogY2xvemUuZXhwbGFuYXRpb24gPSB2YWx1ZTsgYnJlYWtcbiAgICAgIGRlZmF1bHQ6IHRocm93IG5ldyBFcnJvcihgJHtmaWxlfTogVW5iZWthbm50ZXIgU2NobMO8c3NlbCDigJ4ke21bMV194oCcIGltIEzDvGNrZW50ZXh0LmApXG4gICAgfVxuICB9XG4gIGlmIChpbkNvZGUpIHRocm93IG5ldyBFcnJvcihgJHtmaWxlfTogRGVyIENvZGVibG9jayBpbSBMw7xja2VudGV4dCB3aXJkIG5pY2h0IG1pdCBcXGBcXGBcXGAgZ2VzY2hsb3NzZW4uYClcbiAgaWYgKCFjbG96ZS50aXRsZSkgdGhyb3cgbmV3IEVycm9yKGAke2ZpbGV9OiBFaW4gTMO8Y2tlbnRleHQgYnJhdWNodCBlaW5lbiBUaXRlbC5gKVxuICBpZiAoIWNvZGVzLnNvbWUoKGMpID0+IGMuc29tZSgobCkgPT4gbC50cmltKCkpKSkgdGhyb3cgbmV3IEVycm9yKGAke2ZpbGV9OiBMw7xja2VudGV4dCDigJ4ke2Nsb3plLnRpdGxlfeKAnCBicmF1Y2h0IGVpbmVuIENvZGVibG9jay5gKVxuICBjbG96ZS5ibG9ja3MgPSBjb2Rlcy5tYXAoKGNvZGUpID0+IHtcbiAgICAvLyBHZW1laW5zYW1lIEVpbnLDvGNrdW5nIGVudGZlcm5lbiwgZGFtaXQgZGVyIENvZGUgbGlua3MgYmVnaW5udC5cbiAgICBjb25zdCBpbmRlbnQgPSBNYXRoLm1pbiguLi5jb2RlLmZpbHRlcigobCkgPT4gbC50cmltKCkpLm1hcCgobCkgPT4gL14gKi8uZXhlYyhsKSFbMF0ubGVuZ3RoKSlcbiAgICByZXR1cm4gY29kZS5tYXAoKGwpID0+IHNwbGl0R2FwcyhsLnNsaWNlKGluZGVudCksIGZpbGUsIGNsb3plLnRpdGxlKSlcbiAgfSlcbiAgaWYgKCFjbG96ZUdhcHMoY2xvemUpLmxlbmd0aCkge1xuICAgIHRocm93IG5ldyBFcnJvcihgJHtmaWxlfTogTMO8Y2tlbnRleHQg4oCeJHtjbG96ZS50aXRsZX3igJwgYnJhdWNodCBtaW5kZXN0ZW5zIGVpbmUgTMO8Y2tlIFtb4oCmXV0uYClcbiAgfVxuICByZXR1cm4gY2xvemVcbn1cblxuZnVuY3Rpb24gc3BsaXRHYXBzKGxpbmU6IHN0cmluZywgZmlsZTogc3RyaW5nLCB0aXRsZTogc3RyaW5nKTogQ2xvemVQYXJ0W10ge1xuICBjb25zdCBwYXJ0czogQ2xvemVQYXJ0W10gPSBbXVxuICBsZXQgYXQgPSAwXG4gIGZvciAoY29uc3QgbSBvZiBsaW5lLm1hdGNoQWxsKGdhcFBhdHRlcm4pKSB7XG4gICAgaWYgKG0uaW5kZXghID4gYXQpIHBhcnRzLnB1c2gobGluZS5zbGljZShhdCwgbS5pbmRleCkpXG4gICAgY29uc3QgYW5zd2VycyA9IG1bMV0uc3BsaXQoL1xccytcXHxcXHMrLykubWFwKChhKSA9PiBhLnRyaW0oKSkuZmlsdGVyKEJvb2xlYW4pXG4gICAgaWYgKCFhbnN3ZXJzLmxlbmd0aCkgdGhyb3cgbmV3IEVycm9yKGAke2ZpbGV9OiBMZWVyZSBMw7xja2UgaW0gTMO8Y2tlbnRleHQg4oCeJHt0aXRsZX3igJwuYClcbiAgICBwYXJ0cy5wdXNoKHsgYW5zd2VycyB9KVxuICAgIGF0ID0gbS5pbmRleCEgKyBtWzBdLmxlbmd0aFxuICB9XG4gIGlmIChhdCA8IGxpbmUubGVuZ3RoKSBwYXJ0cy5wdXNoKGxpbmUuc2xpY2UoYXQpKVxuICBpZiAocGFydHMuc29tZSgocCkgPT4gdHlwZW9mIHAgPT09ICdzdHJpbmcnICYmIChwLmluY2x1ZGVzKCdbWycpIHx8IHAuaW5jbHVkZXMoJ11dJykpKSkge1xuICAgIHRocm93IG5ldyBFcnJvcihgJHtmaWxlfTogVW52b2xsc3TDpG5kaWdlIEzDvGNrZSBpbSBMw7xja2VudGV4dCDigJ4ke3RpdGxlfeKAnDog4oCeJHtsaW5lfeKAnC5gKVxuICB9XG4gIHJldHVybiBwYXJ0c1xufVxuXG4vKiogQWxsZSBMw7xja2VuIGluIFJlaWhlbmZvbGdlLiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGNsb3plR2FwcyhjbG96ZTogQ2xvemUpOiBzdHJpbmdbXVtdIHtcbiAgcmV0dXJuIGNsb3plLmJsb2Nrcy5mbGF0KCkuZmxhdE1hcCgobCkgPT4gbC5mbGF0TWFwKChwKSA9PiAodHlwZW9mIHAgPT09ICdzdHJpbmcnID8gW10gOiBbcC5hbnN3ZXJzXSkpKVxufVxuXG4vKiogTGVlcnplaWNoZW4gesOkaGxlbiBuaWNodDogYGkgPSBpICsgMWAgdW5kIGBpPWkrMWAgc2luZCBnbGVpY2guIEdyb8OfL2tsZWluIHrDpGhsdCAod2llIGluIEphdmEpLiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGNsb3plQW5zd2VyUmlnaHQoYW5zd2Vyczogc3RyaW5nW10sIGlucHV0OiBzdHJpbmcpOiBib29sZWFuIHtcbiAgY29uc3Qgbm9ybSA9IChzOiBzdHJpbmcpID0+IHMucmVwbGFjZSgvXFxzKy9nLCAnJylcbiAgcmV0dXJuIG5vcm0oaW5wdXQpICE9PSAnJyAmJiBhbnN3ZXJzLnNvbWUoKGEpID0+IG5vcm0oYSkgPT09IG5vcm0oaW5wdXQpKVxufVxuIl0sImZpbGUiOiIvd2ViL3NyYy9sZWFybi9jbG96ZS50cyJ9 - -//# vitestCache=W3siZmlsZSI6IjEiLCJpZCI6IjEiLCJ1cmwiOiIyIiwiaW1wb3J0cyI6IjMiLCJtYXBwaW5ncyI6ZmFsc2UsImRlcHMiOiI0IiwiZHluYW1pY0RlcHMiOiI1Iiwic3RhdGljTW9ja3MiOm51bGx9LCIvaG9tZS91c2VyL3Zpc3VzdHJ1Y3Qtc3dpZnR1aS93ZWIvc3JjL2xlYXJuL2Nsb3plLnRzIiwiL3dlYi9zcmMvbGVhcm4vY2xvemUudHMiLHsidXJscyI6IjYiLCJpZHMiOiI3In0sW10sW10sW10se31d \ No newline at end of file diff --git a/web/lessons/de/20-java.md b/web/lessons/de/20-java.md index b4345bd4..9b5cea49 100644 --- a/web/lessons/de/20-java.md +++ b/web/lessons/de/20-java.md @@ -159,7 +159,7 @@ java Einmaleins ``` - `java -version` zeigt, welche Java-Version installiert ist. Kommt eine Fehlermeldung, fehlt Java noch. -- `javac Einmaleins.java` startet den Compiler. Danach liegt `Einmaleins.class` im selben Ordner. +- `javac Einmaleins.java` startet den Compiler. Danach hast du zwei Dateien im Ordner: `Einmaleins.java` mit deinem Quellcode und neu `Einmaleins.class` mit dem Bytecode. - `java Einmaleins` startet die JVM mit deinem Bytecode. Den Klassennamen schreibst du hier ohne `.class`. Klappt `java -version`, aber `javac -version` nicht, ist nur eine JRE installiert. Dann fehlt dir das JDK. diff --git a/web/lessons/en/20-java.md b/web/lessons/en/20-java.md index 290826c2..41ceb154 100644 --- a/web/lessons/en/20-java.md +++ b/web/lessons/en/20-java.md @@ -159,7 +159,7 @@ java TimesTable ``` - `java -version` shows which Java version is installed. If you get an error message, Java is still missing. -- `javac TimesTable.java` starts the compiler. Afterwards `TimesTable.class` is in the same folder. +- `javac TimesTable.java` starts the compiler. Afterwards there are two files in the folder: `TimesTable.java` with your source code and the new `TimesTable.class` with the bytecode. - `java TimesTable` starts the JVM with your bytecode. Here you write the class name without `.class`. If `java -version` works but `javac -version` doesn't, only a JRE is installed. Then you are missing the JDK. diff --git a/web/lessons/pt/20-java.md b/web/lessons/pt/20-java.md index af6af256..d56e82e5 100644 --- a/web/lessons/pt/20-java.md +++ b/web/lessons/pt/20-java.md @@ -159,7 +159,7 @@ java Tabuada ``` - `java -version` mostra que versão do Java está instalada. Se aparecer uma mensagem de erro, ainda falta o Java. -- `javac Tabuada.java` inicia o compilador. Depois, o `Tabuada.class` fica na mesma pasta. +- `javac Tabuada.java` inicia o compilador. Depois tens dois ficheiros na pasta: o `Tabuada.java` com o teu código-fonte e o novo `Tabuada.class` com o bytecode. - `java Tabuada` inicia a JVM com o teu bytecode. Aqui escreves o nome da classe sem `.class`. Se `java -version` funcionar mas `javac -version` não, só tens um JRE instalado. Nesse caso falta-te o JDK. diff --git a/website/app/assets/flowApp-Bn4c4hPI.js b/website/app/assets/flowApp-B2mFVVBJ.js similarity index 99% rename from website/app/assets/flowApp-Bn4c4hPI.js rename to website/app/assets/flowApp-B2mFVVBJ.js index 39b49c76..32277b57 100644 --- a/website/app/assets/flowApp-Bn4c4hPI.js +++ b/website/app/assets/flowApp-B2mFVVBJ.js @@ -1,4 +1,4 @@ -var dt=Object.defineProperty;var lt=(n,t,e)=>t in n?dt(n,t,{enumerable:!0,configurable:!0,writable:!0,value:e}):n[t]=e;var y=(n,t,e)=>lt(n,typeof t!="symbol"?t+"":t,e);import{t as h,g as ct,i as I,w as ht,n as ut,f as ft,o as G,q as pt,u as gt,v as wt,x as vt,y as mt,l as xt}from"./index-CzgrZgZa.js";const et=["start","anweisung","ein","verzweigung","unterprogramm","ende"],m=20,st={start:"#d1f2d9",ende:"#d1f2d9",anweisung:"#e5f0ff",ein:"#f2e6ff",verzweigung:"#fff4d6",unterprogramm:"#e5f0ff"},H=16,yt=170;function bt(n,t,e){const i=[];for(const s of n.split(` +var dt=Object.defineProperty;var lt=(n,t,e)=>t in n?dt(n,t,{enumerable:!0,configurable:!0,writable:!0,value:e}):n[t]=e;var y=(n,t,e)=>lt(n,typeof t!="symbol"?t+"":t,e);import{t as h,g as ct,i as I,w as ht,n as ut,f as ft,o as G,q as pt,u as gt,v as wt,x as vt,y as mt,l as xt}from"./index-Dntu0aWH.js";const et=["start","anweisung","ein","verzweigung","unterprogramm","ende"],m=20,st={start:"#d1f2d9",ende:"#d1f2d9",anweisung:"#e5f0ff",ein:"#f2e6ff",verzweigung:"#fff4d6",unterprogramm:"#e5f0ff"},H=16,yt=170;function bt(n,t,e){const i=[];for(const s of n.split(` `)){let o="";for(const r of s.split(/\s+/).filter(Boolean)){const a=o?`${o} ${r}`:r;o&&e(a)>t?(i.push(o),o=r):o=a}i.push(o)}return i.length?i:[""]}const q=n=>Math.round(n/m)*m;function C(n,t){const e=bt(n.text,yt,t),i=Math.max(0,...e.map(t)),s=e.length*H;let o,r;if(n.shape==="verzweigung")o=Math.max(140,i*1.7+30),r=Math.max(80,s*1.8+24);else{const a=n.shape==="ein"?44:n.shape==="unterprogramm"?40:n.shape==="anweisung"?24:36;o=Math.max(n.shape==="start"||n.shape==="ende"?100:120,i+a),r=Math.max(40,s+18)}return{x:n.x,y:n.y,w:Math.ceil(o/m)*m,h:Math.ceil(r/m)*m,lines:e}}function V(n){return n==="ende"?[]:n==="verzweigung"?["ja","nein"]:["out"]}const D=n=>n!=="start";function P(n,t,e){var s;if(e==="out")return"bottom";const i=((s=n.yesRight)==null?void 0:s.includes(t.id))??!1;return e==="ja"===i?"right":"bottom"}function F(n,t){return t==="bottom"?[n.x,n.y+n.h/2]:[n.x+n.w/2,n.y]}const _t=n=>[n.x,n.y-n.h/2];function $t(n,t,e,i=0){const[s,o]=F(n,t),[r,a]=_t(e),d=m,u=Math.max(n.x+n.w/2,e.x+e.w/2)+d*(1.5+i);if(t==="bottom"){if(a>=o+d){if(s===r)return[[s,o],[r,a]];const l=o+d;return[[s,o],[s,l],[r,l],[r,a]]}return[[s,o],[s,o+d],[u,o+d],[u,a-d],[r,a-d],[r,a]]}const p=e.x-e.w/2;if(p>=s+d&&Math.abs(e.y-o)=o+d){if(r>=s+d)return[[s,o],[r,o],[r,a]];const l=s+d;return[[s,o],[l,o],[l,a-d],[r,a-d],[r,a]]}const f=Math.max(s+d,u);return[[s,o],[f,o],[f,a-d],[r,a-d],[r,a]]}function nt(n=""){return{title:n,nodes:[],edges:[]}}function it(n,t){const e=new Set([...n.nodes.map(s=>s.id),...n.edges.map(s=>s.id)]);let i=1;for(;e.has(`${t}${i}`);)i++;return`${t}${i}`}function O(n,t,e,i,s){const o=it(n,"n");return{doc:{...n,nodes:[...n.nodes,{id:o,shape:t,x:q(e),y:q(i),text:s}]},id:o}}function J(n,t,e,i){return{...n,nodes:n.nodes.map(s=>s.id===t?{...s,x:Math.max(m*4,q(e)),y:Math.max(m*2,q(i))}:s)}}function Lt(n,t,e){return{...n,nodes:n.nodes.map(i=>i.id===t?{...i,text:e}:i)}}function _(n,t,e,i){const s=n.nodes.find(a=>a.id===t),o=n.nodes.find(a=>a.id===i);if(!s||!o||t===i||!V(s.shape).includes(e)||!D(o.shape))return n;const r=n.edges.filter(a=>!(a.from===t&&a.port===e));return{...n,edges:[...r,{id:it(n,"e"),from:t,port:e,to:i}]}}function Et(n,t){return V(t.shape).find(e=>!n.edges.some(i=>i.from===t.id&&i.port===e))}function kt(n,t){var e;return{...n,nodes:n.nodes.filter(i=>i.id!==t),edges:n.edges.filter(i=>i.from!==t&&i.to!==t),yesRight:(e=n.yesRight)==null?void 0:e.filter(i=>i!==t)}}function St(n,t){return{...n,edges:n.edges.filter(e=>e.id!==t)}}function ot(n,t){const e=new Set(n.yesRight??[]);return e.has(t)?e.delete(t):e.add(t),{...n,yesRight:[...e]}}function b(n){return JSON.stringify({format:"visuflow",version:1,...n},null,2)}function W(n){let t;try{t=JSON.parse(n)}catch{return}if(!t||typeof t!="object")return;const e=t;if(!Array.isArray(e.nodes)||!Array.isArray(e.edges))return;const i=[];for(const o of e.nodes)!o||typeof o.id!="string"||!et.includes(o.shape)||!Number.isFinite(o.x)||!Number.isFinite(o.y)||i.some(r=>r.id===o.id)||i.push({id:o.id,shape:o.shape,x:o.x,y:o.y,text:typeof o.text=="string"?o.text:""});let s={title:typeof e.title=="string"?e.title:"",nodes:i,edges:[]};for(const o of e.edges)!o||typeof o.from!="string"||typeof o.to!="string"||typeof o.port!="string"||(s=_(s,o.from,o.port,o.to));return Array.isArray(e.yesRight)&&(s.yesRight=e.yesRight.filter(o=>typeof o=="string"&&i.some(r=>r.id===o))),s}const z="http://www.w3.org/2000/svg",X="visuflow.doc",Mt=100,Y=14,rt=`${Y}px -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif`,T="#1c1c1e",w=n=>n.replace(/[&<>"]/g,t=>({"&":"&","<":"<",">":">",'"':"""})[t]);function At(n){try{return localStorage.getItem(n)}catch{return null}}function Z(n,t){try{localStorage.setItem(n,t)}catch{}}function It(){const n=xt(),t=n==="pt-PT"?"pt":n==="de"?"de":"en";return`${/\/app\/(index\.html)?$/.test(location.pathname)?"../":"https://visustruct.org/"}${t}/index.html`}function j(n,t,e){const i=URL.createObjectURL(new Blob([t],{type:e})),s=document.createElement("a");s.href=i,s.download=n,s.click(),setTimeout(()=>URL.revokeObjectURL(i),1e3)}function v(n,t={}){const e=document.createElementNS(z,n);for(const[i,s]of Object.entries(t))e.setAttribute(i,String(s));return e}let N;function R(n){return N===void 0&&(N=document.createElement("canvas").getContext("2d")),N?(N.font=rt,N.measureText(n).width):n.length*Y*.55}const Ct=n=>h(`web_visuflow_shape_${n}`),B=n=>h(`web_visuflow_text_${n}`);function at(n,t){const e=t.x-t.w/2,i=t.x+t.w/2,s=t.y-t.h/2,o=t.y+t.h/2;return n==="verzweigung"?v("path",{d:`M${t.x} ${s} L${i} ${t.y} L${t.x} ${o} L${e} ${t.y} Z`}):n==="ein"?v("path",{d:`M${e+14} ${s} L${i} ${s} L${i-14} ${o} L${e} ${o} Z`}):n==="unterprogramm"?v("path",{d:`M${e} ${s} H${i} V${o} H${e} Z M${e+10} ${s} V${o} M${i-10} ${s} V${o}`}):v("rect",{x:e,y:s,width:t.w,height:t.h,rx:n==="anweisung"?2:t.h/2})}function Rt(n){const t=v("text",{"text-anchor":"middle","font-size":Y,fill:T});return n.lines.forEach((e,i)=>{const s=v("tspan",{x:n.x,y:n.y+5+(i-(n.lines.length-1)/2)*H});s.textContent=e,t.append(s)}),t}function Q(n){const t=v("svg",{viewBox:"0 0 64 36",width:64,height:36,"aria-hidden":"true"}),e=at(n,{x:32,y:18,w:n==="verzweigung"?54:56,h:n==="verzweigung"?32:26});return e.setAttribute("fill",st[n]),e.setAttribute("stroke",T),e.setAttribute("stroke-width","1.5"),t.append(e),t.outerHTML}function tt(){let n=nt(h("web_visuflow_example_title"));const t=[],e=(p,f,l,c)=>{const g=O(n,p,f,l,c);n=g.doc,t.push(g.id)};e("start",240,60,B("start")),e("anweisung",240,160,h("web_visuflow_example_water")),e("anweisung",240,260,h("web_visuflow_example_bag")),e("verzweigung",240,380,h("web_visuflow_example_hot")),e("anweisung",480,380,h("web_visuflow_example_wait")),e("anweisung",240,500,h("web_visuflow_example_drink")),e("ende",240,600,B("ende"));const[i,s,o,r,a,d,u]=t;return n=_(n,i,"out",s),n=_(n,s,"out",o),n=_(n,o,"out",r),n=ot(n,r),n=_(n,r,"ja",a),n=_(n,a,"out",r),n=_(n,r,"nein",d),n=_(n,d,"out",u),n}function Tt(){return O(nt(),"start",240,60,B("start")).doc}class Pt{constructor(t){y(this,"shell");y(this,"svg");y(this,"scroller");y(this,"status");y(this,"titleInput");y(this,"doc");y(this,"selection");y(this,"history",[]);y(this,"future",[]);y(this,"editor");y(this,"dragLine");document.documentElement.classList.add("visuflow-theme"),history.replaceState(history.state,"",`${location.pathname}?visuflow${location.hash}`),this.doc=W(At(X)??"")??tt(),this.shell=document.createElement("div"),this.shell.className="shell visuflow",t.replaceWith(this.shell),this.build(),this.render(),window.addEventListener("keydown",e=>this.onKey(e))}build(){const t=(l,c,g,x=c)=>``,e=et.map(l=>``).join("");this.shell.innerHTML=`
    VisuFlow ${w(h("web_visuflow_subtitle"))} diff --git a/website/app/assets/index-CzgrZgZa.js b/website/app/assets/index-Dntu0aWH.js similarity index 99% rename from website/app/assets/index-CzgrZgZa.js rename to website/app/assets/index-Dntu0aWH.js index 8efcae5e..ba393748 100644 --- a/website/app/assets/index-CzgrZgZa.js +++ b/website/app/assets/index-Dntu0aWH.js @@ -6600,7 +6600,7 @@ java Einmaleins \`\`\` - \`java -version\` zeigt, welche Java-Version installiert ist. Kommt eine Fehlermeldung, fehlt Java noch. -- \`javac Einmaleins.java\` startet den Compiler. Danach liegt \`Einmaleins.class\` im selben Ordner. +- \`javac Einmaleins.java\` startet den Compiler. Danach hast du zwei Dateien im Ordner: \`Einmaleins.java\` mit deinem Quellcode und neu \`Einmaleins.class\` mit dem Bytecode. - \`java Einmaleins\` startet die JVM mit deinem Bytecode. Den Klassennamen schreibst du hier ohne \`.class\`. Klappt \`java -version\`, aber \`javac -version\` nicht, ist nur eine JRE installiert. Dann fehlt dir das JDK. @@ -18751,7 +18751,7 @@ java TimesTable \`\`\` - \`java -version\` shows which Java version is installed. If you get an error message, Java is still missing. -- \`javac TimesTable.java\` starts the compiler. Afterwards \`TimesTable.class\` is in the same folder. +- \`javac TimesTable.java\` starts the compiler. Afterwards there are two files in the folder: \`TimesTable.java\` with your source code and the new \`TimesTable.class\` with the bytecode. - \`java TimesTable\` starts the JVM with your bytecode. Here you write the class name without \`.class\`. If \`java -version\` works but \`javac -version\` doesn't, only a JRE is installed. Then you are missing the JDK. @@ -30913,7 +30913,7 @@ java Tabuada \`\`\` - \`java -version\` mostra que versão do Java está instalada. Se aparecer uma mensagem de erro, ainda falta o Java. -- \`javac Tabuada.java\` inicia o compilador. Depois, o \`Tabuada.class\` fica na mesma pasta. +- \`javac Tabuada.java\` inicia o compilador. Depois tens dois ficheiros na pasta: o \`Tabuada.java\` com o teu código-fonte e o novo \`Tabuada.class\` com o bytecode. - \`java Tabuada\` inicia a JVM com o teu bytecode. Aqui escreves o nome da classe sem \`.class\`. Se \`java -version\` funcionar mas \`javac -version\` não, só tens um JRE instalado. Nesse caso falta-te o JDK. @@ -64284,7 +64284,7 @@ ${l}`)}Na=aM(((o=e.find(([l])=>l==="begriffe.md"))==null?void 0:o[1])??"")}const

    ${Me(p("simulation_trace"))}

    ${Me(p("simulation_variables"))}

    ${Me(p("simulation_output"))}

    - `;const e=a=>this.element.querySelector(a);this.buttons={play:e("[data-sim=play]"),pause:e("[data-sim=pause]"),step:e("[data-sim=step]"),stop:e("[data-sim=stop]")},this.buttons.play.addEventListener("click",()=>this.play()),this.buttons.pause.addEventListener("click",()=>this.pause()),this.buttons.step.addEventListener("click",()=>this.step()),this.buttons.stop.addEventListener("click",()=>this.reset()),this.editButton=e(".sim-edit"),this.editButton.addEventListener("click",()=>this.onEdit());const t=e("[data-sim=highlight]");t.value=this.highlightMode,t.addEventListener("change",()=>{this.highlightMode=t.value,Ku(Xu,this.highlightMode)});const n=e("[data-sim=delay]");n.value=this.delay,n.addEventListener("change",()=>{this.delay=n.value,Ku(Ir,this.delay)}),this.inputSection=e(".sim-input > div"),this.trace=e(".sim-trace"),this.variables=e(".sim-vars"),this.output=e(".sim-output"),this.notice=e(".sim-notice")}collectOutput(){const e=this.engine.state.outputLines;for(;this.printedr.localeCompare(o));if(n.length===0)this.variables.innerHTML=`

    ${Me(p("simulation_variables_placeholder"))}

    `;else{const r=document.createElement("table");for(const o of n){const l=r.insertRow();l.insertCell().textContent=o;const u=e.variables.get(o),m=l.insertCell();u.kind==="grid"?m.append(sg(u)):m.textContent=_e(u)}this.variables.replaceChildren(r)}e.outputLines.length===0&&e.files.size===0?this.output.innerHTML=`

    ${Me(p("simulation_output_placeholder"))}

    `:(this.output.replaceChildren(...e.outputLines.map(r=>{const o=document.createElement("div");return o.textContent=r,o}),...ag(e.files)),this.output.scrollTop=this.output.scrollHeight)}updateInput(){const e=this.engine.state.inputRequest,t=this.inputSection;if(t.parentElement.classList.toggle("active",!!e),!e){t.innerHTML=`

    ${Me(p("simulation_input_placeholder"))}

    `;return}let n=t.querySelector("form");if(!n){n=document.createElement("form"),n.innerHTML=`

    `;const l=n.querySelector("input");n.addEventListener("submit",u=>{u.preventDefault(),this.submitInput(l)}),t.replaceChildren(n),requestAnimationFrame(()=>l.focus())}const a=this.engine.state.outputLines;n.querySelector(".sim-prompt").textContent=e.prompt||(a[a.length-1]??"");const s=n.querySelector("input");s.inputMode=e.valueType==="string"||e.valueType==="boolean"?"text":"decimal";const r=this.engine.state.inputErrorNotice,o=n.querySelector(".sim-input-error");o.textContent=r?t1(r):"",o.hidden=!r}}function sg(i){const e=document.createElement("table");e.className="sim-grid";for(const t of i.value){const n=e.insertRow();for(const a of t){const s=n.insertCell();s.textContent=String(a),a===!0&&(s.className="sim-grid-true")}}return e}const x1=Array.from("ABCDEFGHIJKLMNOPQRSTUVWXYZ"),Gn=360/x1.length,UM="http://www.w3.org/2000/svg";function Fe(i,e={},...t){const n=document.createElement(i);for(const[a,s]of Object.entries(e))n.setAttribute(a,s);return n.append(...t),n}function xt(i,e={},t){const n=document.createElementNS(UM,i);for(const[a,s]of Object.entries(e))n.setAttribute(a,String(s));return t!==void 0&&(n.textContent=t),n}function $M(i,e){const t=(e%26+26)%26;return Array.from(i).map(n=>{const a=n.charCodeAt(0);return a>=65&&a<=90?String.fromCharCode((a-65+t)%26+65):a>=97&&a<=122?String.fromCharCode((a-97+t)%26+97):n}).join("")}function em(i,e){const t=xt("g",{class:e}),n=x1.map((a,s)=>{const r=xt("g",{transform:`rotate(${s*Gn})`});return r.append(xt("text",{x:0,y:-i,"text-anchor":"middle","dominant-baseline":"central"},a)),t.append(r),r});return{group:t,cells:n}}function YM(i,e){let t=i,n=!1,a=-t*Gn;const s=Fe("section",{class:"learn-game learn-caesar"});s.append(Fe("div",{class:"learn-game-head"},Fe("strong",{},p("web_learn_caesar_title")))),s.append(Fe("p",{class:"learn-game-status"},p("web_learn_caesar_hint")));const r=xt("svg",{viewBox:"-200 -200 400 400",class:"learn-caesar-disc",role:"img"});r.append(xt("circle",{r:196,class:"outer-disc"})),r.append(xt("path",{d:XM(196,92,Gn/2),class:"window"}));const o=em(168,"outer-letters");r.append(o.group);for(let A=0;A{o.cells.forEach((B,E)=>B.classList.toggle("marked",E===A)),u.cells.forEach((B,E)=>B.classList.toggle("marked",A!==void 0&&E===(A+t)%26))},T=()=>{m.textContent=String(t),l.setAttribute("transform",`rotate(${a})`),r.setAttribute("aria-label",p("web_learn_caesar_key_fmt",t)),x.textContent=p(n?"web_learn_caesar_secret":"web_learn_caesar_plain"),w.textContent=p(n?"web_learn_caesar_plain":"web_learn_caesar_secret"),f.classList.toggle("active",!n),b.classList.toggle("active",n),I.textContent=$M(v.value,n?-t:t)||" ";const A=Array.from(v.value.toUpperCase()).reverse().find(E=>x1.includes(E));if(A===void 0)return k();const B=x1.indexOf(A);k(n?(B-t+26)%26:B)},j=A=>{t=(A%26+26)%26,a=-t*Gn,T()};c.addEventListener("click",()=>j(t-1)),d.addEventListener("click",()=>j(t+1)),f.addEventListener("click",()=>{var A;n&&(v.value=((A=I.textContent)==null?void 0:A.trim())??""),n=!1,T()}),b.addEventListener("click",()=>{var A;n||(v.value=((A=I.textContent)==null?void 0:A.trim())??""),n=!0,T()}),v.addEventListener("input",T),o.cells.forEach((A,B)=>A.addEventListener("click",()=>k(B)));let D;const O=A=>{const B=r.getBoundingClientRect();return Math.atan2(A.clientY-(B.top+B.height/2),A.clientX-(B.left+B.width/2))*180/Math.PI};l.addEventListener("pointerdown",A=>{const B=A;D=O(B)-a,l.classList.add("dragging"),r.setPointerCapture(B.pointerId),B.preventDefault()}),r.addEventListener("pointermove",A=>{if(D===void 0)return;a=O(A)-D,l.setAttribute("transform",`rotate(${a})`);const B=Math.round(-a/Gn);if((B%26+26)%26!==t){t=(B%26+26)%26;const E=a;T(),a=E,l.setAttribute("transform",`rotate(${a})`)}});const C=()=>{D!==void 0&&(D=void 0,l.classList.remove("dragging"),j(t))};return r.addEventListener("pointerup",C),r.addEventListener("pointercancel",C),T(),s}function XM(i,e,t){const n=(a,s)=>{const r=(s-90)*Math.PI/180;return`${(a*Math.cos(r)).toFixed(2)} ${(a*Math.sin(r)).toFixed(2)}`};return`M ${n(i,-t)} A ${i} ${i} 0 0 1 ${n(i,t)} L ${n(e,t)} A ${e} ${e} 0 0 0 ${n(e,-t)} Z`}const l0=i=>p(`web_visubot_part_${i}`),rg=new WeakMap;function og(i,e,t,n){const a=document.createElement("div");a.className="visubot-model";const s=document.createElement("div");s.className="visubot-stage";const r=document.createElement("div");r.className="visubot-part-label",r.hidden=!0,s.append(r);const o=(c,d,h)=>{r.hidden=!1,r.textContent=l0(c),r.style.left=`${Math.min(d+12,s.clientWidth-140)}px`,r.style.top=`${h+12}px`},l=document.createElement("p");l.className="visubot-model-hint hint",l.textContent=p("web_visubot_tap_part"),l.hidden=!!n,a.append(s,l);const u=K(async()=>{const{Robot3D:c}=await import("./robot3d-BNw8Z2K3.js");return{Robot3D:c}},[],import.meta.url).then(({Robot3D:c})=>{const d=new c(s);d.showcase(),d.highlight(i),i.includes("leds")&&d.setLed([40,90,255]),d.focusOn([],e==="unten"||e==="bottom"?"":e,!1,1),d.focusOn(i,e,t);let h;return s.addEventListener("pointerdown",g=>h={x:g.clientX,y:g.clientY}),s.addEventListener("pointerup",g=>{if(!h||Math.hypot(g.clientX-h.x,g.clientY-h.y)>5)return;const f=d.partAt(g.clientX,g.clientY);if(!f)return;if(n)return n(f);d.highlight(f);const b=s.getBoundingClientRect();o(f,g.clientX-b.left,g.clientY-b.top)}),s.addEventListener("pointermove",g=>{if(g.pointerType!=="mouse"||n)return;const f=d.partAt(g.clientX,g.clientY);if(r.hidden=!f,!f)return;const b=s.getBoundingClientRect();o(f,g.clientX-b.left,g.clientY-b.top)}),s.addEventListener("pointerleave",()=>r.hidden=!0),d}).catch(c=>{console.error(c),s.textContent=p("web_visubot_no_3d")}),m={box:a,ready:u,focus:i,view:e};return rg.set(a,m),m}function KM(i,e,t=!1){return og(i,e,t).box}function eZ(i){const e=i.querySelector(".visubot-model"),t=e&&rg.get(e);for(const n of i.querySelectorAll("[data-robot-part]")){const a=(n.dataset.robotPart??"").split(",").filter(Boolean);if(n.title=a.map(l0).join(", "),!t)continue;const s=()=>void t.ready.then(o=>o==null?void 0:o.highlight(a)),r=()=>void t.ready.then(o=>o==null?void 0:o.highlight(t.focus));n.addEventListener("mouseenter",s),n.addEventListener("focus",s),n.addEventListener("mouseleave",r),n.addEventListener("blur",r),n.addEventListener("click",()=>{t.ready.then(o=>{o==null||o.highlight(a),o==null||o.focusOn(a,t.view)}),t.box.scrollIntoView({block:"nearest",behavior:"smooth"})})}}function tZ(i,e){let t=0;const n=document.createElement("div");n.className="visubot-quiz-question";const a=document.createElement("p");a.className="visubot-quiz-feedback",a.setAttribute("aria-live","polite");const s=()=>{n.innerHTML=Tn(`**${t+1}/${i.length}** ${i[t].question}`)},r=og([],void 0,!1,l=>{if(!(t>=i.length)){if(r.ready.then(u=>u==null?void 0:u.highlight(l)),l!==i[t].part){a.className="visubot-quiz-feedback wrong",a.textContent=p("web_visubot_quiz_wrong_fmt",l0(l));return}t++,a.className="visubot-quiz-feedback right",t{u.forEach(v=>{window.clearTimeout(v),window.clearInterval(v)}),u=[]},c=()=>{a.textContent=`${p("web_game_round_fmt",o+1,r)} · ${p("web_game_score_fmt",l)}`},d=()=>{const v=$("button",{class:"primary"},o+1{o++,o{const v=i.rounds[o],w=i.seconds,I=$("div",{class:"learn-bomb-fuse"},$("span",{})),z=$("span",{class:"learn-bomb-time"}),k=$("div",{class:"learn-bomb","aria-live":"polite"},$("span",{class:"learn-bomb-icon","aria-hidden":"true"},"💣"),z,I),T=$("div",{class:"learn-game-feedback",role:"status"}),j=v.code.split(` + `;const e=a=>this.element.querySelector(a);this.buttons={play:e("[data-sim=play]"),pause:e("[data-sim=pause]"),step:e("[data-sim=step]"),stop:e("[data-sim=stop]")},this.buttons.play.addEventListener("click",()=>this.play()),this.buttons.pause.addEventListener("click",()=>this.pause()),this.buttons.step.addEventListener("click",()=>this.step()),this.buttons.stop.addEventListener("click",()=>this.reset()),this.editButton=e(".sim-edit"),this.editButton.addEventListener("click",()=>this.onEdit());const t=e("[data-sim=highlight]");t.value=this.highlightMode,t.addEventListener("change",()=>{this.highlightMode=t.value,Ku(Xu,this.highlightMode)});const n=e("[data-sim=delay]");n.value=this.delay,n.addEventListener("change",()=>{this.delay=n.value,Ku(Ir,this.delay)}),this.inputSection=e(".sim-input > div"),this.trace=e(".sim-trace"),this.variables=e(".sim-vars"),this.output=e(".sim-output"),this.notice=e(".sim-notice")}collectOutput(){const e=this.engine.state.outputLines;for(;this.printedr.localeCompare(o));if(n.length===0)this.variables.innerHTML=`

    ${Me(p("simulation_variables_placeholder"))}

    `;else{const r=document.createElement("table");for(const o of n){const l=r.insertRow();l.insertCell().textContent=o;const u=e.variables.get(o),m=l.insertCell();u.kind==="grid"?m.append(sg(u)):m.textContent=_e(u)}this.variables.replaceChildren(r)}e.outputLines.length===0&&e.files.size===0?this.output.innerHTML=`

    ${Me(p("simulation_output_placeholder"))}

    `:(this.output.replaceChildren(...e.outputLines.map(r=>{const o=document.createElement("div");return o.textContent=r,o}),...ag(e.files)),this.output.scrollTop=this.output.scrollHeight)}updateInput(){const e=this.engine.state.inputRequest,t=this.inputSection;if(t.parentElement.classList.toggle("active",!!e),!e){t.innerHTML=`

    ${Me(p("simulation_input_placeholder"))}

    `;return}let n=t.querySelector("form");if(!n){n=document.createElement("form"),n.innerHTML=`

    `;const l=n.querySelector("input");n.addEventListener("submit",u=>{u.preventDefault(),this.submitInput(l)}),t.replaceChildren(n),requestAnimationFrame(()=>l.focus())}const a=this.engine.state.outputLines;n.querySelector(".sim-prompt").textContent=e.prompt||(a[a.length-1]??"");const s=n.querySelector("input");s.inputMode=e.valueType==="string"||e.valueType==="boolean"?"text":"decimal";const r=this.engine.state.inputErrorNotice,o=n.querySelector(".sim-input-error");o.textContent=r?t1(r):"",o.hidden=!r}}function sg(i){const e=document.createElement("table");e.className="sim-grid";for(const t of i.value){const n=e.insertRow();for(const a of t){const s=n.insertCell();s.textContent=String(a),a===!0&&(s.className="sim-grid-true")}}return e}const x1=Array.from("ABCDEFGHIJKLMNOPQRSTUVWXYZ"),Gn=360/x1.length,UM="http://www.w3.org/2000/svg";function Fe(i,e={},...t){const n=document.createElement(i);for(const[a,s]of Object.entries(e))n.setAttribute(a,s);return n.append(...t),n}function xt(i,e={},t){const n=document.createElementNS(UM,i);for(const[a,s]of Object.entries(e))n.setAttribute(a,String(s));return t!==void 0&&(n.textContent=t),n}function $M(i,e){const t=(e%26+26)%26;return Array.from(i).map(n=>{const a=n.charCodeAt(0);return a>=65&&a<=90?String.fromCharCode((a-65+t)%26+65):a>=97&&a<=122?String.fromCharCode((a-97+t)%26+97):n}).join("")}function em(i,e){const t=xt("g",{class:e}),n=x1.map((a,s)=>{const r=xt("g",{transform:`rotate(${s*Gn})`});return r.append(xt("text",{x:0,y:-i,"text-anchor":"middle","dominant-baseline":"central"},a)),t.append(r),r});return{group:t,cells:n}}function YM(i,e){let t=i,n=!1,a=-t*Gn;const s=Fe("section",{class:"learn-game learn-caesar"});s.append(Fe("div",{class:"learn-game-head"},Fe("strong",{},p("web_learn_caesar_title")))),s.append(Fe("p",{class:"learn-game-status"},p("web_learn_caesar_hint")));const r=xt("svg",{viewBox:"-200 -200 400 400",class:"learn-caesar-disc",role:"img"});r.append(xt("circle",{r:196,class:"outer-disc"})),r.append(xt("path",{d:XM(196,92,Gn/2),class:"window"}));const o=em(168,"outer-letters");r.append(o.group);for(let A=0;A{o.cells.forEach((B,E)=>B.classList.toggle("marked",E===A)),u.cells.forEach((B,E)=>B.classList.toggle("marked",A!==void 0&&E===(A+t)%26))},T=()=>{m.textContent=String(t),l.setAttribute("transform",`rotate(${a})`),r.setAttribute("aria-label",p("web_learn_caesar_key_fmt",t)),x.textContent=p(n?"web_learn_caesar_secret":"web_learn_caesar_plain"),w.textContent=p(n?"web_learn_caesar_plain":"web_learn_caesar_secret"),f.classList.toggle("active",!n),b.classList.toggle("active",n),I.textContent=$M(v.value,n?-t:t)||" ";const A=Array.from(v.value.toUpperCase()).reverse().find(E=>x1.includes(E));if(A===void 0)return k();const B=x1.indexOf(A);k(n?(B-t+26)%26:B)},j=A=>{t=(A%26+26)%26,a=-t*Gn,T()};c.addEventListener("click",()=>j(t-1)),d.addEventListener("click",()=>j(t+1)),f.addEventListener("click",()=>{var A;n&&(v.value=((A=I.textContent)==null?void 0:A.trim())??""),n=!1,T()}),b.addEventListener("click",()=>{var A;n||(v.value=((A=I.textContent)==null?void 0:A.trim())??""),n=!0,T()}),v.addEventListener("input",T),o.cells.forEach((A,B)=>A.addEventListener("click",()=>k(B)));let D;const O=A=>{const B=r.getBoundingClientRect();return Math.atan2(A.clientY-(B.top+B.height/2),A.clientX-(B.left+B.width/2))*180/Math.PI};l.addEventListener("pointerdown",A=>{const B=A;D=O(B)-a,l.classList.add("dragging"),r.setPointerCapture(B.pointerId),B.preventDefault()}),r.addEventListener("pointermove",A=>{if(D===void 0)return;a=O(A)-D,l.setAttribute("transform",`rotate(${a})`);const B=Math.round(-a/Gn);if((B%26+26)%26!==t){t=(B%26+26)%26;const E=a;T(),a=E,l.setAttribute("transform",`rotate(${a})`)}});const C=()=>{D!==void 0&&(D=void 0,l.classList.remove("dragging"),j(t))};return r.addEventListener("pointerup",C),r.addEventListener("pointercancel",C),T(),s}function XM(i,e,t){const n=(a,s)=>{const r=(s-90)*Math.PI/180;return`${(a*Math.cos(r)).toFixed(2)} ${(a*Math.sin(r)).toFixed(2)}`};return`M ${n(i,-t)} A ${i} ${i} 0 0 1 ${n(i,t)} L ${n(e,t)} A ${e} ${e} 0 0 0 ${n(e,-t)} Z`}const l0=i=>p(`web_visubot_part_${i}`),rg=new WeakMap;function og(i,e,t,n){const a=document.createElement("div");a.className="visubot-model";const s=document.createElement("div");s.className="visubot-stage";const r=document.createElement("div");r.className="visubot-part-label",r.hidden=!0,s.append(r);const o=(c,d,h)=>{r.hidden=!1,r.textContent=l0(c),r.style.left=`${Math.min(d+12,s.clientWidth-140)}px`,r.style.top=`${h+12}px`},l=document.createElement("p");l.className="visubot-model-hint hint",l.textContent=p("web_visubot_tap_part"),l.hidden=!!n,a.append(s,l);const u=K(async()=>{const{Robot3D:c}=await import("./robot3d-SvNK2bGm.js");return{Robot3D:c}},[],import.meta.url).then(({Robot3D:c})=>{const d=new c(s);d.showcase(),d.highlight(i),i.includes("leds")&&d.setLed([40,90,255]),d.focusOn([],e==="unten"||e==="bottom"?"":e,!1,1),d.focusOn(i,e,t);let h;return s.addEventListener("pointerdown",g=>h={x:g.clientX,y:g.clientY}),s.addEventListener("pointerup",g=>{if(!h||Math.hypot(g.clientX-h.x,g.clientY-h.y)>5)return;const f=d.partAt(g.clientX,g.clientY);if(!f)return;if(n)return n(f);d.highlight(f);const b=s.getBoundingClientRect();o(f,g.clientX-b.left,g.clientY-b.top)}),s.addEventListener("pointermove",g=>{if(g.pointerType!=="mouse"||n)return;const f=d.partAt(g.clientX,g.clientY);if(r.hidden=!f,!f)return;const b=s.getBoundingClientRect();o(f,g.clientX-b.left,g.clientY-b.top)}),s.addEventListener("pointerleave",()=>r.hidden=!0),d}).catch(c=>{console.error(c),s.textContent=p("web_visubot_no_3d")}),m={box:a,ready:u,focus:i,view:e};return rg.set(a,m),m}function KM(i,e,t=!1){return og(i,e,t).box}function eZ(i){const e=i.querySelector(".visubot-model"),t=e&&rg.get(e);for(const n of i.querySelectorAll("[data-robot-part]")){const a=(n.dataset.robotPart??"").split(",").filter(Boolean);if(n.title=a.map(l0).join(", "),!t)continue;const s=()=>void t.ready.then(o=>o==null?void 0:o.highlight(a)),r=()=>void t.ready.then(o=>o==null?void 0:o.highlight(t.focus));n.addEventListener("mouseenter",s),n.addEventListener("focus",s),n.addEventListener("mouseleave",r),n.addEventListener("blur",r),n.addEventListener("click",()=>{t.ready.then(o=>{o==null||o.highlight(a),o==null||o.focusOn(a,t.view)}),t.box.scrollIntoView({block:"nearest",behavior:"smooth"})})}}function tZ(i,e){let t=0;const n=document.createElement("div");n.className="visubot-quiz-question";const a=document.createElement("p");a.className="visubot-quiz-feedback",a.setAttribute("aria-live","polite");const s=()=>{n.innerHTML=Tn(`**${t+1}/${i.length}** ${i[t].question}`)},r=og([],void 0,!1,l=>{if(!(t>=i.length)){if(r.ready.then(u=>u==null?void 0:u.highlight(l)),l!==i[t].part){a.className="visubot-quiz-feedback wrong",a.textContent=p("web_visubot_quiz_wrong_fmt",l0(l));return}t++,a.className="visubot-quiz-feedback right",t{u.forEach(v=>{window.clearTimeout(v),window.clearInterval(v)}),u=[]},c=()=>{a.textContent=`${p("web_game_round_fmt",o+1,r)} · ${p("web_game_score_fmt",l)}`},d=()=>{const v=$("button",{class:"primary"},o+1{o++,o{const v=i.rounds[o],w=i.seconds,I=$("div",{class:"learn-bomb-fuse"},$("span",{})),z=$("span",{class:"learn-bomb-time"}),k=$("div",{class:"learn-bomb","aria-live":"polite"},$("span",{class:"learn-bomb-icon","aria-hidden":"true"},"💣"),z,I),T=$("div",{class:"learn-game-feedback",role:"status"}),j=v.code.split(` `).map((E,U)=>{const ee=$("button",{class:"ln",type:"button"},E||" ");return ee.disabled=!E.trim(),ee.addEventListener("click",()=>A(U+1===v.wrongLine?"right":"wrong",ee)),ee}),D=$("div",{class:"learn-game-code learn-bomb-code mono",dir:"ltr"},...j),O=Date.now(),C=()=>{if(!t.isConnected&&Date.now()-O>1e3)return m();const E=Math.max(0,w-(Date.now()-O)/1e3);z.textContent=p("web_game_time_fmt",Math.ceil(E)),I.firstChild.style.width=`${E/w*100}%`,k.classList.toggle("hurry",E<=5),E<=0&&A("time")},A=(E,U)=>{m(),j.forEach((Ie,fe)=>{Ie.disabled=!0,fe+1===v.wrongLine&&Ie.classList.add("right")}),U&&E==="wrong"&&U.classList.add("wrong");const ee=E==="right";ee&&l++,c(),k.classList.add(ee?"defused":"boom"),k.firstChild.textContent=ee?"✂️":"💥",T.className=`learn-game-feedback ${ee?"right":"wrong"}`;const he=d();T.replaceChildren($("p",{},p(ee?"web_game_defused":E==="time"?"web_game_boom_time":"web_game_boom_wrong")),Fn("div",{class:"learn-game-explain"},v.explanation),$("p",{class:"learn-bomb-fix"},`${p("web_game_fix")} `,$("code",{},v.fix.trim())),he),he.focus({preventScroll:!0})};s.replaceChildren(k,Fn("p",{class:"learn-game-question"},v.question),D,T),C();const B=window.setInterval(C,200);u.push(B)},g=()=>{const v=i.rounds[o],w=[];v.code.trim()&&w.push(nm(v.code).element),w.push(Fn("p",{class:"learn-game-question"},v.question),$("p",{class:"learn-order-hint"},p("web_game_order_hint")));const I=$("div",{class:"learn-game-options learn-order"}),z=$("div",{class:"learn-game-feedback",role:"status"});let k=0;const T=iZ(v.options.length).map(D=>{const O=$("span",{class:"learn-order-badge","aria-hidden":"true"}),C=$("span",{});C.innerHTML=Ce(v.options[D].text);const A=$("button",{},O,C);return A.addEventListener("click",()=>{if(D!==k)return A.classList.add("wrong"),j(!1);A.classList.add("right"),O.textContent=String(++k),A.disabled=!0,k===v.options.length&&j(!0)}),I.append(A),{k:D,b:A,badge:O}}),j=D=>{for(const{k:C,b:A,badge:B}of[...T].sort((E,U)=>E.k-U.k))A.disabled=!0,B.textContent=String(C+1),I.append(A);D&&l++,c(),z.className=`learn-game-feedback ${D?"right":"wrong"}`;const O=d();z.replaceChildren($("p",{},p(D?"web_game_right":"web_game_wrong_short")),Fn("div",{class:"learn-game-explain"},v.explanation),O),O.focus({preventScroll:!0})};s.replaceChildren(...w,I,z)},f=()=>{if(m(),i.kind==="bombe"||i.kind==="reihenfolge"){c(),i.kind==="bombe"?h():g();return}const v=i.rounds[o];c();const w=nm(v.code),I=[];let z;i.kind==="zuhoerer"?(z=aZ(Gh(v.code),w),I.push($("div",{class:"learn-swing-row"},w.element,z.element)),v.clicks.length&&I.push($("p",{class:"learn-swing-clicks"},`${p("web_game_clicks")} `,...v.clicks.flatMap((O,C)=>[...C?[" → "]:[],$("code",{},O)])))):v.code.trim()&&I.push(w.element),I.push(Fn("p",{class:"learn-game-question"},v.question));const k=$("div",{class:`learn-game-options ${i.kind==="layout"?"pictures":""}`}),T=$("div",{class:"learn-game-feedback",role:"status"}),j=v.options.map(O=>{const C=$("button",{});return i.kind==="layout"?C.append(rZ(O.text)):O.text.includes(` `)?C.append(sZ(O.text)):C.innerHTML=Ce(O.text),C.addEventListener("click",()=>D(O.right,C)),k.append(C),C}),D=(O,C)=>{j.forEach((B,E)=>{B.disabled=!0,v.options[E].right&&B.classList.add("right")}),O||C.classList.add("wrong"),O&&l++,c(),T.className=`learn-game-feedback ${O?"right":"wrong"}`;const A=d();T.replaceChildren($("p",{},p(O?"web_game_right":"web_game_wrong_short")),Fn("div",{class:"learn-game-explain"},v.explanation)),T.append(A),z&&(u=z.replay(v.clicks,()=>A.before($("p",{class:"learn-swing-try"},p("web_game_try"))))),A.focus({preventScroll:!0})};s.replaceChildren(...I,k,T)},b=()=>{m(),a.textContent="";const v=$("button",{class:"primary"},p("web_game_again"));v.addEventListener("click",()=>{o=l=0,f()}),s.replaceChildren($("p",{class:"learn-game-result"},p("web_game_done_fmt",l,r)),$("p",{},p(l===r?"web_game_perfect":l>=r*.7?"web_game_good":"web_game_practice_short")),v)},x=$("button",{class:"primary"},p("web_game_start"));return x.addEventListener("click",f),s.append(Fn("p",{},i.intro),x),t}function iZ(i){const e=[...Array(i).keys()];for(;e.every((t,n)=>t===n);)for(let t=i-1;t>0;t--){const n=Math.floor(Math.random()*(t+1));[e[t],e[n]]=[e[n],e[t]]}return e}function nm(i){const e=i.split(` `).map(n=>$("div",{class:"ln"},n||" "));return{element:$("pre",{class:"learn-game-code mono",dir:"ltr"},...e),highlight(n,a){e.forEach((s,r)=>s.classList.toggle("hit",n!==void 0&&r>=n&&r<=(a??n)))}}}function aZ(i,e){const t=Hh(i),n=$("div",{class:"learn-swing-window",dir:"ltr"});n.append($("div",{class:"learn-swing-title"},i.title||" "));const a=$("div",{class:"learn-swing-body"}),s=new Map;for(const c of i.labels){const d=$("div",{class:"learn-swing-label"},t.texts[c.name]);s.set(c.name,d),a.append(d)}const r=i.buttons.map(c=>{const d=$("button",{class:"learn-swing-button",disabled:""},t.texts[c.name]);return s.set(c.name,d),a.append(d),d}),o=$("p",{class:"learn-swing-event",role:"status"}),l=$("pre",{class:"learn-swing-console mono",hidden:""});n.append(a,o,l);const u=c=>{var h,g;const d=s.get(c.button);d.classList.add("pressed"),window.setTimeout(()=>d.classList.remove("pressed"),350),e.highlight((h=c.listener)==null?void 0:h.from,(g=c.listener)==null?void 0:g.to),o.textContent=c.listener?p("web_game_event_fmt",d.textContent??""):p("web_game_nobody"),o.className=`learn-swing-event ${c.listener?"heard":"nobody"}`;for(const[f,b]of Object.entries(c.texts)){const x=s.get(f);x&&x.textContent!==b&&(x.textContent=b,x.classList.remove("changed"),x.offsetWidth,x.classList.add("changed"))}c.console.length&&(l.hidden=!1,l.textContent+=c.console.map(f=>`${f} @@ -64299,7 +64299,7 @@ ${l}`)}Na=aM(((o=e.find(([l])=>l==="begriffe.md"))==null?void 0:o[1])??"")}const ${a}`));this.body.append(s),this.foldReference(s)}}foldReference(e){const t="visustruct.reference.open";let n=[];try{n=JSON.parse(localStorage.getItem(t)??"[]")}catch{}for(const a of[...e.querySelectorAll("h2")]){const s=a.textContent??"",r=_("details",{class:"reference-group"});r.open=n.includes(s);const o=_("summary",{},s);for(a.replaceWith(r),r.append(o);r.nextSibling&&r.nextSibling.nodeName!=="H2";)r.append(r.nextSibling);r.addEventListener("toggle",()=>{n=r.open?[...new Set([...n,s])]:n.filter(l=>l!==s);try{localStorage.setItem(t,JSON.stringify(n))}catch{}})}}showReference(){this.tab="reference",this.persist(),this.render()}persist(){be.setView({tab:this.tab,lesson:this.lessonId,task:this.taskId})}openLesson(e){this.tab="lessons",this.lessonId=e,this.returnTo=void 0,this.persist(),this.render(),this.body.scrollTop=0}renderLessonList(){this.body.append(_("p",{class:"hint"},p("web_learn_intro")));for(const e of IZ()){this.body.append(_("h3",{class:"learn-section"},e.name));const t=_("ol",{class:"learn-list"});for(const n of e.lessons){const a=be.lesson(n.id),s=a.done?"✓":a.step>0?p("web_learn_step_of_fmt",a.step+1,n.steps.length):"",r=_("button",{class:"learn-item"+(a.done?" done":""),"data-lesson":n.id},_("span",{class:"learn-num"},String(n.number)),_("span",{class:"learn-item-text"},_("strong",{},n.robot?`🤖 ${n.title}`:n.title),_("small",{},n.summary)),_("span",{class:"learn-status"},s));r.addEventListener("click",()=>this.openLesson(n.id)),t.append(_("li",{},r))}this.body.append(t)}this.body.append(this.renderTeacherBox())}renderLesson(e){var u;const t=be.lesson(e.id),n=Math.min(t.step,e.steps.length-1),a=e.steps[n],s=_("button",{class:"learn-back"},`← ${p("web_learn_all_lessons")}`);s.addEventListener("click",()=>this.openLesson(void 0));const r=_("nav",{class:"learn-progress","aria-label":p("web_learn_step_of_fmt",n+1,e.steps.length)});r.append(...e.steps.map((m,c)=>{const d=p("web_learn_step_fmt",c+1,m.title),h=cthis.goToStep(e,c)),g})),this.body.append(_("div",{class:"learn-lesson-head"},_("div",{class:"learn-head-row"},s,this.stepNav(e,n,t.done,"learn-nav learn-nav-top")),_("p",{class:"learn-kicker"},`${p("web_learn_lesson_fmt",e.number)} · ${e.section}${e.robot?" · 🤖 VisuBot":""}`),_("h2",{class:"learn-title"},_("span",{class:"learn-num","aria-hidden":"true"},String(e.number)),e.title),r,_("h3",{class:"learn-step-title"},`${n+1}. ${a.title}`)));const o=((u=this.returnTo)==null?void 0:u.lesson)===e.id&&this.returnTo.step!==n?this.returnTo:void 0,l=()=>{const m=_("button",{class:"learn-return"},`↩ ${p("web_learn_back_to_checklist")}`);return m.addEventListener("click",()=>{this.returnTo=void 0,this.goToStep(e,o.step),this.body.scrollTop=o.scroll}),m};o&&this.body.append(l()),a.blocks.forEach((m,c)=>this.body.append(this.renderBlock(m,`${n}-${c}`,e))),lm(this.body),eZ(this.body),this.openNeededColumns(a.blocks),rm(this.body,Na),this.body.append(this.stepNav(e,n,t.done,"learn-nav")),o&&this.body.append(l())}stepNav(e,t,n,a){const s=_("div",{class:a}),r=_("button",{},`← ${p("web_learn_back")}`);if(r.disabled=t===0,r.addEventListener("click",()=>this.goToStep(e,t-1)),s.append(r),tthis.goToStep(e,t+1)),s.append(o)}else{const o=_("button",{class:"primary"},n?`✓ ${p("web_learn_done")}`:p("web_learn_finish"));o.addEventListener("click",()=>{be.updateLesson(e.id,{done:!0});const l=Ct.find(u=>u.number===e.number+1);this.openLesson(l==null?void 0:l.id)}),s.append(o)}return s}goToStep(e,t){be.updateLesson(e.id,{step:t}),this.render(),this.body.scrollTop=0}openNeededColumns(e){const t=e.flatMap(n=>n.kind==="exercise"?[n.exercise]:[]);yZ(this.body)?(this.host.showEditor(),xZ(this.body)&&this.host.reveal(["palette"])):vZ(this.body)?this.host.showFiles():t.some(n=>n.code!=="java")?this.host.showEditor():(t.length>0||this.body.querySelector(".lesson-code[data-lang=java]"))&&this.host.showJava(),wZ(this.body)&&this.host.showLiveCode()}renderTaskList(){this.body.append(_("p",{class:"hint"},p("web_learn_tasks_intro")));const e=_("ul",{class:"learn-list"});for(const t of An){const n=this.taskExercises(t),a=n.length>0&&n.every(o=>be.exercise(o.id).done),s=Ct.find(o=>o.number===t.after),r=_("button",{class:"learn-item"+(a?" done":""),"data-task":t.id},_("span",{class:"learn-num","aria-label":p("web_learn_level_fmt",t.level)},"★".repeat(t.level)),_("span",{class:"learn-item-text"},_("strong",{},t.title),_("small",{},s?p("web_learn_after_fmt",s.number,s.title):"")),_("span",{class:"learn-status"},a?"✓":""));r.addEventListener("click",()=>{this.taskId=t.id,this.persist(),this.render(),this.body.scrollTop=0}),e.append(_("li",{},r))}this.body.append(e,this.renderTeacherBox())}renderTeacherBox(){const e=_("details",{class:"learn-teacher"},_("summary",{},p("web_learn_teacher")));if($u()){e.setAttribute("open","");const s=_("button",{},p("web_learn_teacher_off"));return s.addEventListener("click",()=>{VM(),this.render()}),e.append(_("p",{},p("web_learn_teacher_on")),s),e}const t=_("input",{type:"password",autocomplete:"off","aria-label":p("web_learn_teacher_code"),placeholder:p("web_learn_teacher_code")}),n=_("p",{class:"learn-result",role:"status"}),a=_("form",{class:"group"},t,_("button",{type:"submit"},p("web_learn_teacher_unlock")));return a.addEventListener("submit",async s=>{s.preventDefault(),await HM(t.value)?this.render():(n.className="learn-result info",n.textContent=p("web_learn_teacher_wrong"))}),e.append(_("p",{class:"hint"},p("web_learn_teacher_intro")),a,n),e}taskExercises(e){return e.blocks.flatMap(t=>t.kind==="exercise"?[t.exercise]:[])}renderTask(e){const t=_("button",{class:"learn-back"},`← ${p("web_learn_all_tasks")}`);t.addEventListener("click",()=>{this.taskId=void 0,this.persist(),this.render()});const n=Ct.find(a=>a.number===e.after);if(this.body.append(t,_("h2",{class:"learn-title"},e.title)),n){const a=_("button",{class:"link-button"},p("web_learn_after_fmt",n.number,n.title));a.addEventListener("click",()=>this.openLesson(n.id)),this.body.append(_("p",{class:"learn-kicker"},a))}e.blocks.forEach((a,s)=>this.body.append(this.renderBlock(a,`task-${s}`))),lm(this.body),this.openNeededColumns(e.blocks),rm(this.body,Na)}renderBlock(e,t,n){switch(e.kind){case"markdown":return this.withOpenButtons(tt("div",{class:"learn-text"},Tn(e.text)));case"diagram":return this.renderDiagram(e.file,e.caption);case"exercise":return this.renderExercise(e.exercise);case"competences":return this.renderCompetences(e.items);case"checklist":return this.renderChecklist(e.items,t,n);case"quiz":return this.renderQuiz(e.questions,t,n);case"brag":return this.renderBrag(e.text,e.tip);case"images":return this.renderImages(e.files,e.caption);case"graphic":return this.renderGraphic(e.file,e.caption,e.labeled);case"game":return this.renderGame(e.game);case"roundGame":return nZ(e.game,ra);case"rescueGame":return oZ(e.game,ra);case"caesar":return YM(e.key,e.text);case"cloze":return uZ(e.cloze);case"pap":return pZ(e.pap);case"textFile":return ig(e.name,e.content);case"robotModel":return KM(e.focus,e.view,e.spin);case"robotQuiz":return tZ(e.tasks,e.done)}}renderBrag(e,t=!1){const n=_("aside",{class:"learn-brag"});n.append(_("img",{src:ra,alt:"",width:"48",height:"48"}));const a=_("div",{},_("p",{class:"learn-brag-title"},p(t?"web_learn_ludwig_tip":"web_learn_brag")));return a.append(tt("div",{class:"learn-text"},Tn(e))),n.append(a),n}renderGame(e){const n=_("section",{class:"learn-game"}),a=_("div",{class:"learn-game-head"});a.append(_("img",{src:ra,alt:"",width:"40",height:"40"}),_("strong",{},p("web_game_title")));const s=_("p",{class:"learn-game-status"}),r=_("div",{class:"learn-game-stage"});n.append(a,s,r);let o=0,l=0;const u=()=>{const d=cx(e,o,10);s.textContent=`${p("web_game_round_fmt",o+1,10)} · ${p("web_game_score_fmt",l)}`;const h=_("div",{class:"learn-game-values mono"});for(const[w,I]of dx(d))h.append(_("code",{},`${w} = ${I}`));const g=_("div",{class:"group learn-game-answers"}),f=_("button",{class:"learn-game-true"},`✓ ${p("web_game_true")}`),b=_("button",{class:"learn-game-false"},`✗ ${p("web_game_false")}`);g.append(f,b);const x=_("div",{class:"learn-game-feedback",role:"status"}),v=w=>{f.disabled=b.disabled=!0;const I=w===d.answer;I&&l++,s.textContent=`${p("web_game_round_fmt",o+1,10)} · ${p("web_game_score_fmt",l)}`,x.className=`learn-game-feedback ${I?"right":"wrong"}`;const z=_("div",{class:"learn-game-steps mono"});ux(d.condition,d.values).forEach((T,j)=>z.append(_("div",{},`${j?"→ ":""}${T}`)));const k=_("button",{class:"primary"},o+1<10?p("web_game_next"):p("web_game_finish"));k.addEventListener("click",()=>{o++,o<10?u():m()}),x.replaceChildren(_("p",{},p(I?"web_game_right":"web_game_wrong")),z,k),k.focus()};f.addEventListener("click",()=>v(!0)),b.addEventListener("click",()=>v(!1)),r.replaceChildren(h,_("div",{class:"learn-game-condition mono"},d.condition),g,x)},m=()=>{s.textContent="";const d=_("button",{class:"primary"},p("web_game_again"));d.addEventListener("click",()=>{o=l=0,u()}),r.replaceChildren(_("p",{class:"learn-game-result"},p("web_game_done_fmt",l,10)),_("p",{},p(l===10?"web_game_perfect":l>=10*.7?"web_game_good":"web_game_practice")),d)},c=_("button",{class:"primary"},p("web_game_start"));return c.addEventListener("click",u),r.append(_("p",{},p("web_game_intro")),c),n}renderImages(e,t){const n=_("figure",{class:"learn-figure"}),a=_("div",{class:"learn-images"});for(const s of e){const r=zr(s);r&&a.append(_("img",{src:r,alt:"",loading:"lazy"}))}return n.append(a),t&&n.append(tt("figcaption",{},Ce(t))),n}renderGraphic(e,t,n){const a=_("figure",{class:"learn-figure"}),s=zr(e),r=n?zr(n):void 0;if(s&&r){const o=_("img",{class:"learn-graphic",src:s,alt:"",loading:"lazy"}),l=_("button",{class:"learn-graphic-toggle",type:"button",title:p("web_learn_graphic_labels"),"aria-pressed":"false"},o);l.addEventListener("click",()=>{const u=l.getAttribute("aria-pressed")!=="true";l.setAttribute("aria-pressed",String(u)),o.src=u?r:s}),a.append(l,_("p",{class:"learn-graphic-hint"},p("web_learn_graphic_labels")))}else s&&a.append(_("img",{class:"learn-graphic",src:s,alt:"",loading:"lazy"}));return t&&a.append(tt("figcaption",{},Ce(t))),a}withOpenButtons(e){for(const t of e.querySelectorAll("pre.lesson-code[data-open=editor]")){const n=t.textContent??"",a=_("button",{class:"learn-open-code"},p("web_learn_open_in_editor"));a.addEventListener("click",()=>this.host.openJavaCode(n)),t.after(a)}return e}renderDiagram(e,t){const n=ti(e),a=_("figure",{class:"learn-figure"});if(!n)return a;const s=this.host.preview(n);s&&a.append(_("div",{class:"learn-preview",dir:"ltr"},s)),t&&a.append(tt("figcaption",{},Ce(t)));const r=_("button",{},p("web_learn_open_in_editor"));return r.addEventListener("click",()=>this.host.openDiagram(n,e)),a.append(r),a}renderExercise(e){const t=_("section",{class:"learn-exercise","data-exercise":e.id}),n=()=>be.exercise(e.id),a=_("span",{class:"learn-badge"},`✓ ${p("web_learn_solved")}`);a.hidden=!n().done;const s=e.code==="java"?p("web_learn_solve_in_code",p("web_live_title")):p("web_learn_solve_in_editor",p("web_editor_title"));t.append(_("h4",{},`${p("web_learn_exercise")}: ${e.title}`,a),_("p",{class:"learn-where"},s),tt("div",{class:"learn-text"},Tn(e.task)));const r=_("div",{class:"learn-result",role:"status"}),o=_("div",{class:"learn-hints"}),l=_("div",{class:"group"}),u=_("button",{class:"primary"},p("web_learn_open_exercise"));u.addEventListener("click",()=>{const d=n().xml;let h=um(e);if(d)try{h=Nl(d)}catch{}this.host.openExercise(e,h)});const m=_("button",{},p("web_learn_check"));if(m.addEventListener("click",()=>{const d=this.host.exerciseDocument(e.id);if(!d){r.className="learn-result info",r.textContent=p("web_learn_open_first");return}if(d.elements.every(Bl)){r.className="learn-result info",r.textContent=p("web_learn_empty");return}this.host.stopSimulation();const h=ax(d,e.tests,this.host.subprogramsFor(e.id),Ja),g=sx(d),f=e.requires.map(v=>v==="forZaehlSchleife"?"forSchleife":v).filter(v=>v in S&&!g.has(S[v])),b=e.loopDepth!==void 0&&Do(d.elements)v.passed)&&f.length===0&&!b;this.showResult(r,h,f,x,b),x&&(be.updateExercise(e.id,{done:!0}),a.hidden=!1)}),l.append(u,m),e.hints.length>0){const d=_("button",{},p("web_learn_hint"));d.addEventListener("click",()=>{const h=o.children.length;if(h>=e.hints.length)return;const g=e.hints.length>1?`**${p("web_learn_hint_fmt",h+1,e.hints.length)}:** `:"";o.append(tt("aside",{class:"lesson-note"},Tn(g+e.hints[h]))),d.textContent=p("web_learn_hint_more"),d.toggleAttribute("disabled",h+1>=e.hints.length)}),l.append(d)}const c=_("button",{class:"danger-text"},p("web_learn_reset"));if(c.addEventListener("click",()=>{if(c.dataset.confirm!=="1"){c.dataset.confirm="1",c.textContent=p("web_learn_reset_confirm"),setTimeout(()=>{c.dataset.confirm="",c.textContent=p("web_learn_reset")},4e3);return}be.resetExercise(e.id),this.host.resetExercise(e.id,um(e)),a.hidden=!0,r.replaceChildren(),r.className="learn-result",c.dataset.confirm="",c.textContent=p("web_learn_reset")}),l.append(c),t.append(l,o,r),$u()&&e.solution){const d=ti(e.solution);if(d){const h=_("details",{class:"learn-solution"},_("summary",{},p("web_learn_solution")));h.addEventListener("toggle",()=>{if(!h.open||h.querySelector(".learn-preview"))return;const g=this.host.preview(d);g&&h.append(_("div",{class:"learn-preview",dir:"ltr"},g));const f=_("button",{},p("web_learn_open_in_editor"));f.addEventListener("click",()=>{this.host.openDiagram(d,e.solution);for(const b of e.subprograms){const x=ti(b);x&&this.host.openDiagram(x,b)}});for(const b of e.subprograms){const x=ti(b),v=x&&this.host.preview(x);v&&h.append(_("div",{class:"learn-preview",dir:"ltr"},v))}h.append(f)}),t.append(h)}}return t}showResult(e,t,n,a,s){var o,l,u,m,c;e.className="learn-result "+(a?"ok":"fail"),e.replaceChildren(_("p",{class:"learn-result-head"},a?`🎉 ${p("web_learn_passed")}`:p("web_learn_failed")));for(const d of n)e.append(_("p",{},`✗ ${p("web_learn_missing_fmt",kZ(S[d]))}`));s&&e.append(_("p",{},`✗ ${p("web_visubot_depth_fmt",s)}`));const r=_("ul",{class:"learn-tests",dir:"auto"});for(const d of t){const h=d.test.world?t.filter(x=>x.test.world).indexOf(d)+1:0,g=d.test.world?`🗺 ${p("web_visubot_world_fmt",h)}`:d.test.actions?`🤖 ${p("web_visubot_actions")}`:d.test.sensors?`🎛 ${Object.entries(d.test.sensors).map(([x,v])=>`mbot.${x}() = ${v.join(" → ")}`).join(", ")}`:d.test.drive?`🤖 ${p("web_visubot_drive")}`:d.test.inputs.length?p("web_learn_input_fmt",d.test.inputs.join(", ")):p("web_learn_no_input"),f=[`${d.passed?"✓":"✗"} ${g}`],b=_("div",{class:"learn-test-detail"});if(d.test.drive&&b.append(_("span",{},`${p("web_learn_expected")}: `,_("code",{},X1(d.test.drive)||"–")),_("span",{},`${p("web_learn_actual")}: `,_("code",{},X1(d.result.drive??[])||"–"))),d.test.actions&&b.append(_("span",{},`${p("web_learn_expected")}: `,_("code",{},X1(d.test.actions)||"–")),_("span",{},`${p("web_learn_actual")}: `,_("code",{},X1(d.result.actions??[])||"–"))),d.test.led!==void 0){const x=v=>p(v?"web_visubot_led_on":"web_visubot_led_off");b.append(_("span",{},`💡 ${p("web_learn_expected")}: ${x(d.test.led)} · ${p("web_learn_actual")}: ${x(d.result.led)}`))}if(d.test.tone!==void 0){const x=v=>p(v?"web_visubot_tone_yes":"web_visubot_tone_no");b.append(_("span",{},`🔊 ${p("web_learn_expected")}: ${x(d.test.tone)} · ${p("web_learn_actual")}: ${x(d.result.tone)}`))}d.test.screen!==void 0&&b.append(_("span",{},`📺 ${p("web_learn_expected")}: `,_("code",{},d.test.screen),` · ${p("web_learn_actual")}: `,_("code",{},d.result.screen??"–"))),d.test.world&&(((l=(o=Ja(d.test.world))==null?void 0:o.goals)!=null&&l.length||(m=(u=Ja(d.test.world))==null?void 0:u.targets)!=null&&m.length)&&b.append(_("span",{},d.result.atGoal?`✓ ${p("web_visubot_goal_reached")}`:`✗ ${p("web_visubot_goal_missed")}`)),d.result.bumps&&b.append(_("span",{class:"learn-error"},`⚠︎ ${p("web_visubot_bumps")}: ${d.result.bumps}`))),(!d.test.drive&&!d.test.world&&!d.test.sensors&&!d.test.actions||d.result.outputs.length)&&b.append(_("span",{},`${p("web_learn_expected")}: `,_("code",{},d.test.expected.join(" | ")||"–")),_("span",{},`${p("web_learn_actual")}: `,_("code",{},d.result.outputs.join(" | ")||"–")));for(const x of d.test.files??[])b.append(_("span",{},`📄 ${x.name}, ${p("web_learn_expected")}: `,_("code",{},x.lines.join(" | ")||"–")),_("span",{},`📄 ${x.name}, ${p("web_learn_actual")}: `,_("code",{},Fh((c=d.result.files)==null?void 0:c.get(x.name)).join(" | ")||"–")));d.result.error&&b.append(_("span",{class:"learn-error"},t1(d.result.error))),d.result.missingInput&&b.append(_("span",{class:"learn-error"},p("web_learn_missing_input"))),d.result.tooManySteps&&b.append(_("span",{class:"learn-error"},p("web_learn_too_many_steps"))),!d.passed&&d.result.unusedInputs&&b.append(_("span",{class:"learn-error"},p("web_learn_unused_input"))),r.append(_("li",{class:d.passed?"ok":"fail"},...f,b))}e.append(r)}renderCompetences(e){const t=_("aside",{class:"learn-competences"},_("p",{class:"learn-competences-title"},p("web_learn_competences_intro"))),n=_("ul",{});for(const a of e)n.append(tt("li",{},Ce(a)));return t.append(n),t}renderChecklist(e,t,n){const a=[{value:"umbrella",icon:"☂️",label:p("web_learn_rating_umbrella")},{value:"cloud",icon:"⛅",label:p("web_learn_rating_cloud")},{value:"sun",icon:"☀️",label:p("web_learn_rating_sun")}],s=_("div",{class:"learn-checklist-wrap"}),r=_("p",{class:"learn-rating-legend"});for(const l of a)r.append(_("span",{},`${l.icon} ${l.label}`));const o=_("ul",{class:"learn-checklist"});return s.append(r,o),e.forEach((l,u)=>{var v;const m=`${t}-${u}`,c=n?(v=be.lesson(n.id).checks)==null?void 0:v[m]:void 0;let d=c===!0?"sun":c||void 0;const h=tt("span",{class:"learn-check-text"},Ce(l.text)),g=_("span",{class:"learn-rating",role:"group","aria-label":h.textContent??""}),f=a.map(w=>{const I=_("button",{class:"learn-rating-button",title:w.label,"aria-label":w.label},w.icon);return I.addEventListener("click",()=>{if(d=d===w.value?void 0:w.value,b(),!n)return;const z={...be.lesson(n.id).checks??{}};d?z[m]=d:delete z[m],be.updateLesson(n.id,{checks:Object.keys(z).length?z:void 0})}),I}),b=()=>{f.forEach((w,I)=>w.setAttribute("aria-pressed",String(a[I].value===d))),x.dataset.rating=d??""};g.append(...f);const x=_("li",{},h,g);if(n&&l.step!==void 0){const w=l.step,I=p("web_learn_step_fmt",w+1,n.steps[w].title),z=_("button",{class:"link-button learn-check-link",title:I,"aria-label":`${p("web_learn_review")}: ${I}`},p("web_learn_review"));z.addEventListener("click",()=>{this.returnTo={lesson:n.id,step:be.lesson(n.id).step,scroll:this.body.scrollTop},this.goToStep(n,w)}),x.append(z)}b(),o.append(x)}),s}renderQuiz(e,t,n){const a=_("div",{class:"learn-quiz"}),s=_("p",{class:"learn-score",role:"status"}),r=()=>n?be.lesson(n.id).quiz??{}:{},o=_("div",{class:"learn-review"}),l=()=>{const u=r(),m=(f,b)=>f.pairs?f.pairs.every((x,v)=>u[`${t}-${b}-${v}`]!==void 0):u[`${t}-${b}`]!==void 0,c=(f,b)=>{var x;return!!(f.pairs?f.pairs.every((v,w)=>mm(f)[u[`${t}-${b}-${w}`]]===f.pairs[w].right):(x=f.options[u[`${t}-${b}`]])!=null&&x.correct)},d=e.filter(m).length,h=e.filter(c).length,g=d===e.length;s.textContent=g?p("web_learn_score_fmt",h,e.length):"",o.replaceChildren(),g&&n&&this.fillChecklistReview(o,n,e,f=>c(e[f],f))};return e.forEach((u,m)=>{const c=`${t}-${m}`,d=_("fieldset",{},tt("legend",{},Ce(u.question))),h=tt("p",{class:"learn-explanation"},Ce(u.explanation??""));if(u.pairs){d.append(this.renderMatch(u,c,r,n,h,l),h),a.append(d);return}const g=f=>{d.querySelectorAll("button").forEach((b,x)=>{b.classList.toggle("right",f!==void 0&&u.options[x].correct),b.classList.toggle("wrong",f===x&&!u.options[x].correct),b.setAttribute("aria-pressed",String(f===x))}),h.hidden=f===void 0||!u.explanation};u.options.forEach((f,b)=>{const x=tt("button",{class:"learn-option"},Ce(f.text));x.addEventListener("click",()=>{n&&be.updateLesson(n.id,{quiz:{...r(),[c]:b}}),g(b),l()}),d.append(x)}),d.append(h),g(r()[c]),a.append(d)}),a.append(s,o),l(),a}fillChecklistReview(e,t,n,a){const s={sun:"☀️",cloud:"⛅",umbrella:"☂️"},r=be.lesson(t.id).checks??{},o=[];let l=0;t.steps.forEach((u,m)=>u.blocks.forEach((c,d)=>{c.kind==="checklist"&&c.items.forEach((h,g)=>{const f=r[`${m}-${d}-${g}`],b=f===!0?"sun":f||void 0,x=h.step===void 0?[]:n.map((k,T)=>k.step===h.step?T:-1).filter(k=>k>=0),v=x.filter(k=>!a(k));let w="";b==="sun"&&v.length?w=p("web_learn_review_overrated_fmt",v.map(k=>k+1).join(", ")):b&&b!=="sun"&&x.length&&!v.length&&(w=p("web_learn_review_underrated")),w&&l++;const I=_("li",{class:w?"learn-review-deviation":""}),z=tt("span",{class:"learn-check-text"},Ce(h.text));if(w&&z.append(_("br",{}),_("em",{},w)),I.append(z,_("span",{class:"learn-review-icon","aria-label":p(b?`web_learn_rating_${b}`:"web_learn_review_unrated")},b?s[b]:"–")),w&&b==="sun"&&h.step!==void 0){const k=h.step,T=_("button",{class:"link-button learn-check-link"},p("web_learn_review"));T.addEventListener("click",()=>{this.returnTo={lesson:t.id,step:be.lesson(t.id).step,scroll:this.body.scrollTop},this.goToStep(t,k)}),I.append(T)}o.push(I)})})),o.length&&e.append(_("p",{class:"learn-review-title"},`📋 ${p("web_learn_review_title")}`),_("p",{},p(l?"web_learn_review_hint":"web_learn_review_match")),_("ul",{class:"learn-checklist"},...o))}renderMatch(e,t,n,a,s,r){const o=e.pairs,l=mm(e),u=_("div",{class:"learn-match"});let m={};const c=()=>a?n():m,d=b=>a?be.updateLesson(a.id,{quiz:b}):m=b,h=b=>c()[`${t}-${b}`],g=o.map(b=>{const x=_("select",{class:"learn-match-select"});x.append(_("option",{value:""},"–")),l.forEach((w,I)=>x.append(_("option",{value:String(I)},w)));const v=tt("label",{class:"learn-match-left"},Ce(b.left));return v.append(x),u.append(v),x}),f=()=>{const b=o.every((x,v)=>h(v)!==void 0);g.forEach((x,v)=>{const w=h(v);x.value=w===void 0?"":String(w),x.classList.toggle("right",b&&l[w]===o[v].right),x.classList.toggle("wrong",b&&l[w]!==o[v].right)}),s.hidden=!b||!e.explanation};return g.forEach((b,x)=>b.addEventListener("change",()=>{const v={...c()};b.value===""?delete v[`${t}-${x}`]:v[`${t}-${x}`]=Number(b.value),d(v),f(),r()})),f(),u}}function mm(i){return(i.pairs??[]).map(e=>e.right).sort((e,t)=>e.localeCompare(t,"de"))}const _Z=""+new URL("visubot-CyGFOI9V.webp",import.meta.url).href,Us="visustruct.visubot";function $s(){try{return localStorage.getItem(Us)}catch{return null}}function ui(){const i=$s();return i==="1"||i==="kurs"?"on":"off"}const dg=()=>$s()==="2";function hg(){try{localStorage.setItem(Us,"2")}catch{}}const gg=()=>$s()==="3";function pg(){try{localStorage.setItem(Us,"3")}catch{}}const jZ=()=>$s()!==null;function Sr(i){try{localStorage.setItem(Us,i==="on"?"1":"0")}catch{}}const AZ=`VisuBot`,Hn=()=>ui()!=="off",cm=i=>i.replace(/[&<>"]/g,e=>({"&":"&","<":"<",">":">",'"':"""})[e]);function Lo(){const i=dg()?"object":gg()?"flow":ui(),e=(n,a)=>``,t={off:"web_visubot_world_visustruct_hint",on:"web_visubot_world_visubot_hint",object:"web_visuobject_world_hint",flow:"web_visuflow_world_hint"}[i];return`
    ${e("off","VisuStruct")}${e("on","🤖 VisuBot")}${e("object","VisuObject")}${e("flow","VisuFlow")}
    - ${cm(p(t))}`}class PZ{constructor(e=Ii){y(this,"element");y(this,"world");y(this,"view");y(this,"loading");y(this,"status");y(this,"stage");y(this,"picker");y(this,"applied",0);y(this,"sent",0);y(this,"liveStatus");y(this,"viewport");y(this,"stopListening");y(this,"realSensors");y(this,"controls",{getBrightness:50,getLoudness:0,getPitch:0,getRoll:0});y(this,"pressTimers",new Map);y(this,"check");y(this,"checking",!1);y(this,"onWorldChange");this.world=new ds(e),this.element=document.createElement("section"),this.element.className="visubot",this.element.innerHTML=`

    ${p("web_visubot_world")}

    ${p("web_visubot_world_in_preview")}

    ${CZ()}${OZ()}`,this.stage=this.element.querySelector(".visubot-stage"),this.picker=this.element.querySelector(".visubot-worlds"),this.status=this.element.querySelector(".visubot-status"),this.liveStatus=this.element.querySelector(".visubot-live"),this.viewport=this.element.querySelector(".visubot-viewport"),this.stopListening=ge.listen(()=>this.updateLive()),this.setupControls(),this.check=this.element.querySelector(".visubot-check"),this.setupCheck(),this.updateLive(),this.updateStatus()}show(){this.loading??(this.loading=K(async()=>{const{Robot3D:e}=await import("./robot3d-BNw8Z2K3.js");return{Robot3D:e}},[],import.meta.url).then(({Robot3D:e})=>{this.view=new e(this.stage),this.view.setWorld(this.world.setup),this.view.place(this.world.pose,this.world.trail),this.view.setLeds(this.world.leds)}).catch(()=>{this.stage.textContent=p("web_visubot_no_3d")}))}restoreViewport(){this.viewport.parentElement!==this.element&&this.liveStatus.after(this.viewport)}setWorlds(e){this.picker.replaceChildren(),this.picker.hidden=e.length<2,e.forEach((t,n)=>{const a=document.createElement("button");a.textContent=p("web_visubot_world_fmt",n+1),a.addEventListener("click",()=>this.useWorld(t,a)),this.picker.append(a)}),this.useWorld(e[0]??Ii,this.picker.firstElementChild)}useWorld(e,t){var n,a,s,r,o;for(const l of this.picker.children)l.classList.toggle("active",l===t);e!==this.world.setup&&(this.world=new ds(e),this.applied=0,this.sent=0,(n=this.view)==null||n.setWorld(e),(a=this.view)==null||a.place(this.world.pose,this.world.trail),(s=this.view)==null||s.setLed(void 0),(r=this.view)==null||r.setScreen(void 0),this.updateStatus(),(o=this.onWorldChange)==null||o.call(this))}reset(){var e,t,n;this.world.reset(),this.applied=0,this.sent=0,this.realSensors=void 0,(e=this.view)==null||e.place(this.world.pose,this.world.trail),(t=this.view)==null||t.setLed(void 0),(n=this.view)==null||n.setScreen(void 0),this.updateStatus()}prepare(e){e.robotSensors={...this.controls,...this.world.sensors()}}setupControls(){for(const e of this.element.querySelectorAll(".visubot-controls input[type=range]")){const t=e.parentElement.querySelector("output"),n=()=>{this.controls[e.name]=Number(e.value),t.textContent=e.value};e.addEventListener("input",n),n()}for(const e of this.element.querySelectorAll(".visubot-controls button[name]"))e.addEventListener("click",()=>{const t=e.name;this.controls[t]=!0,e.classList.add("pressed"),window.clearTimeout(this.pressTimers.get(t)),this.pressTimers.set(t,window.setTimeout(()=>{this.controls[t]=!1,e.classList.remove("pressed")},1e3))})}setupCheck(){for(const e of this.check.querySelectorAll("button[data-py]"))e.addEventListener("click",()=>{const{after:t,wait:n}=e.dataset;ge.run(e.dataset.py).then(()=>t?new Promise(a=>setTimeout(a,Number(n))).then(()=>ge.run(t)):void 0).catch(a=>this.liveFailed(a))});this.check.addEventListener("toggle",()=>void this.readCheck())}async readCheck(){if(!this.checking){this.checking=!0;try{for(;this.check.open&&ge.connected;){for(const e of this.check.querySelectorAll("[data-sensor]")){if(!this.check.open||!ge.connected)break;const t=e.dataset.sensor,n=await ge.ask(jt[t].python).catch(()=>{});n!==void 0&&(e.textContent=typeof jt[t].simulated=="boolean"?n===!0||typeof n=="number"&&n!==0?"✓":"–":String(typeof n=="number"?Math.round(n*10)/10:n))}await new Promise(e=>setTimeout(e,200))}}finally{this.checking=!1}}}get live(){return ge.connected}async prepareLive(e,t=[]){const n={};for(const a of new Set(["getDistance","getLine",...t])){const s=await ge.ask(jt[a].python);typeof jt[a].simulated=="boolean"?n[a]=s===!0||typeof s=="number"&&s!==0:typeof jt[a].simulated=="string"?n[a]=typeof s=="string"?s:String(jt[a].simulated):n[a]=typeof s=="number"?a==="getDistance"?Math.round(s):s:0}this.realSensors=n,e.robotSensors={...this.controls,...this.world.sensors(),...n}}async drive(e){for(;this.sentsetTimeout(n,t.args[0]))}}liveFailed(e){ge.disconnect(e instanceof Error?e.message:String(e))}updateLive(){this.liveStatus.textContent=bg(),this.liveStatus.classList.toggle("connected",ge.connected),this.check.hidden=!ge.connected,ge.connected||(this.check.open=!1),this.updateStatus()}follow(e,t){var a,s,r,o;for(;this.appliedl!==0);this.world.tick(s0),n&&((o=this.view)==null||o.moveTo(this.world.pose,this.world.trail,t)),this.updateStatus()}dispose(){var e;this.stopListening();for(const t of this.pressTimers.values())window.clearTimeout(t);(e=this.view)==null||e.dispose(),this.view=void 0,this.loading=void 0}updateStatus(){const e=this.world.lineState().toString(2).padStart(4,"0"),t=[`${p("web_visubot_distance")}: ${this.world.distance()} cm`,`${p("web_visubot_line")}: ${e}`];this.world.bumps>0&&t.push(`⚠︎ ${p("web_visubot_bumps")}: ${this.world.bumps}`),this.world.screen!==void 0&&t.push(`📺 ${this.world.screen}`),this.realSensors&&ge.connected&&t.push(`🤖 ${p("web_visubot_distance")}: ${this.realSensors.getDistance} cm · ${p("web_visubot_line")}: ${Number(this.realSensors.getLine).toString(2).padStart(4,"0")}`),this.status.textContent=t.join(" · ")}}let H1;function fg(i,e){try{H1??(H1=new AudioContext);const t=H1.createOscillator(),n=H1.createGain();t.type="square",t.frequency.value=Math.max(20,Math.min(2e4,i)),n.gain.value=.05,t.connect(n).connect(H1.destination);const a=H1.currentTime+Math.min(Math.max(e,0),5e3)/1e3;t.start(),t.stop(a)}catch{}}function CZ(){const i=(t,n,a,s,r)=>``,e=(t,n,a)=>``;return`
    🎛 ${p("web_visubot_controls")} + ${cm(p(t))}`}class PZ{constructor(e=Ii){y(this,"element");y(this,"world");y(this,"view");y(this,"loading");y(this,"status");y(this,"stage");y(this,"picker");y(this,"applied",0);y(this,"sent",0);y(this,"liveStatus");y(this,"viewport");y(this,"stopListening");y(this,"realSensors");y(this,"controls",{getBrightness:50,getLoudness:0,getPitch:0,getRoll:0});y(this,"pressTimers",new Map);y(this,"check");y(this,"checking",!1);y(this,"onWorldChange");this.world=new ds(e),this.element=document.createElement("section"),this.element.className="visubot",this.element.innerHTML=`

    ${p("web_visubot_world")}

    ${p("web_visubot_world_in_preview")}

    ${CZ()}${OZ()}`,this.stage=this.element.querySelector(".visubot-stage"),this.picker=this.element.querySelector(".visubot-worlds"),this.status=this.element.querySelector(".visubot-status"),this.liveStatus=this.element.querySelector(".visubot-live"),this.viewport=this.element.querySelector(".visubot-viewport"),this.stopListening=ge.listen(()=>this.updateLive()),this.setupControls(),this.check=this.element.querySelector(".visubot-check"),this.setupCheck(),this.updateLive(),this.updateStatus()}show(){this.loading??(this.loading=K(async()=>{const{Robot3D:e}=await import("./robot3d-SvNK2bGm.js");return{Robot3D:e}},[],import.meta.url).then(({Robot3D:e})=>{this.view=new e(this.stage),this.view.setWorld(this.world.setup),this.view.place(this.world.pose,this.world.trail),this.view.setLeds(this.world.leds)}).catch(()=>{this.stage.textContent=p("web_visubot_no_3d")}))}restoreViewport(){this.viewport.parentElement!==this.element&&this.liveStatus.after(this.viewport)}setWorlds(e){this.picker.replaceChildren(),this.picker.hidden=e.length<2,e.forEach((t,n)=>{const a=document.createElement("button");a.textContent=p("web_visubot_world_fmt",n+1),a.addEventListener("click",()=>this.useWorld(t,a)),this.picker.append(a)}),this.useWorld(e[0]??Ii,this.picker.firstElementChild)}useWorld(e,t){var n,a,s,r,o;for(const l of this.picker.children)l.classList.toggle("active",l===t);e!==this.world.setup&&(this.world=new ds(e),this.applied=0,this.sent=0,(n=this.view)==null||n.setWorld(e),(a=this.view)==null||a.place(this.world.pose,this.world.trail),(s=this.view)==null||s.setLed(void 0),(r=this.view)==null||r.setScreen(void 0),this.updateStatus(),(o=this.onWorldChange)==null||o.call(this))}reset(){var e,t,n;this.world.reset(),this.applied=0,this.sent=0,this.realSensors=void 0,(e=this.view)==null||e.place(this.world.pose,this.world.trail),(t=this.view)==null||t.setLed(void 0),(n=this.view)==null||n.setScreen(void 0),this.updateStatus()}prepare(e){e.robotSensors={...this.controls,...this.world.sensors()}}setupControls(){for(const e of this.element.querySelectorAll(".visubot-controls input[type=range]")){const t=e.parentElement.querySelector("output"),n=()=>{this.controls[e.name]=Number(e.value),t.textContent=e.value};e.addEventListener("input",n),n()}for(const e of this.element.querySelectorAll(".visubot-controls button[name]"))e.addEventListener("click",()=>{const t=e.name;this.controls[t]=!0,e.classList.add("pressed"),window.clearTimeout(this.pressTimers.get(t)),this.pressTimers.set(t,window.setTimeout(()=>{this.controls[t]=!1,e.classList.remove("pressed")},1e3))})}setupCheck(){for(const e of this.check.querySelectorAll("button[data-py]"))e.addEventListener("click",()=>{const{after:t,wait:n}=e.dataset;ge.run(e.dataset.py).then(()=>t?new Promise(a=>setTimeout(a,Number(n))).then(()=>ge.run(t)):void 0).catch(a=>this.liveFailed(a))});this.check.addEventListener("toggle",()=>void this.readCheck())}async readCheck(){if(!this.checking){this.checking=!0;try{for(;this.check.open&&ge.connected;){for(const e of this.check.querySelectorAll("[data-sensor]")){if(!this.check.open||!ge.connected)break;const t=e.dataset.sensor,n=await ge.ask(jt[t].python).catch(()=>{});n!==void 0&&(e.textContent=typeof jt[t].simulated=="boolean"?n===!0||typeof n=="number"&&n!==0?"✓":"–":String(typeof n=="number"?Math.round(n*10)/10:n))}await new Promise(e=>setTimeout(e,200))}}finally{this.checking=!1}}}get live(){return ge.connected}async prepareLive(e,t=[]){const n={};for(const a of new Set(["getDistance","getLine",...t])){const s=await ge.ask(jt[a].python);typeof jt[a].simulated=="boolean"?n[a]=s===!0||typeof s=="number"&&s!==0:typeof jt[a].simulated=="string"?n[a]=typeof s=="string"?s:String(jt[a].simulated):n[a]=typeof s=="number"?a==="getDistance"?Math.round(s):s:0}this.realSensors=n,e.robotSensors={...this.controls,...this.world.sensors(),...n}}async drive(e){for(;this.sentsetTimeout(n,t.args[0]))}}liveFailed(e){ge.disconnect(e instanceof Error?e.message:String(e))}updateLive(){this.liveStatus.textContent=bg(),this.liveStatus.classList.toggle("connected",ge.connected),this.check.hidden=!ge.connected,ge.connected||(this.check.open=!1),this.updateStatus()}follow(e,t){var a,s,r,o;for(;this.appliedl!==0);this.world.tick(s0),n&&((o=this.view)==null||o.moveTo(this.world.pose,this.world.trail,t)),this.updateStatus()}dispose(){var e;this.stopListening();for(const t of this.pressTimers.values())window.clearTimeout(t);(e=this.view)==null||e.dispose(),this.view=void 0,this.loading=void 0}updateStatus(){const e=this.world.lineState().toString(2).padStart(4,"0"),t=[`${p("web_visubot_distance")}: ${this.world.distance()} cm`,`${p("web_visubot_line")}: ${e}`];this.world.bumps>0&&t.push(`⚠︎ ${p("web_visubot_bumps")}: ${this.world.bumps}`),this.world.screen!==void 0&&t.push(`📺 ${this.world.screen}`),this.realSensors&&ge.connected&&t.push(`🤖 ${p("web_visubot_distance")}: ${this.realSensors.getDistance} cm · ${p("web_visubot_line")}: ${Number(this.realSensors.getLine).toString(2).padStart(4,"0")}`),this.status.textContent=t.join(" · ")}}let H1;function fg(i,e){try{H1??(H1=new AudioContext);const t=H1.createOscillator(),n=H1.createGain();t.type="square",t.frequency.value=Math.max(20,Math.min(2e4,i)),n.gain.value=.05,t.connect(n).connect(H1.destination);const a=H1.currentTime+Math.min(Math.max(e,0),5e3)/1e3;t.start(),t.stop(a)}catch{}}function CZ(){const i=(t,n,a,s,r)=>``,e=(t,n,a)=>``;return`
    🎛 ${p("web_visubot_controls")}

    ${p("web_visubot_controls_hint")}

    ${i("getBrightness","web_visubot_sensor_brightness",0,100,50)} ${i("getLoudness","web_visubot_sensor_loudness",0,100,0)} @@ -64528,7 +64528,7 @@ ${i}

    ${yn(p("web_visubot_preview_hint"))}

    -

    `;const e=t=>this.element.querySelector(t);this.heightBar=e(".robotpreview-height"),this.stage=e(".robotpreview-stage"),this.status=e(".robotpreview-status"),this.picker=e(".visubot-worlds"),this.playButton=e(".robotpreview-play"),this.stackButton=e(".robotpreview-stack"),this.playButton.addEventListener("click",()=>this.playTimer===void 0?this.play():this.stopPlaying(!0)),this.stackButton.addEventListener("click",()=>this.onToggleStacked()),e(".learn-hide").addEventListener("click",()=>this.onHide()),this.rail=document.createElement("button"),this.rail.className="learn-rail robotpreview-rail",this.setStacked(!1),this.relabel()}hostSimulation(e){var t;e!==this.simulation&&((t=this.simulation)==null||t.remove(),this.simulation=e,this.element.classList.toggle("simulation",!!e),e&&(this.pause(),this.status.after(e)),this.relabel())}relabel(){const e=a=>this.element.querySelector(a),t=!!this.simulation;e("h2").textContent=`🤖 ${p(t?"web_visubot_preview_sim_title":"web_visubot_preview_title")}`,e(".hint").textContent=p(t?"web_visubot_preview_sim_hint":"web_visubot_preview_hint"),this.heightBar.title=p("web_visubot_preview_resize");const n=e(".learn-hide");n.title=p("web_visubot_preview_hide"),n.setAttribute("aria-label",p("web_visubot_preview_hide")),this.rail.title=p("web_visubot_preview_show"),this.rail.innerHTML=`${_t}🤖 ${yn(p("web_visubot_preview_title"))}`,this.setStacked(this.stackButton.textContent==="▥"),this.stopPlaying(!1),this.worldsKey=void 0,this.lastKey=void 0}setStacked(e){const t=e?"web_visubot_preview_side":"web_visubot_preview_stack";this.stackButton.innerHTML=e?"▥":"⬓",this.stackButton.className="icon robotpreview-stack",this.stackButton.dataset.tip=p(t),this.stackButton.setAttribute("aria-label",p(t))}show(){this.loading??(this.loading=K(async()=>{const{Robot3D:e}=await import("./robot3d-BNw8Z2K3.js");return{Robot3D:e}},[],import.meta.url).then(({Robot3D:e})=>{var t;this.view=new e(this.stage),this.view.setWorld(this.setup),this.showFrame((t=this.result)==null?void 0:t.frames.at(-1))}).catch(()=>{this.stage.textContent=p("web_visubot_no_3d")}))}update(e,t,n,a,s){if(this.simulation)return;this.show(),a!==this.worldsKey&&(this.worldsKey=a,this.setWorlds(n)),this.input={doc:e,resolve:t};const r=JSON.stringify(s)+` +

    `;const e=t=>this.element.querySelector(t);this.heightBar=e(".robotpreview-height"),this.stage=e(".robotpreview-stage"),this.status=e(".robotpreview-status"),this.picker=e(".visubot-worlds"),this.playButton=e(".robotpreview-play"),this.stackButton=e(".robotpreview-stack"),this.playButton.addEventListener("click",()=>this.playTimer===void 0?this.play():this.stopPlaying(!0)),this.stackButton.addEventListener("click",()=>this.onToggleStacked()),e(".learn-hide").addEventListener("click",()=>this.onHide()),this.rail=document.createElement("button"),this.rail.className="learn-rail robotpreview-rail",this.setStacked(!1),this.relabel()}hostSimulation(e){var t;e!==this.simulation&&((t=this.simulation)==null||t.remove(),this.simulation=e,this.element.classList.toggle("simulation",!!e),e&&(this.pause(),this.status.after(e)),this.relabel())}relabel(){const e=a=>this.element.querySelector(a),t=!!this.simulation;e("h2").textContent=`🤖 ${p(t?"web_visubot_preview_sim_title":"web_visubot_preview_title")}`,e(".hint").textContent=p(t?"web_visubot_preview_sim_hint":"web_visubot_preview_hint"),this.heightBar.title=p("web_visubot_preview_resize");const n=e(".learn-hide");n.title=p("web_visubot_preview_hide"),n.setAttribute("aria-label",p("web_visubot_preview_hide")),this.rail.title=p("web_visubot_preview_show"),this.rail.innerHTML=`${_t}🤖 ${yn(p("web_visubot_preview_title"))}`,this.setStacked(this.stackButton.textContent==="▥"),this.stopPlaying(!1),this.worldsKey=void 0,this.lastKey=void 0}setStacked(e){const t=e?"web_visubot_preview_side":"web_visubot_preview_stack";this.stackButton.innerHTML=e?"▥":"⬓",this.stackButton.className="icon robotpreview-stack",this.stackButton.dataset.tip=p(t),this.stackButton.setAttribute("aria-label",p(t))}show(){this.loading??(this.loading=K(async()=>{const{Robot3D:e}=await import("./robot3d-SvNK2bGm.js");return{Robot3D:e}},[],import.meta.url).then(({Robot3D:e})=>{var t;this.view=new e(this.stage),this.view.setWorld(this.setup),this.showFrame((t=this.result)==null?void 0:t.frames.at(-1))}).catch(()=>{this.stage.textContent=p("web_visubot_no_3d")}))}update(e,t,n,a,s){if(this.simulation)return;this.show(),a!==this.worldsKey&&(this.worldsKey=a,this.setWorlds(n)),this.input={doc:e,resolve:t};const r=JSON.stringify(s)+` `+JSON.stringify(e);r!==this.lastKey&&(this.lastKey=r,window.clearTimeout(this.pending),this.pending=window.setTimeout(()=>this.recompute(),120))}setWorlds(e){this.worlds=e,this.picker.replaceChildren(),this.picker.hidden=e.length<2,e.forEach((t,n)=>{const a=document.createElement("button");a.textContent=p("web_visubot_world_fmt",n+1),a.addEventListener("click",()=>this.useWorld(t)),this.picker.append(a)}),this.useWorld(e[0]??Ii)}useWorld(e){var t;this.worlds.forEach((n,a)=>{var s;return(s=this.picker.children[a])==null?void 0:s.classList.toggle("active",n===e)}),!(e===this.setup&&this.result)&&(this.setup=e,(t=this.view)==null||t.setWorld(e),this.recompute())}recompute(){var e;if(this.pending=void 0,this.stopPlaying(!1),!!this.input){try{this.result=qF(this.input.doc,this.input.resolve,this.setup)}catch{this.result=void 0}this.showFrame((e=this.result)==null?void 0:e.frames.at(-1)),this.updateStatus()}}showFrame(e,t=0){if(!this.view)return;const n=e??{pose:{...this.setup.start},trail:[{x:this.setup.start.x,y:this.setup.start.y}],leds:Array(5).fill(void 0),screen:void 0};t>0?this.view.moveTo(n.pose,n.trail,t):this.view.place(n.pose,n.trail),this.view.setLeds(n.leds),this.view.setScreen(n.screen)}play(){var a;const e=(a=this.result)==null?void 0:a.frames;if(!e||e.length<2||!this.view)return;this.stopPlaying(!1);let t=0;this.showFrame(e[0]),this.playButton.innerHTML=se.stop,this.playButton.dataset.tip=p("web_visubot_preview_stop"),this.playButton.setAttribute("aria-label",p("web_visubot_preview_stop"));const n=()=>{if(t++,t>=e.length){this.stopPlaying(!1);return}const s=e[t];s.tone&&fg(s.tone[0],s.tone[1]),this.showFrame(s,io-30),this.playTimer=window.setTimeout(n,io)};this.playTimer=window.setTimeout(n,io)}stopPlaying(e){var t;this.playTimer!==void 0&&window.clearTimeout(this.playTimer),this.playTimer=void 0,this.playButton.innerHTML=se.play,this.playButton.dataset.tip=p("web_visubot_preview_play"),this.playButton.setAttribute("aria-label",p("web_visubot_preview_play")),e&&this.showFrame((t=this.result)==null?void 0:t.frames.at(-1))}updateStatus(){const e=this.result;if(this.playButton.disabled=!e||e.frames.length<2,!e){this.status.textContent="";return}const t=[p("web_visubot_preview_distance_fmt",e.distance)];e.bumps>0&&t.push(`⚠︎ ${p("web_visubot_bumps")}: ${e.bumps}`),e.stop==="input"?t.push(p("web_visubot_preview_input")):e.stop==="limit"?t.push(p("web_visubot_preview_limit")):e.stop==="error"&&e.notice&&t.push(`⚠︎ ${t1(e.notice)}`),this.status.textContent=t.join(" · ")}pause(){window.clearTimeout(this.pending),this.pending=void 0,this.lastKey=void 0,this.stopPlaying(!1)}}const $F={left:12,top:10},YF=8,Es=8e3,xi=16,ao=12,i2="#fafafa";function a2(i){const e=i.caption.trim();return e===""?p("diagram_title_placeholder"):e}function od(i){let e=i.trim().replace(/\.visustruct$/i,"");if(e==="")return"";for(e=e.replace(/\s/g,"-").replace(/[/:\\*?"<>|]/g,"-");e.includes("--");)e=e.replace(/--/g,"-");return e=e.replace(/^-+|-+$/g,""),e.length>120&&(e=e.slice(0,120).replace(/^-+|-+$/g,"")),e}function ld(i,e){return od(i.caption)||od(e)||"VisuStruct"}function XF(i,e,t){const n=i.split(/\s+/),a=[];let s="";for(const r of n){const o=s?`${s} ${r}`:r;s&&t(o,xi,"bold")>e?(a.push(s),s=r):s=o}if(s&&a.push(s),a.length>2){let r=a.slice(1).join(" ");for(;r.length>1&&t(r+"…",xi,"bold")>e;)r=r.slice(0,-1);return[a[0],r+"…"]}return a}function ud(i,e,t,n=320){const a={...i,elements:i.elements.map(Xa)},s=new Vd(e,t).layout(a,$F),r=Math.min(Es,Math.max(n,s.canvasSize.width)),o=Math.min(Es,Math.max(n,s.canvasSize.height));if(r<=2||o<=2)return;const l=XF(a2(i),r-2*ao,t),u=Math.ceil(xi*1.2),m=Math.min(56,l.length*u+2),c=m+o,d=new $d(e,t).render(s,{width:r,height:o},void 0,YF);d.setAttribute("y",String(m)),d.removeAttribute("class");const h=Se("svg",{xmlns:"http://www.w3.org/2000/svg",width:r,height:c,viewBox:`0 0 ${r} ${c}`});h.append(Se("rect",{x:0,y:0,width:r,height:c,fill:i2}));const g=Se("text",{x:ao,y:0,"font-family":Ns,"font-size":xi,"font-weight":600,fill:"black"});return l.forEach((f,b)=>{const x=Se("tspan",{x:ao,y:b*u+xi});x.textContent=f,g.append(x)}),h.append(g,d),{svg:h,width:r,height:c}}function s2(i){return` `+new XMLSerializer().serializeToString(i.svg)}async function md(i,e){const t=Math.max(1,Math.min(e,Es/i.width,Es/i.height)),n=URL.createObjectURL(new Blob([s2(i)],{type:"image/svg+xml"}));try{const a=new Image;a.src=n,await a.decode();const s=document.createElement("canvas");s.width=Math.round(i.width*t),s.height=Math.round(i.height*t);const r=s.getContext("2d");return r.fillStyle=i2,r.fillRect(0,0,s.width,s.height),r.drawImage(a,0,0,s.width,s.height),s}finally{URL.revokeObjectURL(n)}}function KF(i){return new Promise((e,t)=>i.toBlob(n=>n?e(n):t(new Error("PNG konnte nicht erzeugt werden.")),"image/png"))}function eR(i,e){const a=Math.max(1,i),s=Math.max(1,e),r=f=>{const b=f.width-64,x=f.height-64;return{s:Math.min(b/a,x/s)*.98,cw:b,ch:x}},o={width:595,height:842},l={width:842,height:595},u=r(o),m=r(l),[c,d]=m.s>u.s?[l,m]:[o,u],h=a*d.s,g=s*d.s;return{page:c,draw:{x:32+(d.cw-h)/2,y:32+(d.ch-g)/2,width:h,height:g}}}async function tR(i){const e=new Blob([i]).stream().pipeThrough(new CompressionStream("deflate"));return new Uint8Array(await new Response(e).arrayBuffer())}function cd(i){let e="FEFF";for(let t=0;t`}async function nR(i,e,t,n,a){const{page:s,draw:r}=eR(n.width,n.height),o=await tR(i),l=x=>(Math.round(x*100)/100).toString(),u=`q ${l(r.width)} 0 0 ${l(r.height)} ${l(r.x)} ${l(s.height-r.y-r.height)} cm /Im0 Do Q`,m=new TextEncoder,c=[["<< /Type /Catalog /Pages 2 0 R >>"],["<< /Type /Pages /Kids [3 0 R] /Count 1 >>"],[`<< /Type /Page /Parent 2 0 R /MediaBox [0 0 ${s.width} ${s.height}] /Resources << /XObject << /Im0 4 0 R >> >> /Contents 5 0 R >>`],[`<< /Type /XObject /Subtype /Image /Width ${e} /Height ${t} /ColorSpace /DeviceRGB /BitsPerComponent 8 /Filter /FlateDecode /Length ${o.length} >> stream @@ -64836,4 +64836,4 @@ ${c}

    ${W(p("close_unsaved_title"))}

    ${W(p("web_discard_message_fmt",this.fileName))}

    - `,t.addEventListener("click",n=>{const a=n.target.dataset.r;a===void 0&&n.target!==t||(t.remove(),e(a==="1"))}),document.body.append(t),t.querySelector('[data-r="0"]').focus()}):Promise.resolve(!0)}showMessage(e){this.statusLine.textContent=e,this.statusLine.classList.add("message"),setTimeout(()=>{this.statusLine.classList.remove("message"),this.updateStatus()},6e3)}loadXML(e,t,n){let a;try{a=Nl(e)}catch(s){this.showMessage(p("web_err_unreadable_fmt",t,s.message));return}(this.dirty||this.tab.fileName||this.tab.exerciseId)&&this.addTab(),this.doc=a,this.tab.fileName=t.replace(/\.(strk|xml)$/i,".visustruct"),this.fileHandle=n&&/\.visustruct$/i.test(t)?n:void 0,this.resetHistory()}async open(e){const t=window;if(!t.showOpenFilePicker||this.inViewer)return e.click();try{const[n]=await t.showOpenFilePicker({types:pd()}),a=await n.getFile();this.loadXML(await a.text(),a.name,n)}catch{}}async save(){var n,a;if(!this.downloads&&await this.saveToWorkspace())return;const e=new Blob([u1(this.doc)],{type:"application/xml"}),t=window;try{if(this.downloads){const s=this.fileName+".txt";await this.downloads.save({filename:s,data:e}),(n=this.tab).fileName??(n.fileName=this.fileName),this.dirty=!1,this.render(),this.showMessage(p("web_saved_txt_fmt",s));return}if(!this.fileHandle&&t.showSaveFilePicker&&!this.inViewer&&(this.fileHandle=await t.showSaveFilePicker({suggestedName:this.fileName,types:pd()}),this.tab.fileName=this.fileHandle.name),this.fileHandle){const s=await this.fileHandle.createWritable();await s.write(e),await s.close()}else{const s=document.createElement("a");s.href=URL.createObjectURL(e),s.download=this.fileName,s.click(),setTimeout(()=>URL.revokeObjectURL(s.href),1e3)}(a=this.tab).fileName??(a.fileName=this.fileName),this.dirty=!1,this.render()}catch{}}async exportDiagram(e){if(e==="visustruct"){const s=ld(this.doc,un(this.tab));return this.offerDownload(`${s}.visustruct`,new Blob([u1(this.doc)],{type:"application/xml"}))}const t=ud(this.doc,this.metrics,this.measure);if(!t){this.showMessage(p(e==="print"?"err_diagram_too_small_print":"err_diagram_too_small_export"));return}const n=ld(this.doc,un(this.tab)),a=Math.max(2,window.devicePixelRatio||1)*this.zoom;try{switch(e){case"svg":{t.svg.setAttribute("width",String(t.width*this.zoom)),t.svg.setAttribute("height",String(t.height*this.zoom)),await this.offerDownload(`${n}.svg`,new Blob([s2(t)],{type:"image/svg+xml"}));break}case"png":{const s=await md(t,a);await this.offerDownload(`${n}.png`,await KF(s));break}case"pdf":{const s=await md(t,Math.max(a,3)),r=await nR(iR(s),s.width,s.height,t,a2(this.doc));await this.offerDownload(`${n}.pdf`,r);break}case"print":this.printDiagram(t);break}}catch(s){this.showMessage(p("web_export_failed_fmt",s instanceof Error?s.message:String(s)))}}printDiagram(e){const t=document.createElement("div");t.className="print-sheet",e.svg.removeAttribute("width"),e.svg.removeAttribute("height"),t.append(e.svg),document.body.append(t);const n=()=>t.remove();window.addEventListener("afterprint",n,{once:!0});try{window.print()}catch{n(),this.showMessage(`${p("err_print_unavailable")} ${p("web_print_hint")}`);return}setTimeout(n,6e4)}async offerDownload(e,t){try{if(this.downloads){try{await this.downloads.save({filename:e,data:t}),this.showMessage(p("web_saved_fmt",e))}catch{await this.downloads.save({filename:e+".txt",data:t}),this.showMessage(p("web_saved_txt_fmt",e+".txt"))}return}const n=document.createElement("a");n.href=URL.createObjectURL(t),n.download=e,n.click(),setTimeout(()=>URL.revokeObjectURL(n.href),1e3)}catch{this.showMessage(p("err_save_failed_fmt",e))}}setupFileDrop(){window.addEventListener("dragover",e=>{var t;(t=e.dataTransfer)!=null&&t.types.includes("Files")&&(e.preventDefault(),this.root.classList.add("file-drag"))}),window.addEventListener("dragleave",e=>{e.relatedTarget===null&&this.root.classList.remove("file-drag")}),window.addEventListener("drop",async e=>{var n;this.root.classList.remove("file-drag");const t=(n=e.dataTransfer)==null?void 0:n.files[0];t&&(e.preventDefault(),this.loadXML(await t.text(),t.name))})}onKeyDown(e){var a,s;const t=e.metaKey||e.ctrlKey,n=e.target instanceof HTMLTextAreaElement||e.target instanceof HTMLInputElement||((a=e.target)==null?void 0:a.isContentEditable)===!0;if(t&&e.key.toLowerCase()==="s")e.preventDefault(),this.save();else if(t&&e.key.toLowerCase()==="p")e.preventDefault(),this.simulating||this.exportDiagram("print");else if(t&&e.key.toLowerCase()==="o")e.preventDefault(),this.open(this.root.querySelector("input[type=file]"));else{if(n||this.simulating)return;t&&e.key.toLowerCase()==="z"?(e.preventDefault(),e.shiftKey?this.redo():this.undo()):t&&e.key.toLowerCase()==="c"&&!((s=getSelection())!=null&&s.toString())?this.copySelection()&&e.preventDefault():t&&e.key.toLowerCase()==="x"?(e.preventDefault(),this.cutSelection()):t&&e.key.toLowerCase()==="v"?(e.preventDefault(),this.paste()):t&&e.key.toLowerCase()==="y"?(e.preventDefault(),this.redo()):e.key==="Delete"||e.key==="Backspace"?(e.preventDefault(),this.deleteSelection()):e.key==="Escape"&&(this.drag?this.endDrag():(this.selected=void 0,this.render()))}}svgPoint(e,t){if(!this.svg)return;const n=this.svg.getBoundingClientRect(),a=e-n.left,s=t-n.top;if(!(a<0||s<0||a>n.width||s>n.height))return{x:a/this.zoom,y:s/this.zoom}}nodeAt(e,t){for(let n=this.flat.length-1;n>=0;n--){const a=this.flat[n].frame;if(e>=a.x&&e<=a.x+a.width&&t>=a.y&&t<=a.y+a.height)return this.flat[n]}}onCanvasPointerDown(e){if(this.simulating)return;const t=this.svgPoint(e.clientX,e.clientY);if(!t)return;document.activeElement instanceof HTMLElement&&document.activeElement.blur();const n=this.nodeAt(t.x,t.y),a=n&&this.selected&&fo(n.idPath,this.selected);this.selected=n==null?void 0:n.idPath,this.render(),n&&e.pointerType!=="touch"&&!(In(this.doc,n.idPath)&&!a)&&this.beginDrag(e,{kind:"move",path:n.idPath})}beginDrag(e,t){e.button!==0||this.simulating||(e.preventDefault(),this.drag={source:t,pointerId:e.pointerId,startX:e.clientX,startY:e.clientY,active:!1})}onPointerMove(e){const t=this.drag;if(!t||e.pointerId!==t.pointerId)return;if(!t.active){if(Math.hypot(e.clientX-t.startX,e.clientY-t.startY)<5)return;t.active=!0,t.ghost=this.makeGhost(t.source),document.body.append(t.ghost),this.root.classList.add("dragging")}t.ghost.style.transform=`translate(${e.clientX+12}px, ${e.clientY+12}px)`,this.autoScroll(e.clientX,e.clientY);const n=this.svgPoint(e.clientX,e.clientY);t.target=n?this.dropTargetAt(n.x,n.y,t.source):void 0,this.showDropTarget(t.target)}onPointerUp(e){const t=this.drag;!t||e.pointerId!==t.pointerId||(t.active&&t.target?this.applyDrop(t.source,t.target):!t.active&&t.source.kind==="palette"?this.insertNearSelection(t.source.make()):!t.active&&t.source.kind==="sensor"&&this.insertSensor(t.source.text),this.endDrag())}endDrag(){var e,t;(t=(e=this.drag)==null?void 0:e.ghost)==null||t.remove(),this.drag=void 0,this.root.classList.remove("dragging"),this.showDropTarget(void 0)}makeGhost(e){const t=document.createElement("div");if(t.className="drag-ghost",e.kind==="palette"||e.kind==="sensor")t.textContent=e.label;else{const n=Ot(this.doc,e.path);t.textContent=`${so(n.type)}: ${Zl(n)[0]}`}return t}autoScroll(e,t){const n=this.canvasHost.getBoundingClientRect(),a=40,s=12;t>n.bottom-a&&tn.top-a&&(this.canvasHost.scrollTop-=s),e>n.right-a&&en.left-a&&(this.canvasHost.scrollLeft-=s)}dropTargetAt(e,t,n){var l;const a=((l=this.layout)==null?void 0:l.elements)??[],s=this.nodeAt(e,t);if(n.kind==="sensor")return!s||In(this.doc,s.idPath)?void 0:gd.includes(Ot(this.doc,s.idPath).type)?{kind:"condition",path:s.idPath,frame:s.frame}:void 0;if(!s){const u=a[a.length-1];if(!u)return;const m=u.frame.y+u.frame.height;return t>m?n.kind==="move"&&n.path.length===1&&n.path[0]===a.length-1?void 0:{kind:"rootAppend",frame:{x:u.frame.x,y:m,width:u.frame.width,height:0}}:t=n.path.length&&n.path.every((u,m)=>r[m]===u)?void 0:In(this.doc,r)?{kind:"replace",path:r,frame:s.frame}:{kind:t"]/g,e=>({"&":"&","<":"<",">":">",'"':"""})[e])}function Zd(i){if(!i)return[];for(const e of[...Ct.flatMap(t=>t.steps.flatMap(n=>n.blocks)),...An.flatMap(t=>t.blocks)])if(!(e.kind!=="exercise"||e.exercise.id!==i))return e.exercise.tests.flatMap(t=>{const n=t.world?Ja(t.world):void 0;return n?[n]:[]});return[]}let Jt,Ol,Dl;function Bd(i){const e=i.dataset.tip;if(!e)return;Jt??(Jt=Object.assign(document.createElement("div"),{className:"tooltip",role:"tooltip"})),Jt.isConnected||document.body.append(Jt),Jt.textContent=e,Jt.hidden=!1;const t=i.getBoundingClientRect(),n=Jt.offsetWidth,a=Jt.offsetHeight,s=Math.min(Math.max(8,t.left+t.width/2-n/2),window.innerWidth-n-8),r=t.bottom+6+a{if(i.pointerType==="touch")return;const e=i.target.closest("[data-tip]");e!==Dl&&(uo(),e&&(Dl=e,Ol=window.setTimeout(()=>Bd(e),350)))}),document.addEventListener("focusin",i=>{const e=i.target.closest("[data-tip]");uo(),e!=null&&e.matches(":focus-visible")&&Bd(e)});for(const i of["pointerdown","focusout","scroll","keydown"])document.addEventListener(i,uo,!0)}const Ml="visustruct.reloadedAfterError";function u2(){try{const i=Number(sessionStorage.getItem(Ml));if(i&&Date.now()-i<3e4)return!1;sessionStorage.setItem(Ml,String(Date.now()))}catch{return!1}return location.reload(),!0}function SR(i){console.error(i);const e=(navigator.language||"").toLowerCase().startsWith("de"),t=document.createElement("div");t.className="startup-error";const n=document.createElement("h1");n.textContent=e?"VisuStruct konnte nicht starten":"VisuStruct could not start";const a=document.createElement("p");a.textContent=e?"Wahrscheinlich gibt es gerade eine neue Version. Lade die Seite neu. Hilft das nicht, drücke Strg+Umschalt+R (Mac: ⌘⇧R).":"There is probably a new version. Reload the page. If that does not help, press Ctrl+Shift+R (Mac: ⌘⇧R).";const s=document.createElement("button");s.textContent=e?"Neu laden":"Reload",s.addEventListener("click",()=>location.reload());const r=document.createElement("pre");r.textContent=String(i instanceof Error?i.message:i),t.append(n,a,s,r),(document.getElementById("app")??document.body).replaceWith(t)}window.addEventListener("vite:preloadError",i=>{u2()&&i.preventDefault()});const TR=X2();Promise.all([ah(TR,!1),ih($2(),!1)]).then(()=>{l2(),kR();const i=new URLSearchParams(location.search);i.has("visuobject")&&hg(),i.has("visuflow")&&pg();const e=document.getElementById("app"),t=!i.has("visustruct")&&!i.has("visubot");if(dg()&&t)return K(async()=>{const{ObjectApp:n}=await import("./objectApp-Caze4o4v.js").then(a=>a.g);return{ObjectApp:n}},[],import.meta.url).then(({ObjectApp:n})=>void new n(e));if(gg()&&t)return K(async()=>{const{FlowApp:n}=await import("./flowApp-Bn4c4hPI.js");return{FlowApp:n}},[],import.meta.url).then(({FlowApp:n})=>void new n(e));new wR(e)}).then(()=>{try{sessionStorage.removeItem(Ml)}catch{}}).catch(i=>{/dynamically imported module|Importing a module script failed|error loading dynamically/i.test(String(i))&&u2()||SR(i)});export{qn as C,_F as J,Qb as L,K as _,hF as a,BF as b,Yf as c,OR as d,pg as e,Sr as f,vR as g,la as h,se as i,WZ as j,LZ as k,s1 as l,CR as m,hg as n,od as o,CF as p,s2 as q,hm as r,RZ as s,p as t,md as u,KF as v,Lo as w,nR as x,iR as y}; + `,t.addEventListener("click",n=>{const a=n.target.dataset.r;a===void 0&&n.target!==t||(t.remove(),e(a==="1"))}),document.body.append(t),t.querySelector('[data-r="0"]').focus()}):Promise.resolve(!0)}showMessage(e){this.statusLine.textContent=e,this.statusLine.classList.add("message"),setTimeout(()=>{this.statusLine.classList.remove("message"),this.updateStatus()},6e3)}loadXML(e,t,n){let a;try{a=Nl(e)}catch(s){this.showMessage(p("web_err_unreadable_fmt",t,s.message));return}(this.dirty||this.tab.fileName||this.tab.exerciseId)&&this.addTab(),this.doc=a,this.tab.fileName=t.replace(/\.(strk|xml)$/i,".visustruct"),this.fileHandle=n&&/\.visustruct$/i.test(t)?n:void 0,this.resetHistory()}async open(e){const t=window;if(!t.showOpenFilePicker||this.inViewer)return e.click();try{const[n]=await t.showOpenFilePicker({types:pd()}),a=await n.getFile();this.loadXML(await a.text(),a.name,n)}catch{}}async save(){var n,a;if(!this.downloads&&await this.saveToWorkspace())return;const e=new Blob([u1(this.doc)],{type:"application/xml"}),t=window;try{if(this.downloads){const s=this.fileName+".txt";await this.downloads.save({filename:s,data:e}),(n=this.tab).fileName??(n.fileName=this.fileName),this.dirty=!1,this.render(),this.showMessage(p("web_saved_txt_fmt",s));return}if(!this.fileHandle&&t.showSaveFilePicker&&!this.inViewer&&(this.fileHandle=await t.showSaveFilePicker({suggestedName:this.fileName,types:pd()}),this.tab.fileName=this.fileHandle.name),this.fileHandle){const s=await this.fileHandle.createWritable();await s.write(e),await s.close()}else{const s=document.createElement("a");s.href=URL.createObjectURL(e),s.download=this.fileName,s.click(),setTimeout(()=>URL.revokeObjectURL(s.href),1e3)}(a=this.tab).fileName??(a.fileName=this.fileName),this.dirty=!1,this.render()}catch{}}async exportDiagram(e){if(e==="visustruct"){const s=ld(this.doc,un(this.tab));return this.offerDownload(`${s}.visustruct`,new Blob([u1(this.doc)],{type:"application/xml"}))}const t=ud(this.doc,this.metrics,this.measure);if(!t){this.showMessage(p(e==="print"?"err_diagram_too_small_print":"err_diagram_too_small_export"));return}const n=ld(this.doc,un(this.tab)),a=Math.max(2,window.devicePixelRatio||1)*this.zoom;try{switch(e){case"svg":{t.svg.setAttribute("width",String(t.width*this.zoom)),t.svg.setAttribute("height",String(t.height*this.zoom)),await this.offerDownload(`${n}.svg`,new Blob([s2(t)],{type:"image/svg+xml"}));break}case"png":{const s=await md(t,a);await this.offerDownload(`${n}.png`,await KF(s));break}case"pdf":{const s=await md(t,Math.max(a,3)),r=await nR(iR(s),s.width,s.height,t,a2(this.doc));await this.offerDownload(`${n}.pdf`,r);break}case"print":this.printDiagram(t);break}}catch(s){this.showMessage(p("web_export_failed_fmt",s instanceof Error?s.message:String(s)))}}printDiagram(e){const t=document.createElement("div");t.className="print-sheet",e.svg.removeAttribute("width"),e.svg.removeAttribute("height"),t.append(e.svg),document.body.append(t);const n=()=>t.remove();window.addEventListener("afterprint",n,{once:!0});try{window.print()}catch{n(),this.showMessage(`${p("err_print_unavailable")} ${p("web_print_hint")}`);return}setTimeout(n,6e4)}async offerDownload(e,t){try{if(this.downloads){try{await this.downloads.save({filename:e,data:t}),this.showMessage(p("web_saved_fmt",e))}catch{await this.downloads.save({filename:e+".txt",data:t}),this.showMessage(p("web_saved_txt_fmt",e+".txt"))}return}const n=document.createElement("a");n.href=URL.createObjectURL(t),n.download=e,n.click(),setTimeout(()=>URL.revokeObjectURL(n.href),1e3)}catch{this.showMessage(p("err_save_failed_fmt",e))}}setupFileDrop(){window.addEventListener("dragover",e=>{var t;(t=e.dataTransfer)!=null&&t.types.includes("Files")&&(e.preventDefault(),this.root.classList.add("file-drag"))}),window.addEventListener("dragleave",e=>{e.relatedTarget===null&&this.root.classList.remove("file-drag")}),window.addEventListener("drop",async e=>{var n;this.root.classList.remove("file-drag");const t=(n=e.dataTransfer)==null?void 0:n.files[0];t&&(e.preventDefault(),this.loadXML(await t.text(),t.name))})}onKeyDown(e){var a,s;const t=e.metaKey||e.ctrlKey,n=e.target instanceof HTMLTextAreaElement||e.target instanceof HTMLInputElement||((a=e.target)==null?void 0:a.isContentEditable)===!0;if(t&&e.key.toLowerCase()==="s")e.preventDefault(),this.save();else if(t&&e.key.toLowerCase()==="p")e.preventDefault(),this.simulating||this.exportDiagram("print");else if(t&&e.key.toLowerCase()==="o")e.preventDefault(),this.open(this.root.querySelector("input[type=file]"));else{if(n||this.simulating)return;t&&e.key.toLowerCase()==="z"?(e.preventDefault(),e.shiftKey?this.redo():this.undo()):t&&e.key.toLowerCase()==="c"&&!((s=getSelection())!=null&&s.toString())?this.copySelection()&&e.preventDefault():t&&e.key.toLowerCase()==="x"?(e.preventDefault(),this.cutSelection()):t&&e.key.toLowerCase()==="v"?(e.preventDefault(),this.paste()):t&&e.key.toLowerCase()==="y"?(e.preventDefault(),this.redo()):e.key==="Delete"||e.key==="Backspace"?(e.preventDefault(),this.deleteSelection()):e.key==="Escape"&&(this.drag?this.endDrag():(this.selected=void 0,this.render()))}}svgPoint(e,t){if(!this.svg)return;const n=this.svg.getBoundingClientRect(),a=e-n.left,s=t-n.top;if(!(a<0||s<0||a>n.width||s>n.height))return{x:a/this.zoom,y:s/this.zoom}}nodeAt(e,t){for(let n=this.flat.length-1;n>=0;n--){const a=this.flat[n].frame;if(e>=a.x&&e<=a.x+a.width&&t>=a.y&&t<=a.y+a.height)return this.flat[n]}}onCanvasPointerDown(e){if(this.simulating)return;const t=this.svgPoint(e.clientX,e.clientY);if(!t)return;document.activeElement instanceof HTMLElement&&document.activeElement.blur();const n=this.nodeAt(t.x,t.y),a=n&&this.selected&&fo(n.idPath,this.selected);this.selected=n==null?void 0:n.idPath,this.render(),n&&e.pointerType!=="touch"&&!(In(this.doc,n.idPath)&&!a)&&this.beginDrag(e,{kind:"move",path:n.idPath})}beginDrag(e,t){e.button!==0||this.simulating||(e.preventDefault(),this.drag={source:t,pointerId:e.pointerId,startX:e.clientX,startY:e.clientY,active:!1})}onPointerMove(e){const t=this.drag;if(!t||e.pointerId!==t.pointerId)return;if(!t.active){if(Math.hypot(e.clientX-t.startX,e.clientY-t.startY)<5)return;t.active=!0,t.ghost=this.makeGhost(t.source),document.body.append(t.ghost),this.root.classList.add("dragging")}t.ghost.style.transform=`translate(${e.clientX+12}px, ${e.clientY+12}px)`,this.autoScroll(e.clientX,e.clientY);const n=this.svgPoint(e.clientX,e.clientY);t.target=n?this.dropTargetAt(n.x,n.y,t.source):void 0,this.showDropTarget(t.target)}onPointerUp(e){const t=this.drag;!t||e.pointerId!==t.pointerId||(t.active&&t.target?this.applyDrop(t.source,t.target):!t.active&&t.source.kind==="palette"?this.insertNearSelection(t.source.make()):!t.active&&t.source.kind==="sensor"&&this.insertSensor(t.source.text),this.endDrag())}endDrag(){var e,t;(t=(e=this.drag)==null?void 0:e.ghost)==null||t.remove(),this.drag=void 0,this.root.classList.remove("dragging"),this.showDropTarget(void 0)}makeGhost(e){const t=document.createElement("div");if(t.className="drag-ghost",e.kind==="palette"||e.kind==="sensor")t.textContent=e.label;else{const n=Ot(this.doc,e.path);t.textContent=`${so(n.type)}: ${Zl(n)[0]}`}return t}autoScroll(e,t){const n=this.canvasHost.getBoundingClientRect(),a=40,s=12;t>n.bottom-a&&tn.top-a&&(this.canvasHost.scrollTop-=s),e>n.right-a&&en.left-a&&(this.canvasHost.scrollLeft-=s)}dropTargetAt(e,t,n){var l;const a=((l=this.layout)==null?void 0:l.elements)??[],s=this.nodeAt(e,t);if(n.kind==="sensor")return!s||In(this.doc,s.idPath)?void 0:gd.includes(Ot(this.doc,s.idPath).type)?{kind:"condition",path:s.idPath,frame:s.frame}:void 0;if(!s){const u=a[a.length-1];if(!u)return;const m=u.frame.y+u.frame.height;return t>m?n.kind==="move"&&n.path.length===1&&n.path[0]===a.length-1?void 0:{kind:"rootAppend",frame:{x:u.frame.x,y:m,width:u.frame.width,height:0}}:t=n.path.length&&n.path.every((u,m)=>r[m]===u)?void 0:In(this.doc,r)?{kind:"replace",path:r,frame:s.frame}:{kind:t"]/g,e=>({"&":"&","<":"<",">":">",'"':"""})[e])}function Zd(i){if(!i)return[];for(const e of[...Ct.flatMap(t=>t.steps.flatMap(n=>n.blocks)),...An.flatMap(t=>t.blocks)])if(!(e.kind!=="exercise"||e.exercise.id!==i))return e.exercise.tests.flatMap(t=>{const n=t.world?Ja(t.world):void 0;return n?[n]:[]});return[]}let Jt,Ol,Dl;function Bd(i){const e=i.dataset.tip;if(!e)return;Jt??(Jt=Object.assign(document.createElement("div"),{className:"tooltip",role:"tooltip"})),Jt.isConnected||document.body.append(Jt),Jt.textContent=e,Jt.hidden=!1;const t=i.getBoundingClientRect(),n=Jt.offsetWidth,a=Jt.offsetHeight,s=Math.min(Math.max(8,t.left+t.width/2-n/2),window.innerWidth-n-8),r=t.bottom+6+a{if(i.pointerType==="touch")return;const e=i.target.closest("[data-tip]");e!==Dl&&(uo(),e&&(Dl=e,Ol=window.setTimeout(()=>Bd(e),350)))}),document.addEventListener("focusin",i=>{const e=i.target.closest("[data-tip]");uo(),e!=null&&e.matches(":focus-visible")&&Bd(e)});for(const i of["pointerdown","focusout","scroll","keydown"])document.addEventListener(i,uo,!0)}const Ml="visustruct.reloadedAfterError";function u2(){try{const i=Number(sessionStorage.getItem(Ml));if(i&&Date.now()-i<3e4)return!1;sessionStorage.setItem(Ml,String(Date.now()))}catch{return!1}return location.reload(),!0}function SR(i){console.error(i);const e=(navigator.language||"").toLowerCase().startsWith("de"),t=document.createElement("div");t.className="startup-error";const n=document.createElement("h1");n.textContent=e?"VisuStruct konnte nicht starten":"VisuStruct could not start";const a=document.createElement("p");a.textContent=e?"Wahrscheinlich gibt es gerade eine neue Version. Lade die Seite neu. Hilft das nicht, drücke Strg+Umschalt+R (Mac: ⌘⇧R).":"There is probably a new version. Reload the page. If that does not help, press Ctrl+Shift+R (Mac: ⌘⇧R).";const s=document.createElement("button");s.textContent=e?"Neu laden":"Reload",s.addEventListener("click",()=>location.reload());const r=document.createElement("pre");r.textContent=String(i instanceof Error?i.message:i),t.append(n,a,s,r),(document.getElementById("app")??document.body).replaceWith(t)}window.addEventListener("vite:preloadError",i=>{u2()&&i.preventDefault()});const TR=X2();Promise.all([ah(TR,!1),ih($2(),!1)]).then(()=>{l2(),kR();const i=new URLSearchParams(location.search);i.has("visuobject")&&hg(),i.has("visuflow")&&pg();const e=document.getElementById("app"),t=!i.has("visustruct")&&!i.has("visubot");if(dg()&&t)return K(async()=>{const{ObjectApp:n}=await import("./objectApp-Thy8-AED.js").then(a=>a.g);return{ObjectApp:n}},[],import.meta.url).then(({ObjectApp:n})=>void new n(e));if(gg()&&t)return K(async()=>{const{FlowApp:n}=await import("./flowApp-B2mFVVBJ.js");return{FlowApp:n}},[],import.meta.url).then(({FlowApp:n})=>void new n(e));new wR(e)}).then(()=>{try{sessionStorage.removeItem(Ml)}catch{}}).catch(i=>{/dynamically imported module|Importing a module script failed|error loading dynamically/i.test(String(i))&&u2()||SR(i)});export{qn as C,_F as J,Qb as L,K as _,hF as a,BF as b,Yf as c,OR as d,pg as e,Sr as f,vR as g,la as h,se as i,WZ as j,LZ as k,s1 as l,CR as m,hg as n,od as o,CF as p,s2 as q,hm as r,RZ as s,p as t,md as u,KF as v,Lo as w,nR as x,iR as y}; diff --git a/website/app/assets/objectApp-Caze4o4v.js b/website/app/assets/objectApp-Thy8-AED.js similarity index 99% rename from website/app/assets/objectApp-Caze4o4v.js rename to website/app/assets/objectApp-Thy8-AED.js index 469fdf57..4b10648f 100644 --- a/website/app/assets/objectApp-Caze4o4v.js +++ b/website/app/assets/objectApp-Thy8-AED.js @@ -1,5 +1,5 @@ -const __vite__mapDeps=(i,m=__vite__mapDeps,d=(m.f||(m.f=["./projectZip-BKS-Blr6.js","./index-CzgrZgZa.js","./index-DVwLXYFw.css"])))=>i.map(i=>d[i]); -var Ns=Object.defineProperty;var Os=(a,e,t)=>e in a?Ns(a,e,{enumerable:!0,configurable:!0,writable:!0,value:t}):a[e]=t;var E=(a,e,t)=>Os(a,typeof e!="symbol"?e+"":e,t);import{t as d,i as ie,s as Ps,m as Is,g as Ds,w as Rs,J as Hs,c as Bs,a as Ws,b as Ye,p as zs,d as Vs,e as Us,f as Js,_ as wt,h as $t,j as Ks,r as _t,k as Xs,l as ct}from"./index-CzgrZgZa.js";function Ys(a){const e=[];let t=0;for(;ti.map(i=>d[i]); +var Ns=Object.defineProperty;var Os=(a,e,t)=>e in a?Ns(a,e,{enumerable:!0,configurable:!0,writable:!0,value:t}):a[e]=t;var E=(a,e,t)=>Os(a,typeof e!="symbol"?e+"":e,t);import{t as d,i as ie,s as Ps,m as Is,g as Ds,w as Rs,J as Hs,c as Bs,a as Ws,b as Ye,p as zs,d as Vs,e as Us,f as Js,_ as wt,h as $t,j as Ks,r as _t,k as Xs,l as ct}from"./index-Dntu0aWH.js";function Ys(a){const e=[];let t=0;for(;te.text===","?", ":e.text).join("")}function ms(a){const e=[[]];let t=0;for(const s of a)s.text==="<"||s.text==="("||s.text==="["||s.text==="{"?t++:(s.text===">"||s.text===")"||s.text==="]"||s.text==="}")&&t--,s.text===","&&t===0?e.push([]):e[e.length-1].push(s);return e.filter(s=>s.length>0)}function ft(a){var t,s;const e=[];for(let i=0;i{const t=ft(e).filter(i=>i.text!=="final"),s=t[t.length-1];return{name:s!=null&&s.word?s.text:"",type:lt(t.slice(0,-1))}})}function kt(a,e,t,s){var x,L;const i=ft(a),n=new Set;let o=0;for(;o"));const r=i.slice(o);if(r.length===0||a.length===0)return[];const c=a[0].from,l=r.findIndex(S=>S.text==="("),h=r.findIndex(S=>S.text==="="),u=l>0&&(h<0||lS.text==="="),y=_<0?g:g.slice(0,_);let w=y.length-1;for(;w>0&&!y[w].word;)w--;if(w<1)return[];const $=lt(y.slice(0,w)),p=m.length>1,v=[];return m.forEach((S,k)=>{var C;const j=S.findIndex(F=>F.text==="="),M=j<0?S:S.slice(0,j),A=k===0?y[w]:M.find(F=>F.word);if(!A)return;const R=M.filter(F=>F.from>A.from&&F.text==="[").length;v.push({kind:"field",name:A.text,type:$+"[]".repeat(R),params:[],visibility:xt(n,f),isStatic:n.has("static"),isAbstract:!1,from:c,to:s,headerFrom:c,headerTo:k===0?((C=M[M.length-1])==null?void 0:C.to)??A.to:A.to,shared:p,nameFrom:A.from,nameTo:A.to})}),v}function Zs(a,e,t){var n;let s=[],i=e;for(;ih.text==="="),c=ye(a,i,"{","}");if(r){s.push(...a.slice(i,c)),i=c;continue}const l=s.map(h=>h.text);l.includes("class")||l.includes("interface")||l.includes("enum")||s.length>0&&t.members.push(...kt(s,t.name,t.kind==="interface",((n=a[c-1])==null?void 0:n.to)??o.to)),s=[],i=c;continue}s.push(o),i++}return t.bodyEnd=a.length>0?a[a.length-1].to:0,i}function oe(a){var n,o,r,c;const e=Ys(a),t=[];let s=[],i=0;for(;iw.text==="class"||w.text==="interface"),f=u>=0?h[u+1]:void 0;if(!(f!=null&&f.word)){i=ye(e,i,"{","}"),s=[];continue}let m=u;for(;m>0&&(fs.has(h[m-1].text)||h[m-1].text==="@");)m--;const g={name:f.text,kind:h[u].text==="interface"?"interface":"class",isAbstract:h.slice(m,u).some(w=>w.text==="abstract"),interfaces:[],members:[],from:((n=s[s.indexOf(h[m])])==null?void 0:n.from)??h[m].from,to:0,headerFrom:((o=s[s.indexOf(h[m])])==null?void 0:o.from)??h[m].from,headerTo:h[h.length-1].to,nameFrom:f.from,nameTo:f.to,bodyEnd:0};let _=u+2;((r=h[_])==null?void 0:r.text)==="<"&&(_=ye(h,_,"<",">"));let y="";for(;_")-1:w.word&&y==="extends"&&g.kind==="class"?g.superclass??(g.superclass=w.text):w.word&&y&&g.interfaces.push(w.text)}i=Zs(e,i+1,g),g.to=((c=e[i-1])==null?void 0:c.to)??a.length,t.push(g),s=[]}return t}function Fe(a){const e=/^([\p{L}_$][\p{L}\p{N}_$]*)(\[\])+$/u.exec(a);if(e)return{name:e[1],many:!0};const t=/^(?:ArrayList|LinkedList|List|Set|HashSet|TreeSet|Collection|Queue|Deque|ArrayDeque|Stack|Vector)<([\p{L}_$][\p{L}\p{N}_$]*)>$/u.exec(a);return t?{name:t[1],many:!0}:{name:a,many:!1}}function Qs(a){const e=new Set(a.map(s=>s.name)),t=[];for(const s of a){s.superclass&&e.has(s.superclass)&&t.push({kind:"extends",from:s.name,to:s.superclass});for(const i of s.interfaces)e.has(i)&&t.push({kind:s.kind==="interface"?"extends":"implements",from:s.name,to:i});for(const i of s.members){if(i.kind!=="field")continue;const n=Fe(i.type);e.has(n.name)&&t.push({kind:"association",from:s.name,to:n.name,role:i.name,multiplicity:n.many?"0..*":"1"})}}return t}function Ge(a){const e=a.params.map(t=>`${t.name}: ${t.type}`).join(", ");return a.kind==="field"?`${a.visibility} ${a.name}: ${a.type}`:a.kind==="constructor"?`${a.visibility} ${a.name}(${e})`:`${a.visibility} ${a.name}(${e}): ${a.type}`}const ei=/^[\p{L}_$][\p{L}\p{N}_$]*$/u;function Ve(a){var c;let e=a.trim().replace(/;$/,"").trim();if(!e)return;let t;/^[+\-#~]/.test(e)&&(t=e[0],e=e.slice(1).trim());let s=!1;const i=e.split(/\s+/);for(;["static","public","private","protected"].includes(i[0]);){const l=i.shift();l==="static"?s=!0:t??(t=l==="public"?"+":l==="private"?"-":"#")}e=i.join(" ");const n=e.indexOf("(");if(n>=0){const l=e.lastIndexOf(")");if(lg.trim()).filter(Boolean).map(g=>{const _=/^([\p{L}_$][\p{L}\p{N}_$]*)\s*:\s*(.+)$/u.exec(g);if(_)return{name:_[1],type:_[2].replace(/\s+/g,"")};const y=/^(.+)\s+([\p{L}_$][\p{L}\p{N}_$]*)$/u.exec(g);return y?{name:y[2],type:y[1].replace(/\s+/g,"")}:{name:g,type:"int"}});return{kind:"method",visibility:t,name:h,type:u==null?void 0:u.replace(/\s+/g,""),params:m,isStatic:s}}const o=/^([\p{L}_$][\p{L}\p{N}_$]*)\s*(?::\s*(.+))?$/u.exec(e);if(o)return{kind:"field",visibility:t,name:o[1],type:(c=o[2])==null?void 0:c.replace(/\s+/g,""),params:[],isStatic:s};const r=/^(.+?)\s+([\p{L}_$][\p{L}\p{N}_$]*)$/u.exec(e);if(r)return{kind:"field",visibility:t,name:r[2],type:r[1].replace(/\s+/g,""),params:[],isStatic:s}}const ti={"+":"public ","-":"private ","#":"protected ","~":""};function si(a){return/^(int|long|short|byte)$/.test(a)?"0":/^(double|float)$/.test(a)?"0.0":a==="boolean"?"false":a==="char"?"' '":"null"}function bs(a,e,t){const s=e.kind==="interface",i=s?"":ti[a.visibility??(a.kind==="field"?"-":"+")],n=a.isStatic?"static ":"";if(a.kind==="field")return`${i}${n}${a.type??"int"} ${a.name}`;const o=a.params.map(r=>`${r.type} ${r.name}`).join(", ");return a.name===e.name?`${i}${a.name}(${o})`:`${i}${n}${t&&!s?"abstract ":""}${a.type??"void"} ${a.name}(${o})`}const Ue=(a,e)=>a.lastIndexOf(` `,e-1)+1;function mt(a,e,t){const s=Ue(a,e),i=a.slice(s,e);let n=t;for(;ns.path===e)&&e!==this.active&&this.openFile(e),this.editor.setMarks({placeholders:[],problems:[],current:t},!0)}showDebugState(){const e=this.dbg;if(!e)return;e.frames=e.vm.stack();const t=e.vm.heap(),s=e.frames[e.frame];s&&this.showLine(s.pos.file,s.pos.line);const i=e.values.size===0&&e.vars.size===0,n=new Set,o=new Map;for(const h of t)for(const u of h.fields){const f=`dbg${h.id}.${u.name}`;o.set(f,u.value),!i&&e.values.get(f)!==u.value&&n.add(f)}e.values=o;const r=new Set,c=new Map;e.frames.forEach((h,u)=>{for(const f of h.vars){const m=`${e.frames.length-u}|${h.title}|${f.name}`;c.set(m,f.value),!i&&e.vars.get(m)!==f.value&&r.add(`${h.title}|${f.name}`)}}),e.vars=c;const l={objects:this.liveObjects(t),changed:n,frames:e.frames,frame:e.frame,changedVars:r,onFrame:h=>{e.frame=h,l.frame=h;const u=e.frames[h];u&&this.showLine(u.pos.file,u.pos.line),this.objectDiagram.renderInspector()},move:(h,u)=>e.places.set(h,u)};this.objectDiagram.live=l,this.sequence=e.vm.sequence(),this.diagramMode==="object"&&this.objectDiagram.render(),this.diagramMode==="sequence"&&this.renderSequence()}renderSequence(){var n,o,r;const e=this.shell.querySelector(".vo-seqcanvas"),t=e.querySelector(".vo-seq"),s=e.querySelector(".vo-empty"),i=this.sequence;if(s.hidden=!!i&&i.events.length>0,s.textContent=d(i?"web_visuobject_seq_no_calls":"web_visuobject_seq_empty"),!i||!i.events.length)t.innerHTML="",t.setAttribute("width","0");else{const c=((n=this.dbg)==null?void 0:n.state)==="paused"||((o=this.dbg)==null?void 0:o.state)==="input",{svg:l,width:h,height:u}=Ti(i,c?i.events.length-1:void 0);t.innerHTML=l+(i.truncated?`${b(d("web_visuobject_seq_truncated"))}`:""),t.setAttribute("width",String(h)),t.setAttribute("height",String(u)),c&&((r=t.querySelector(".vo-seq-msg.current"))==null||r.scrollIntoView({block:"nearest",inline:"nearest"}))}this.renderSequenceInspector()}renderSequenceInspector(){if(this.objectDiagram.live)return this.objectDiagram.renderInspector();this.inspector.innerHTML=`

    ${b(d("web_visuobject_seq_hint"))}

    `}liveObjects(e){const t=this.dbg,s=this.project.objects??[],i=c=>40+c.fields.length*20,n=[],o=[],r=[];for(const c of e){const l=`dbg${c.id}`,h=t.places.get(l)??s.find(u=>u.name===c.name&&u.cls===c.cls);if(!h){r.push(c);continue}t.places.set(l,{x:h.x,y:h.y}),n.push({x:h.x,y:h.y,w:260,h:i(c)})}for(const c of r){const l=i(c);let h={x:24,y:24};e:for(let u=24;u<6e3;u+=30)for(let f=24;f<=24+3*320;f+=320)if(n.every(m=>f+260+30<=m.x||m.x+m.w+30<=f||u+l+30<=m.y||m.y+m.h+30<=u)){h={x:f,y:u};break e}t.places.set(`dbg${c.id}`,h),n.push({...h,w:260,h:l})}for(const c of e){const l=`dbg${c.id}`;o.push({id:l,name:c.name,cls:c.cls,...t.places.get(l),values:Object.fromEntries(c.fields.map(h=>[h.name,h.value]))})}return o}stopDebug(e,t=!1){const s=this.dbg;s&&clearTimeout(s.timer),this.dbg=void 0,s&&(this.sequence=s.vm.sequence()),this.objectDiagram.live=void 0,this.consolePane().input.hidden=!0,this.shell.querySelector(".vo-dbg-controls").hidden=!0,this.shell.querySelector("[data-action=stop]").disabled=!0,this.shell.querySelector("[data-action=run]").disabled=!1,t||this.editor.setMarks({placeholders:[],problems:[]},!1),e&&this.debugStatus(d(e),t),this.diagramMode==="object"&&this.objectDiagram.render(),this.diagramMode==="sequence"&&this.renderSequence()}chooseWorld(e){if(e!=="object"){if(e==="flow"){Us(),location.href=`${location.pathname}?visuflow${location.hash}`;return}Js(e),location.href=`${location.pathname}?${e==="on"?"visubot":"visustruct"}${location.hash}`}}get activeFile(){return this.project.files.find(e=>e.path===this.active)}showActive(){const e=this.activeFile;this.editor.setText((e==null?void 0:e.text)??""),this.editor.setBreakpoints(e?this.breakpoints.get(e.path)??[]:[]),this.editor.setReadOnly(!e),e&&!this.openTabs.includes(e.path)&&this.openTabs.push(e.path),this.renderTabs(),J(ot,this.active??"")}renderTabs(){if(this.openTabs=this.openTabs.filter(e=>this.project.files.some(t=>t.path===e)),J(cs,JSON.stringify(this.openTabs)),this.openTabs.length===0){this.tabs.innerHTML=`${b(d("web_visuobject_no_file"))}`;return}this.tabs.innerHTML=this.openTabs.map(e=>{const t=e===this.active,s=this.isDirty(e);return`
    -
    `}).join("")}onTabClick(e){var i;const t=e.target,s=(i=t.closest("[data-tab]"))==null?void 0:i.dataset.tab;if(s){if(t.closest("[data-close]"))return this.closeTab(s);this.treeSelection=`file:${s}`,this.openFile(s)}}closeTab(e){const t=this.openTabs.indexOf(e);t<0||(this.openTabs.splice(t,1),e===this.active?(this.active=this.openTabs[Math.min(t,this.openTabs.length-1)],this.lastTyping=0,this.showActive(),this.refresh()):this.renderTabs())}snapshot(){return JSON.stringify({project:this.project,active:this.active})}remember(){this.history.push(this.snapshot()),this.history.length>kn&&this.history.shift(),this.future=[]}setProject(e,t=this.active){var s;this.remember(),this.lastTyping=0,this.project=e,this.active=e.files.some(i=>i.path===t)?t:(s=e.files[0])==null?void 0:s.path,this.showActive(),this.refresh()}openFile(e){if(e===this.active)return;this.active=e,this.lastTyping=0,this.showActive();const t=D(e);this.currentPackage=t,this.open.set(`pkg:${t}`,!0),this.refresh()}typed(){const e=this.activeFile;if(!e)return;const t=Date.now();t-this.lastTyping>1500&&this.remember(),this.lastTyping=t,this.project=$e(this.project,e.path,this.editor.text),this.saveBreakpoints(),this.dbg&&this.stopDebug("web_visuobject_dbg_code_changed"),this.refresh(),clearTimeout(this.renameTimer),this.renameTimer=window.setTimeout(()=>this.syncFileName(),700)}syncFileName(){var c;const e=this.activeFile;if(!e||this.editing)return;const t=Q(e.path).replace(/\.java$/i,""),s=this.classes.filter(l=>l.path===e.path);if(s.length===0||s.some(l=>l.name===t))return;const i=((c=/\bpublic\s+(?:abstract\s+|final\s+)*(?:class|interface|enum)\s+(\w+)/.exec(e.text))==null?void 0:c[1])??s[0].name;if(!pe.test(i)||s.filter(l=>l.name===i).length!==1)return;const n=le(D(e.path),`${i}.java`);if(this.project.files.some(l=>l.path===n))return;let o=Oe(this.project,e.path,n);const r=this.positions.get(t);r&&!this.positions.has(i)&&this.positions.set(i,r);for(const l of Object.keys(o.uml??{}))l.startsWith(`${t}.`)&&(o={...o,uml:ke(o.uml,l,i+l.slice(t.length))});this.openTabs=this.openTabs.map(l=>l===e.path?n:l),this.treeSelection===`file:${e.path}`&&(this.treeSelection=`file:${n}`),this.isOpen(`file:${e.path}`)&&this.open.set(`file:${n}`,!0),this.project=o,this.active=n,J(ot,n),this.savePositions(),this.refresh()}undo(e){const t=e?this.future:this.history,s=e?this.history:this.future,i=t.pop();if(i===void 0)return;s.push(this.snapshot());const n=JSON.parse(i);this.project=n.project,this.active=n.active,this.lastTyping=0,this.showActive(),this.refresh()}refresh(){J(os,Pe(this.project)),this.renderTabs(),this.classes=Ct(this.project),this.selection&&!this.findClass(this.selection.cls)&&(this.selection=void 0),this.relSelection&&!this.findRelation(this.relSelection)&&!this.findDependency(this.relSelection)&&(this.relSelection=void 0),this.editing||(this.render(),this.renderTree())}ownTypesAt(e){const t=this.activeFile;if(!t)return;const s=this.editor.view.state.doc.toString(),i=X(D(t.path)),n=oe(s).map(l=>({...l,pkg:i})),o=new Set(n.map(l=>l.name)),r=n.find(l=>l.headerFrom<=e&&e<=l.bodyEnd),c=ct()==="de"?"de":ct()==="pt-PT"?"pt":"en";return Ji([...n,...this.classes.filter(l=>l.path!==t.path&&!o.has(l.name))],{cls:r==null?void 0:r.name,pkg:i},c)}findClass(e){return this.classes.find(t=>t.name===e)}caretMoved(){var n,o;const e=this.editor.caret,t=this.classes.find(r=>r.path===this.active&&e>=r.from&&e<=r.to),s=t==null?void 0:t.members.findIndex(r=>e>=r.from&&e<=r.to),i=t?{cls:t.name,member:s!==void 0&&s>=0?s:void 0}:void 0;(i==null?void 0:i.cls)===((n=this.selection)==null?void 0:n.cls)&&(i==null?void 0:i.member)===((o=this.selection)==null?void 0:o.member)||(this.selection=i,this.editing||(this.render(),this.renderTree()))}showInCode(e,t){e.path!==this.active&&(this.active=e.path,this.lastTyping=0,this.showActive());const s=this.editor.view,[i,n]=t?[t.headerFrom,t.headerTo]:[e.nameFrom,e.nameTo],o=Math.min(n,s.state.doc.length);s.dispatch({selection:{anchor:Math.min(i,o),head:o},scrollIntoView:!0})}message(e,t=!1){this.status.textContent=e,this.status.classList.toggle("hint",t)}openFiles(){const e=document.createElement("input");e.type="file",e.multiple=!0,e.accept=".zip,.java,.visuobject,application/zip,text/plain",e.addEventListener("change",()=>void this.readFiles([...e.files??[]])),e.click()}async readFiles(e){var t;if(e.length!==0)try{const s=e.find(r=>/\.zip$/i.test(r.name));if(s){const{projectFromZip:r}=await wt(async()=>{const{projectFromZip:l}=await import("./projectZip-BKS-Blr6.js");return{projectFromZip:l}},__vite__mapDeps([0,1,2]),import.meta.url),c=r(new Uint8Array(await s.arrayBuffer()),s.name.replace(/\.zip$/i,""));await this.newProject(c);return}const i=e.find(r=>/\.visuobject$/i.test(r.name));if(i){const r=qt(await i.text());if(!r)throw new Error("format");await this.newProject(r);return}const n=At(this.project.name,await Promise.all(e.map(async r=>({name:r.name,text:await r.text()}))));let o=this.project;for(const r of n.files)o=et(o,r.path,r.text);this.setProject(o,(t=n.files[0])==null?void 0:t.path)}catch{this.message(d("web_visuobject_open_failed"))}}async save(){this.workspace?await this.writeCurrent():await this.downloadZip()}async downloadZip(){const{projectToZip:e}=await wt(async()=>{const{projectToZip:s}=await import("./projectZip-BKS-Blr6.js");return{projectToZip:s}},__vite__mapDeps([0,1,2]),import.meta.url),t=e(this.project);Sn(`${this.project.name||"Projekt"}.zip`,t.slice().buffer,"application/zip")}isDirty(e){var t;return!this.workspace||this.saved===void 0?!1:e===void 0?this.saved!==Pe(this.project):this.savedFiles.get(e)!==((t=this.project.files.find(s=>s.path===e))==null?void 0:t.text)}markSaved(){this.saved=Pe(this.project),this.savedFiles=new Map(this.project.files.map(e=>[e.path,e.text]))}async restoreWorkspace(){if(!$t())return;const e=await Ks(us);if(e!=null&&e.ready){const t=await _t(e.handle);if(t)return this.useWorkspace(t.root,!0)}this.pendingFolder=e==null?void 0:e.handle,this.renderWorkspace()}async useWorkspace(e,t=!1){var s;this.workspace=e,this.pendingFolder=void 0,J(rt,"0");try{this.projects=await is(e);const i=se(We),n=this.project;if(t&&i&&this.projects.includes(i)){const o={active:this.active,tabs:[...this.openTabs],positions:new Map(this.positions)};await this.loadProject(i),this.positions=o.positions,this.savePositions(),Pe(n)!==this.saved&&(this.project=n),this.openTabs=o.tabs.filter(r=>this.project.files.some(c=>c.path===r)),this.active=this.project.files.some(r=>r.path===o.active)?o.active:(s=this.project.files[0])==null?void 0:s.path,this.showActive(),this.refresh()}else!this.projects.some(o=>o.toLowerCase()===ge(n.name).toLowerCase())&&n.files.length?(this.folder=ge(n.name),await this.writeCurrent(!1)):this.projects.length?await this.loadProject(this.projects.includes(i??"")?i:this.projects[0]):(this.folder=ge(n.name),await this.writeCurrent(!1))}catch(i){this.message(d("web_visuobject_ws_failed",String((i==null?void 0:i.message)??i)))}this.renderWorkspace(),this.refresh()}async loadProject(e){var i;const{project:t,positions:s}=await yn(this.workspace,e);this.folder=e,this.project=t,this.markSaved(),this.message(""),this.history=[],this.future=[],this.lastTyping=0,this.selection=void 0,this.relSelection=void 0,this.treeSelection=void 0,this.currentPackage=void 0,this.positions=new Map(Object.entries(s)),this.savePositions(),this.openTabs=[],this.active=(i=t.files[0])==null?void 0:i.path,J(We,e),this.showActive(),this.refresh()}async writeCurrent(e=!0){const t=this.workspace;if(!t)return!1;const s=ge(this.project.name),i=this.folder,n=new Set(this.classes.map(r=>r.name)),o=Object.fromEntries([...this.positions].filter(([r])=>n.has(r)));if(s!==i&&this.projects.some(r=>r!==i&&r.toLowerCase()===s.toLowerCase()))return this.message(d("web_visuobject_ws_taken",this.project.name)),!1;try{return await _n(t,s,this.project,o),i&&i!==s&&this.projects.includes(i)&&await t.remove(i),this.folder=s,this.projects=await is(t),J(We,s),this.markSaved(),e&&this.message(d("web_visuobject_ws_saved",t.name,s),!0),this.refresh(),!0}catch(r){return this.message(d("web_visuobject_ws_failed",String((r==null?void 0:r.message)??r))),!1}}async switchProject(e){if(!(!this.workspace||e===this.folder)&&!(this.isDirty()&&!await this.writeCurrent(!1)))try{await this.loadProject(e)}catch(t){this.message(d("web_visuobject_ws_failed",String((t==null?void 0:t.message)??t)))}}async newProject(e,t,s=!1){var n,o;if(!this.workspace){this.setProject(e,t??((n=e.files[0])==null?void 0:n.path)),e.files.length===0&&!s&&this.editProjectName();return}if(this.isDirty()&&!await this.writeCurrent(!1))return;const i=ns(ge(e.name),this.projects);this.project={...e,name:i},this.folder=i,this.history=[],this.future=[],this.openTabs=[],this.positions.clear(),this.savePositions(),this.active=e.files.some(r=>r.path===t)?t:(o=e.files[0])==null?void 0:o.path,this.showActive(),this.refresh(),await this.writeCurrent(!1)&&(this.message(d("web_visuobject_ws_created",i),!0),e.files.length===0&&!s&&this.editProjectName())}get currentPlace(){const e=this.currentPackage??(this.active?D(this.active):ce(this.project)[0]??"");return{root:U(e),pkg:X(e)}}async newFromWizard(e){var u;const t=this.currentPlace,s=(f,m)=>{let g=f;for(let _=2;m(g);_++)g=f+_;return g},i=await on(e,{roots:ue(this.project),packagesIn:f=>ce(this.project,f).map(X),classes:this.classes,root:t.root,pkg:t.pkg,suggest:f=>f==="project"?ns(d("web_visuobject_project_name"),this.workspace?[...this.projects,this.folder??""]:[]):f==="folder"?s("test",m=>ue(this.project).includes(m)):f==="package"?s(d("web_visuobject_new_package_name"),m=>ce(this.project).includes(re(t.root,m))):this.uniqueClassName(d(f==="class"?"web_visuobject_new_class_name":"web_visuobject_new_interface_name")),check:(f,m,g,_)=>{if(!m)return d("web_visuobject_new_name_missing");if(f==="project")return this.workspace&&this.projects.some(y=>y!==this.folder&&y.toLowerCase()===ge(m).toLowerCase())?d("web_visuobject_ws_taken",m):void 0;if(f==="folder")return!Je(m)||ue(this.project).includes(m)?d("web_visuobject_bad_folder",m):void 0;if(f==="package")return!Mt(m)||ce(this.project).includes(re(g,m))?d("web_visuobject_bad_package",m):void 0;if(!pe.test(m))return d("web_visuobject_bad_name",m);if(this.findClass(m)||this.project.files.some(y=>y.path===le(re(g,_),`${m}.java`)))return d("web_visuobject_new_exists",m);if(m.charAt(0)!==m.charAt(0).toUpperCase())return d("web_visuobject_new_upper")}});if(!i)return;const{name:n,root:o,pkg:r}=i;if(e==="project")return this.newProject({name:n,files:[],packages:[]},void 0,!0);if(this.message(""),e==="folder")return this.currentPackage=re(n,""),this.treeSelection=`root:${n}`,this.open.set(`root:${n}`,!0),this.setProject(bi(this.project,n));if(e==="package"){const f=re(o,n);return this.currentPackage=f,this.treeSelection=`pkg:${f}`,this.open.set(`root:${o}`,!0),this.setProject(fi(this.project,f))}const c=re(o,r),l=le(c,`${n}.java`);this.currentPackage=c,this.selection={cls:n},this.open.set(`root:${o}`,!0),this.open.set(`pkg:${c}`,!0),this.setProject(et(this.project,l,this.sectioned(sn(i.options),n)),l);const h=this.findClass(n);h&&this.showInCode(h),(u=this.canvas.querySelector(`.uml-class[data-class="${CSS.escape(n)}"]`))==null||u.scrollIntoView({block:"nearest",inline:"nearest"})}editProjectName(){this.treeSelection="project",this.renderTree(),this.startEditing(this.tree.querySelector('[data-node="project"] > .vo-row .vo-label'))}renderWorkspace(){const e=this.wsBox;e.hidden=!$t();const t=this.shell.querySelector("[data-action=save]");if(t.dataset.tip=d(this.workspace?"web_visuobject_save_ws_tip":"web_visuobject_save_tip"),e.hidden)return;const s=(i,n,o="text-button",r)=>``;this.workspace?(e.className="vo-ws",e.innerHTML=`${b(this.workspace.name)} + `}).join("")}onTabClick(e){var i;const t=e.target,s=(i=t.closest("[data-tab]"))==null?void 0:i.dataset.tab;if(s){if(t.closest("[data-close]"))return this.closeTab(s);this.treeSelection=`file:${s}`,this.openFile(s)}}closeTab(e){const t=this.openTabs.indexOf(e);t<0||(this.openTabs.splice(t,1),e===this.active?(this.active=this.openTabs[Math.min(t,this.openTabs.length-1)],this.lastTyping=0,this.showActive(),this.refresh()):this.renderTabs())}snapshot(){return JSON.stringify({project:this.project,active:this.active})}remember(){this.history.push(this.snapshot()),this.history.length>kn&&this.history.shift(),this.future=[]}setProject(e,t=this.active){var s;this.remember(),this.lastTyping=0,this.project=e,this.active=e.files.some(i=>i.path===t)?t:(s=e.files[0])==null?void 0:s.path,this.showActive(),this.refresh()}openFile(e){if(e===this.active)return;this.active=e,this.lastTyping=0,this.showActive();const t=D(e);this.currentPackage=t,this.open.set(`pkg:${t}`,!0),this.refresh()}typed(){const e=this.activeFile;if(!e)return;const t=Date.now();t-this.lastTyping>1500&&this.remember(),this.lastTyping=t,this.project=$e(this.project,e.path,this.editor.text),this.saveBreakpoints(),this.dbg&&this.stopDebug("web_visuobject_dbg_code_changed"),this.refresh(),clearTimeout(this.renameTimer),this.renameTimer=window.setTimeout(()=>this.syncFileName(),700)}syncFileName(){var c;const e=this.activeFile;if(!e||this.editing)return;const t=Q(e.path).replace(/\.java$/i,""),s=this.classes.filter(l=>l.path===e.path);if(s.length===0||s.some(l=>l.name===t))return;const i=((c=/\bpublic\s+(?:abstract\s+|final\s+)*(?:class|interface|enum)\s+(\w+)/.exec(e.text))==null?void 0:c[1])??s[0].name;if(!pe.test(i)||s.filter(l=>l.name===i).length!==1)return;const n=le(D(e.path),`${i}.java`);if(this.project.files.some(l=>l.path===n))return;let o=Oe(this.project,e.path,n);const r=this.positions.get(t);r&&!this.positions.has(i)&&this.positions.set(i,r);for(const l of Object.keys(o.uml??{}))l.startsWith(`${t}.`)&&(o={...o,uml:ke(o.uml,l,i+l.slice(t.length))});this.openTabs=this.openTabs.map(l=>l===e.path?n:l),this.treeSelection===`file:${e.path}`&&(this.treeSelection=`file:${n}`),this.isOpen(`file:${e.path}`)&&this.open.set(`file:${n}`,!0),this.project=o,this.active=n,J(ot,n),this.savePositions(),this.refresh()}undo(e){const t=e?this.future:this.history,s=e?this.history:this.future,i=t.pop();if(i===void 0)return;s.push(this.snapshot());const n=JSON.parse(i);this.project=n.project,this.active=n.active,this.lastTyping=0,this.showActive(),this.refresh()}refresh(){J(os,Pe(this.project)),this.renderTabs(),this.classes=Ct(this.project),this.selection&&!this.findClass(this.selection.cls)&&(this.selection=void 0),this.relSelection&&!this.findRelation(this.relSelection)&&!this.findDependency(this.relSelection)&&(this.relSelection=void 0),this.editing||(this.render(),this.renderTree())}ownTypesAt(e){const t=this.activeFile;if(!t)return;const s=this.editor.view.state.doc.toString(),i=X(D(t.path)),n=oe(s).map(l=>({...l,pkg:i})),o=new Set(n.map(l=>l.name)),r=n.find(l=>l.headerFrom<=e&&e<=l.bodyEnd),c=ct()==="de"?"de":ct()==="pt-PT"?"pt":"en";return Ji([...n,...this.classes.filter(l=>l.path!==t.path&&!o.has(l.name))],{cls:r==null?void 0:r.name,pkg:i},c)}findClass(e){return this.classes.find(t=>t.name===e)}caretMoved(){var n,o;const e=this.editor.caret,t=this.classes.find(r=>r.path===this.active&&e>=r.from&&e<=r.to),s=t==null?void 0:t.members.findIndex(r=>e>=r.from&&e<=r.to),i=t?{cls:t.name,member:s!==void 0&&s>=0?s:void 0}:void 0;(i==null?void 0:i.cls)===((n=this.selection)==null?void 0:n.cls)&&(i==null?void 0:i.member)===((o=this.selection)==null?void 0:o.member)||(this.selection=i,this.editing||(this.render(),this.renderTree()))}showInCode(e,t){e.path!==this.active&&(this.active=e.path,this.lastTyping=0,this.showActive());const s=this.editor.view,[i,n]=t?[t.headerFrom,t.headerTo]:[e.nameFrom,e.nameTo],o=Math.min(n,s.state.doc.length);s.dispatch({selection:{anchor:Math.min(i,o),head:o},scrollIntoView:!0})}message(e,t=!1){this.status.textContent=e,this.status.classList.toggle("hint",t)}openFiles(){const e=document.createElement("input");e.type="file",e.multiple=!0,e.accept=".zip,.java,.visuobject,application/zip,text/plain",e.addEventListener("change",()=>void this.readFiles([...e.files??[]])),e.click()}async readFiles(e){var t;if(e.length!==0)try{const s=e.find(r=>/\.zip$/i.test(r.name));if(s){const{projectFromZip:r}=await wt(async()=>{const{projectFromZip:l}=await import("./projectZip-BgHQOrUW.js");return{projectFromZip:l}},__vite__mapDeps([0,1,2]),import.meta.url),c=r(new Uint8Array(await s.arrayBuffer()),s.name.replace(/\.zip$/i,""));await this.newProject(c);return}const i=e.find(r=>/\.visuobject$/i.test(r.name));if(i){const r=qt(await i.text());if(!r)throw new Error("format");await this.newProject(r);return}const n=At(this.project.name,await Promise.all(e.map(async r=>({name:r.name,text:await r.text()}))));let o=this.project;for(const r of n.files)o=et(o,r.path,r.text);this.setProject(o,(t=n.files[0])==null?void 0:t.path)}catch{this.message(d("web_visuobject_open_failed"))}}async save(){this.workspace?await this.writeCurrent():await this.downloadZip()}async downloadZip(){const{projectToZip:e}=await wt(async()=>{const{projectToZip:s}=await import("./projectZip-BgHQOrUW.js");return{projectToZip:s}},__vite__mapDeps([0,1,2]),import.meta.url),t=e(this.project);Sn(`${this.project.name||"Projekt"}.zip`,t.slice().buffer,"application/zip")}isDirty(e){var t;return!this.workspace||this.saved===void 0?!1:e===void 0?this.saved!==Pe(this.project):this.savedFiles.get(e)!==((t=this.project.files.find(s=>s.path===e))==null?void 0:t.text)}markSaved(){this.saved=Pe(this.project),this.savedFiles=new Map(this.project.files.map(e=>[e.path,e.text]))}async restoreWorkspace(){if(!$t())return;const e=await Ks(us);if(e!=null&&e.ready){const t=await _t(e.handle);if(t)return this.useWorkspace(t.root,!0)}this.pendingFolder=e==null?void 0:e.handle,this.renderWorkspace()}async useWorkspace(e,t=!1){var s;this.workspace=e,this.pendingFolder=void 0,J(rt,"0");try{this.projects=await is(e);const i=se(We),n=this.project;if(t&&i&&this.projects.includes(i)){const o={active:this.active,tabs:[...this.openTabs],positions:new Map(this.positions)};await this.loadProject(i),this.positions=o.positions,this.savePositions(),Pe(n)!==this.saved&&(this.project=n),this.openTabs=o.tabs.filter(r=>this.project.files.some(c=>c.path===r)),this.active=this.project.files.some(r=>r.path===o.active)?o.active:(s=this.project.files[0])==null?void 0:s.path,this.showActive(),this.refresh()}else!this.projects.some(o=>o.toLowerCase()===ge(n.name).toLowerCase())&&n.files.length?(this.folder=ge(n.name),await this.writeCurrent(!1)):this.projects.length?await this.loadProject(this.projects.includes(i??"")?i:this.projects[0]):(this.folder=ge(n.name),await this.writeCurrent(!1))}catch(i){this.message(d("web_visuobject_ws_failed",String((i==null?void 0:i.message)??i)))}this.renderWorkspace(),this.refresh()}async loadProject(e){var i;const{project:t,positions:s}=await yn(this.workspace,e);this.folder=e,this.project=t,this.markSaved(),this.message(""),this.history=[],this.future=[],this.lastTyping=0,this.selection=void 0,this.relSelection=void 0,this.treeSelection=void 0,this.currentPackage=void 0,this.positions=new Map(Object.entries(s)),this.savePositions(),this.openTabs=[],this.active=(i=t.files[0])==null?void 0:i.path,J(We,e),this.showActive(),this.refresh()}async writeCurrent(e=!0){const t=this.workspace;if(!t)return!1;const s=ge(this.project.name),i=this.folder,n=new Set(this.classes.map(r=>r.name)),o=Object.fromEntries([...this.positions].filter(([r])=>n.has(r)));if(s!==i&&this.projects.some(r=>r!==i&&r.toLowerCase()===s.toLowerCase()))return this.message(d("web_visuobject_ws_taken",this.project.name)),!1;try{return await _n(t,s,this.project,o),i&&i!==s&&this.projects.includes(i)&&await t.remove(i),this.folder=s,this.projects=await is(t),J(We,s),this.markSaved(),e&&this.message(d("web_visuobject_ws_saved",t.name,s),!0),this.refresh(),!0}catch(r){return this.message(d("web_visuobject_ws_failed",String((r==null?void 0:r.message)??r))),!1}}async switchProject(e){if(!(!this.workspace||e===this.folder)&&!(this.isDirty()&&!await this.writeCurrent(!1)))try{await this.loadProject(e)}catch(t){this.message(d("web_visuobject_ws_failed",String((t==null?void 0:t.message)??t)))}}async newProject(e,t,s=!1){var n,o;if(!this.workspace){this.setProject(e,t??((n=e.files[0])==null?void 0:n.path)),e.files.length===0&&!s&&this.editProjectName();return}if(this.isDirty()&&!await this.writeCurrent(!1))return;const i=ns(ge(e.name),this.projects);this.project={...e,name:i},this.folder=i,this.history=[],this.future=[],this.openTabs=[],this.positions.clear(),this.savePositions(),this.active=e.files.some(r=>r.path===t)?t:(o=e.files[0])==null?void 0:o.path,this.showActive(),this.refresh(),await this.writeCurrent(!1)&&(this.message(d("web_visuobject_ws_created",i),!0),e.files.length===0&&!s&&this.editProjectName())}get currentPlace(){const e=this.currentPackage??(this.active?D(this.active):ce(this.project)[0]??"");return{root:U(e),pkg:X(e)}}async newFromWizard(e){var u;const t=this.currentPlace,s=(f,m)=>{let g=f;for(let _=2;m(g);_++)g=f+_;return g},i=await on(e,{roots:ue(this.project),packagesIn:f=>ce(this.project,f).map(X),classes:this.classes,root:t.root,pkg:t.pkg,suggest:f=>f==="project"?ns(d("web_visuobject_project_name"),this.workspace?[...this.projects,this.folder??""]:[]):f==="folder"?s("test",m=>ue(this.project).includes(m)):f==="package"?s(d("web_visuobject_new_package_name"),m=>ce(this.project).includes(re(t.root,m))):this.uniqueClassName(d(f==="class"?"web_visuobject_new_class_name":"web_visuobject_new_interface_name")),check:(f,m,g,_)=>{if(!m)return d("web_visuobject_new_name_missing");if(f==="project")return this.workspace&&this.projects.some(y=>y!==this.folder&&y.toLowerCase()===ge(m).toLowerCase())?d("web_visuobject_ws_taken",m):void 0;if(f==="folder")return!Je(m)||ue(this.project).includes(m)?d("web_visuobject_bad_folder",m):void 0;if(f==="package")return!Mt(m)||ce(this.project).includes(re(g,m))?d("web_visuobject_bad_package",m):void 0;if(!pe.test(m))return d("web_visuobject_bad_name",m);if(this.findClass(m)||this.project.files.some(y=>y.path===le(re(g,_),`${m}.java`)))return d("web_visuobject_new_exists",m);if(m.charAt(0)!==m.charAt(0).toUpperCase())return d("web_visuobject_new_upper")}});if(!i)return;const{name:n,root:o,pkg:r}=i;if(e==="project")return this.newProject({name:n,files:[],packages:[]},void 0,!0);if(this.message(""),e==="folder")return this.currentPackage=re(n,""),this.treeSelection=`root:${n}`,this.open.set(`root:${n}`,!0),this.setProject(bi(this.project,n));if(e==="package"){const f=re(o,n);return this.currentPackage=f,this.treeSelection=`pkg:${f}`,this.open.set(`root:${o}`,!0),this.setProject(fi(this.project,f))}const c=re(o,r),l=le(c,`${n}.java`);this.currentPackage=c,this.selection={cls:n},this.open.set(`root:${o}`,!0),this.open.set(`pkg:${c}`,!0),this.setProject(et(this.project,l,this.sectioned(sn(i.options),n)),l);const h=this.findClass(n);h&&this.showInCode(h),(u=this.canvas.querySelector(`.uml-class[data-class="${CSS.escape(n)}"]`))==null||u.scrollIntoView({block:"nearest",inline:"nearest"})}editProjectName(){this.treeSelection="project",this.renderTree(),this.startEditing(this.tree.querySelector('[data-node="project"] > .vo-row .vo-label'))}renderWorkspace(){const e=this.wsBox;e.hidden=!$t();const t=this.shell.querySelector("[data-action=save]");if(t.dataset.tip=d(this.workspace?"web_visuobject_save_ws_tip":"web_visuobject_save_tip"),e.hidden)return;const s=(i,n,o="text-button",r)=>``;this.workspace?(e.className="vo-ws",e.innerHTML=`${b(this.workspace.name)} ${s("zip",d("web_visuobject_ws_zip"),"text-button",d("web_visuobject_ws_zip_tip"))} ${s("switch",d("web_visuobject_ws_switch"),"text-button")}`):this.pendingFolder?(e.className="vo-ws",e.innerHTML=`${s("reopen",d("web_visuobject_ws_reopen",this.pendingFolder.name),"text-button primary")}${s("switch",d("web_visuobject_ws_switch"),"text-button")}`):se(rt)==="1"?(e.className="vo-ws",e.innerHTML=s("open",d("web_visuobject_ws_choose"),"text-button",d("web_visuobject_ws_hint"))):(e.className="vo-ws ask",e.innerHTML=`

    ${b(d("web_visuobject_ws_question"))}

    ${b(d("web_visuobject_ws_hint"))}

    diff --git a/website/app/assets/projectZip-BKS-Blr6.js b/website/app/assets/projectZip-BgHQOrUW.js similarity index 99% rename from website/app/assets/projectZip-BKS-Blr6.js rename to website/app/assets/projectZip-BgHQOrUW.js index 1ccb6803..d668e47d 100644 --- a/website/app/assets/projectZip-BKS-Blr6.js +++ b/website/app/assets/projectZip-BgHQOrUW.js @@ -1 +1 @@ -import{p as Br,d as Er,a as mr,i as Gr,b as Qr,c as Vr,u as Lr,n as _r,o as pr,e as br,r as dr,f as re,s as ee}from"./objectApp-Caze4o4v.js";import"./index-CzgrZgZa.js";var M=Uint8Array,K=Uint16Array,Tr=Int32Array,hr=new M([0,0,0,0,0,0,0,0,1,1,1,1,2,2,2,2,3,3,3,3,4,4,4,4,5,5,5,5,0,0,0,0]),gr=new M([0,0,0,0,1,1,2,2,3,3,4,4,5,5,6,6,7,7,8,8,9,9,10,10,11,11,12,12,13,13,0,0]),Sr=new M([16,17,18,0,8,7,9,6,10,5,11,4,12,3,13,2,14,1,15]),Wr=function(r,e){for(var n=new K(31),a=0;a<31;++a)n[a]=e+=1<>1|(F&21845)<<1;b=(b&52428)>>2|(b&13107)<<2,b=(b&61680)>>4|(b&3855)<<4,Cr[F]=((b&65280)>>8|(b&255)<<8)>>1}var V=(function(r,e,n){for(var a=r.length,f=0,v=new K(e);f>l]=c}else for(s=new K(a),f=0;f>15-r[f]);return s}),d=new M(288);for(var F=0;F<144;++F)d[F]=8;for(var F=144;F<256;++F)d[F]=9;for(var F=256;F<280;++F)d[F]=7;for(var F=280;F<288;++F)d[F]=8;var ir=new M(32);for(var F=0;F<32;++F)ir[F]=5;var ae=V(d,9,0),fe=V(d,9,1),ve=V(ir,5,0),te=V(ir,5,1),xr=function(r){for(var e=r[0],n=1;ne&&(e=r[n]);return e},X=function(r,e,n){var a=e/8|0;return(r[a]|r[a+1]<<8)>>(e&7)&n},yr=function(r,e){var n=e/8|0;return(r[n]|r[n+1]<<8|r[n+2]<<16)>>(e&7)},Ur=function(r){return(r+7)/8|0},lr=function(r,e,n){return(e==null||e<0)&&(e=0),(n==null||n>r.length)&&(n=r.length),new M(r.subarray(e,n))},oe=["unexpected EOF","invalid block type","invalid length/literal","invalid distance","stream finished","no stream handler",,"no callback","invalid UTF-8 data","extra field too long","date not in range 1980-2099","filename too long","stream finishing","invalid zip data"],I=function(r,e,n){var a=new Error(e||oe[r]);if(a.code=r,Error.captureStackTrace&&Error.captureStackTrace(a,I),!n)throw a;return a},ie=function(r,e,n,a){var f=r.length,v=a?a.length:0;if(!f||e.f&&!e.l)return n||new M(0);var i=!n,s=i||e.i!=2,l=e.i;i&&(n=new M(f*3));var c=function(fr){var vr=n.length;if(fr>vr){var nr=new M(Math.max(vr*2,fr));nr.set(n),n=nr}},t=e.f||0,o=e.p||0,u=e.b||0,h=e.l,y=e.d,w=e.m,x=e.n,T=f*8;do{if(!h){t=X(r,o,1);var z=X(r,o+1,3);if(o+=3,z)if(z==1)h=fe,y=te,w=9,x=5;else if(z==2){var U=X(r,o,31)+257,A=X(r,o+10,15)+4,m=U+X(r,o+5,31)+1;o+=14;for(var g=new M(m),B=new M(19),j=0;j>4;if(C<16)g[j++]=C;else{var E=0,k=0;for(C==16?(k=3+X(r,o,3),o+=2,E=g[j-1]):C==17?(k=3+X(r,o,7),o+=3):C==18&&(k=11+X(r,o,127),o+=7);k--;)g[j++]=E}}var W=g.subarray(0,U),J=g.subarray(U);w=xr(W),x=xr(J),h=V(W,w,1),y=V(J,x,1)}else I(1);else{var C=Ur(o)+4,O=r[C-4]|r[C-3]<<8,$=C+O;if($>f){l&&I(0);break}s&&c(u+O),n.set(r.subarray(C,$),u),e.b=u+=O,e.p=o=$*8,e.f=t;continue}if(o>T){l&&I(0);break}}s&&c(u+131072);for(var ar=(1<>4;if(o+=E&15,o>T){l&&I(0);break}if(E||I(2),q<256)n[u++]=q;else if(q==256){L=o,h=null;break}else{var H=q-254;if(q>264){var j=q-257,S=hr[j];H=X(r,o,(1<>4;G||I(3),o+=G&15;var J=ne[rr];if(rr>3){var S=gr[rr];J+=yr(r,o)&(1<T){l&&I(0);break}s&&c(u+131072);var er=u+H;if(u>8},tr=function(r,e,n){n<<=e&7;var a=e/8|0;r[a]|=n,r[a+1]|=n>>8,r[a+2]|=n>>16},Fr=function(r,e){for(var n=[],a=0;au&&(u=v[a].s);var h=new K(u+1),y=Or(n[t-1],h,0);if(y>e){var a=0,w=0,x=y-e,T=1<e)w+=T-(1<>=x;w>0;){var C=v[a].s;h[C]=0&&w;--a){var O=v[a].s;h[O]==e&&(--h[O],++w)}y=e}return{t:new M(h),l:y}},Or=function(r,e,n){return r.s==-1?Math.max(Or(r.l,e,n+1),Or(r.r,e,n+1)):e[r.s]=n},Nr=function(r){for(var e=r.length;e&&!r[--e];);for(var n=new K(++e),a=0,f=r[0],v=1,i=function(l){n[a++]=l},s=1;s<=e;++s)if(r[s]==f&&s!=e)++v;else{if(!f&&v>2){for(;v>138;v-=138)i(32754);v>2&&(i(v>10?v-11<<5|28690:v-3<<5|12305),v=0)}else if(v>3){for(i(f),--v;v>6;v-=6)i(8304);v>2&&(i(v-3<<5|8208),v=0)}for(;v--;)i(f);v=1,f=r[s]}return{c:n.subarray(0,a),n:e}},or=function(r,e){for(var n=0,a=0;a>8,r[f+2]=r[f]^255,r[f+3]=r[f+1]^255;for(var v=0;v4&&!B[Sr[D-1]];--D);var p=c+5<<3,Z=or(f,d)+or(v,ir)+i,P=or(f,u)+or(v,w)+i+14+3*D+or(A,B)+2*A[16]+3*A[17]+7*A[18];if(l>=0&&p<=Z&&p<=P)return Kr(e,t,r.subarray(l,l+c));var E,k,W,J;if(_(e,t,1+(P15&&(_(e,t,q[m]>>5&127),t+=q[m]>>12)}}else E=ae,k=d,W=ve,J=ir;for(var m=0;m255){var H=S>>18&31;tr(e,t,E[H+257]),t+=k[H+257],H>7&&(_(e,t,S>>23&31),t+=hr[H]);var G=S&31;tr(e,t,W[G]),t+=J[G],G>3&&(tr(e,t,S>>5&8191),t+=gr[G])}else tr(e,t,E[S]),t+=k[S]}return tr(e,t,E[256]),t+k[256]},le=new Tr([65540,131080,131088,131104,262176,1048704,1048832,2114560,2117632]),Rr=new M(0),se=function(r,e,n,a,f,v){var i=v.z||r.length,s=new M(a+i+5*(1+Math.ceil(i/7e3))+f),l=s.subarray(a,s.length-f),c=v.l,t=(v.r||0)&7;if(e){t&&(l[0]=v.r>>3);for(var o=le[e-1],u=o>>13,h=o&8191,y=(1<7e3||B>24576)&&(E>423||!c)){t=Dr(r,l,0,O,$,U,m,B,D,g-D,t),B=A=m=0,D=g;for(var k=0;k<286;++k)$[k]=0;for(var k=0;k<30;++k)U[k]=0}var W=2,J=0,ar=h,R=Z-P&32767;if(E>2&&p==C(g-R))for(var L=Math.min(u,E)-1,q=Math.min(32767,g),H=Math.min(258,E);R<=q&&--ar&&Z!=P;){if(r[g+W]==r[g+W-R]){for(var S=0;SW){if(W=S,J=R,S>L)break;for(var G=Math.min(R,S-2),rr=0,k=0;krr&&(rr=ur,P=er)}}}Z=P,P=w[Z],R+=Z-P&32767}if(J){O[B++]=268435456|Mr[W]<<18|Jr[J];var fr=Mr[W]&31,vr=Jr[J]&31;m+=hr[fr]+gr[vr],++$[257+fr],++U[vr],j=g+W,++A}else O[B++]=r[g],++$[r[g]]}}for(g=Math.max(g,j);g=i&&(l[t/8|0]=c,nr=i),t=Kr(l,t+1,r.subarray(g,nr))}v.i=i}return lr(s,0,a+Ur(t)+f)},ue=(function(){for(var r=new Int32Array(256),e=0;e<256;++e){for(var n=e,a=9;--a;)n=(n&1&&-306674912)^n>>>1;r[e]=n}return r})(),ce=function(){var r=-1;return{p:function(e){for(var n=r,a=0;a>>8;r=n},d:function(){return~r}}},he=function(r,e,n,a,f){if(!f&&(f={l:1},e.dictionary)){var v=e.dictionary.subarray(-32768),i=new M(v.length+r.length);i.set(v),i.set(r,v.length),r=i,f.w=v.length}return se(r,e.level==null?6:e.level,e.mem==null?f.l?Math.ceil(Math.max(8,Math.min(13,Math.log(r.length)))*1.5):20:12+e.mem,n,a,f)},Xr=function(r,e){var n={};for(var a in r)n[a]=r[a];for(var a in e)n[a]=e[a];return n},Q=function(r,e){return r[e]|r[e+1]<<8},Y=function(r,e){return(r[e]|r[e+1]<<8|r[e+2]<<16|r[e+3]<<24)>>>0},kr=function(r,e){return Y(r,e)+Y(r,e+4)*4294967296},N=function(r,e,n){for(;n;++e)r[e]=n,n>>>=8};function ge(r,e){return he(r,e||{},0,0)}function we(r,e){return ie(r,{i:2},e&&e.out,e&&e.dictionary)}var Yr=function(r,e,n,a){for(var f in r){var v=r[f],i=e+f,s=a;Array.isArray(v)&&(s=Xr(a,v[1]),v=v[0]),v instanceof M?n[i]=[v,s]:(n[i+="/"]=[new M(0),s],Yr(v,i,n,a))}},Ir=typeof TextEncoder<"u"&&new TextEncoder,Ar=typeof TextDecoder<"u"&&new TextDecoder,me=0;try{Ar.decode(Rr,{stream:!0}),me=1}catch{}var xe=function(r){for(var e="",n=0;;){var a=r[n++],f=(a>127)+(a>223)+(a>239);if(n+f>r.length)return{s:e,r:lr(r,n-1)};f?f==3?(a=((a&15)<<18|(r[n++]&63)<<12|(r[n++]&63)<<6|r[n++]&63)-65536,e+=String.fromCharCode(55296|a>>10,56320|a&1023)):f&1?e+=String.fromCharCode((a&31)<<6|r[n++]&63):e+=String.fromCharCode((a&15)<<12|(r[n++]&63)<<6|r[n++]&63):e+=String.fromCharCode(a)}};function cr(r,e){var n;if(Ir)return Ir.encode(r);for(var a=r.length,f=new M(r.length+(r.length>>1)),v=0,i=function(c){f[v++]=c},n=0;nf.length){var s=new M(v+8+(a-n<<1));s.set(f),f=s}var l=r.charCodeAt(n);l<128||e?i(l):l<2048?(i(192|l>>6),i(128|l&63)):l>55295&&l<57344?(l=65536+(l&1047552)|r.charCodeAt(++n)&1023,i(240|l>>18),i(128|l>>12&63),i(128|l>>6&63),i(128|l&63)):(i(224|l>>12),i(128|l>>6&63),i(128|l&63))}return lr(f,0,v)}function jr(r,e){if(e){for(var n="",a=0;a65535&&I(9),e+=a+4}return e},Pr=function(r,e,n,a,f,v,i,s){var l=a.length,c=n.extra,t=s&&s.length,o=zr(c);N(r,e,i!=null?33639248:67324752),e+=4,i!=null&&(r[e++]=20,r[e++]=n.os),r[e]=20,e+=2,r[e++]=n.flag<<1|(v<0&&8),r[e++]=f&&8,r[e++]=n.compression&255,r[e++]=n.compression>>8;var u=new Date(n.mtime==null?Date.now():n.mtime),h=u.getFullYear()-1980;if((h<0||h>119)&&I(10),N(r,e,h<<25|u.getMonth()+1<<21|u.getDate()<<16|u.getHours()<<11|u.getMinutes()<<5|u.getSeconds()>>1),e+=4,v!=-1&&(N(r,e,n.crc),N(r,e+4,v<0?-v-2:v),N(r,e+8,n.size)),N(r,e+12,l),N(r,e+14,o),e+=16,i!=null&&(N(r,e,t),N(r,e+6,n.attrs),N(r,e+10,i),e+=14),r.set(a,e),e+=l,o)for(var y in c){var w=c[y],x=w.length;N(r,e,+y),N(r,e+2,x),r.set(w,e+4),e+=4+x}return t&&(r.set(s,e),e+=t),e},Se=function(r,e,n,a,f){N(r,e,101010256),N(r,e+8,n),N(r,e+10,n),N(r,e+12,a),N(r,e+16,f)};function Me(r,e){e||(e={});var n={},a=[];Yr(r,"",n,e);var f=0,v=0;for(var i in n){var s=n[i],l=s[0],c=s[1],t=c.level==0?0:8,o=cr(i),u=o.length,h=c.comment,y=h&&cr(h),w=y&&y.length,x=zr(c.extra);u>65535&&I(11);var T=t?ge(l,c):l,z=T.length,C=ce();C.p(l),a.push(Xr(c,{size:l.length,crc:C.d(),c:T,f:o,m:y,u:u!=i.length||y&&h.length!=w,o:f,compression:t})),f+=30+u+x+z,v+=76+2*(u+x)+(w||0)+z}for(var O=new M(v+22),$=f,U=v-f,A=0;A65558)&&I(13);var f=Q(r,a+8);if(!f)return{};var v=Y(r,a+16),i=v==4294967295||f==65535;if(i){var s=Y(r,a-12);i=Y(r,s)==101075792,i&&(f=Y(r,s+32),v=Y(r,s+48))}for(var l=0;l|]/g,"_")||"Projekt",n={};for(const l of r.files)n[`${e}/${br(l.path)}`]=new Uint8Array(cr(l.text));const a=[...r.packages.map(l=>`${e}/${dr(l)}/${re(l).replace(/\./g,"/")}/`),...ee(r).map(l=>`${e}/${l}/`)];for(const l of a)Object.keys(n).some(c=>c.startsWith(l))||(n[l.replace(/\/\/$/,"/")]=new Uint8Array);return(r.uml&&Object.keys(r.uml).length||(f=r.notes)!=null&&f.length||(v=r.objects)!=null&&v.length)&&(n[`${e}/${$r}`]=new Uint8Array(cr(JSON.stringify({format:"visuobject",version:1,uml:r.uml??{},...(i=r.notes)!=null&&i.length?{notes:r.notes}:{},...(s=r.objects)!=null&&s.length?{objects:r.objects}:{}},null,2)))),Me(n,{level:6})}function ze(r,e){var c;const n=Ce(r),a=Object.entries(n).filter(([t])=>/\.java$/i.test(t)&&!t.startsWith("__MACOSX/")).map(([t,o])=>({name:t,text:jr(o)})),f=new Set(Object.keys(n).map(t=>t.split("/")[0])),v=f.size===1&&Object.keys(n).some(t=>t.includes("/"))?[...f][0]:e,i=v!==e,s=Br(v,[]);for(const t of a){const o=Br(v,[{name:t.name.slice(t.name.lastIndexOf("/")+1),text:t.text}]).files[0],u=t.name.split("/").slice(i?1:0,-1),h=Er(o.text).split(".").filter(Boolean),w=u.slice(u.length-h.length).join("/")===h.join("/")?u.slice(0,u.length-h.length).join("/"):"",x=w&&w!==mr&&w.split("/").every(Gr)&&!w.includes(":")?w:mr,T=Qr(Vr(x,Er(o.text)),o.path.slice(o.path.lastIndexOf("/")+1));s.files=[...s.files.filter(z=>z.path!==T),{...o,path:T}],x!==mr&&!((c=s.sourceFolders)!=null&&c.includes(x))&&(s.sourceFolders=[...s.sourceFolders??[],x])}const l=Object.entries(n).find(([t])=>t===$r||t.endsWith(`/${$r}`));if(l)try{const t=JSON.parse(jr(l[1])),o=Lr(t.uml);o&&(s.uml=o);const u=_r(t.notes);u&&(s.notes=u);const h=pr(t.objects);h&&(s.objects=h)}catch{}return s}export{ze as projectFromZip,je as projectToZip}; +import{p as Br,d as Er,a as mr,i as Gr,b as Qr,c as Vr,u as Lr,n as _r,o as pr,e as br,r as dr,f as re,s as ee}from"./objectApp-Thy8-AED.js";import"./index-Dntu0aWH.js";var M=Uint8Array,K=Uint16Array,Tr=Int32Array,hr=new M([0,0,0,0,0,0,0,0,1,1,1,1,2,2,2,2,3,3,3,3,4,4,4,4,5,5,5,5,0,0,0,0]),gr=new M([0,0,0,0,1,1,2,2,3,3,4,4,5,5,6,6,7,7,8,8,9,9,10,10,11,11,12,12,13,13,0,0]),Sr=new M([16,17,18,0,8,7,9,6,10,5,11,4,12,3,13,2,14,1,15]),Wr=function(r,e){for(var n=new K(31),a=0;a<31;++a)n[a]=e+=1<>1|(F&21845)<<1;b=(b&52428)>>2|(b&13107)<<2,b=(b&61680)>>4|(b&3855)<<4,Cr[F]=((b&65280)>>8|(b&255)<<8)>>1}var V=(function(r,e,n){for(var a=r.length,f=0,v=new K(e);f>l]=c}else for(s=new K(a),f=0;f>15-r[f]);return s}),d=new M(288);for(var F=0;F<144;++F)d[F]=8;for(var F=144;F<256;++F)d[F]=9;for(var F=256;F<280;++F)d[F]=7;for(var F=280;F<288;++F)d[F]=8;var ir=new M(32);for(var F=0;F<32;++F)ir[F]=5;var ae=V(d,9,0),fe=V(d,9,1),ve=V(ir,5,0),te=V(ir,5,1),xr=function(r){for(var e=r[0],n=1;ne&&(e=r[n]);return e},X=function(r,e,n){var a=e/8|0;return(r[a]|r[a+1]<<8)>>(e&7)&n},yr=function(r,e){var n=e/8|0;return(r[n]|r[n+1]<<8|r[n+2]<<16)>>(e&7)},Ur=function(r){return(r+7)/8|0},lr=function(r,e,n){return(e==null||e<0)&&(e=0),(n==null||n>r.length)&&(n=r.length),new M(r.subarray(e,n))},oe=["unexpected EOF","invalid block type","invalid length/literal","invalid distance","stream finished","no stream handler",,"no callback","invalid UTF-8 data","extra field too long","date not in range 1980-2099","filename too long","stream finishing","invalid zip data"],I=function(r,e,n){var a=new Error(e||oe[r]);if(a.code=r,Error.captureStackTrace&&Error.captureStackTrace(a,I),!n)throw a;return a},ie=function(r,e,n,a){var f=r.length,v=a?a.length:0;if(!f||e.f&&!e.l)return n||new M(0);var i=!n,s=i||e.i!=2,l=e.i;i&&(n=new M(f*3));var c=function(fr){var vr=n.length;if(fr>vr){var nr=new M(Math.max(vr*2,fr));nr.set(n),n=nr}},t=e.f||0,o=e.p||0,u=e.b||0,h=e.l,y=e.d,w=e.m,x=e.n,T=f*8;do{if(!h){t=X(r,o,1);var z=X(r,o+1,3);if(o+=3,z)if(z==1)h=fe,y=te,w=9,x=5;else if(z==2){var U=X(r,o,31)+257,A=X(r,o+10,15)+4,m=U+X(r,o+5,31)+1;o+=14;for(var g=new M(m),B=new M(19),j=0;j>4;if(C<16)g[j++]=C;else{var E=0,k=0;for(C==16?(k=3+X(r,o,3),o+=2,E=g[j-1]):C==17?(k=3+X(r,o,7),o+=3):C==18&&(k=11+X(r,o,127),o+=7);k--;)g[j++]=E}}var W=g.subarray(0,U),J=g.subarray(U);w=xr(W),x=xr(J),h=V(W,w,1),y=V(J,x,1)}else I(1);else{var C=Ur(o)+4,O=r[C-4]|r[C-3]<<8,$=C+O;if($>f){l&&I(0);break}s&&c(u+O),n.set(r.subarray(C,$),u),e.b=u+=O,e.p=o=$*8,e.f=t;continue}if(o>T){l&&I(0);break}}s&&c(u+131072);for(var ar=(1<>4;if(o+=E&15,o>T){l&&I(0);break}if(E||I(2),q<256)n[u++]=q;else if(q==256){L=o,h=null;break}else{var H=q-254;if(q>264){var j=q-257,S=hr[j];H=X(r,o,(1<>4;G||I(3),o+=G&15;var J=ne[rr];if(rr>3){var S=gr[rr];J+=yr(r,o)&(1<T){l&&I(0);break}s&&c(u+131072);var er=u+H;if(u>8},tr=function(r,e,n){n<<=e&7;var a=e/8|0;r[a]|=n,r[a+1]|=n>>8,r[a+2]|=n>>16},Fr=function(r,e){for(var n=[],a=0;au&&(u=v[a].s);var h=new K(u+1),y=Or(n[t-1],h,0);if(y>e){var a=0,w=0,x=y-e,T=1<e)w+=T-(1<>=x;w>0;){var C=v[a].s;h[C]=0&&w;--a){var O=v[a].s;h[O]==e&&(--h[O],++w)}y=e}return{t:new M(h),l:y}},Or=function(r,e,n){return r.s==-1?Math.max(Or(r.l,e,n+1),Or(r.r,e,n+1)):e[r.s]=n},Nr=function(r){for(var e=r.length;e&&!r[--e];);for(var n=new K(++e),a=0,f=r[0],v=1,i=function(l){n[a++]=l},s=1;s<=e;++s)if(r[s]==f&&s!=e)++v;else{if(!f&&v>2){for(;v>138;v-=138)i(32754);v>2&&(i(v>10?v-11<<5|28690:v-3<<5|12305),v=0)}else if(v>3){for(i(f),--v;v>6;v-=6)i(8304);v>2&&(i(v-3<<5|8208),v=0)}for(;v--;)i(f);v=1,f=r[s]}return{c:n.subarray(0,a),n:e}},or=function(r,e){for(var n=0,a=0;a>8,r[f+2]=r[f]^255,r[f+3]=r[f+1]^255;for(var v=0;v4&&!B[Sr[D-1]];--D);var p=c+5<<3,Z=or(f,d)+or(v,ir)+i,P=or(f,u)+or(v,w)+i+14+3*D+or(A,B)+2*A[16]+3*A[17]+7*A[18];if(l>=0&&p<=Z&&p<=P)return Kr(e,t,r.subarray(l,l+c));var E,k,W,J;if(_(e,t,1+(P15&&(_(e,t,q[m]>>5&127),t+=q[m]>>12)}}else E=ae,k=d,W=ve,J=ir;for(var m=0;m255){var H=S>>18&31;tr(e,t,E[H+257]),t+=k[H+257],H>7&&(_(e,t,S>>23&31),t+=hr[H]);var G=S&31;tr(e,t,W[G]),t+=J[G],G>3&&(tr(e,t,S>>5&8191),t+=gr[G])}else tr(e,t,E[S]),t+=k[S]}return tr(e,t,E[256]),t+k[256]},le=new Tr([65540,131080,131088,131104,262176,1048704,1048832,2114560,2117632]),Rr=new M(0),se=function(r,e,n,a,f,v){var i=v.z||r.length,s=new M(a+i+5*(1+Math.ceil(i/7e3))+f),l=s.subarray(a,s.length-f),c=v.l,t=(v.r||0)&7;if(e){t&&(l[0]=v.r>>3);for(var o=le[e-1],u=o>>13,h=o&8191,y=(1<7e3||B>24576)&&(E>423||!c)){t=Dr(r,l,0,O,$,U,m,B,D,g-D,t),B=A=m=0,D=g;for(var k=0;k<286;++k)$[k]=0;for(var k=0;k<30;++k)U[k]=0}var W=2,J=0,ar=h,R=Z-P&32767;if(E>2&&p==C(g-R))for(var L=Math.min(u,E)-1,q=Math.min(32767,g),H=Math.min(258,E);R<=q&&--ar&&Z!=P;){if(r[g+W]==r[g+W-R]){for(var S=0;SW){if(W=S,J=R,S>L)break;for(var G=Math.min(R,S-2),rr=0,k=0;krr&&(rr=ur,P=er)}}}Z=P,P=w[Z],R+=Z-P&32767}if(J){O[B++]=268435456|Mr[W]<<18|Jr[J];var fr=Mr[W]&31,vr=Jr[J]&31;m+=hr[fr]+gr[vr],++$[257+fr],++U[vr],j=g+W,++A}else O[B++]=r[g],++$[r[g]]}}for(g=Math.max(g,j);g=i&&(l[t/8|0]=c,nr=i),t=Kr(l,t+1,r.subarray(g,nr))}v.i=i}return lr(s,0,a+Ur(t)+f)},ue=(function(){for(var r=new Int32Array(256),e=0;e<256;++e){for(var n=e,a=9;--a;)n=(n&1&&-306674912)^n>>>1;r[e]=n}return r})(),ce=function(){var r=-1;return{p:function(e){for(var n=r,a=0;a>>8;r=n},d:function(){return~r}}},he=function(r,e,n,a,f){if(!f&&(f={l:1},e.dictionary)){var v=e.dictionary.subarray(-32768),i=new M(v.length+r.length);i.set(v),i.set(r,v.length),r=i,f.w=v.length}return se(r,e.level==null?6:e.level,e.mem==null?f.l?Math.ceil(Math.max(8,Math.min(13,Math.log(r.length)))*1.5):20:12+e.mem,n,a,f)},Xr=function(r,e){var n={};for(var a in r)n[a]=r[a];for(var a in e)n[a]=e[a];return n},Q=function(r,e){return r[e]|r[e+1]<<8},Y=function(r,e){return(r[e]|r[e+1]<<8|r[e+2]<<16|r[e+3]<<24)>>>0},kr=function(r,e){return Y(r,e)+Y(r,e+4)*4294967296},N=function(r,e,n){for(;n;++e)r[e]=n,n>>>=8};function ge(r,e){return he(r,e||{},0,0)}function we(r,e){return ie(r,{i:2},e&&e.out,e&&e.dictionary)}var Yr=function(r,e,n,a){for(var f in r){var v=r[f],i=e+f,s=a;Array.isArray(v)&&(s=Xr(a,v[1]),v=v[0]),v instanceof M?n[i]=[v,s]:(n[i+="/"]=[new M(0),s],Yr(v,i,n,a))}},Ir=typeof TextEncoder<"u"&&new TextEncoder,Ar=typeof TextDecoder<"u"&&new TextDecoder,me=0;try{Ar.decode(Rr,{stream:!0}),me=1}catch{}var xe=function(r){for(var e="",n=0;;){var a=r[n++],f=(a>127)+(a>223)+(a>239);if(n+f>r.length)return{s:e,r:lr(r,n-1)};f?f==3?(a=((a&15)<<18|(r[n++]&63)<<12|(r[n++]&63)<<6|r[n++]&63)-65536,e+=String.fromCharCode(55296|a>>10,56320|a&1023)):f&1?e+=String.fromCharCode((a&31)<<6|r[n++]&63):e+=String.fromCharCode((a&15)<<12|(r[n++]&63)<<6|r[n++]&63):e+=String.fromCharCode(a)}};function cr(r,e){var n;if(Ir)return Ir.encode(r);for(var a=r.length,f=new M(r.length+(r.length>>1)),v=0,i=function(c){f[v++]=c},n=0;nf.length){var s=new M(v+8+(a-n<<1));s.set(f),f=s}var l=r.charCodeAt(n);l<128||e?i(l):l<2048?(i(192|l>>6),i(128|l&63)):l>55295&&l<57344?(l=65536+(l&1047552)|r.charCodeAt(++n)&1023,i(240|l>>18),i(128|l>>12&63),i(128|l>>6&63),i(128|l&63)):(i(224|l>>12),i(128|l>>6&63),i(128|l&63))}return lr(f,0,v)}function jr(r,e){if(e){for(var n="",a=0;a65535&&I(9),e+=a+4}return e},Pr=function(r,e,n,a,f,v,i,s){var l=a.length,c=n.extra,t=s&&s.length,o=zr(c);N(r,e,i!=null?33639248:67324752),e+=4,i!=null&&(r[e++]=20,r[e++]=n.os),r[e]=20,e+=2,r[e++]=n.flag<<1|(v<0&&8),r[e++]=f&&8,r[e++]=n.compression&255,r[e++]=n.compression>>8;var u=new Date(n.mtime==null?Date.now():n.mtime),h=u.getFullYear()-1980;if((h<0||h>119)&&I(10),N(r,e,h<<25|u.getMonth()+1<<21|u.getDate()<<16|u.getHours()<<11|u.getMinutes()<<5|u.getSeconds()>>1),e+=4,v!=-1&&(N(r,e,n.crc),N(r,e+4,v<0?-v-2:v),N(r,e+8,n.size)),N(r,e+12,l),N(r,e+14,o),e+=16,i!=null&&(N(r,e,t),N(r,e+6,n.attrs),N(r,e+10,i),e+=14),r.set(a,e),e+=l,o)for(var y in c){var w=c[y],x=w.length;N(r,e,+y),N(r,e+2,x),r.set(w,e+4),e+=4+x}return t&&(r.set(s,e),e+=t),e},Se=function(r,e,n,a,f){N(r,e,101010256),N(r,e+8,n),N(r,e+10,n),N(r,e+12,a),N(r,e+16,f)};function Me(r,e){e||(e={});var n={},a=[];Yr(r,"",n,e);var f=0,v=0;for(var i in n){var s=n[i],l=s[0],c=s[1],t=c.level==0?0:8,o=cr(i),u=o.length,h=c.comment,y=h&&cr(h),w=y&&y.length,x=zr(c.extra);u>65535&&I(11);var T=t?ge(l,c):l,z=T.length,C=ce();C.p(l),a.push(Xr(c,{size:l.length,crc:C.d(),c:T,f:o,m:y,u:u!=i.length||y&&h.length!=w,o:f,compression:t})),f+=30+u+x+z,v+=76+2*(u+x)+(w||0)+z}for(var O=new M(v+22),$=f,U=v-f,A=0;A65558)&&I(13);var f=Q(r,a+8);if(!f)return{};var v=Y(r,a+16),i=v==4294967295||f==65535;if(i){var s=Y(r,a-12);i=Y(r,s)==101075792,i&&(f=Y(r,s+32),v=Y(r,s+48))}for(var l=0;l|]/g,"_")||"Projekt",n={};for(const l of r.files)n[`${e}/${br(l.path)}`]=new Uint8Array(cr(l.text));const a=[...r.packages.map(l=>`${e}/${dr(l)}/${re(l).replace(/\./g,"/")}/`),...ee(r).map(l=>`${e}/${l}/`)];for(const l of a)Object.keys(n).some(c=>c.startsWith(l))||(n[l.replace(/\/\/$/,"/")]=new Uint8Array);return(r.uml&&Object.keys(r.uml).length||(f=r.notes)!=null&&f.length||(v=r.objects)!=null&&v.length)&&(n[`${e}/${$r}`]=new Uint8Array(cr(JSON.stringify({format:"visuobject",version:1,uml:r.uml??{},...(i=r.notes)!=null&&i.length?{notes:r.notes}:{},...(s=r.objects)!=null&&s.length?{objects:r.objects}:{}},null,2)))),Me(n,{level:6})}function ze(r,e){var c;const n=Ce(r),a=Object.entries(n).filter(([t])=>/\.java$/i.test(t)&&!t.startsWith("__MACOSX/")).map(([t,o])=>({name:t,text:jr(o)})),f=new Set(Object.keys(n).map(t=>t.split("/")[0])),v=f.size===1&&Object.keys(n).some(t=>t.includes("/"))?[...f][0]:e,i=v!==e,s=Br(v,[]);for(const t of a){const o=Br(v,[{name:t.name.slice(t.name.lastIndexOf("/")+1),text:t.text}]).files[0],u=t.name.split("/").slice(i?1:0,-1),h=Er(o.text).split(".").filter(Boolean),w=u.slice(u.length-h.length).join("/")===h.join("/")?u.slice(0,u.length-h.length).join("/"):"",x=w&&w!==mr&&w.split("/").every(Gr)&&!w.includes(":")?w:mr,T=Qr(Vr(x,Er(o.text)),o.path.slice(o.path.lastIndexOf("/")+1));s.files=[...s.files.filter(z=>z.path!==T),{...o,path:T}],x!==mr&&!((c=s.sourceFolders)!=null&&c.includes(x))&&(s.sourceFolders=[...s.sourceFolders??[],x])}const l=Object.entries(n).find(([t])=>t===$r||t.endsWith(`/${$r}`));if(l)try{const t=JSON.parse(jr(l[1])),o=Lr(t.uml);o&&(s.uml=o);const u=_r(t.notes);u&&(s.notes=u);const h=pr(t.objects);h&&(s.objects=h)}catch{}return s}export{ze as projectFromZip,je as projectToZip}; diff --git a/website/app/assets/robot3d-BNw8Z2K3.js b/website/app/assets/robot3d-SvNK2bGm.js similarity index 99% rename from website/app/assets/robot3d-BNw8Z2K3.js rename to website/app/assets/robot3d-SvNK2bGm.js index b367ce72..3db6e696 100644 --- a/website/app/assets/robot3d-BNw8Z2K3.js +++ b/website/app/assets/robot3d-SvNK2bGm.js @@ -1,4 +1,4 @@ -var gl=Object.defineProperty;var _l=(i,t,e)=>t in i?gl(i,t,{enumerable:!0,configurable:!0,writable:!0,value:e}):i[t]=e;var le=(i,t,e)=>_l(i,typeof t!="symbol"?t+"":t,e);import{C as rn,L as oo}from"./index-CzgrZgZa.js";/** +var gl=Object.defineProperty;var _l=(i,t,e)=>t in i?gl(i,t,{enumerable:!0,configurable:!0,writable:!0,value:e}):i[t]=e;var le=(i,t,e)=>_l(i,typeof t!="symbol"?t+"":t,e);import{C as rn,L as oo}from"./index-Dntu0aWH.js";/** * @license * Copyright 2010-2025 Three.js Authors * SPDX-License-Identifier: MIT diff --git a/website/app/index.html b/website/app/index.html index 6fb96b9b..922f7c45 100644 --- a/website/app/index.html +++ b/website/app/index.html @@ -6,7 +6,7 @@ VisuStruct Web - +