From ce7d2af6f1288fc7cbe067132dcdfec17776fb3b Mon Sep 17 00:00:00 2001 From: Claude Date: Fri, 30 Oct 2026 17:07:51 +0000 Subject: [PATCH] Web 0.13.8: Schleife in Lektion 1 als gekipptes L MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Statt „Klammer links“ heißt die Schleifenform im Struktogramm jetzt „gekipptes L“ (en upside-down L, pt L invertido), im Text, im Vergleich und im Wissenstest. Co-Authored-By: Claude Opus 5.5 Claude-Session: https://claude.ai/code/session_01Ugz28UN7HvRoMmJHmaecJn --- CHANGELOG.md | 1 + web/lessons/de/01-was-ist-ein-struktogramm.md | 16 ++--- web/lessons/en/01-was-ist-ein-struktogramm.md | 16 ++--- web/lessons/pt/01-was-ist-ein-struktogramm.md | 16 ++--- web/package-lock.json | 4 +- web/package.json | 2 +- .../{index-FLiLJX9D.js => index-Bx-6trOD.js} | 60 +++++++++---------- ...tApp-B5M5sW_m.js => objectApp-D9StvWDS.js} | 8 +-- ...Zip-NDe93a6D.js => projectZip-DrvMtqWX.js} | 2 +- ...obot3d-DuVc6opp.js => robot3d-VilOVDMf.js} | 2 +- website/app/index.html | 2 +- 11 files changed, 65 insertions(+), 64 deletions(-) rename website/app/assets/{index-FLiLJX9D.js => index-Bx-6trOD.js} (99%) rename website/app/assets/{objectApp-B5M5sW_m.js => objectApp-D9StvWDS.js} (99%) rename website/app/assets/{projectZip-NDe93a6D.js => projectZip-DrvMtqWX.js} (99%) rename website/app/assets/{robot3d-DuVc6opp.js => robot3d-VilOVDMf.js} (99%) diff --git a/CHANGELOG.md b/CHANGELOG.md index fba36096..8e190bfa 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,7 @@ The format is loosely inspired by Keep a Changelog. ### Added +- **Web 0.13.8, loop in lesson 1 is a „gekipptes L“:** lesson 1 no longer calls the loop shape in the Struktogramm a „Klammer links“ but a „gekipptes L“ (condition on top, strip on the left), in the text, the comparison and the quiz (en „upside-down L“, pt „L invertido“). - **Web 0.13.7, statements without class are coloured too:** when Programmieren shows the code without `class` and `main` (e.g. „Aufstehen;“, „Zähne putzen;“ in lesson 1), the statements now sit in a yellow block like a method, matching the yellow statements in the Struktogramm; loops and branches inside keep their own colours. Statements are now always yellow, also inside a loop or branch (own yellow stripe in the code, yellow box in the Struktogramm and in lesson 1); only the empty ø takes the colour of its block. A loop with pseudocode condition (`while (Tee noch zu heiß) {`) is coloured up to its closing brace. - **Web 0.13.6, lesson header pinned at the top:** in a lesson step the header (← Alle Lektionen, lesson title, step numbers, step title) stays at the top of the lesson column with its own ← Zurück / Weiter → buttons next to „Alle Lektionen“; only the step content below scrolls. The buttons at the end of the step stay as well. - **Web 0.13.4, Pseudocode switch in the toolbar and simulation of pseudocode:** the checkbox „Pseudocode“ now sits in the toolbar left of ⇄ (before it was only in the code window). For a diagram marked as pseudocode (e.g. „Tee kochen“ in Lektion 1) the simulation no longer runs the boxes as Java: it only highlights them one after another, and for a condition („Regnet es?“), a loop or a Fallauswahl it asks for the answer (true/false or ja/nein, case name). Programmieren shows no Java errors for pseudocode. Lektion 1 now mentions spaghetti code right where it says a Struktogramm has no jumps. diff --git a/web/lessons/de/01-was-ist-ein-struktogramm.md b/web/lessons/de/01-was-ist-ein-struktogramm.md index edee9db1..73ad3d27 100644 --- a/web/lessons/de/01-was-ist-ein-struktogramm.md +++ b/web/lessons/de/01-was-ist-ein-struktogramm.md @@ -79,8 +79,8 @@ Soll etwas **mehrmals** passieren, schreibt man es nicht mehrmals hin. Stattdess So sieht sie aus: - Oben steht die Bedingung, zum Beispiel *Teller nicht leer*. -- Die Schritte, die wiederholt werden, stehen **eingerückt** darunter. Links bildet der Kasten eine **Klammer** um sie. -- Vor jedem Durchlauf wird die Bedingung geprüft. Solange sie **true** ist, werden die Schritte in der Klammer noch einmal ausgeführt. Ist sie **false**, geht es unter der Schleife weiter. +- Die Schritte, die wiederholt werden, stehen **eingerückt** darunter. Oben und links bildet der Kasten ein **gekipptes L** um sie. +- Vor jedem Durchlauf wird die Bedingung geprüft. Solange sie **true** ist, werden die Schritte im gekippten L noch einmal ausgeführt. Ist sie **false**, geht es unter der Schleife weiter. ::: diagramm l1-wiederholung.visustruct Solange der Teller nicht leer ist, wird ein Bissen gegessen. Danach wird der Teller abgeräumt. @@ -93,7 +93,7 @@ Solange der Teller nicht leer ist, wird ein Bissen gegessen. Danach wird der Tel Richtig nützlich werden die Bausteine, wenn man sie kombiniert. Das Diagramm enthält alle drei: eine Sequenz von oben nach unten, eine [Verzweigung]{.blau} und eine [Schleife]{.rosa}. Gelb sind die einfachen [Anweisungen]{.gelb}. Auch die Anweisungen in einer Verzweigung oder Schleife sind gelb. Genau genommen ist das ganze Diagramm eine Sequenz, denn auch Verzweigung und Schleife stehen in der Reihe von oben nach unten. ::: diagramm l1-grundbausteine.visustruct -Die Verzweigung erkennst du am Dreieck, die Schleife an der Klammer links. Alles zusammen steht in einer Sequenz. +Die Verzweigung erkennst du am Dreieck, die Schleife am gekippten L. Alles zusammen steht in einer Sequenz. ::: Die Kästen können auch **ineinander geschachtelt** werden: In einer Schleife oder einem Zweig können wieder Sequenzen, Verzweigungen und Schleifen stehen. @@ -137,7 +137,7 @@ Tee trinken ### Im Vergleich -- **Struktogramm:** Kästen ineinander, die Schleife ist eine Klammer links. Die Struktur siehst du auf einen Blick, wilde Sprünge sind unmöglich. +- **Struktogramm:** Kästen ineinander, die Schleife ist ein gekipptes L. Die Struktur siehst du auf einen Blick, wilde Sprünge sind unmöglich. - **PAP:** Symbole mit Pfeilen, die Schleife ist ein Pfeil zurück nach oben. Sehr anschaulich, aber bei großen Plänen schnell unübersichtlich. - **Pseudocode:** Text mit Einrückung, die Schleife steht zwischen SOLANGE und ENDE SOLANGE. Schnell geschrieben und schon nah am Programmcode. @@ -235,10 +235,10 @@ richtig: Verzweigung > Sprünge gibt es im Struktogramm nicht. Sequenz, Verzweigung und Wiederholung reichen für jeden Algorithmus. ? Woran erkennst du im Struktogramm eine Verzweigung? -- [ ] An einer Klammer auf der linken Seite +- [ ] An einem gekippten L - [x] An einem Dreieck mit der Bedingung und zwei Spalten darunter - [ ] An mehreren Rechtecken untereinander -> Die Klammer gehört zur Schleife, Rechtecke untereinander sind eine Sequenz. +> Das gekippte L gehört zur Schleife, Rechtecke untereinander sind eine Sequenz. ? Wann wird der Inhalt einer Schleife noch einmal ausgeführt? - [x] Solange die Bedingung true ist @@ -253,10 +253,10 @@ richtig: Verzweigung > Ein Algorithmus ist unabhängig von der Programmiersprache. Ein Struktogramm ist eine Möglichkeit, ihn aufzuschreiben. ? Woran erkennst du in einem Programmablaufplan (PAP) eine Schleife? -- [ ] An einer Klammer auf der linken Seite +- [ ] An einem gekippten L - [x] An einem Pfeil, der zurück nach oben führt - [ ] Am Wort SOLANGE -> Die Klammer gehört zum Struktogramm, SOLANGE zum Pseudocode. +> Das gekippte L gehört zum Struktogramm, SOLANGE zum Pseudocode. ? Ordne jedem Symbol im PAP seine Bedeutung zu. = Oval -> Start oder Ende diff --git a/web/lessons/en/01-was-ist-ein-struktogramm.md b/web/lessons/en/01-was-ist-ein-struktogramm.md index f8bcc63e..88b8546b 100644 --- a/web/lessons/en/01-was-ist-ein-struktogramm.md +++ b/web/lessons/en/01-was-ist-ein-struktogramm.md @@ -79,8 +79,8 @@ If something should happen **several times**, you do not write it down several t This is what it looks like: - At the top is the condition, for example *Plate not empty*. -- The steps that are repeated are **indented** below it. On the left, the box forms a **bracket** around them. -- Before every pass the condition is checked. As long as it is **true**, the steps inside the bracket run once more. If it is **false**, the program continues below the loop. +- The steps that are repeated are **indented** below it. At the top and on the left, the box forms an **upside-down L** around them. +- Before every pass the condition is checked. As long as it is **true**, the steps inside the upside-down L run once more. If it is **false**, the program continues below the loop. ::: diagramm l1-wiederholung.visustruct As long as the plate is not empty, you take a bite. After that, the plate is cleared. @@ -93,7 +93,7 @@ As long as the plate is not empty, you take a bite. After that, the plate is cle The building blocks become really useful when you combine them. This diagram contains all three: a sequence from top to bottom, a [branch]{.blau} and a [loop]{.rosa}. The yellow boxes are simple [statements]{.gelb}. The statements inside a branch or a loop are yellow too. Strictly speaking, the whole diagram is a sequence, because the branch and the loop also stand in the row from top to bottom. ::: diagramm l1-grundbausteine.visustruct -You recognise the branch by its triangle and the loop by the bracket on the left. Everything together sits in a sequence. +You recognise the branch by its triangle and the loop by its upside-down L. Everything together sits in a sequence. ::: The boxes can also be **nested** inside each other: a loop or a path can contain sequences, branches and loops again. @@ -137,7 +137,7 @@ Drink the tea ### Compared -- **Structure chart:** boxes inside boxes, the loop is a bracket on the left. You see the structure at a glance, and wild jumps are impossible. +- **Structure chart:** boxes inside boxes, the loop is an upside-down L. You see the structure at a glance, and wild jumps are impossible. - **Flowchart:** symbols with arrows, the loop is an arrow back up. Very easy to picture, but big charts quickly get confusing. - **Pseudocode:** text with indentation, the loop sits between WHILE and END WHILE. Quick to write and already close to program code. @@ -235,10 +235,10 @@ richtig: branch > There are no jumps in a structure chart. Sequence, branch and loop are enough for every algorithm. ? How do you recognise a branch in a structure chart? -- [ ] By a bracket on the left side +- [ ] By an upside-down L - [x] By a triangle with the condition and two columns below it - [ ] By several rectangles on top of each other -> The bracket belongs to the loop, and rectangles on top of each other are a sequence. +> The upside-down L belongs to the loop, and rectangles on top of each other are a sequence. ? When does the inside of a loop run once more? - [x] As long as the condition is true @@ -253,10 +253,10 @@ richtig: branch > An algorithm does not depend on a programming language. A structure chart is one way to write it down. ? How do you recognise a loop in a flowchart? -- [ ] By a bracket on the left side +- [ ] By an upside-down L - [x] By an arrow that leads back up - [ ] By the word WHILE -> The bracket belongs to the structure chart, and WHILE to pseudocode. +> The upside-down L belongs to the structure chart, and WHILE to pseudocode. ? Match each flowchart symbol to its meaning. = Oval -> Start or end diff --git a/web/lessons/pt/01-was-ist-ein-struktogramm.md b/web/lessons/pt/01-was-ist-ein-struktogramm.md index 981c8410..07b82256 100644 --- a/web/lessons/pt/01-was-ist-ein-struktogramm.md +++ b/web/lessons/pt/01-was-ist-ein-struktogramm.md @@ -79,8 +79,8 @@ Se uma coisa deve acontecer **várias vezes**, não a escreves várias vezes. Em É assim que se parece: - Em cima está a condição, por exemplo *Prato não vazio*. -- Os passos que se repetem ficam **recuados** por baixo dela. À esquerda, o bloco forma um **parêntese** à volta deles. -- Antes de cada iteração, a condição é verificada. Enquanto for **true**, os passos dentro do parêntese são executados mais uma vez. Se for **false**, o programa continua por baixo do ciclo. +- Os passos que se repetem ficam **recuados** por baixo dela. Em cima e à esquerda, o bloco forma um **L invertido** à volta deles. +- Antes de cada iteração, a condição é verificada. Enquanto for **true**, os passos dentro do L invertido são executados mais uma vez. Se for **false**, o programa continua por baixo do ciclo. ::: diagramm l1-wiederholung.visustruct Enquanto o prato não estiver vazio, dás uma garfada. Depois, o prato é levantado. @@ -93,7 +93,7 @@ Enquanto o prato não estiver vazio, dás uma garfada. Depois, o prato é levant Os blocos básicos tornam-se realmente úteis quando os combinas. Este diagrama contém os três: uma sequência de cima para baixo, uma [decisão]{.blau} e um [ciclo]{.rosa}. As caixas amarelas são [instruções]{.gelb} simples. As instruções dentro de uma decisão ou de um ciclo também são amarelas. Em rigor, o diagrama todo é uma sequência, porque a decisão e o ciclo também estão na fila de cima para baixo. ::: diagramm l1-grundbausteine.visustruct -Reconheces a decisão pelo triângulo e o ciclo pelo parêntese à esquerda. Tudo junto forma uma sequência. +Reconheces a decisão pelo triângulo e o ciclo pelo L invertido. Tudo junto forma uma sequência. ::: Os blocos também podem ser **encaixados** uns dentro dos outros: um ciclo ou um ramo pode voltar a conter sequências, decisões e ciclos. @@ -137,7 +137,7 @@ Beber o chá ### Comparação -- **Estrutograma:** blocos dentro de blocos, o ciclo é um parêntese à esquerda. Vês a estrutura num relance, e saltos malucos são impossíveis. +- **Estrutograma:** blocos dentro de blocos, o ciclo é um L invertido. Vês a estrutura num relance, e saltos malucos são impossíveis. - **Fluxograma:** símbolos com setas, o ciclo é uma seta que volta para cima. Muito fácil de imaginar, mas os fluxogramas grandes ficam depressa confusos. - **Pseudocódigo:** texto com indentação, o ciclo fica entre ENQUANTO e FIM ENQUANTO. Rápido de escrever e já perto do código de um programa. @@ -235,10 +235,10 @@ richtig: decisão > Num estrutograma não há saltos. Sequência, decisão e ciclo chegam para qualquer algoritmo. ? Como reconheces uma decisão num estrutograma? -- [ ] Por um parêntese do lado esquerdo +- [ ] Por um L invertido - [x] Por um triângulo com a condição e duas colunas por baixo - [ ] Por vários retângulos uns por cima dos outros -> O parêntese pertence ao ciclo, e retângulos uns por cima dos outros são uma sequência. +> O L invertido pertence ao ciclo, e retângulos uns por cima dos outros são uma sequência. ? Quando é que o interior de um ciclo é executado mais uma vez? - [x] Enquanto a condição for verdadeira @@ -253,10 +253,10 @@ richtig: decisão > Um algoritmo não depende de nenhuma linguagem de programação. Um estrutograma é uma forma de o escrever. ? Como reconheces um ciclo num fluxograma? -- [ ] Por um parêntese do lado esquerdo +- [ ] Por um L invertido - [x] Por uma seta que volta para cima - [ ] Pela palavra ENQUANTO -> O parêntese pertence ao estrutograma, e ENQUANTO ao pseudocódigo. +> O L invertido pertence ao estrutograma, e ENQUANTO ao pseudocódigo. ? Associa cada símbolo do fluxograma ao seu significado. = Oval -> Início ou fim diff --git a/web/package-lock.json b/web/package-lock.json index 3b133508..57bf80fc 100644 --- a/web/package-lock.json +++ b/web/package-lock.json @@ -1,12 +1,12 @@ { "name": "visustruct-web", - "version": "0.13.7", + "version": "0.13.8", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "visustruct-web", - "version": "0.13.7", + "version": "0.13.8", "dependencies": { "@codemirror/autocomplete": "^6.20.4", "@codemirror/commands": "^6.11.1", diff --git a/web/package.json b/web/package.json index f44b6326..7462aca0 100644 --- a/web/package.json +++ b/web/package.json @@ -1,7 +1,7 @@ { "name": "visustruct-web", "private": true, - "version": "0.13.7", + "version": "0.13.8", "type": "module", "scripts": { "dev": "vite", diff --git a/website/app/assets/index-FLiLJX9D.js b/website/app/assets/index-Bx-6trOD.js similarity index 99% rename from website/app/assets/index-FLiLJX9D.js rename to website/app/assets/index-Bx-6trOD.js index 5e3cd6d5..3c302fd3 100644 --- a/website/app/assets/index-FLiLJX9D.js +++ b/website/app/assets/index-Bx-6trOD.js @@ -371,8 +371,8 @@ Soll etwas **mehrmals** passieren, schreibt man es nicht mehrmals hin. Stattdess So sieht sie aus: - Oben steht die Bedingung, zum Beispiel *Teller nicht leer*. -- Die Schritte, die wiederholt werden, stehen **eingerückt** darunter. Links bildet der Kasten eine **Klammer** um sie. -- Vor jedem Durchlauf wird die Bedingung geprüft. Solange sie **true** ist, werden die Schritte in der Klammer noch einmal ausgeführt. Ist sie **false**, geht es unter der Schleife weiter. +- Die Schritte, die wiederholt werden, stehen **eingerückt** darunter. Oben und links bildet der Kasten ein **gekipptes L** um sie. +- Vor jedem Durchlauf wird die Bedingung geprüft. Solange sie **true** ist, werden die Schritte im gekippten L noch einmal ausgeführt. Ist sie **false**, geht es unter der Schleife weiter. ::: diagramm l1-wiederholung.visustruct Solange der Teller nicht leer ist, wird ein Bissen gegessen. Danach wird der Teller abgeräumt. @@ -385,7 +385,7 @@ Solange der Teller nicht leer ist, wird ein Bissen gegessen. Danach wird der Tel Richtig nützlich werden die Bausteine, wenn man sie kombiniert. Das Diagramm enthält alle drei: eine Sequenz von oben nach unten, eine [Verzweigung]{.blau} und eine [Schleife]{.rosa}. Gelb sind die einfachen [Anweisungen]{.gelb}. Auch die Anweisungen in einer Verzweigung oder Schleife sind gelb. Genau genommen ist das ganze Diagramm eine Sequenz, denn auch Verzweigung und Schleife stehen in der Reihe von oben nach unten. ::: diagramm l1-grundbausteine.visustruct -Die Verzweigung erkennst du am Dreieck, die Schleife an der Klammer links. Alles zusammen steht in einer Sequenz. +Die Verzweigung erkennst du am Dreieck, die Schleife am gekippten L. Alles zusammen steht in einer Sequenz. ::: Die Kästen können auch **ineinander geschachtelt** werden: In einer Schleife oder einem Zweig können wieder Sequenzen, Verzweigungen und Schleifen stehen. @@ -429,7 +429,7 @@ Tee trinken ### Im Vergleich -- **Struktogramm:** Kästen ineinander, die Schleife ist eine Klammer links. Die Struktur siehst du auf einen Blick, wilde Sprünge sind unmöglich. +- **Struktogramm:** Kästen ineinander, die Schleife ist ein gekipptes L. Die Struktur siehst du auf einen Blick, wilde Sprünge sind unmöglich. - **PAP:** Symbole mit Pfeilen, die Schleife ist ein Pfeil zurück nach oben. Sehr anschaulich, aber bei großen Plänen schnell unübersichtlich. - **Pseudocode:** Text mit Einrückung, die Schleife steht zwischen SOLANGE und ENDE SOLANGE. Schnell geschrieben und schon nah am Programmcode. @@ -527,10 +527,10 @@ richtig: Verzweigung > Sprünge gibt es im Struktogramm nicht. Sequenz, Verzweigung und Wiederholung reichen für jeden Algorithmus. ? Woran erkennst du im Struktogramm eine Verzweigung? -- [ ] An einer Klammer auf der linken Seite +- [ ] An einem gekippten L - [x] An einem Dreieck mit der Bedingung und zwei Spalten darunter - [ ] An mehreren Rechtecken untereinander -> Die Klammer gehört zur Schleife, Rechtecke untereinander sind eine Sequenz. +> Das gekippte L gehört zur Schleife, Rechtecke untereinander sind eine Sequenz. ? Wann wird der Inhalt einer Schleife noch einmal ausgeführt? - [x] Solange die Bedingung true ist @@ -545,10 +545,10 @@ richtig: Verzweigung > Ein Algorithmus ist unabhängig von der Programmiersprache. Ein Struktogramm ist eine Möglichkeit, ihn aufzuschreiben. ? Woran erkennst du in einem Programmablaufplan (PAP) eine Schleife? -- [ ] An einer Klammer auf der linken Seite +- [ ] An einem gekippten L - [x] An einem Pfeil, der zurück nach oben führt - [ ] Am Wort SOLANGE -> Die Klammer gehört zum Struktogramm, SOLANGE zum Pseudocode. +> Das gekippte L gehört zum Struktogramm, SOLANGE zum Pseudocode. ? Ordne jedem Symbol im PAP seine Bedeutung zu. = Oval -> Start oder Ende @@ -11453,8 +11453,8 @@ If something should happen **several times**, you do not write it down several t This is what it looks like: - At the top is the condition, for example *Plate not empty*. -- The steps that are repeated are **indented** below it. On the left, the box forms a **bracket** around them. -- Before every pass the condition is checked. As long as it is **true**, the steps inside the bracket run once more. If it is **false**, the program continues below the loop. +- The steps that are repeated are **indented** below it. At the top and on the left, the box forms an **upside-down L** around them. +- Before every pass the condition is checked. As long as it is **true**, the steps inside the upside-down L run once more. If it is **false**, the program continues below the loop. ::: diagramm l1-wiederholung.visustruct As long as the plate is not empty, you take a bite. After that, the plate is cleared. @@ -11467,7 +11467,7 @@ As long as the plate is not empty, you take a bite. After that, the plate is cle The building blocks become really useful when you combine them. This diagram contains all three: a sequence from top to bottom, a [branch]{.blau} and a [loop]{.rosa}. The yellow boxes are simple [statements]{.gelb}. The statements inside a branch or a loop are yellow too. Strictly speaking, the whole diagram is a sequence, because the branch and the loop also stand in the row from top to bottom. ::: diagramm l1-grundbausteine.visustruct -You recognise the branch by its triangle and the loop by the bracket on the left. Everything together sits in a sequence. +You recognise the branch by its triangle and the loop by its upside-down L. Everything together sits in a sequence. ::: The boxes can also be **nested** inside each other: a loop or a path can contain sequences, branches and loops again. @@ -11511,7 +11511,7 @@ Drink the tea ### Compared -- **Structure chart:** boxes inside boxes, the loop is a bracket on the left. You see the structure at a glance, and wild jumps are impossible. +- **Structure chart:** boxes inside boxes, the loop is an upside-down L. You see the structure at a glance, and wild jumps are impossible. - **Flowchart:** symbols with arrows, the loop is an arrow back up. Very easy to picture, but big charts quickly get confusing. - **Pseudocode:** text with indentation, the loop sits between WHILE and END WHILE. Quick to write and already close to program code. @@ -11609,10 +11609,10 @@ richtig: branch > There are no jumps in a structure chart. Sequence, branch and loop are enough for every algorithm. ? How do you recognise a branch in a structure chart? -- [ ] By a bracket on the left side +- [ ] By an upside-down L - [x] By a triangle with the condition and two columns below it - [ ] By several rectangles on top of each other -> The bracket belongs to the loop, and rectangles on top of each other are a sequence. +> The upside-down L belongs to the loop, and rectangles on top of each other are a sequence. ? When does the inside of a loop run once more? - [x] As long as the condition is true @@ -11627,10 +11627,10 @@ richtig: branch > An algorithm does not depend on a programming language. A structure chart is one way to write it down. ? How do you recognise a loop in a flowchart? -- [ ] By a bracket on the left side +- [ ] By an upside-down L - [x] By an arrow that leads back up - [ ] By the word WHILE -> The bracket belongs to the structure chart, and WHILE to pseudocode. +> The upside-down L belongs to the structure chart, and WHILE to pseudocode. ? Match each flowchart symbol to its meaning. = Oval -> Start or end @@ -22531,8 +22531,8 @@ Se uma coisa deve acontecer **várias vezes**, não a escreves várias vezes. Em É assim que se parece: - Em cima está a condição, por exemplo *Prato não vazio*. -- Os passos que se repetem ficam **recuados** por baixo dela. À esquerda, o bloco forma um **parêntese** à volta deles. -- Antes de cada iteração, a condição é verificada. Enquanto for **true**, os passos dentro do parêntese são executados mais uma vez. Se for **false**, o programa continua por baixo do ciclo. +- Os passos que se repetem ficam **recuados** por baixo dela. Em cima e à esquerda, o bloco forma um **L invertido** à volta deles. +- Antes de cada iteração, a condição é verificada. Enquanto for **true**, os passos dentro do L invertido são executados mais uma vez. Se for **false**, o programa continua por baixo do ciclo. ::: diagramm l1-wiederholung.visustruct Enquanto o prato não estiver vazio, dás uma garfada. Depois, o prato é levantado. @@ -22545,7 +22545,7 @@ Enquanto o prato não estiver vazio, dás uma garfada. Depois, o prato é levant Os blocos básicos tornam-se realmente úteis quando os combinas. Este diagrama contém os três: uma sequência de cima para baixo, uma [decisão]{.blau} e um [ciclo]{.rosa}. As caixas amarelas são [instruções]{.gelb} simples. As instruções dentro de uma decisão ou de um ciclo também são amarelas. Em rigor, o diagrama todo é uma sequência, porque a decisão e o ciclo também estão na fila de cima para baixo. ::: diagramm l1-grundbausteine.visustruct -Reconheces a decisão pelo triângulo e o ciclo pelo parêntese à esquerda. Tudo junto forma uma sequência. +Reconheces a decisão pelo triângulo e o ciclo pelo L invertido. Tudo junto forma uma sequência. ::: Os blocos também podem ser **encaixados** uns dentro dos outros: um ciclo ou um ramo pode voltar a conter sequências, decisões e ciclos. @@ -22589,7 +22589,7 @@ Beber o chá ### Comparação -- **Estrutograma:** blocos dentro de blocos, o ciclo é um parêntese à esquerda. Vês a estrutura num relance, e saltos malucos são impossíveis. +- **Estrutograma:** blocos dentro de blocos, o ciclo é um L invertido. Vês a estrutura num relance, e saltos malucos são impossíveis. - **Fluxograma:** símbolos com setas, o ciclo é uma seta que volta para cima. Muito fácil de imaginar, mas os fluxogramas grandes ficam depressa confusos. - **Pseudocódigo:** texto com indentação, o ciclo fica entre ENQUANTO e FIM ENQUANTO. Rápido de escrever e já perto do código de um programa. @@ -22687,10 +22687,10 @@ richtig: decisão > Num estrutograma não há saltos. Sequência, decisão e ciclo chegam para qualquer algoritmo. ? Como reconheces uma decisão num estrutograma? -- [ ] Por um parêntese do lado esquerdo +- [ ] Por um L invertido - [x] Por um triângulo com a condição e duas colunas por baixo - [ ] Por vários retângulos uns por cima dos outros -> O parêntese pertence ao ciclo, e retângulos uns por cima dos outros são uma sequência. +> O L invertido pertence ao ciclo, e retângulos uns por cima dos outros são uma sequência. ? Quando é que o interior de um ciclo é executado mais uma vez? - [x] Enquanto a condição for verdadeira @@ -22705,10 +22705,10 @@ richtig: decisão > Um algoritmo não depende de nenhuma linguagem de programação. Um estrutograma é uma forma de o escrever. ? Como reconheces um ciclo num fluxograma? -- [ ] Por um parêntese do lado esquerdo +- [ ] Por um L invertido - [x] Por uma seta que volta para cima - [ ] Pela palavra ENQUANTO -> O parêntese pertence ao estrutograma, e ENQUANTO ao pseudocódigo. +> O L invertido pertence ao estrutograma, e ENQUANTO ao pseudocódigo. ? Associa cada símbolo do fluxograma ao seu significado. = Oval -> Início ou fim @@ -60311,7 +60311,7 @@ ${l}`)}La=SB(((o=e.find(([l])=>l==="begriffe.md"))==null?void 0:o[1])??"")}const

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

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

${Ae(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,Vu(Hu,this.highlightMode)});const n=e("[data-sim=delay]");n.value=this.delay,n.addEventListener("change",()=>{this.delay=n.value,Vu(fr,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=`

${Ae(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(Uh(u)):m.textContent=we(u)}this.variables.replaceChildren(r)}e.outputLines.length===0&&e.files.size===0?this.output.innerHTML=`

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

`:(this.output.replaceChildren(...e.outputLines.map(r=>{const o=document.createElement("div");return o.textContent=r,o}),...qh(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=`

${Ae(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?Kn(r):"",o.hidden=!r}}function Uh(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 f1=Array.from("ABCDEFGHIJKLMNOPQRSTUVWXYZ"),Jn=360/f1.length,lD="http://www.w3.org/2000/svg";function Me(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 ft(i,e={},t){const n=document.createElementNS(lD,i);for(const[a,s]of Object.entries(e))n.setAttribute(a,String(s));return t!==void 0&&(n.textContent=t),n}function uD(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 Qu(i,e){const t=ft("g",{class:e}),n=f1.map((a,s)=>{const r=ft("g",{transform:`rotate(${s*Jn})`});return r.append(ft("text",{x:0,y:-i,"text-anchor":"middle","dominant-baseline":"central"},a)),t.append(r),r});return{group:t,cells:n}}function mD(i,e){let t=i,n=!1,a=-t*Jn;const s=Me("section",{class:"learn-game learn-caesar"});s.append(Me("div",{class:"learn-game-head"},Me("strong",{},p("web_learn_caesar_title")))),s.append(Me("p",{class:"learn-game-status"},p("web_learn_caesar_hint")));const r=ft("svg",{viewBox:"-200 -200 400 400",class:"learn-caesar-disc",role:"img"});r.append(ft("circle",{r:196,class:"outer-disc"})),r.append(ft("path",{d:cD(196,92,Jn/2),class:"window"}));const o=Qu(168,"outer-letters");r.append(o.group);for(let O=0;O{o.cells.forEach((W,E)=>W.classList.toggle("marked",E===O)),u.cells.forEach((W,E)=>W.classList.toggle("marked",O!==void 0&&E===(O+t)%26))},_=()=>{m.textContent=String(t),l.setAttribute("transform",`rotate(${a})`),r.setAttribute("aria-label",p("web_learn_caesar_key_fmt",t)),b.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),x.classList.toggle("active",n),I.textContent=uD(v.value,n?-t:t)||" ";const O=Array.from(v.value.toUpperCase()).reverse().find(E=>f1.includes(E));if(O===void 0)return S();const W=f1.indexOf(O);S(n?(W-t+26)%26:W)},T=O=>{t=(O%26+26)%26,a=-t*Jn,_()};c.addEventListener("click",()=>T(t-1)),d.addEventListener("click",()=>T(t+1)),f.addEventListener("click",()=>{var O;n&&(v.value=((O=I.textContent)==null?void 0:O.trim())??""),n=!1,_()}),x.addEventListener("click",()=>{var O;n||(v.value=((O=I.textContent)==null?void 0:O.trim())??""),n=!0,_()}),v.addEventListener("input",_),o.cells.forEach((O,W)=>O.addEventListener("click",()=>S(W)));let j;const C=O=>{const W=r.getBoundingClientRect();return Math.atan2(O.clientY-(W.top+W.height/2),O.clientX-(W.left+W.width/2))*180/Math.PI};l.addEventListener("pointerdown",O=>{const W=O;j=C(W)-a,l.classList.add("dragging"),r.setPointerCapture(W.pointerId),W.preventDefault()}),r.addEventListener("pointermove",O=>{if(j===void 0)return;a=C(O)-j,l.setAttribute("transform",`rotate(${a})`);const W=Math.round(-a/Jn);if((W%26+26)%26!==t){t=(W%26+26)%26;const E=a;_(),a=E,l.setAttribute("transform",`rotate(${a})`)}});const P=()=>{j!==void 0&&(j=void 0,l.classList.remove("dragging"),T(t))};return r.addEventListener("pointerup",P),r.addEventListener("pointercancel",P),_(),s}function cD(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 t0=i=>p(`web_visubot_part_${i}`),$h=new WeakMap;function Yh(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=t0(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=q(async()=>{const{Robot3D:c}=await import("./robot3d-DuVc6opp.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 x=s.getBoundingClientRect();o(f,g.clientX-x.left,g.clientY-x.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 x=s.getBoundingClientRect();o(f,g.clientX-x.left,g.clientY-x.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 $h.set(a,m),m}function dD(i,e,t=!1){return Yh(i,e,t).box}function hD(i){const e=i.querySelector(".visubot-model"),t=e&&$h.get(e);for(const n of i.querySelectorAll("[data-robot-part]")){const a=(n.dataset.robotPart??"").split(",").filter(Boolean);if(n.title=a.map(t0).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 gD(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=kn(`**${t+1}/${i.length}** ${i[t].question}`)},r=Yh([],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",t0(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=V("button",{class:"primary"},o+1{o++,o{const v=i.rounds[o],w=i.seconds,I=V("div",{class:"learn-bomb-fuse"},V("span",{})),z=V("span",{class:"learn-bomb-time"}),S=V("div",{class:"learn-bomb","aria-live":"polite"},V("span",{class:"learn-bomb-icon","aria-hidden":"true"},"💣"),z,I),_=V("div",{class:"learn-game-feedback",role:"status"}),T=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,Vu(Hu,this.highlightMode)});const n=e("[data-sim=delay]");n.value=this.delay,n.addEventListener("change",()=>{this.delay=n.value,Vu(fr,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=`

${Ae(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(Uh(u)):m.textContent=we(u)}this.variables.replaceChildren(r)}e.outputLines.length===0&&e.files.size===0?this.output.innerHTML=`

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

`:(this.output.replaceChildren(...e.outputLines.map(r=>{const o=document.createElement("div");return o.textContent=r,o}),...qh(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=`

${Ae(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?Kn(r):"",o.hidden=!r}}function Uh(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 f1=Array.from("ABCDEFGHIJKLMNOPQRSTUVWXYZ"),Jn=360/f1.length,lD="http://www.w3.org/2000/svg";function Me(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 ft(i,e={},t){const n=document.createElementNS(lD,i);for(const[a,s]of Object.entries(e))n.setAttribute(a,String(s));return t!==void 0&&(n.textContent=t),n}function uD(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 Qu(i,e){const t=ft("g",{class:e}),n=f1.map((a,s)=>{const r=ft("g",{transform:`rotate(${s*Jn})`});return r.append(ft("text",{x:0,y:-i,"text-anchor":"middle","dominant-baseline":"central"},a)),t.append(r),r});return{group:t,cells:n}}function mD(i,e){let t=i,n=!1,a=-t*Jn;const s=Me("section",{class:"learn-game learn-caesar"});s.append(Me("div",{class:"learn-game-head"},Me("strong",{},p("web_learn_caesar_title")))),s.append(Me("p",{class:"learn-game-status"},p("web_learn_caesar_hint")));const r=ft("svg",{viewBox:"-200 -200 400 400",class:"learn-caesar-disc",role:"img"});r.append(ft("circle",{r:196,class:"outer-disc"})),r.append(ft("path",{d:cD(196,92,Jn/2),class:"window"}));const o=Qu(168,"outer-letters");r.append(o.group);for(let O=0;O{o.cells.forEach((W,E)=>W.classList.toggle("marked",E===O)),u.cells.forEach((W,E)=>W.classList.toggle("marked",O!==void 0&&E===(O+t)%26))},_=()=>{m.textContent=String(t),l.setAttribute("transform",`rotate(${a})`),r.setAttribute("aria-label",p("web_learn_caesar_key_fmt",t)),b.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),x.classList.toggle("active",n),I.textContent=uD(v.value,n?-t:t)||" ";const O=Array.from(v.value.toUpperCase()).reverse().find(E=>f1.includes(E));if(O===void 0)return S();const W=f1.indexOf(O);S(n?(W-t+26)%26:W)},T=O=>{t=(O%26+26)%26,a=-t*Jn,_()};c.addEventListener("click",()=>T(t-1)),d.addEventListener("click",()=>T(t+1)),f.addEventListener("click",()=>{var O;n&&(v.value=((O=I.textContent)==null?void 0:O.trim())??""),n=!1,_()}),x.addEventListener("click",()=>{var O;n||(v.value=((O=I.textContent)==null?void 0:O.trim())??""),n=!0,_()}),v.addEventListener("input",_),o.cells.forEach((O,W)=>O.addEventListener("click",()=>S(W)));let j;const C=O=>{const W=r.getBoundingClientRect();return Math.atan2(O.clientY-(W.top+W.height/2),O.clientX-(W.left+W.width/2))*180/Math.PI};l.addEventListener("pointerdown",O=>{const W=O;j=C(W)-a,l.classList.add("dragging"),r.setPointerCapture(W.pointerId),W.preventDefault()}),r.addEventListener("pointermove",O=>{if(j===void 0)return;a=C(O)-j,l.setAttribute("transform",`rotate(${a})`);const W=Math.round(-a/Jn);if((W%26+26)%26!==t){t=(W%26+26)%26;const E=a;_(),a=E,l.setAttribute("transform",`rotate(${a})`)}});const P=()=>{j!==void 0&&(j=void 0,l.classList.remove("dragging"),T(t))};return r.addEventListener("pointerup",P),r.addEventListener("pointercancel",P),_(),s}function cD(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 t0=i=>p(`web_visubot_part_${i}`),$h=new WeakMap;function Yh(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=t0(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=q(async()=>{const{Robot3D:c}=await import("./robot3d-VilOVDMf.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 x=s.getBoundingClientRect();o(f,g.clientX-x.left,g.clientY-x.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 x=s.getBoundingClientRect();o(f,g.clientX-x.left,g.clientY-x.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 $h.set(a,m),m}function dD(i,e,t=!1){return Yh(i,e,t).box}function hD(i){const e=i.querySelector(".visubot-model"),t=e&&$h.get(e);for(const n of i.querySelectorAll("[data-robot-part]")){const a=(n.dataset.robotPart??"").split(",").filter(Boolean);if(n.title=a.map(t0).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 gD(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=kn(`**${t+1}/${i.length}** ${i[t].question}`)},r=Yh([],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",t0(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=V("button",{class:"primary"},o+1{o++,o{const v=i.rounds[o],w=i.seconds,I=V("div",{class:"learn-bomb-fuse"},V("span",{})),z=V("span",{class:"learn-bomb-time"}),S=V("div",{class:"learn-bomb","aria-live":"polite"},V("span",{class:"learn-bomb-icon","aria-hidden":"true"},"💣"),z,I),_=V("div",{class:"learn-game-feedback",role:"status"}),T=v.code.split(` `).map((E,Q)=>{const $=V("button",{class:"ln",type:"button"},E||" ");return $.disabled=!E.trim(),$.addEventListener("click",()=>O(Q+1===v.wrongLine?"right":"wrong",$)),$}),j=V("div",{class:"learn-game-code learn-bomb-code mono",dir:"ltr"},...T),C=Date.now(),P=()=>{if(!t.isConnected&&Date.now()-C>1e3)return m();const E=Math.max(0,w-(Date.now()-C)/1e3);z.textContent=p("web_game_time_fmt",Math.ceil(E)),I.firstChild.style.width=`${E/w*100}%`,S.classList.toggle("hurry",E<=5),E<=0&&O("time")},O=(E,Q)=>{m(),T.forEach((Te,xe)=>{Te.disabled=!0,xe+1===v.wrongLine&&Te.classList.add("right")}),Q&&E==="wrong"&&Q.classList.add("wrong");const $=E==="right";$&&l++,c(),S.classList.add($?"defused":"boom"),S.firstChild.textContent=$?"✂️":"💥",_.className=`learn-game-feedback ${$?"right":"wrong"}`;const he=d();_.replaceChildren(V("p",{},p($?"web_game_defused":E==="time"?"web_game_boom_time":"web_game_boom_wrong")),Nn("div",{class:"learn-game-explain"},v.explanation),V("p",{class:"learn-bomb-fix"},`${p("web_game_fix")} `,V("code",{},v.fix.trim())),he),he.focus({preventScroll:!0})};s.replaceChildren(S,Nn("p",{class:"learn-game-question"},v.question),j,_),P();const W=window.setInterval(P,200);u.push(W)},g=()=>{const v=i.rounds[o],w=[];v.code.trim()&&w.push(Uu(v.code).element),w.push(Nn("p",{class:"learn-game-question"},v.question),V("p",{class:"learn-order-hint"},p("web_game_order_hint")));const I=V("div",{class:"learn-game-options learn-order"}),z=V("div",{class:"learn-game-feedback",role:"status"});let S=0;const _=fD(v.options.length).map(j=>{const C=V("span",{class:"learn-order-badge","aria-hidden":"true"}),P=V("span",{});P.innerHTML=Re(v.options[j].text);const O=V("button",{},C,P);return O.addEventListener("click",()=>{if(j!==S)return O.classList.add("wrong"),T(!1);O.classList.add("right"),C.textContent=String(++S),O.disabled=!0,S===v.options.length&&T(!0)}),I.append(O),{k:j,b:O,badge:C}}),T=j=>{for(const{k:P,b:O,badge:W}of[..._].sort((E,Q)=>E.k-Q.k))O.disabled=!0,W.textContent=String(P+1),I.append(O);j&&l++,c(),z.className=`learn-game-feedback ${j?"right":"wrong"}`;const C=d();z.replaceChildren(V("p",{},p(j?"web_game_right":"web_game_wrong_short")),Nn("div",{class:"learn-game-explain"},v.explanation),C),C.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=Uu(v.code),I=[];let z;i.kind==="zuhoerer"?(z=xD(Zh(v.code),w),I.push(V("div",{class:"learn-swing-row"},w.element,z.element)),v.clicks.length&&I.push(V("p",{class:"learn-swing-clicks"},`${p("web_game_clicks")} `,...v.clicks.flatMap((C,P)=>[...P?[" → "]:[],V("code",{},C)])))):v.code.trim()&&I.push(w.element),I.push(Nn("p",{class:"learn-game-question"},v.question));const S=V("div",{class:`learn-game-options ${i.kind==="layout"?"pictures":""}`}),_=V("div",{class:"learn-game-feedback",role:"status"}),T=v.options.map(C=>{const P=V("button",{});return i.kind==="layout"?P.append(vD(C.text)):C.text.includes(` `)?P.append(bD(C.text)):P.innerHTML=Re(C.text),P.addEventListener("click",()=>j(C.right,P)),S.append(P),P}),j=(C,P)=>{T.forEach((W,E)=>{W.disabled=!0,v.options[E].right&&W.classList.add("right")}),C||P.classList.add("wrong"),C&&l++,c(),_.className=`learn-game-feedback ${C?"right":"wrong"}`;const O=d();_.replaceChildren(V("p",{},p(C?"web_game_right":"web_game_wrong_short")),Nn("div",{class:"learn-game-explain"},v.explanation)),_.append(O),z&&(u=z.replay(v.clicks,()=>O.before(V("p",{class:"learn-swing-try"},p("web_game_try"))))),O.focus({preventScroll:!0})};s.replaceChildren(...I,S,_)},x=()=>{m(),a.textContent="";const v=V("button",{class:"primary"},p("web_game_again"));v.addEventListener("click",()=>{o=l=0,f()}),s.replaceChildren(V("p",{class:"learn-game-result"},p("web_game_done_fmt",l,r)),V("p",{},p(l===r?"web_game_perfect":l>=r*.7?"web_game_good":"web_game_practice_short")),v)},b=V("button",{class:"primary"},p("web_game_start"));return b.addEventListener("click",f),s.append(Nn("p",{},i.intro),b),t}function fD(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 Uu(i){const e=i.split(` `).map(n=>V("div",{class:"ln"},n||" "));return{element:V("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 xD(i,e){const t=Mh(i),n=V("div",{class:"learn-swing-window",dir:"ltr"});n.append(V("div",{class:"learn-swing-title"},i.title||" "));const a=V("div",{class:"learn-swing-body"}),s=new Map;for(const c of i.labels){const d=V("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=V("button",{class:"learn-swing-button",disabled:""},t.texts[c.name]);return s.set(c.name,d),a.append(d),d}),o=V("p",{class:"learn-swing-event",role:"status"}),l=V("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,x]of Object.entries(c.texts)){const b=s.get(f);b&&b.textContent!==x&&(b.textContent=x,b.classList.remove("changed"),b.offsetWidth,b.classList.add("changed"))}c.console.length&&(l.hidden=!1,l.textContent+=c.console.map(f=>`${f} @@ -60326,7 +60326,7 @@ ${l}`)}La=SB(((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=A("details",{class:"reference-group"});r.open=n.includes(s);const o=A("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(){ge.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(A("p",{class:"hint"},p("web_learn_intro")));for(const e of jD()){this.body.append(A("h3",{class:"learn-section"},e.name));const t=A("ol",{class:"learn-list"});for(const n of e.lessons){const a=ge.lesson(n.id),s=a.done?"✓":a.step>0?p("web_learn_step_of_fmt",a.step+1,n.steps.length):"",r=A("button",{class:"learn-item"+(a.done?" done":""),"data-lesson":n.id},A("span",{class:"learn-num"},String(n.number)),A("span",{class:"learn-item-text"},A("strong",{},n.robot?`🤖 ${n.title}`:n.title),A("small",{},n.summary)),A("span",{class:"learn-status"},s));r.addEventListener("click",()=>this.openLesson(n.id)),t.append(A("li",{},r))}this.body.append(t)}this.body.append(this.renderTeacherBox())}renderLesson(e){var u;const t=ge.lesson(e.id),n=Math.min(t.step,e.steps.length-1),a=e.steps[n],s=A("button",{class:"learn-back"},`← ${p("web_learn_all_lessons")}`);s.addEventListener("click",()=>this.openLesson(void 0));const r=A("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(A("div",{class:"learn-lesson-head"},A("div",{class:"learn-head-row"},s,this.stepNav(e,n,t.done,"learn-nav learn-nav-top")),A("p",{class:"learn-kicker"},`${p("web_learn_lesson_fmt",e.number)} · ${e.section}${e.robot?" · 🤖 VisuBot":""}`),A("h2",{class:"learn-title"},A("span",{class:"learn-num","aria-hidden":"true"},String(e.number)),e.title),r,A("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=A("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))),Ku(this.body),hD(this.body),this.openNeededColumns(a.blocks),Xu(this.body,La),this.body.append(this.stepNav(e,n,t.done,"learn-nav")),o&&this.body.append(l())}stepNav(e,t,n,a){const s=A("div",{class:a}),r=A("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=A("button",{class:"primary"},n?`✓ ${p("web_learn_done")}`:p("web_learn_finish"));o.addEventListener("click",()=>{ge.updateLesson(e.id,{done:!0});const l=Ot.find(u=>u.number===e.number+1);this.openLesson(l==null?void 0:l.id)}),s.append(o)}return s}goToStep(e,t){ge.updateLesson(e.id,{step:t}),this.render(),this.body.scrollTop=0}openNeededColumns(e){const t=e.flatMap(n=>n.kind==="exercise"?[n.exercise]:[]);OD(this.body)?this.host.showEditor():TD(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(),AD(this.body)&&this.host.showLiveCode()}renderTaskList(){this.body.append(A("p",{class:"hint"},p("web_learn_tasks_intro")));const e=A("ul",{class:"learn-list"});for(const t of Tn){const n=this.taskExercises(t),a=n.length>0&&n.every(o=>ge.exercise(o.id).done),s=Ot.find(o=>o.number===t.after),r=A("button",{class:"learn-item"+(a?" done":""),"data-task":t.id},A("span",{class:"learn-num","aria-label":p("web_learn_level_fmt",t.level)},"★".repeat(t.level)),A("span",{class:"learn-item-text"},A("strong",{},t.title),A("small",{},s?p("web_learn_after_fmt",s.number,s.title):"")),A("span",{class:"learn-status"},a?"✓":""));r.addEventListener("click",()=>{this.taskId=t.id,this.persist(),this.render(),this.body.scrollTop=0}),e.append(A("li",{},r))}this.body.append(e,this.renderTeacherBox())}renderTeacherBox(){const e=A("details",{class:"learn-teacher"},A("summary",{},p("web_learn_teacher")));if(Ru()){e.setAttribute("open","");const s=A("button",{},p("web_learn_teacher_off"));return s.addEventListener("click",()=>{sD(),this.render()}),e.append(A("p",{},p("web_learn_teacher_on")),s),e}const t=A("input",{type:"password",autocomplete:"off","aria-label":p("web_learn_teacher_code"),placeholder:p("web_learn_teacher_code")}),n=A("p",{class:"learn-result",role:"status"}),a=A("form",{class:"group"},t,A("button",{type:"submit"},p("web_learn_teacher_unlock")));return a.addEventListener("submit",async s=>{s.preventDefault(),await aD(t.value)?this.render():(n.className="learn-result info",n.textContent=p("web_learn_teacher_wrong"))}),e.append(A("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=A("button",{class:"learn-back"},`← ${p("web_learn_all_tasks")}`);t.addEventListener("click",()=>{this.taskId=void 0,this.persist(),this.render()});const n=Ot.find(a=>a.number===e.after);if(this.body.append(t,A("h2",{class:"learn-title"},e.title)),n){const a=A("button",{class:"link-button"},p("web_learn_after_fmt",n.number,n.title));a.addEventListener("click",()=>this.openLesson(n.id)),this.body.append(A("p",{class:"learn-kicker"},a))}e.blocks.forEach((a,s)=>this.body.append(this.renderBlock(a,`task-${s}`))),Ku(this.body),this.openNeededColumns(e.blocks),Xu(this.body,La)}renderBlock(e,t,n){switch(e.kind){case"markdown":return gt("div",{class:"learn-text"},kn(e.text));case"diagram":return this.renderDiagram(e.file,e.caption);case"exercise":return this.renderExercise(e.exercise);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);case"game":return this.renderGame(e.game);case"roundGame":return pD(e.game,aa);case"rescueGame":return yD(e.game,aa);case"caesar":return mD(e.key,e.text);case"cloze":return zD(e.cloze);case"textFile":return Qh(e.name,e.content);case"robotModel":return dD(e.focus,e.view,e.spin);case"robotQuiz":return gD(e.tasks,e.done)}}renderBrag(e,t=!1){const n=A("aside",{class:"learn-brag"});n.append(A("img",{src:aa,alt:"",width:"48",height:"48"}));const a=A("div",{},A("p",{class:"learn-brag-title"},p(t?"web_learn_ludwig_tip":"web_learn_brag")));return a.append(gt("div",{class:"learn-text"},kn(e))),n.append(a),n}renderGame(e){const n=A("section",{class:"learn-game"}),a=A("div",{class:"learn-game-head"});a.append(A("img",{src:aa,alt:"",width:"40",height:"40"}),A("strong",{},p("web_game_title")));const s=A("p",{class:"learn-game-status"}),r=A("div",{class:"learn-game-stage"});n.append(a,s,r);let o=0,l=0;const u=()=>{const d=$x(e,o,10);s.textContent=`${p("web_game_round_fmt",o+1,10)} · ${p("web_game_score_fmt",l)}`;const h=A("div",{class:"learn-game-values mono"});for(const[w,I]of Yx(d))h.append(A("code",{},`${w} = ${I}`));const g=A("div",{class:"group learn-game-answers"}),f=A("button",{class:"learn-game-true"},`✓ ${p("web_game_true")}`),x=A("button",{class:"learn-game-false"},`✗ ${p("web_game_false")}`);g.append(f,x);const b=A("div",{class:"learn-game-feedback",role:"status"}),v=w=>{f.disabled=x.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)}`,b.className=`learn-game-feedback ${I?"right":"wrong"}`;const z=A("div",{class:"learn-game-steps mono"});qx(d.condition,d.values).forEach((_,T)=>z.append(A("div",{},`${T?"→ ":""}${_}`)));const S=A("button",{class:"primary"},o+1<10?p("web_game_next"):p("web_game_finish"));S.addEventListener("click",()=>{o++,o<10?u():m()}),b.replaceChildren(A("p",{},p(I?"web_game_right":"web_game_wrong")),z,S),S.focus()};f.addEventListener("click",()=>v(!0)),x.addEventListener("click",()=>v(!1)),r.replaceChildren(h,A("div",{class:"learn-game-condition mono"},d.condition),g,b)},m=()=>{s.textContent="";const d=A("button",{class:"primary"},p("web_game_again"));d.addEventListener("click",()=>{o=l=0,u()}),r.replaceChildren(A("p",{class:"learn-game-result"},p("web_game_done_fmt",l,10)),A("p",{},p(l===10?"web_game_perfect":l>=10*.7?"web_game_good":"web_game_practice")),d)},c=A("button",{class:"primary"},p("web_game_start"));return c.addEventListener("click",u),r.append(A("p",{},p("web_game_intro")),c),n}renderImages(e,t){const n=A("figure",{class:"learn-figure"}),a=A("div",{class:"learn-images"});for(const s of e){const r=Fu(s);r&&a.append(A("img",{src:r,alt:"",loading:"lazy"}))}return n.append(a),t&&n.append(gt("figcaption",{},Re(t))),n}renderGraphic(e,t){const n=A("figure",{class:"learn-figure"}),a=Fu(e);return a&&n.append(A("img",{class:"learn-graphic",src:a,alt:"",loading:"lazy"})),t&&n.append(gt("figcaption",{},Re(t))),n}renderDiagram(e,t){const n=X1(e),a=A("figure",{class:"learn-figure"});if(!n)return a;const s=this.host.preview(n);s&&a.append(A("div",{class:"learn-preview",dir:"ltr"},s)),t&&a.append(gt("figcaption",{},Re(t)));const r=A("button",{},p("web_learn_open_in_editor"));return r.addEventListener("click",()=>this.host.openDiagram(n,e)),a.append(r),a}renderExercise(e){const t=A("section",{class:"learn-exercise","data-exercise":e.id}),n=()=>ge.exercise(e.id),a=A("span",{class:"learn-badge"},`✓ ${p("web_learn_solved")}`);a.hidden=!n().done,t.append(A("h4",{},`${p("web_learn_exercise")}: ${e.title}`,a),gt("div",{class:"learn-text"},kn(e.task)));const s=A("div",{class:"learn-result",role:"status"}),r=A("div",{class:"learn-hints"}),o=A("div",{class:"group"}),l=A("button",{class:"primary"},p("web_learn_open_exercise"));l.addEventListener("click",()=>{const c=n().xml;let d=em(e);if(c)try{d=Bl(c)}catch{}this.host.openExercise(e,d)});const u=A("button",{},p("web_learn_check"));if(u.addEventListener("click",()=>{const c=this.host.exerciseDocument(e.id);if(!c){s.className="learn-result info",s.textContent=p("web_learn_open_first");return}if(c.elements.every(Al)){s.className="learn-result info",s.textContent=p("web_learn_empty");return}this.host.stopSimulation();const d=Rx(c,e.tests,this.host.subprogramsFor(e.id),Wa),h=Gx(c),g=e.requires.map(b=>b==="forZaehlSchleife"?"forSchleife":b).filter(b=>b in k&&!h.has(k[b])),f=e.loopDepth!==void 0&&_o(c.elements)b.passed)&&g.length===0&&!f;this.showResult(s,d,g,x,f),x&&(ge.updateExercise(e.id,{done:!0}),a.hidden=!1)}),o.append(l,u),e.hints.length>0){const c=A("button",{},p("web_learn_hint"));c.addEventListener("click",()=>{const d=r.children.length;if(d>=e.hints.length)return;const h=e.hints.length>1?`**${p("web_learn_hint_fmt",d+1,e.hints.length)}:** `:"";r.append(gt("aside",{class:"lesson-note"},kn(h+e.hints[d]))),c.textContent=p("web_learn_hint_more"),c.toggleAttribute("disabled",d+1>=e.hints.length)}),o.append(c)}const m=A("button",{class:"danger-text"},p("web_learn_reset"));if(m.addEventListener("click",()=>{if(m.dataset.confirm!=="1"){m.dataset.confirm="1",m.textContent=p("web_learn_reset_confirm"),setTimeout(()=>{m.dataset.confirm="",m.textContent=p("web_learn_reset")},4e3);return}ge.resetExercise(e.id),this.host.resetExercise(e.id,em(e)),a.hidden=!0,s.replaceChildren(),s.className="learn-result",m.dataset.confirm="",m.textContent=p("web_learn_reset")}),o.append(m),t.append(o,r,s),Ru()&&e.solution){const c=X1(e.solution);if(c){const d=A("details",{class:"learn-solution"},A("summary",{},p("web_learn_solution")));d.addEventListener("toggle",()=>{if(!d.open||d.querySelector(".learn-preview"))return;const h=this.host.preview(c);h&&d.append(A("div",{class:"learn-preview",dir:"ltr"},h));const g=A("button",{},p("web_learn_open_in_editor"));g.addEventListener("click",()=>{this.host.openDiagram(c,e.solution);for(const f of e.subprograms){const x=X1(f);x&&this.host.openDiagram(x,f)}});for(const f of e.subprograms){const x=X1(f),b=x&&this.host.preview(x);b&&d.append(A("div",{class:"learn-preview",dir:"ltr"},b))}d.append(g)}),t.append(d)}}return t}showResult(e,t,n,a,s){var o,l,u,m,c;e.className="learn-result "+(a?"ok":"fail"),e.replaceChildren(A("p",{class:"learn-result-head"},a?`🎉 ${p("web_learn_passed")}`:p("web_learn_failed")));for(const d of n)e.append(A("p",{},`✗ ${p("web_learn_missing_fmt",CD(k[d]))}`));s&&e.append(A("p",{},`✗ ${p("web_visubot_depth_fmt",s)}`));const r=A("ul",{class:"learn-tests",dir:"auto"});for(const d of t){const h=d.test.world?t.filter(b=>b.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(([b,v])=>`mbot.${b}() = ${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}`],x=A("div",{class:"learn-test-detail"});if(d.test.drive&&x.append(A("span",{},`${p("web_learn_expected")}: `,A("code",{},U1(d.test.drive)||"–")),A("span",{},`${p("web_learn_actual")}: `,A("code",{},U1(d.result.drive??[])||"–"))),d.test.actions&&x.append(A("span",{},`${p("web_learn_expected")}: `,A("code",{},U1(d.test.actions)||"–")),A("span",{},`${p("web_learn_actual")}: `,A("code",{},U1(d.result.actions??[])||"–"))),d.test.led!==void 0){const b=v=>p(v?"web_visubot_led_on":"web_visubot_led_off");x.append(A("span",{},`💡 ${p("web_learn_expected")}: ${b(d.test.led)} · ${p("web_learn_actual")}: ${b(d.result.led)}`))}if(d.test.tone!==void 0){const b=v=>p(v?"web_visubot_tone_yes":"web_visubot_tone_no");x.append(A("span",{},`🔊 ${p("web_learn_expected")}: ${b(d.test.tone)} · ${p("web_learn_actual")}: ${b(d.result.tone)}`))}d.test.screen!==void 0&&x.append(A("span",{},`📺 ${p("web_learn_expected")}: `,A("code",{},d.test.screen),` · ${p("web_learn_actual")}: `,A("code",{},d.result.screen??"–"))),d.test.world&&(((l=(o=Wa(d.test.world))==null?void 0:o.goals)!=null&&l.length||(m=(u=Wa(d.test.world))==null?void 0:u.targets)!=null&&m.length)&&x.append(A("span",{},d.result.atGoal?`✓ ${p("web_visubot_goal_reached")}`:`✗ ${p("web_visubot_goal_missed")}`)),d.result.bumps&&x.append(A("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)&&x.append(A("span",{},`${p("web_learn_expected")}: `,A("code",{},d.test.expected.join(" | ")||"–")),A("span",{},`${p("web_learn_actual")}: `,A("code",{},d.result.outputs.join(" | ")||"–")));for(const b of d.test.files??[])x.append(A("span",{},`📄 ${b.name}, ${p("web_learn_expected")}: `,A("code",{},b.lines.join(" | ")||"–")),A("span",{},`📄 ${b.name}, ${p("web_learn_actual")}: `,A("code",{},Bh((c=d.result.files)==null?void 0:c.get(b.name)).join(" | ")||"–")));d.result.error&&x.append(A("span",{class:"learn-error"},Kn(d.result.error))),d.result.missingInput&&x.append(A("span",{class:"learn-error"},p("web_learn_missing_input"))),d.result.tooManySteps&&x.append(A("span",{class:"learn-error"},p("web_learn_too_many_steps"))),!d.passed&&d.result.unusedInputs&&x.append(A("span",{class:"learn-error"},p("web_learn_unused_input"))),r.append(A("li",{class:d.passed?"ok":"fail"},...f,x))}e.append(r)}renderChecklist(e,t,n){const a=A("ul",{class:"learn-checklist"});return e.forEach((s,r)=>{var c;const o=`${t}-${r}`,l=A("input",{type:"checkbox"});l.checked=!!(n&&((c=ge.lesson(n.id).checks)!=null&&c[o])),l.addEventListener("change",()=>{if(!n)return;const d={...ge.lesson(n.id).checks??{},[o]:l.checked};ge.updateLesson(n.id,{checks:d})});const u=A("label",{},l);u.insertAdjacentHTML("beforeend"," "+Re(s.text));const m=A("li",{},u);if(n&&s.step!==void 0){const d=s.step,h=p("web_learn_step_fmt",d+1,n.steps[d].title),g=A("button",{class:"link-button learn-check-link",title:h,"aria-label":`${p("web_learn_review")}: ${h}`},p("web_learn_review"));g.addEventListener("click",()=>{this.returnTo={lesson:n.id,step:ge.lesson(n.id).step,scroll:this.body.scrollTop},this.goToStep(n,d)}),m.append(g)}a.append(m)}),a}renderQuiz(e,t,n){const a=A("div",{class:"learn-quiz"}),s=A("p",{class:"learn-score",role:"status"}),r=()=>n?ge.lesson(n.id).quiz??{}:{},o=()=>{const l=r(),u=(h,g)=>h.pairs?h.pairs.every((f,x)=>l[`${t}-${g}-${x}`]!==void 0):l[`${t}-${g}`]!==void 0,m=(h,g)=>{var f;return h.pairs?h.pairs.every((x,b)=>tm(h)[l[`${t}-${g}-${b}`]]===h.pairs[b].right):(f=h.options[l[`${t}-${g}`]])==null?void 0:f.correct},c=e.filter(u).length,d=e.filter(m).length;s.textContent=c===e.length?p("web_learn_score_fmt",d,e.length):""};return e.forEach((l,u)=>{const m=`${t}-${u}`,c=A("fieldset",{},gt("legend",{},Re(l.question))),d=gt("p",{class:"learn-explanation"},Re(l.explanation??""));if(l.pairs){c.append(this.renderMatch(l,m,r,n,d,o),d),a.append(c);return}const h=g=>{c.querySelectorAll("button").forEach((f,x)=>{f.classList.toggle("right",g!==void 0&&l.options[x].correct),f.classList.toggle("wrong",g===x&&!l.options[x].correct),f.setAttribute("aria-pressed",String(g===x))}),d.hidden=g===void 0||!l.explanation};l.options.forEach((g,f)=>{const x=gt("button",{class:"learn-option"},Re(g.text));x.addEventListener("click",()=>{n&&ge.updateLesson(n.id,{quiz:{...r(),[m]:f}}),h(f),o()}),c.append(x)}),c.append(d),h(r()[m]),a.append(c)}),a.append(s),o(),a}renderMatch(e,t,n,a,s,r){const o=e.pairs,l=tm(e),u=A("div",{class:"learn-match"});let m={};const c=()=>a?n():m,d=x=>a?ge.updateLesson(a.id,{quiz:x}):m=x,h=x=>c()[`${t}-${x}`],g=o.map(x=>{const b=A("select",{class:"learn-match-select"});b.append(A("option",{value:""},"–")),l.forEach((w,I)=>b.append(A("option",{value:String(I)},w)));const v=gt("label",{class:"learn-match-left"},Re(x.left));return v.append(b),u.append(v),b}),f=()=>{const x=o.every((b,v)=>h(v)!==void 0);g.forEach((b,v)=>{const w=h(v);b.value=w===void 0?"":String(w),b.classList.toggle("right",x&&l[w]===o[v].right),b.classList.toggle("wrong",x&&l[w]!==o[v].right)}),s.hidden=!x||!e.explanation};return g.forEach((x,b)=>x.addEventListener("change",()=>{const v={...c()};x.value===""?delete v[`${t}-${b}`]:v[`${t}-${b}`]=Number(x.value),d(v),f(),r()})),f(),u}}function tm(i){return(i.pairs??[]).map(e=>e.right).sort((e,t)=>e.localeCompare(t,"de"))}const ZD=""+new URL("visubot-CyGFOI9V.webp",import.meta.url).href,i0="visustruct.visubot";function a0(){try{return localStorage.getItem(i0)}catch{return null}}function ri(){const i=a0();return i==="1"||i==="kurs"?"on":"off"}const Kh=()=>a0()==="2";function eg(){try{localStorage.setItem(i0,"2")}catch{}}const MD=()=>a0()!==null;function br(i){try{localStorage.setItem(i0,i==="on"?"1":"0")}catch{}}const LD=`VisuBot`,Rn=()=>ri()!=="off",nm=i=>i.replace(/[&<>"]/g,e=>({"&":"&","<":"<",">":">",'"':"""})[e]);function Po(){const i=Kh()?"object":ri(),e=(n,a)=>``,t={off:"web_visubot_world_visustruct_hint",on:"web_visubot_world_visubot_hint",object:"web_visuobject_world_hint"}[i];return`
${e("off","VisuStruct")}${e("on","🤖 VisuBot")}${e("object","VisuObject")}
- ${nm(p(t))}`}class WD{constructor(e=yi){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 us(e),this.element=document.createElement("section"),this.element.className="visubot",this.element.innerHTML=`

${p("web_visubot_world")}

${p("web_visubot_world_in_preview")}

${ED()}${ND()}`,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=le.listen(()=>this.updateLive()),this.setupControls(),this.check=this.element.querySelector(".visubot-check"),this.setupCheck(),this.updateLive(),this.updateStatus()}show(){this.loading??(this.loading=q(async()=>{const{Robot3D:e}=await import("./robot3d-DuVc6opp.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]??yi,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 us(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;le.run(e.dataset.py).then(()=>t?new Promise(a=>setTimeout(a,Number(n))).then(()=>le.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&&le.connected;){for(const e of this.check.querySelectorAll("[data-sensor]")){if(!this.check.open||!le.connected)break;const t=e.dataset.sensor,n=await le.ask(St[t].python).catch(()=>{});n!==void 0&&(e.textContent=typeof St[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 le.connected}async prepareLive(e,t=[]){const n={};for(const a of new Set(["getDistance","getLine",...t])){const s=await le.ask(St[a].python);typeof St[a].simulated=="boolean"?n[a]=s===!0||typeof s=="number"&&s!==0:typeof St[a].simulated=="string"?n[a]=typeof s=="string"?s:String(St[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){le.disconnect(e instanceof Error?e.message:String(e))}updateLive(){this.liveStatus.textContent=ng(),this.liveStatus.classList.toggle("connected",le.connected),this.check.hidden=!le.connected,le.connected||(this.check.open=!1),this.updateStatus()}follow(e,t){var a,s,r,o;for(;this.appliedl!==0);this.world.tick(Xl),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&&le.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 J1;function tg(i,e){try{J1??(J1=new AudioContext);const t=J1.createOscillator(),n=J1.createGain();t.type="square",t.frequency.value=Math.max(20,Math.min(2e4,i)),n.gain.value=.05,t.connect(n).connect(J1.destination);const a=J1.currentTime+Math.min(Math.max(e,0),5e3)/1e3;t.start(),t.stop(a)}catch{}}function ED(){const i=(t,n,a,s,r)=>``,e=(t,n,a)=>``;return`
🎛 ${p("web_visubot_controls")} + ${nm(p(t))}`}class WD{constructor(e=yi){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 us(e),this.element=document.createElement("section"),this.element.className="visubot",this.element.innerHTML=`

${p("web_visubot_world")}

${p("web_visubot_world_in_preview")}

${ED()}${ND()}`,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=le.listen(()=>this.updateLive()),this.setupControls(),this.check=this.element.querySelector(".visubot-check"),this.setupCheck(),this.updateLive(),this.updateStatus()}show(){this.loading??(this.loading=q(async()=>{const{Robot3D:e}=await import("./robot3d-VilOVDMf.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]??yi,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 us(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;le.run(e.dataset.py).then(()=>t?new Promise(a=>setTimeout(a,Number(n))).then(()=>le.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&&le.connected;){for(const e of this.check.querySelectorAll("[data-sensor]")){if(!this.check.open||!le.connected)break;const t=e.dataset.sensor,n=await le.ask(St[t].python).catch(()=>{});n!==void 0&&(e.textContent=typeof St[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 le.connected}async prepareLive(e,t=[]){const n={};for(const a of new Set(["getDistance","getLine",...t])){const s=await le.ask(St[a].python);typeof St[a].simulated=="boolean"?n[a]=s===!0||typeof s=="number"&&s!==0:typeof St[a].simulated=="string"?n[a]=typeof s=="string"?s:String(St[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){le.disconnect(e instanceof Error?e.message:String(e))}updateLive(){this.liveStatus.textContent=ng(),this.liveStatus.classList.toggle("connected",le.connected),this.check.hidden=!le.connected,le.connected||(this.check.open=!1),this.updateStatus()}follow(e,t){var a,s,r,o;for(;this.appliedl!==0);this.world.tick(Xl),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&&le.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 J1;function tg(i,e){try{J1??(J1=new AudioContext);const t=J1.createOscillator(),n=J1.createGain();t.type="square",t.frequency.value=Math.max(20,Math.min(2e4,i)),n.gain.value=.05,t.connect(n).connect(J1.destination);const a=J1.currentTime+Math.min(Math.max(e,0),5e3)/1e3;t.start(),t.stop(a)}catch{}}function ED(){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)} @@ -60555,7 +60555,7 @@ ${i}

${bn(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=`${kt}🤖 ${bn(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=q(async()=>{const{Robot3D:e}=await import("./robot3d-DuVc6opp.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=`${kt}🤖 ${bn(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=q(async()=>{const{Robot3D:e}=await import("./robot3d-VilOVDMf.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]??yi)}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=nJ(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=ne.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&&tg(s.tone[0],s.tone[1]),this.showFrame(s,$r-30),this.playTimer=window.setTimeout(n,$r)};this.playTimer=window.setTimeout(n,$r)}stopPlaying(e){var t;this.playTimer!==void 0&&window.clearTimeout(this.playTimer),this.playTimer=void 0,this.playButton.innerHTML=ne.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(`⚠︎ ${Kn(e.notice)}`),this.status.textContent=t.join(" · ")}pause(){window.clearTimeout(this.pending),this.pending=void 0,this.lastKey=void 0,this.stopPlaying(!1)}}const aJ={left:12,top:10},sJ=8,Ms=8e3,pi=16,Yr=12,Jf="#fafafa";function Rf(i){const e=i.caption.trim();return e===""?p("diagram_title_placeholder"):e}function Xc(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 Kc(i,e){return Xc(i.caption)||Xc(e)||"VisuStruct"}function rJ(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,pi,"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+"…",pi,"bold")>e;)r=r.slice(0,-1);return[a[0],r+"…"]}return a}function ed(i,e,t,n=320){const a={...i,elements:i.elements.map(Ua)},s=new Ld(e,t).layout(a,aJ),r=Math.min(Ms,Math.max(n,s.canvasSize.width)),o=Math.min(Ms,Math.max(n,s.canvasSize.height));if(r<=2||o<=2)return;const l=rJ(Rf(i),r-2*Yr,t),u=Math.ceil(pi*1.2),m=Math.min(56,l.length*u+2),c=m+o,d=new Fd(e,t).render(s,{width:r,height:o},void 0,sJ);d.setAttribute("y",String(m)),d.removeAttribute("class");const h=ve("svg",{xmlns:"http://www.w3.org/2000/svg",width:r,height:c,viewBox:`0 0 ${r} ${c}`});h.append(ve("rect",{x:0,y:0,width:r,height:c,fill:Jf}));const g=ve("text",{x:Yr,y:0,"font-family":Ls,"font-size":pi,"font-weight":600,fill:"black"});return l.forEach((f,x)=>{const b=ve("tspan",{x:Yr,y:x*u+pi});b.textContent=f,g.append(b)}),h.append(g,d),{svg:h,width:r,height:c}}function Gf(i){return` `+new XMLSerializer().serializeToString(i.svg)}async function td(i,e){const t=Math.max(1,Math.min(e,Ms/i.width,Ms/i.height)),n=URL.createObjectURL(new Blob([Gf(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=Jf,r.fillRect(0,0,s.width,s.height),r.drawImage(a,0,0,s.width,s.height),s}finally{URL.revokeObjectURL(n)}}function oJ(i){return new Promise((e,t)=>i.toBlob(n=>n?e(n):t(new Error("PNG konnte nicht erzeugt werden.")),"image/png"))}function lJ(i,e){const a=Math.max(1,i),s=Math.max(1,e),r=f=>{const x=f.width-64,b=f.height-64;return{s:Math.min(x/a,b/s)*.98,cw:x,ch:b}},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 uJ(i){const e=new Blob([i]).stream().pipeThrough(new CompressionStream("deflate"));return new Uint8Array(await new Response(e).arrayBuffer())}function nd(i){let e="FEFF";for(let t=0;t`}async function mJ(i,e,t,n,a){const{page:s,draw:r}=lJ(n.width,n.height),o=await uJ(i),l=b=>(Math.round(b*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 @@ -60770,7 +60770,7 @@ ${c}
- ${L(p("web_about_version_fmt").replace("%@","0.13.7"))} + ${L(p("web_about_version_fmt").replace("%@","0.13.8"))}
@@ -60841,7 +60841,7 @@ ${c}

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

-

${L(p("web_about_version_fmt").replace("%@","0.13.7"))}

+

${L(p("web_about_version_fmt").replace("%@","0.13.8"))}

Holger Sebastiao

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

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

${L(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=Bl(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:rd()}),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([o1(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:rd()}),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=Kc(this.doc,on(this.tab));return this.offerDownload(`${s}.visustruct`,new Blob([o1(this.doc)],{type:"application/xml"}))}const t=ed(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=Kc(this.doc,on(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([Gf(t)],{type:"image/svg+xml"}));break}case"png":{const s=await td(t,a);await this.offerDownload(`${n}.png`,await oJ(s));break}case"pdf":{const s=await td(t,Math.max(a,3)),r=await mJ(cJ(s),s.width,s.height,t,Rf(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&&lo(n.idPath,this.selected);this.selected=n==null?void 0:n.idPath,this.render(),n&&e.pointerType!=="touch"&&!(wn(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=At(this.doc,e.path);t.textContent=`${Xr(n.type)}: ${Ol(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||wn(this.doc,s.idPath)?void 0:sd.includes(At(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:wn(this.doc,r)?{kind:"replace",path:r,frame:s.frame}:{kind:t"]/g,e=>({"&":"&","<":"<",">":">",'"':"""})[e])}function _d(i){if(!i)return[];for(const e of[...Ot.flatMap(t=>t.steps.flatMap(n=>n.blocks)),...Tn.flatMap(t=>t.blocks)])if(!(e.kind!=="exercise"||e.exercise.id!==i))return e.exercise.tests.flatMap(t=>{const n=t.world?Wa(t.world):void 0;return n?[n]:[]});return[]}let Et,Sl,_l;function Td(i){const e=i.dataset.tip;if(!e)return;Et??(Et=Object.assign(document.createElement("div"),{className:"tooltip",role:"tooltip"})),Et.isConnected||document.body.append(Et),Et.textContent=e,Et.hidden=!1;const t=i.getBoundingClientRect(),n=Et.offsetWidth,a=Et.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!==_l&&(no(),e&&(_l=e,Sl=window.setTimeout(()=>Td(e),350)))}),document.addEventListener("focusin",i=>{const e=i.target.closest("[data-tip]");no(),e!=null&&e.matches(":focus-visible")&&Td(e)});for(const i of["pointerdown","focusout","scroll","keydown"])document.addEventListener(i,no,!0)}const Tl="visustruct.reloadedAfterError";function qf(){try{const i=Number(sessionStorage.getItem(Tl));if(i&&Date.now()-i<3e4)return!1;sessionStorage.setItem(Tl,String(Date.now()))}catch{return!1}return location.reload(),!0}function BJ(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=>{qf()&&i.preventDefault()});const DJ=L2();Promise.all([Ud(DJ,!1),qd(Z2(),!1)]).then(()=>{Qf(),CJ();const i=new URLSearchParams(location.search);i.has("visuobject")&&eg();const e=document.getElementById("app");if(Kh()&&!i.has("visustruct")&&!i.has("visubot"))return q(async()=>{const{ObjectApp:t}=await import("./objectApp-B5M5sW_m.js").then(n=>n.g);return{ObjectApp:t}},[],import.meta.url).then(({ObjectApp:t})=>new t(e));new AJ(e)}).then(()=>{try{sessionStorage.removeItem(Tl)}catch{}}).catch(i=>{/dynamically imported module|Importing a module script failed|error loading dynamically/i.test(String(i))&&qf()||BJ(i)});export{Vn as C,ZF as J,Cx as L,q as _,wF as a,GF as b,Mf as c,NJ as d,br as e,sa as f,TJ as g,VD as h,ne as i,HD as j,i1 as k,EJ as m,EF as p,am as r,YD as s,p as t,Po as w}; + `,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=Bl(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:rd()}),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([o1(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:rd()}),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=Kc(this.doc,on(this.tab));return this.offerDownload(`${s}.visustruct`,new Blob([o1(this.doc)],{type:"application/xml"}))}const t=ed(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=Kc(this.doc,on(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([Gf(t)],{type:"image/svg+xml"}));break}case"png":{const s=await td(t,a);await this.offerDownload(`${n}.png`,await oJ(s));break}case"pdf":{const s=await td(t,Math.max(a,3)),r=await mJ(cJ(s),s.width,s.height,t,Rf(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&&lo(n.idPath,this.selected);this.selected=n==null?void 0:n.idPath,this.render(),n&&e.pointerType!=="touch"&&!(wn(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=At(this.doc,e.path);t.textContent=`${Xr(n.type)}: ${Ol(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||wn(this.doc,s.idPath)?void 0:sd.includes(At(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:wn(this.doc,r)?{kind:"replace",path:r,frame:s.frame}:{kind:t"]/g,e=>({"&":"&","<":"<",">":">",'"':"""})[e])}function _d(i){if(!i)return[];for(const e of[...Ot.flatMap(t=>t.steps.flatMap(n=>n.blocks)),...Tn.flatMap(t=>t.blocks)])if(!(e.kind!=="exercise"||e.exercise.id!==i))return e.exercise.tests.flatMap(t=>{const n=t.world?Wa(t.world):void 0;return n?[n]:[]});return[]}let Et,Sl,_l;function Td(i){const e=i.dataset.tip;if(!e)return;Et??(Et=Object.assign(document.createElement("div"),{className:"tooltip",role:"tooltip"})),Et.isConnected||document.body.append(Et),Et.textContent=e,Et.hidden=!1;const t=i.getBoundingClientRect(),n=Et.offsetWidth,a=Et.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!==_l&&(no(),e&&(_l=e,Sl=window.setTimeout(()=>Td(e),350)))}),document.addEventListener("focusin",i=>{const e=i.target.closest("[data-tip]");no(),e!=null&&e.matches(":focus-visible")&&Td(e)});for(const i of["pointerdown","focusout","scroll","keydown"])document.addEventListener(i,no,!0)}const Tl="visustruct.reloadedAfterError";function qf(){try{const i=Number(sessionStorage.getItem(Tl));if(i&&Date.now()-i<3e4)return!1;sessionStorage.setItem(Tl,String(Date.now()))}catch{return!1}return location.reload(),!0}function BJ(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=>{qf()&&i.preventDefault()});const DJ=L2();Promise.all([Ud(DJ,!1),qd(Z2(),!1)]).then(()=>{Qf(),CJ();const i=new URLSearchParams(location.search);i.has("visuobject")&&eg();const e=document.getElementById("app");if(Kh()&&!i.has("visustruct")&&!i.has("visubot"))return q(async()=>{const{ObjectApp:t}=await import("./objectApp-D9StvWDS.js").then(n=>n.g);return{ObjectApp:t}},[],import.meta.url).then(({ObjectApp:t})=>new t(e));new AJ(e)}).then(()=>{try{sessionStorage.removeItem(Tl)}catch{}}).catch(i=>{/dynamically imported module|Importing a module script failed|error loading dynamically/i.test(String(i))&&qf()||BJ(i)});export{Vn as C,ZF as J,Cx as L,q as _,wF as a,GF as b,Mf as c,NJ as d,br as e,sa as f,TJ as g,VD as h,ne as i,HD as j,i1 as k,EJ as m,EF as p,am as r,YD as s,p as t,Po as w}; diff --git a/website/app/assets/objectApp-B5M5sW_m.js b/website/app/assets/objectApp-D9StvWDS.js similarity index 99% rename from website/app/assets/objectApp-B5M5sW_m.js rename to website/app/assets/objectApp-D9StvWDS.js index f8659fe1..c43e0560 100644 --- a/website/app/assets/objectApp-B5M5sW_m.js +++ b/website/app/assets/objectApp-D9StvWDS.js @@ -1,5 +1,5 @@ -const __vite__mapDeps=(i,m=__vite__mapDeps,d=(m.f||(m.f=["./projectZip-NDe93a6D.js","./index-FLiLJX9D.js","./index-B-A0tKyY.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,_ as wt,f as $t,h as Js,r as _t,j as Ks,k as ct}from"./index-FLiLJX9D.js";function Xs(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,_ as wt,f as $t,h as Js,r as _t,j as Ks,k as ct}from"./index-Bx-6trOD.js";function Xs(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 Gs(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=Xs(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=Gs(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 Zs(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 Qs=/^[\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 ei={"+":"public ","-":"private ","#":"protected ","~":""};function ti(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?"":ei[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.13.7"))} + ${b(d("web_about_version_fmt").replace("%@","0.13.8"))}
@@ -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}=Ci(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){e!=="object"&&(Us(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>xn&&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 Ui([...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-NDe93a6D.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-NDe93a6D.js");return{projectToZip:s}},__vite__mapDeps([0,1,2]),import.meta.url),t=e(this.project);jn(`${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 Js(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 gn(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 nn(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(mi(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(pi(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(tn(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>xn&&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 Ui([...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-DrvMtqWX.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-DrvMtqWX.js");return{projectToZip:s}},__vite__mapDeps([0,1,2]),import.meta.url),t=e(this.project);jn(`${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 Js(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 gn(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 nn(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(mi(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(pi(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(tn(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-NDe93a6D.js b/website/app/assets/projectZip-DrvMtqWX.js similarity index 99% rename from website/app/assets/projectZip-NDe93a6D.js rename to website/app/assets/projectZip-DrvMtqWX.js index 2eae08fa..58e4e06a 100644 --- a/website/app/assets/projectZip-NDe93a6D.js +++ b/website/app/assets/projectZip-DrvMtqWX.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-B5M5sW_m.js";import"./index-FLiLJX9D.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-D9StvWDS.js";import"./index-Bx-6trOD.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-DuVc6opp.js b/website/app/assets/robot3d-VilOVDMf.js similarity index 99% rename from website/app/assets/robot3d-DuVc6opp.js rename to website/app/assets/robot3d-VilOVDMf.js index b65ae274..1a1a87b1 100644 --- a/website/app/assets/robot3d-DuVc6opp.js +++ b/website/app/assets/robot3d-VilOVDMf.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-FLiLJX9D.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-Bx-6trOD.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 1293539f..1b8a4efb 100644 --- a/website/app/index.html +++ b/website/app/index.html @@ -6,7 +6,7 @@ VisuStruct Web - +