...
jsteuer
2019-12-11 94c5dbd06ea1f662ceaafede992d1f931420e70c
...
5 files modified
7 files added
1 files renamed
1023 ■■■■■ changed files
IDE-API.md 255 ●●●●● patch | view | raw | blame | history
IDE-TOOL-UTILS.md 3 ●●●●● patch | view | raw | blame | history
README.md 254 ●●●●● patch | view | raw | blame | history
dist/es5/ide-tool-utils.js 127 ●●●●● patch | view | raw | blame | history
dist/es5/ide-tool-utils.js.map 1 ●●●● patch | view | raw | blame | history
dist/es6/index.d.ts 18 ●●●●● patch | view | raw | blame | history
dist/es6/index.js 116 ●●●●● patch | view | raw | blame | history
dist/es6/index.js.map 1 ●●●● patch | view | raw | blame | history
package-lock.json 226 ●●●● patch | view | raw | blame | history
package.json 14 ●●●●● patch | view | raw | blame | history
src/index.ts 2 ●●● patch | view | raw | blame | history
src/mathcoach-api.d.ts patch | view | raw | blame | history
tsconfig.json 6 ●●●●● patch | view | raw | blame | history
IDE-API.md
New file
@@ -0,0 +1,255 @@
# MathCoach IDE API
In diesem Paket ([Das Gitblit Repository findet sich hier](https://newton.htwsaar.de/gitblit/summary/mathcoach!mathcoach-ide-api.git))
ist die öffentliche Schnittstelle zur MathCoach Entwicklungsumgebung (IDE) definiert. Mithilfe
dieser Schnittstelle können externe Werkzeuge (z.B. Editoren) erstellt werden. Ziel ist, dass
diese Werkzeuge für den Anwender komfortable - in die IDE integriert -zur Verfügung gestellt werden
können. Darüber hinaus werden als Ergänzung einige Hilfsfunktionen zum Bau von Werkzeugen angeboten.
![Demo](media/usage_author.gif)
*Beispielhafte Anwendung: Eine Datei wird angelegt und einem Demo-Editor geöffnet. Dieser generiert eine
Groovy-Aufgabe*
## Idee
TODO: Grafik (IDE, Werkzeug, Dateien, JSON, usw)
## Entwicklung externer Werkzeuge
-   Externe Werkzeuge müssen unter der Domain von MathCoach erreichbar sein. Zur Entwicklungszeit legt
    man das Werkzeug dazu im www-Verzeichnis ab.
-   Die von der IDE bereitgestellte Bibliothek muss eingebunden werden
        <script src="/mathcoach/ui/ide/ide-lib.js"/>
-   Von nun an steht die IDE API durch die globale Variable `MC` zur Verfügung.
-   **Hinweis**: Erst, wenn das Werkzeug in die IDE integriert und aus dieser heraus
    gestartet wurde, kann die API verwendet werden! Durch nachbilden der API kann
    eine Nutzung ohne IDE ermöglicht werden, siehe `enableOfflineUsageIfNecessary`.
### Empfohlenes Vorgehen
Damit externe Werkzeuge ein einheitliches Verhalten aufweisen, sollte wie folgt vorgegangen werden.
Als erstes muss sichergestellt werden, dass die MathCoach IDE API auch verfügbar ist. Dies ist beispielsweise
nicht der Fall, wenn das Werkzeug ohne die IDE gestartet wurde (und nicht offline-fähig ist) oder die IDE (aus
welchen Gründen auch immer) nicht einsatzbereit ist.
    if(typeof MC !== "undefined"){
        throw new Error("IDE Lib nicht eingebunden"); // TODO: show error to user
    }
    const isReady = await MC.isReady();
    if(!isReady){
        throw new Error("Die MathCoach-API ist nicht einsatzbereit."); // TODO: show error to user
    }
Von nun an kann die IDE API vollständig genutzt werden. Zunächst sollte die Kontext-Datei (die Datei,
mit der das Werkzeug gestartet wurde) geladen werden.
Ist der Inhalt der Kontext-Datei leer, wurde das Werkzeug vermutlich zum ersten mal gestartet das Werkzeug:
-   Sich initialisieren (z.B. mit einem leeren oder beispielhaften internem Datenmodell)
-   Das interne Datenmodell in die Kontext-Datei schreiben
-   Die zugehörige Aufgabe generieren. Siehe auch `contextFileToExerciseFile` weiter unten.
Andernfalls kann das zuvor gespeichertes Datenmodell in den Editor geladen werden.
Anschließend sollte die generierten Aufgaben in der Vorschau gestartet werden, sodass der Benutzer besser
abschätzen kann, wie sich Änderungen im Werkzeug auf die Aufgabe auswirken.
    let contextFile = await MC.ide.getContextFile(); // Datei, mit der der Editor gestartet wurde
    let contextFileContent = await MC.ide.fs.readFile(contextFile);
    let contextFileIsEmpty = contextFileContent === "";
    let exerciseFile = contextFileToExerciseFile(contextFile);
    if(contextFileIsEmpty){
        // TODO: init application with new data model (maybe with example contents)
        // write serialized model to context file, e.g. using JSON.stringify(...)
        let dataModelAsString = JSON.stringify({/* TODO */});
        await MC.ide.fs.writeFile(contextFile, dataModelAsString);
        // generate exercise
        let generatedExerciseCode = "startup { print('Hallo Welt!') }"; // TODO
        await MC.ide.fs.writeFile(exerciseFile, generatedExerciseCode);
    }else{
        // TODO: load data model, e.g. using JSON.parse(contextFileContent)
        // TODO: (overwrite context file and generated exercise file)
        // TODO: init application based on your data model
    }
    // show preview
    await MC.ide.navigator.navigateToExercise(exerciseFile);
Jedes Werkzeug sollte über eine "Speichern"-Funktion verfügen, mit der der Benutzer:
- Das interne Datenmodell in die Kontext-Datei speichert (sodass es später wieder geladen werden kann)
- Die zugehörige Aufgabe wird generiert und die Vorschau zu dieser navigiert
### Hilfunktionen für Werkzeug-Entwickler
Dieses Paket beinhaltet zusätzlich Hilfsfunktionen für Werkzeug-Entwickler.
-   **Aufgaben-Datei ableiten**: Die generierte Aufgabe soll wie die Kontext-Datei benannt sein,
    sodass diese vom Benutzer schnell zugeordnet werden können. Beispielsweise soll ein Werkzeug,
    welches mit der Kontext-Datei `/path/to/myExercise.mcq.json` gestartet wird, die
    Aufgabe `/path/to/myExercise.groovy` erzeugen.
        import { contextFileToExerciseFile } from "@mathcoach/ide-api";
        let contextFile = await MC.ide.getContextFile()
        let exerciseFile = contextFileToExerciseFile(contextFile);
-   **Standalone-Werkzeuge**: Werkzeuge können ohne IDE-Anbindung entwickelt und getestet
    werden. Dazu wird die IDE API nachgebildet - aktuell auf Basis des `LocalStorage` des
    Browsers.
        import { enableOfflineUsageIfNecessary } from "@mathcoach/ide-api";
        let offline: boolean = enableOfflineUsageIfNecessary();
        // now use the IDE API
### Beispiele
Im Verzeichnis `./examples/` finden sich Beispiele für externe Werkzeuge.
### Kleinere Werkzeuge
Für kleiner Werkzeuge bietet es sich an im WWW-Verzeichnis zu entwickeln  (z.B.
`myTool/tool.html` und `myTool/tool.js`). Die MathCoach-IDE stellt Autovervollständigung beim
Editieren der `tool.js`-Datei zur Verfügung. Da es sich um eine JavaScript-Datei handelt,
ist keine Typsicherheit gegeben. Das Werkzeug muss lokal in die IDE integriert werden, siehe
weiter unten.
![Demo](media/usage_tool_developer.gif)
### Größere Werkzeuge
Für größere Werkzeuge sollte ein Build-System wie [webpack](https://webpack.js.org/)
oder [PARCEL](https://parceljs.org/) in Kombination mit
[TypeScript](https://www.typescriptlang.org/) verwendet werden. Das Werkzeug muss nach dem
Build-Prozess in das WWW-Verzeichnis kopiert und ebenfalls lokal in die IDE integriert werden, siehe
weiter unten.
Die MathCoach-API kann auch als npm-Package eingebunden werden, sodass eine typsichere
und komfortable Entwicklung (z.B. mit Visual Studio Code) möglich ist. Hierzu muss
die `package.json` des Werkzeug-Projektes wie folgt ergänzt werden:
    {
        ...
        "devDependencies": {
            "@mathcoach/ide-api": "git+https://newton.htwsaar.de/gitblit/r/mathcoach/mathcoach-ide-api.git#1.1.0"
        },
        ...
    }
Wie man der Git-Repo URL ansieht, werden Git-Tags verwendet um eine
Versionierung [(Semantic Versioning)](https://semver.org/lang/de/)
der API zu erreichen. Lässt man die Versionierung weg, wird die
aktuellste Version verwendet. (Siehe Gitblit um verfügbare Versionen
einzusehen)
Bei Verwendung einer Entwicklungsumgebung wie Visual Studio Code kann die Typdefinition der
API auch für JavaScript eingebunden werden. Hierfür ist ggf. ein spezielles Kommentar am Anfang
der Datei notwendig (Pfad falls nötig anpassen):
    /// <reference path="../node_modules/@mathcoach/ide-api/mathcoach-api.d.ts"/>
Zertifikat von Newton hinzufügen, damit npm auf das Repository zugreifen kann.
    cd /usr/local/share/ca-certificates/
    sudo mkdir newton.htwsaar.de
    sudo cp path/to/newton.htwsaar.de.crt /usr/local/share/ca-certificates/newton.htwsaar.de/
    sudo chown 755 /usr/local/share/ca-certificates/newton.htwsaar.de
    sudo chown 644 /usr/local/share/ca-certificates/newton.htwsaar.de/newton.htwsaar.de.crt
    sudo update-ca-certificates
## Werkzeuge in die IDE integrieren
Damit die IDE das Werkzeug integrieren kann, muss eine Werkzeug-Deklaration registriert werden. Zur
Entwicklungszeit kann der Werkzeug-Entwickler dies lokal vornehmen. Anschließend können verknüpfte
Dateien mit dem Werkzeug geöffnet werden und erstellt werden (siehe Kontext-Menüs im IDE-Explorer).
Eine Freischaltung des Werkzeugs für alle Autoren erfolgt durch einen Administrator.
### Lokal (Nur für den Entwickler des Werkzeugs)
In der IDE muss eine Werkzeug-Deklaration angelegt werden, dazu muss die Datei `ide-settings.json` editiert werden:
    {
        ...
        "editor.external.declarations": [
            {
                "displayName": "Dummy",
                "entry": "/mathcoach/www/YOURNAME/tool.html",
                "description": "...",
                "developer": "...",
                "extension": "ext"
            }
            ...
        ],
        ...
    }
| Schlüssel | Beschreibung  | Beispiel  |
|---------------|---|---|
| displayName   | Der Name des Werkzeugs  |  `"Fill-In-Blank-Editor"`  |
| entry         | Der Einstiegspunkt für das Werkzeugs muss sich auf dem selben Server wie die IDE befinden.  |  `"/mathcoach/www/YOURNAME/tool.html"`  |
| description   | Eine kurze Beschreibung  |   |
| developer     | Name des Werkzeug-Entwicklers  |  |
| extension     | Dateien anhand der Datei-Erweiterung mit dem Werkzeug verknüpfen. Hier sollte etwas eindeutiges gewählt werden  | `"fib.json"` für Dateien wie `someExercise.fib.json`  |
### Global (Für alle Autoren)
-   Das Werkzeug samt Werkzeug-Deklaration muss als `.zip`-Datei an einen Administrator übergeben werden
-   Der Administrator schaltet das Werkzeug nach einer kurzen Prüfung (Keine Konflikte mit anderen
    Dateierweiterung, usw) frei. Beim nächsten Release von MathCoach ist das Werkzeug dann für alle
    Autoren verfügbar.
## Infos zu diesem Repository
    .
    ├── CHANGELOG.md                // Dokumentation von Änderungen der API
    ├── examples                    // Beispiele
    │   ├── ...
    │   └── ...
    ├── src                         // Hilfsfunktionen für Werkzeugentwickler
    │   ├── index.ts                // Einstiegspunkt
    │   └── ...
    ├── mathcoach-api.d.ts          // Definition der API
    ├── package.json
    ├── package-lock.json
    ├── README.md
    └── tsconfig.json
### Dokumentation erzeugen
    npm install && npm run build
### Release einer neuen Version
- Version der API in der `package.json` eintragen
- Beispiele aktualisieren
- Release Tag setzen `git tag -a VERSION -m '...'` und pushen
- IDE-Projekt prüfen:  `package.json`, `ide-lib.js`, ...
IDE-TOOL-UTILS.md
New file
@@ -0,0 +1,3 @@
# IDE TOOL UTILS
....
README.md
@@ -1,255 +1 @@
# MathCoach IDE API
In diesem Paket ([Das Gitblit Repository findet sich hier](https://newton.htwsaar.de/gitblit/summary/mathcoach!mathcoach-ide-api.git))
ist die öffentliche Schnittstelle zur MathCoach Entwicklungsumgebung (IDE) definiert. Mithilfe
dieser Schnittstelle können externe Werkzeuge (z.B. Editoren) erstellt werden. Ziel ist, dass
diese Werkzeuge für den Anwender komfortable - in die IDE integriert -zur Verfügung gestellt werden
können. Darüber hinaus werden als Ergänzung einige Hilfsfunktionen zum Bau von Werkzeugen angeboten.
![Demo](media/usage_author.gif)
*Beispielhafte Anwendung: Eine Datei wird angelegt und einem Demo-Editor geöffnet. Dieser generiert eine
Groovy-Aufgabe*
## Idee
TODO: Grafik (IDE, Werkzeug, Dateien, JSON, usw)
## Entwicklung externer Werkzeuge
-   Externe Werkzeuge müssen unter der Domain von MathCoach erreichbar sein. Zur Entwicklungszeit legt
    man das Werkzeug dazu im www-Verzeichnis ab.
-   Die von der IDE bereitgestellte Bibliothek muss eingebunden werden
        <script src="/mathcoach/ui/ide/ide-lib.js"/>
-   Von nun an steht die IDE API durch die globale Variable `MC` zur Verfügung.
-   **Hinweis**: Erst, wenn das Werkzeug in die IDE integriert und aus dieser heraus
    gestartet wurde, kann die API verwendet werden! Durch nachbilden der API kann
    eine Nutzung ohne IDE ermöglicht werden, siehe `enableOfflineUsageIfNecessary`.
### Empfohlenes Vorgehen
Damit externe Werkzeuge ein einheitliches Verhalten aufweisen, sollte wie folgt vorgegangen werden.
Als erstes muss sichergestellt werden, dass die MathCoach IDE API auch verfügbar ist. Dies ist beispielsweise
nicht der Fall, wenn das Werkzeug ohne die IDE gestartet wurde (und nicht offline-fähig ist) oder die IDE (aus
welchen Gründen auch immer) nicht einsatzbereit ist.
    if(typeof MC !== "undefined"){
        throw new Error("IDE Lib nicht eingebunden"); // TODO: show error to user
    }
    const isReady = await MC.isReady();
    if(!isReady){
        throw new Error("Die MathCoach-API ist nicht einsatzbereit."); // TODO: show error to user
    }
Von nun an kann die IDE API vollständig genutzt werden. Zunächst sollte die Kontext-Datei (die Datei,
mit der das Werkzeug gestartet wurde) geladen werden.
Ist der Inhalt der Kontext-Datei leer, wurde das Werkzeug vermutlich zum ersten mal gestartet das Werkzeug:
-   Sich initialisieren (z.B. mit einem leeren oder beispielhaften internem Datenmodell)
-   Das interne Datenmodell in die Kontext-Datei schreiben
-   Die zugehörige Aufgabe generieren. Siehe auch `contextFileToExerciseFile` weiter unten.
Andernfalls kann das zuvor gespeichertes Datenmodell in den Editor geladen werden.
Anschließend sollte die generierten Aufgaben in der Vorschau gestartet werden, sodass der Benutzer besser
abschätzen kann, wie sich Änderungen im Werkzeug auf die Aufgabe auswirken.
    let contextFile = await MC.ide.getContextFile(); // Datei, mit der der Editor gestartet wurde
    let contextFileContent = await MC.ide.fs.readFile(contextFile);
    let contextFileIsEmpty = contextFileContent === "";
    let exerciseFile = contextFileToExerciseFile(contextFile);
    if(contextFileIsEmpty){
        // TODO: init application with new data model (maybe with example contents)
        // write serialized model to context file, e.g. using JSON.stringify(...)
        let dataModelAsString = JSON.stringify({/* TODO */});
        await MC.ide.fs.writeFile(contextFile, dataModelAsString);
        // generate exercise
        let generatedExerciseCode = "startup { print('Hallo Welt!') }"; // TODO
        await MC.ide.fs.writeFile(exerciseFile, generatedExerciseCode);
    }else{
        // TODO: load data model, e.g. using JSON.parse(contextFileContent)
        // TODO: (overwrite context file and generated exercise file)
        // TODO: init application based on your data model
    }
    // show preview
    await MC.ide.navigator.navigateToExercise(exerciseFile);
Jedes Werkzeug sollte über eine "Speichern"-Funktion verfügen, mit der der Benutzer:
- Das interne Datenmodell in die Kontext-Datei speichert (sodass es später wieder geladen werden kann)
- Die zugehörige Aufgabe wird generiert und die Vorschau zu dieser navigiert
### Hilfunktionen für Werkzeug-Entwickler
Dieses Paket beinhaltet zusätzlich Hilfsfunktionen für Werkzeug-Entwickler.
-   **Aufgaben-Datei ableiten**: Die generierte Aufgabe soll wie die Kontext-Datei benannt sein,
    sodass diese vom Benutzer schnell zugeordnet werden können. Beispielsweise soll ein Werkzeug,
    welches mit der Kontext-Datei `/path/to/myExercise.mcq.json` gestartet wird, die
    Aufgabe `/path/to/myExercise.groovy` erzeugen.
        import { contextFileToExerciseFile } from "@mathcoach/ide-api";
        let contextFile = await MC.ide.getContextFile()
        let exerciseFile = contextFileToExerciseFile(contextFile);
-   **Standalone-Werkzeuge**: Werkzeuge können ohne IDE-Anbindung entwickelt und getestet
    werden. Dazu wird die IDE API nachgebildet - aktuell auf Basis des `LocalStorage` des
    Browsers.
        import { enableOfflineUsageIfNecessary } from "@mathcoach/ide-api";
        let offline: boolean = enableOfflineUsageIfNecessary();
        // now use the IDE API
### Beispiele
Im Verzeichnis `./examples/` finden sich Beispiele für externe Werkzeuge.
### Kleinere Werkzeuge
Für kleiner Werkzeuge bietet es sich an im WWW-Verzeichnis zu entwickeln  (z.B.
`myTool/tool.html` und `myTool/tool.js`). Die MathCoach-IDE stellt Autovervollständigung beim
Editieren der `tool.js`-Datei zur Verfügung. Da es sich um eine JavaScript-Datei handelt,
ist keine Typsicherheit gegeben. Das Werkzeug muss lokal in die IDE integriert werden, siehe
weiter unten.
![Demo](media/usage_tool_developer.gif)
### Größere Werkzeuge
Für größere Werkzeuge sollte ein Build-System wie [webpack](https://webpack.js.org/)
oder [PARCEL](https://parceljs.org/) in Kombination mit
[TypeScript](https://www.typescriptlang.org/) verwendet werden. Das Werkzeug muss nach dem
Build-Prozess in das WWW-Verzeichnis kopiert und ebenfalls lokal in die IDE integriert werden, siehe
weiter unten.
Die MathCoach-API kann auch als npm-Package eingebunden werden, sodass eine typsichere
und komfortable Entwicklung (z.B. mit Visual Studio Code) möglich ist. Hierzu muss
die `package.json` des Werkzeug-Projektes wie folgt ergänzt werden:
    {
        ...
        "devDependencies": {
            "@mathcoach/ide-api": "git+https://newton.htwsaar.de/gitblit/r/mathcoach/mathcoach-ide-api.git#1.1.0"
        },
        ...
    }
Wie man der Git-Repo URL ansieht, werden Git-Tags verwendet um eine
Versionierung [(Semantic Versioning)](https://semver.org/lang/de/)
der API zu erreichen. Lässt man die Versionierung weg, wird die
aktuellste Version verwendet. (Siehe Gitblit um verfügbare Versionen
einzusehen)
Bei Verwendung einer Entwicklungsumgebung wie Visual Studio Code kann die Typdefinition der
API auch für JavaScript eingebunden werden. Hierfür ist ggf. ein spezielles Kommentar am Anfang
der Datei notwendig (Pfad falls nötig anpassen):
    /// <reference path="../node_modules/@mathcoach/ide-api/mathcoach-api.d.ts"/>
Zertifikat von Newton hinzufügen, damit npm auf das Repository zugreifen kann.
    cd /usr/local/share/ca-certificates/
    sudo mkdir newton.htwsaar.de
    sudo cp path/to/newton.htwsaar.de.crt /usr/local/share/ca-certificates/newton.htwsaar.de/
    sudo chown 755 /usr/local/share/ca-certificates/newton.htwsaar.de
    sudo chown 644 /usr/local/share/ca-certificates/newton.htwsaar.de/newton.htwsaar.de.crt
    sudo update-ca-certificates
## Werkzeuge in die IDE integrieren
Damit die IDE das Werkzeug integrieren kann, muss eine Werkzeug-Deklaration registriert werden. Zur
Entwicklungszeit kann der Werkzeug-Entwickler dies lokal vornehmen. Anschließend können verknüpfte
Dateien mit dem Werkzeug geöffnet werden und erstellt werden (siehe Kontext-Menüs im IDE-Explorer).
Eine Freischaltung des Werkzeugs für alle Autoren erfolgt durch einen Administrator.
### Lokal (Nur für den Entwickler des Werkzeugs)
In der IDE muss eine Werkzeug-Deklaration angelegt werden, dazu muss die Datei `ide-settings.json` editiert werden:
    {
        ...
        "editor.external.declarations": [
            {
                "displayName": "Dummy",
                "entry": "/mathcoach/www/YOURNAME/tool.html",
                "description": "...",
                "developer": "...",
                "extension": "ext"
            }
            ...
        ],
        ...
    }
| Schlüssel | Beschreibung  | Beispiel  |
|---------------|---|---|
| displayName   | Der Name des Werkzeugs  |  `"Fill-In-Blank-Editor"`  |
| entry         | Der Einstiegspunkt für das Werkzeugs muss sich auf dem selben Server wie die IDE befinden.  |  `"/mathcoach/www/YOURNAME/tool.html"`  |
| description   | Eine kurze Beschreibung  |   |
| developer     | Name des Werkzeug-Entwicklers  |  |
| extension     | Dateien anhand der Datei-Erweiterung mit dem Werkzeug verknüpfen. Hier sollte etwas eindeutiges gewählt werden  | `"fib.json"` für Dateien wie `someExercise.fib.json`  |
### Global (Für alle Autoren)
-   Das Werkzeug samt Werkzeug-Deklaration muss als `.zip`-Datei an einen Administrator übergeben werden
-   Der Administrator schaltet das Werkzeug nach einer kurzen Prüfung (Keine Konflikte mit anderen
    Dateierweiterung, usw) frei. Beim nächsten Release von MathCoach ist das Werkzeug dann für alle
    Autoren verfügbar.
## Infos zu diesem Repository
    .
    ├── CHANGELOG.md                // Dokumentation von Änderungen der API
    ├── examples                    // Beispiele
    │   ├── ...
    │   └── ...
    ├── src                         // Hilfsfunktionen für Werkzeugentwickler
    │   ├── index.ts                // Einstiegspunkt
    │   └── ...
    ├── mathcoach-api.d.ts          // Definition der API
    ├── package.json
    ├── package-lock.json
    ├── README.md
    └── tsconfig.json
### Dokumentation erzeugen
    npm install && npm run build
### Release einer neuen Version
- Version der API in der `package.json` eintragen
- Beispiele aktualisieren
- Release Tag setzen `git tag -a VERSION -m '...'` und pushen
- IDE-Projekt prüfen:  `package.json`, `ide-lib.js`, ...
dist/es5/ide-tool-utils.js
New file
@@ -0,0 +1,127 @@
this.MC = this.MC || {};
this.MC.IdeUtils = (function (exports) {
    'use strict';
    /// <reference path="./mathcoach-api.d.ts"/>
    var __awaiter = (undefined && undefined.__awaiter) || function (thisArg, _arguments, P, generator) {
        function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
        return new (P || (P = Promise))(function (resolve, reject) {
            function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
            function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
            function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
            step((generator = generator.apply(thisArg, _arguments || [])).next());
        });
    };
    /**
     * Offline MathCoach-API falls notwendig bereitstellen. Dabei wird das Dateisystem durch den
     * LocalStorage des Browsers implementiert - einige Features der IDE (beispielsweise
     * der Navigator) sind nicht verfügbar und führen keine Aktionen durch.
     *
     * **Hinweis**: Wenn die echte MathCoach-API der IDE verfügbar ist, hat der Aufruf
     * dieser Funktion keinen Seiteneffekt.
     *
     * @param contextFileExtension Datei-Erweiterung der Kontext-Datei
     *
     */
    function enableOfflineUsageIfNecessary(contextFileExtension = "dummy.json") {
        const fileIdentifier = (file) => `mock-file://${file.owner}@${file.part}/${file.path}`;
        const traceMethod = (method, args) => console.log(["[MC MOCK API]", " ", method, "(", (args ? args : [""]).join(","), ")"].join(""));
        class MockAPI {
            constructor() {
                this.ide = {
                    getContextFile() {
                        return __awaiter(this, void 0, void 0, function* () {
                            traceMethod("MC.ide.getContextFile");
                            return {
                                owner: "jdoe",
                                path: `/file.${contextFileExtension}`,
                                part: "vfs"
                            };
                        });
                    },
                    getUserName() {
                        return __awaiter(this, void 0, void 0, function* () {
                            traceMethod("MC.ide.getUserName");
                            return "jdoe";
                        });
                    },
                    fs: {
                        readFile(file) {
                            return __awaiter(this, void 0, void 0, function* () {
                                traceMethod("MC.ide.fs.readFile", [JSON.stringify(file)]);
                                return localStorage.getItem(fileIdentifier(file)) || "";
                            });
                        },
                        writeFile(file, text) {
                            return __awaiter(this, void 0, void 0, function* () {
                                traceMethod("MC.ide.fs.writeFile", [JSON.stringify(file), JSON.stringify(`...${text.length} chars...`)]);
                                return localStorage.setItem(fileIdentifier(file), text);
                            });
                        }
                    },
                    navigator: {
                        navigateTo(link, forceOpen) {
                            return __awaiter(this, void 0, void 0, function* () {
                                traceMethod("MC.ide.navigator.navigateTo", [JSON.stringify(link), JSON.stringify(forceOpen ? true : false)]);
                            });
                        },
                        navigateToExercise(file, forceOpen) {
                            return __awaiter(this, void 0, void 0, function* () {
                                traceMethod("MC.ide.navigator.navigateToExercise", [JSON.stringify(file), JSON.stringify(forceOpen ? true : false)]);
                            });
                        }
                    }
                };
            }
            isReady() {
                return __awaiter(this, void 0, void 0, function* () {
                    traceMethod("MC.isReady()");
                    return true;
                });
            }
        }
        if (typeof MC === "undefined") {
            console.warn("you are offline - offline api is used");
            window.MC = new MockAPI(); // fake the MathCoach-API
            return true;
        }
        else {
            return false;
        }
    }
    /**
     * Kontext-Datei auf Aufgaben-Datei abbilden.
     * Beispiel: "/path/to/myExercise.mcq.json" zu "/path/to/myExercise.groovy"
     */
    function contextFileToExerciseFile(contextFile) {
        if (contextFile) {
            if (!contextFile.owner || !(typeof contextFile.owner === "string") || !(contextFile.owner.trim() === "")) {
                throw new Error("Context file has no valid 'owner' property.");
            }
            if (!contextFile.part || !(typeof contextFile.part === "string")) {
                if (contextFile.part !== "vfs" && contextFile.part !== "www") {
                    throw new Error("Context file has no valid 'part' property. Allowed values are 'vfs' and 'www'.");
                }
            }
            if (!contextFile.path || !(typeof contextFile.path === "string") || !(contextFile.owner.trim().startsWith("/"))) {
                throw new Error("Context file has no valid 'path' property.");
            }
        }
        else {
            throw new Error("No context file object given.");
        }
        let file = {
            part: contextFile.part,
            owner: contextFile.owner,
            path: contextFile.path.split(".")[0] + ".groovy"
        };
        return file;
    }
    exports.contextFileToExerciseFile = contextFileToExerciseFile;
    exports.enableOfflineUsageIfNecessary = enableOfflineUsageIfNecessary;
    return exports;
}({}));
//# sourceMappingURL=ide-tool-utils.js.map
dist/es5/ide-tool-utils.js.map
New file
@@ -0,0 +1 @@
{"version":3,"file":"ide-tool-utils.js","sources":["../es6/index.js"],"sourcesContent":["/// <reference path=\"./mathcoach-api.d.ts\"/>\nvar __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {\n    function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }\n    return new (P || (P = Promise))(function (resolve, reject) {\n        function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }\n        function rejected(value) { try { step(generator[\"throw\"](value)); } catch (e) { reject(e); } }\n        function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }\n        step((generator = generator.apply(thisArg, _arguments || [])).next());\n    });\n};\n/**\n * Offline MathCoach-API falls notwendig bereitstellen. Dabei wird das Dateisystem durch den\n * LocalStorage des Browsers implementiert - einige Features der IDE (beispielsweise\n * der Navigator) sind nicht verfügbar und führen keine Aktionen durch.\n *\n * **Hinweis**: Wenn die echte MathCoach-API der IDE verfügbar ist, hat der Aufruf\n * dieser Funktion keinen Seiteneffekt.\n *\n * @param contextFileExtension Datei-Erweiterung der Kontext-Datei\n *\n */\nexport function enableOfflineUsageIfNecessary(contextFileExtension = \"dummy.json\") {\n    const fileIdentifier = (file) => `mock-file://${file.owner}@${file.part}/${file.path}`;\n    const traceMethod = (method, args) => console.log([\"[MC MOCK API]\", \" \", method, \"(\", (args ? args : [\"\"]).join(\",\"), \")\"].join(\"\"));\n    class MockAPI {\n        constructor() {\n            this.ide = {\n                getContextFile() {\n                    return __awaiter(this, void 0, void 0, function* () {\n                        traceMethod(\"MC.ide.getContextFile\");\n                        return {\n                            owner: \"jdoe\",\n                            path: `/file.${contextFileExtension}`,\n                            part: \"vfs\"\n                        };\n                    });\n                },\n                getUserName() {\n                    return __awaiter(this, void 0, void 0, function* () {\n                        traceMethod(\"MC.ide.getUserName\");\n                        return \"jdoe\";\n                    });\n                },\n                fs: {\n                    readFile(file) {\n                        return __awaiter(this, void 0, void 0, function* () {\n                            traceMethod(\"MC.ide.fs.readFile\", [JSON.stringify(file)]);\n                            return localStorage.getItem(fileIdentifier(file)) || \"\";\n                        });\n                    },\n                    writeFile(file, text) {\n                        return __awaiter(this, void 0, void 0, function* () {\n                            traceMethod(\"MC.ide.fs.writeFile\", [JSON.stringify(file), JSON.stringify(`...${text.length} chars...`)]);\n                            return localStorage.setItem(fileIdentifier(file), text);\n                        });\n                    }\n                },\n                navigator: {\n                    navigateTo(link, forceOpen) {\n                        return __awaiter(this, void 0, void 0, function* () {\n                            traceMethod(\"MC.ide.navigator.navigateTo\", [JSON.stringify(link), JSON.stringify(forceOpen ? true : false)]);\n                        });\n                    },\n                    navigateToExercise(file, forceOpen) {\n                        return __awaiter(this, void 0, void 0, function* () {\n                            traceMethod(\"MC.ide.navigator.navigateToExercise\", [JSON.stringify(file), JSON.stringify(forceOpen ? true : false)]);\n                        });\n                    }\n                }\n            };\n        }\n        isReady() {\n            return __awaiter(this, void 0, void 0, function* () {\n                traceMethod(\"MC.isReady()\");\n                return true;\n            });\n        }\n    }\n    if (typeof MC === \"undefined\") {\n        console.warn(\"you are offline - offline api is used\");\n        window.MC = new MockAPI(); // fake the MathCoach-API\n        return true;\n    }\n    else {\n        return false;\n    }\n}\n/**\n * Kontext-Datei auf Aufgaben-Datei abbilden.\n * Beispiel: \"/path/to/myExercise.mcq.json\" zu \"/path/to/myExercise.groovy\"\n */\nexport function contextFileToExerciseFile(contextFile) {\n    if (contextFile) {\n        if (!contextFile.owner || !(typeof contextFile.owner === \"string\") || !(contextFile.owner.trim() === \"\")) {\n            throw new Error(\"Context file has no valid 'owner' property.\");\n        }\n        if (!contextFile.part || !(typeof contextFile.part === \"string\")) {\n            if (contextFile.part !== \"vfs\" && contextFile.part !== \"www\") {\n                throw new Error(\"Context file has no valid 'part' property. Allowed values are 'vfs' and 'www'.\");\n            }\n        }\n        if (!contextFile.path || !(typeof contextFile.path === \"string\") || !(contextFile.owner.trim().startsWith(\"/\"))) {\n            throw new Error(\"Context file has no valid 'path' property.\");\n        }\n    }\n    else {\n        throw new Error(\"No context file object given.\");\n    }\n    let file = {\n        part: contextFile.part,\n        owner: contextFile.owner,\n        path: contextFile.path.split(\".\")[0] + \".groovy\"\n    };\n    return file;\n}\n//# sourceMappingURL=index.js.map"],"names":["this"],"mappings":";;;;IAAA;IACA,IAAI,SAAS,GAAG,CAACA,SAAI,IAAIA,SAAI,CAAC,SAAS,KAAK,UAAU,OAAO,EAAE,UAAU,EAAE,CAAC,EAAE,SAAS,EAAE;IACzF,IAAI,SAAS,KAAK,CAAC,KAAK,EAAE,EAAE,OAAO,KAAK,YAAY,CAAC,GAAG,KAAK,GAAG,IAAI,CAAC,CAAC,UAAU,OAAO,EAAE,EAAE,OAAO,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE;IAChH,IAAI,OAAO,KAAK,CAAC,KAAK,CAAC,GAAG,OAAO,CAAC,EAAE,UAAU,OAAO,EAAE,MAAM,EAAE;IAC/D,QAAQ,SAAS,SAAS,CAAC,KAAK,EAAE,EAAE,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC,OAAO,CAAC,EAAE,EAAE,MAAM,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE;IACnG,QAAQ,SAAS,QAAQ,CAAC,KAAK,EAAE,EAAE,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC,OAAO,CAAC,EAAE,EAAE,MAAM,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE;IACtG,QAAQ,SAAS,IAAI,CAAC,MAAM,EAAE,EAAE,MAAM,CAAC,IAAI,GAAG,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,GAAG,KAAK,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,SAAS,EAAE,QAAQ,CAAC,CAAC,EAAE;IACtH,QAAQ,IAAI,CAAC,CAAC,SAAS,GAAG,SAAS,CAAC,KAAK,CAAC,OAAO,EAAE,UAAU,IAAI,EAAE,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC;IAC9E,KAAK,CAAC,CAAC;IACP,CAAC,CAAC;IACF;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;AACA,IAAO,SAAS,6BAA6B,CAAC,oBAAoB,GAAG,YAAY,EAAE;IACnF,IAAI,MAAM,cAAc,GAAG,CAAC,IAAI,KAAK,CAAC,YAAY,EAAE,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,IAAI,CAAC,IAAI,CAAC,CAAC,EAAE,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC;IAC3F,IAAI,MAAM,WAAW,GAAG,CAAC,MAAM,EAAE,IAAI,KAAK,OAAO,CAAC,GAAG,CAAC,CAAC,eAAe,EAAE,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE,CAAC,IAAI,GAAG,IAAI,GAAG,CAAC,EAAE,CAAC,EAAE,IAAI,CAAC,GAAG,CAAC,EAAE,GAAG,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC;IACzI,IAAI,MAAM,OAAO,CAAC;IAClB,QAAQ,WAAW,GAAG;IACtB,YAAY,IAAI,CAAC,GAAG,GAAG;IACvB,gBAAgB,cAAc,GAAG;IACjC,oBAAoB,OAAO,SAAS,CAAC,IAAI,EAAE,KAAK,CAAC,EAAE,KAAK,CAAC,EAAE,aAAa;IACxE,wBAAwB,WAAW,CAAC,uBAAuB,CAAC,CAAC;IAC7D,wBAAwB,OAAO;IAC/B,4BAA4B,KAAK,EAAE,MAAM;IACzC,4BAA4B,IAAI,EAAE,CAAC,MAAM,EAAE,oBAAoB,CAAC,CAAC;IACjE,4BAA4B,IAAI,EAAE,KAAK;IACvC,yBAAyB,CAAC;IAC1B,qBAAqB,CAAC,CAAC;IACvB,iBAAiB;IACjB,gBAAgB,WAAW,GAAG;IAC9B,oBAAoB,OAAO,SAAS,CAAC,IAAI,EAAE,KAAK,CAAC,EAAE,KAAK,CAAC,EAAE,aAAa;IACxE,wBAAwB,WAAW,CAAC,oBAAoB,CAAC,CAAC;IAC1D,wBAAwB,OAAO,MAAM,CAAC;IACtC,qBAAqB,CAAC,CAAC;IACvB,iBAAiB;IACjB,gBAAgB,EAAE,EAAE;IACpB,oBAAoB,QAAQ,CAAC,IAAI,EAAE;IACnC,wBAAwB,OAAO,SAAS,CAAC,IAAI,EAAE,KAAK,CAAC,EAAE,KAAK,CAAC,EAAE,aAAa;IAC5E,4BAA4B,WAAW,CAAC,oBAAoB,EAAE,CAAC,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IACtF,4BAA4B,OAAO,YAAY,CAAC,OAAO,CAAC,cAAc,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,CAAC;IACpF,yBAAyB,CAAC,CAAC;IAC3B,qBAAqB;IACrB,oBAAoB,SAAS,CAAC,IAAI,EAAE,IAAI,EAAE;IAC1C,wBAAwB,OAAO,SAAS,CAAC,IAAI,EAAE,KAAK,CAAC,EAAE,KAAK,CAAC,EAAE,aAAa;IAC5E,4BAA4B,WAAW,CAAC,qBAAqB,EAAE,CAAC,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,EAAE,IAAI,CAAC,SAAS,CAAC,CAAC,GAAG,EAAE,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC;IACrI,4BAA4B,OAAO,YAAY,CAAC,OAAO,CAAC,cAAc,CAAC,IAAI,CAAC,EAAE,IAAI,CAAC,CAAC;IACpF,yBAAyB,CAAC,CAAC;IAC3B,qBAAqB;IACrB,iBAAiB;IACjB,gBAAgB,SAAS,EAAE;IAC3B,oBAAoB,UAAU,CAAC,IAAI,EAAE,SAAS,EAAE;IAChD,wBAAwB,OAAO,SAAS,CAAC,IAAI,EAAE,KAAK,CAAC,EAAE,KAAK,CAAC,EAAE,aAAa;IAC5E,4BAA4B,WAAW,CAAC,6BAA6B,EAAE,CAAC,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,EAAE,IAAI,CAAC,SAAS,CAAC,SAAS,GAAG,IAAI,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC;IACzI,yBAAyB,CAAC,CAAC;IAC3B,qBAAqB;IACrB,oBAAoB,kBAAkB,CAAC,IAAI,EAAE,SAAS,EAAE;IACxD,wBAAwB,OAAO,SAAS,CAAC,IAAI,EAAE,KAAK,CAAC,EAAE,KAAK,CAAC,EAAE,aAAa;IAC5E,4BAA4B,WAAW,CAAC,qCAAqC,EAAE,CAAC,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,EAAE,IAAI,CAAC,SAAS,CAAC,SAAS,GAAG,IAAI,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC;IACjJ,yBAAyB,CAAC,CAAC;IAC3B,qBAAqB;IACrB,iBAAiB;IACjB,aAAa,CAAC;IACd,SAAS;IACT,QAAQ,OAAO,GAAG;IAClB,YAAY,OAAO,SAAS,CAAC,IAAI,EAAE,KAAK,CAAC,EAAE,KAAK,CAAC,EAAE,aAAa;IAChE,gBAAgB,WAAW,CAAC,cAAc,CAAC,CAAC;IAC5C,gBAAgB,OAAO,IAAI,CAAC;IAC5B,aAAa,CAAC,CAAC;IACf,SAAS;IACT,KAAK;IACL,IAAI,IAAI,OAAO,EAAE,KAAK,WAAW,EAAE;IACnC,QAAQ,OAAO,CAAC,IAAI,CAAC,uCAAuC,CAAC,CAAC;IAC9D,QAAQ,MAAM,CAAC,EAAE,GAAG,IAAI,OAAO,EAAE,CAAC;IAClC,QAAQ,OAAO,IAAI,CAAC;IACpB,KAAK;IACL,SAAS;IACT,QAAQ,OAAO,KAAK,CAAC;IACrB,KAAK;IACL,CAAC;IACD;IACA;IACA;IACA;AACA,IAAO,SAAS,yBAAyB,CAAC,WAAW,EAAE;IACvD,IAAI,IAAI,WAAW,EAAE;IACrB,QAAQ,IAAI,CAAC,WAAW,CAAC,KAAK,IAAI,EAAE,OAAO,WAAW,CAAC,KAAK,KAAK,QAAQ,CAAC,IAAI,EAAE,WAAW,CAAC,KAAK,CAAC,IAAI,EAAE,KAAK,EAAE,CAAC,EAAE;IAClH,YAAY,MAAM,IAAI,KAAK,CAAC,6CAA6C,CAAC,CAAC;IAC3E,SAAS;IACT,QAAQ,IAAI,CAAC,WAAW,CAAC,IAAI,IAAI,EAAE,OAAO,WAAW,CAAC,IAAI,KAAK,QAAQ,CAAC,EAAE;IAC1E,YAAY,IAAI,WAAW,CAAC,IAAI,KAAK,KAAK,IAAI,WAAW,CAAC,IAAI,KAAK,KAAK,EAAE;IAC1E,gBAAgB,MAAM,IAAI,KAAK,CAAC,gFAAgF,CAAC,CAAC;IAClH,aAAa;IACb,SAAS;IACT,QAAQ,IAAI,CAAC,WAAW,CAAC,IAAI,IAAI,EAAE,OAAO,WAAW,CAAC,IAAI,KAAK,QAAQ,CAAC,IAAI,EAAE,WAAW,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC,EAAE;IACzH,YAAY,MAAM,IAAI,KAAK,CAAC,4CAA4C,CAAC,CAAC;IAC1E,SAAS;IACT,KAAK;IACL,SAAS;IACT,QAAQ,MAAM,IAAI,KAAK,CAAC,+BAA+B,CAAC,CAAC;IACzD,KAAK;IACL,IAAI,IAAI,IAAI,GAAG;IACf,QAAQ,IAAI,EAAE,WAAW,CAAC,IAAI;IAC9B,QAAQ,KAAK,EAAE,WAAW,CAAC,KAAK;IAChC,QAAQ,IAAI,EAAE,WAAW,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,SAAS;IACxD,KAAK,CAAC;IACN,IAAI,OAAO,IAAI,CAAC;IAChB,CAAC;;;;;;;;;;;"}
dist/es6/index.d.ts
New file
@@ -0,0 +1,18 @@
/// <reference path="../../src/mathcoach-api.d.ts" />
/**
 * Offline MathCoach-API falls notwendig bereitstellen. Dabei wird das Dateisystem durch den
 * LocalStorage des Browsers implementiert - einige Features der IDE (beispielsweise
 * der Navigator) sind nicht verfügbar und führen keine Aktionen durch.
 *
 * **Hinweis**: Wenn die echte MathCoach-API der IDE verfügbar ist, hat der Aufruf
 * dieser Funktion keinen Seiteneffekt.
 *
 * @param contextFileExtension Datei-Erweiterung der Kontext-Datei
 *
 */
export declare function enableOfflineUsageIfNecessary(contextFileExtension?: string): boolean;
/**
 * Kontext-Datei auf Aufgaben-Datei abbilden.
 * Beispiel: "/path/to/myExercise.mcq.json" zu "/path/to/myExercise.groovy"
 */
export declare function contextFileToExerciseFile(contextFile: MathCoach.File): MathCoach.File;
dist/es6/index.js
New file
@@ -0,0 +1,116 @@
/// <reference path="./mathcoach-api.d.ts"/>
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
    function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
    return new (P || (P = Promise))(function (resolve, reject) {
        function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
        function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
        function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
        step((generator = generator.apply(thisArg, _arguments || [])).next());
    });
};
/**
 * Offline MathCoach-API falls notwendig bereitstellen. Dabei wird das Dateisystem durch den
 * LocalStorage des Browsers implementiert - einige Features der IDE (beispielsweise
 * der Navigator) sind nicht verfügbar und führen keine Aktionen durch.
 *
 * **Hinweis**: Wenn die echte MathCoach-API der IDE verfügbar ist, hat der Aufruf
 * dieser Funktion keinen Seiteneffekt.
 *
 * @param contextFileExtension Datei-Erweiterung der Kontext-Datei
 *
 */
export function enableOfflineUsageIfNecessary(contextFileExtension = "dummy.json") {
    const fileIdentifier = (file) => `mock-file://${file.owner}@${file.part}/${file.path}`;
    const traceMethod = (method, args) => console.log(["[MC MOCK API]", " ", method, "(", (args ? args : [""]).join(","), ")"].join(""));
    class MockAPI {
        constructor() {
            this.ide = {
                getContextFile() {
                    return __awaiter(this, void 0, void 0, function* () {
                        traceMethod("MC.ide.getContextFile");
                        return {
                            owner: "jdoe",
                            path: `/file.${contextFileExtension}`,
                            part: "vfs"
                        };
                    });
                },
                getUserName() {
                    return __awaiter(this, void 0, void 0, function* () {
                        traceMethod("MC.ide.getUserName");
                        return "jdoe";
                    });
                },
                fs: {
                    readFile(file) {
                        return __awaiter(this, void 0, void 0, function* () {
                            traceMethod("MC.ide.fs.readFile", [JSON.stringify(file)]);
                            return localStorage.getItem(fileIdentifier(file)) || "";
                        });
                    },
                    writeFile(file, text) {
                        return __awaiter(this, void 0, void 0, function* () {
                            traceMethod("MC.ide.fs.writeFile", [JSON.stringify(file), JSON.stringify(`...${text.length} chars...`)]);
                            return localStorage.setItem(fileIdentifier(file), text);
                        });
                    }
                },
                navigator: {
                    navigateTo(link, forceOpen) {
                        return __awaiter(this, void 0, void 0, function* () {
                            traceMethod("MC.ide.navigator.navigateTo", [JSON.stringify(link), JSON.stringify(forceOpen ? true : false)]);
                        });
                    },
                    navigateToExercise(file, forceOpen) {
                        return __awaiter(this, void 0, void 0, function* () {
                            traceMethod("MC.ide.navigator.navigateToExercise", [JSON.stringify(file), JSON.stringify(forceOpen ? true : false)]);
                        });
                    }
                }
            };
        }
        isReady() {
            return __awaiter(this, void 0, void 0, function* () {
                traceMethod("MC.isReady()");
                return true;
            });
        }
    }
    if (typeof MC === "undefined") {
        console.warn("you are offline - offline api is used");
        window.MC = new MockAPI(); // fake the MathCoach-API
        return true;
    }
    else {
        return false;
    }
}
/**
 * Kontext-Datei auf Aufgaben-Datei abbilden.
 * Beispiel: "/path/to/myExercise.mcq.json" zu "/path/to/myExercise.groovy"
 */
export function contextFileToExerciseFile(contextFile) {
    if (contextFile) {
        if (!contextFile.owner || !(typeof contextFile.owner === "string") || !(contextFile.owner.trim() === "")) {
            throw new Error("Context file has no valid 'owner' property.");
        }
        if (!contextFile.part || !(typeof contextFile.part === "string")) {
            if (contextFile.part !== "vfs" && contextFile.part !== "www") {
                throw new Error("Context file has no valid 'part' property. Allowed values are 'vfs' and 'www'.");
            }
        }
        if (!contextFile.path || !(typeof contextFile.path === "string") || !(contextFile.owner.trim().startsWith("/"))) {
            throw new Error("Context file has no valid 'path' property.");
        }
    }
    else {
        throw new Error("No context file object given.");
    }
    let file = {
        part: contextFile.part,
        owner: contextFile.owner,
        path: contextFile.path.split(".")[0] + ".groovy"
    };
    return file;
}
//# sourceMappingURL=index.js.map
dist/es6/index.js.map
New file
@@ -0,0 +1 @@
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"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"}
package-lock.json
@@ -4,57 +4,10 @@
  "lockfileVersion": 1,
  "requires": true,
  "dependencies": {
    "@types/events": {
      "version": "3.0.0",
      "resolved": "https://registry.npmjs.org/@types/events/-/events-3.0.0.tgz",
      "integrity": "sha512-EaObqwIvayI5a8dCzhFrjKzVwKLxjoG9T6Ppd5CEo07LRKfQ8Yokw54r5+Wq7FaBQ+yXRvQAYPrHwya1/UFt9g==",
      "dev": true
    },
    "@types/fs-extra": {
      "version": "5.1.0",
      "resolved": "https://registry.npmjs.org/@types/fs-extra/-/fs-extra-5.1.0.tgz",
      "integrity": "sha512-AInn5+UBFIK9FK5xc9yP5e3TQSPNNgjHByqYcj9g5elVBnDQcQL7PlO1CIRy2gWlbwK7UPYqi7vRvFA44dCmYQ==",
      "dev": true,
      "requires": {
        "@types/node": "*"
      }
    },
    "@types/glob": {
      "version": "7.1.1",
      "resolved": "https://registry.npmjs.org/@types/glob/-/glob-7.1.1.tgz",
      "integrity": "sha512-1Bh06cbWJUHMC97acuD6UMG29nMt0Aqz1vF3guLfG+kHHJhy3AyohZFFxYk2f7Q1SQIrNwvncxAE0N/9s70F2w==",
      "dev": true,
      "requires": {
        "@types/events": "*",
        "@types/minimatch": "*",
        "@types/node": "*"
      }
    },
    "@types/handlebars": {
      "version": "4.1.0",
      "resolved": "https://registry.npmjs.org/@types/handlebars/-/handlebars-4.1.0.tgz",
      "integrity": "sha512-gq9YweFKNNB1uFK71eRqsd4niVkXrxHugqWFQkeLRJvGjnxsLr16bYtcsG4tOFwmYi0Bax+wCkbf1reUfdl4kA==",
      "dev": true,
      "requires": {
        "handlebars": "*"
      }
    },
    "@types/highlight.js": {
      "version": "9.12.3",
      "resolved": "https://registry.npmjs.org/@types/highlight.js/-/highlight.js-9.12.3.tgz",
      "integrity": "sha512-pGF/zvYOACZ/gLGWdQH8zSwteQS1epp68yRcVLJMgUck/MjEn/FBYmPub9pXT8C1e4a8YZfHo1CKyV8q1vKUnQ==",
      "dev": true
    },
    "@types/lodash": {
      "version": "4.14.135",
      "resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.14.135.tgz",
      "integrity": "sha512-Ed+tSZ9qM1oYpi5kzdsBuOzcAIn1wDW+e8TFJ50IMJMlSopGdJgKAbhHzN6h1E1OfjlGOr2JepzEWtg9NIfoNg==",
      "dev": true
    },
    "@types/marked": {
      "version": "0.4.2",
      "resolved": "https://registry.npmjs.org/@types/marked/-/marked-0.4.2.tgz",
      "integrity": "sha512-cDB930/7MbzaGF6U3IwSQp6XBru8xWajF5PV2YZZeV8DyiliTuld11afVztGI9+yJZ29il5E+NpGA6ooV/Cjkg==",
    "@types/estree": {
      "version": "0.0.40",
      "resolved": "https://registry.npmjs.org/@types/estree/-/estree-0.0.40.tgz",
      "integrity": "sha512-p3KZgMto/JyxosKGmnLDJ/dG5wf+qTRMUjHJcspC2oQKa4jP7mz+tv0ND56lLBu3ojHlhzY33Ol+khLyNmilkA==",
      "dev": true
    },
    "@types/minimatch": {
@@ -69,14 +22,19 @@
      "integrity": "sha512-LcsGbPomWsad6wmMNv7nBLw7YYYyfdYcz6xryKYQhx89c3XXan+8Q6AJ43G5XDIaklaVkK3mE4fCb0SBvMiPSQ==",
      "dev": true
    },
    "@types/shelljs": {
      "version": "0.8.5",
      "resolved": "https://registry.npmjs.org/@types/shelljs/-/shelljs-0.8.5.tgz",
      "integrity": "sha512-bZgjwIWu9gHCjirKJoOlLzGi5N0QgZ5t7EXEuoqyWCHTuSddURXo3FOBYDyRPNOWzZ6NbkLvZnVkn483Y/tvcQ==",
    "acorn": {
      "version": "7.1.0",
      "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.1.0.tgz",
      "integrity": "sha512-kL5CuoXA/dgxlBbVrflsflzQ3PAas7RYZB52NOm/6839iVYJgKMJ3cQJD+t2i5+qFa8h3MDpEOJiS64E8JLnSQ==",
      "dev": true
    },
    "backbone": {
      "version": "1.4.0",
      "resolved": "https://registry.npmjs.org/backbone/-/backbone-1.4.0.tgz",
      "integrity": "sha512-RLmDrRXkVdouTg38jcgHhyQ/2zjg7a8E6sz2zxfz21Hh17xDJYUHBZimVIt5fUyS8vbfpeSmTL3gUjTEvUV3qQ==",
      "dev": true,
      "requires": {
        "@types/glob": "*",
        "@types/node": "*"
        "underscore": ">=1.8.3"
      }
    },
    "balanced-match": {
@@ -96,9 +54,9 @@
      }
    },
    "commander": {
      "version": "2.20.0",
      "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.0.tgz",
      "integrity": "sha512-7j2y+40w61zy6YC2iRNpUe/NwhNyoXrYpHMrSunaMG64nRnaf96zO/KMQR4OyN/UnE5KLyEBnKHd4aG3rskjpQ==",
      "version": "2.20.3",
      "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz",
      "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==",
      "dev": true,
      "optional": true
    },
@@ -109,12 +67,12 @@
      "dev": true
    },
    "fs-extra": {
      "version": "7.0.1",
      "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-7.0.1.tgz",
      "integrity": "sha512-YJDaCJZEnBmcbw13fvdAM9AwNOJwOzrE4pqMqBq5nFiEqXUqHwlK4B+3pUw6JNvfSPtX05xFHtYy/1ni01eGCw==",
      "version": "8.1.0",
      "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-8.1.0.tgz",
      "integrity": "sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g==",
      "dev": true,
      "requires": {
        "graceful-fs": "^4.1.2",
        "graceful-fs": "^4.2.0",
        "jsonfile": "^4.0.0",
        "universalify": "^0.1.0"
      }
@@ -126,9 +84,9 @@
      "dev": true
    },
    "glob": {
      "version": "7.1.4",
      "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.4.tgz",
      "integrity": "sha512-hkLPepehmnKk41pUGm3sYxoFs/umurYfYJCerbXEyFIWcAzvpipAgVkBqqT9RBKMGjnq6kMuyYwha6csxbiM1A==",
      "version": "7.1.6",
      "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz",
      "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==",
      "dev": true,
      "requires": {
        "fs.realpath": "^1.0.0",
@@ -140,15 +98,15 @@
      }
    },
    "graceful-fs": {
      "version": "4.1.15",
      "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.1.15.tgz",
      "integrity": "sha512-6uHUhOPEBgQ24HM+r6b/QwWfZq+yiFcipKFrOFiBEnWdy5sdzYoi+pJeQaPI5qOLRFqWmAXUPQNsielzdLoecA==",
      "version": "4.2.3",
      "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.3.tgz",
      "integrity": "sha512-a30VEBm4PEdx1dRB7MFK7BejejvCvBronbLjht+sHuGYj8PHs7M/5Z+rt5lw551vZ7yfTCj4Vuyy3mSJytDWRQ==",
      "dev": true
    },
    "handlebars": {
      "version": "4.1.2",
      "resolved": "https://registry.npmjs.org/handlebars/-/handlebars-4.1.2.tgz",
      "integrity": "sha512-nvfrjqvt9xQ8Z/w0ijewdD/vvWDTOweBUm96NTr66Wfvo1mJenBLwcYmPs3TIBP5ruzYGD7Hx/DaM9RmhroGPw==",
      "version": "4.5.3",
      "resolved": "https://registry.npmjs.org/handlebars/-/handlebars-4.5.3.tgz",
      "integrity": "sha512-3yPecJoJHK/4c6aZhSvxOyG4vJKDshV36VHp0iVCDVh7o9w2vwi3NSnL2MMPj3YdduqaBcu7cGbggJQM0br9xA==",
      "dev": true,
      "requires": {
        "neo-async": "^2.6.0",
@@ -158,10 +116,13 @@
      }
    },
    "highlight.js": {
      "version": "9.15.8",
      "resolved": "https://registry.npmjs.org/highlight.js/-/highlight.js-9.15.8.tgz",
      "integrity": "sha512-RrapkKQWwE+wKdF73VsOa2RQdIoO3mxwJ4P8mhbI6KYJUraUHRKM5w5zQQKXNk0xNL4UVRdulV9SBJcmzJNzVA==",
      "dev": true
      "version": "9.17.0",
      "resolved": "https://registry.npmjs.org/highlight.js/-/highlight.js-9.17.0.tgz",
      "integrity": "sha512-PyO7FK7z8ZC7FqBlmAxm4d+1DYaoS6+uaxt9KGkyP1AnmGRLnWmNod1yp9BFjUyHoDF00k+V57gF6X9ifY7f/A==",
      "dev": true,
      "requires": {
        "handlebars": "^4.5.3"
      }
    },
    "inflight": {
      "version": "1.0.6",
@@ -185,6 +146,12 @@
      "integrity": "sha512-mT34yGKMNceBQUoVn7iCDKDntA7SC6gycMAWzGx1z/CMCTV7b2AAtXlo3nRyHZ1FelRkQbQjprHSYGwzLtkVbw==",
      "dev": true
    },
    "jquery": {
      "version": "3.4.1",
      "resolved": "https://registry.npmjs.org/jquery/-/jquery-3.4.1.tgz",
      "integrity": "sha512-36+AdBzCL+y6qjw5Tx7HgzeGCzC81MDDgaUP8ld2zhx58HdqXGoBd+tHdrBMiyjGQs0Hxs/MLZTu/eHNJJuWPw==",
      "dev": true
    },
    "jsonfile": {
      "version": "4.0.0",
      "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz",
@@ -195,15 +162,21 @@
      }
    },
    "lodash": {
      "version": "4.17.11",
      "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.11.tgz",
      "integrity": "sha512-cQKh8igo5QUhZ7lg38DYWAxMvjSAKG0A8wGSVimP07SIUEK2UO+arSRKbRZWtelMtN5V0Hkwh5ryOto/SshYIg==",
      "version": "4.17.15",
      "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.15.tgz",
      "integrity": "sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A==",
      "dev": true
    },
    "lunr": {
      "version": "2.3.8",
      "resolved": "https://registry.npmjs.org/lunr/-/lunr-2.3.8.tgz",
      "integrity": "sha512-oxMeX/Y35PNFuZoHp+jUj5OSEmLCaIH4KTFJh7a93cHBoFmpw2IoPs22VIz7vyO2YUnx2Tn9dzIwO2P/4quIRg==",
      "dev": true
    },
    "marked": {
      "version": "0.4.0",
      "resolved": "https://registry.npmjs.org/marked/-/marked-0.4.0.tgz",
      "integrity": "sha512-tMsdNBgOsrUophCAFQl0XPe6Zqk/uy9gnue+jIIKhykO51hxyu6uNx7zBPy0+y/WKYVZZMspV9YeXLNdKk+iYw==",
      "version": "0.7.0",
      "resolved": "https://registry.npmjs.org/marked/-/marked-0.7.0.tgz",
      "integrity": "sha512-c+yYdCZJQrsRjTPhUx7VKkApw9bwDkNbHUKo1ovgcfDjb2kc8rLuRbIFyXL5WOEUwzSSKo3IXpph2K6DqB/KZg==",
      "dev": true
    },
    "minimatch": {
@@ -274,23 +247,34 @@
      }
    },
    "resolve": {
      "version": "1.11.1",
      "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.11.1.tgz",
      "integrity": "sha512-vIpgF6wfuJOZI7KKKSP+HmiKggadPQAdsp5HiC1mvqnfp0gF1vdwgBWZIdrVft9pgqoMFQN+R7BSWZiBxx+BBw==",
      "version": "1.13.1",
      "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.13.1.tgz",
      "integrity": "sha512-CxqObCX8K8YtAhOBRg+lrcdn+LK+WYOS8tSjqSFbjtrI5PnS63QPhZl4+yKfrU9tdsbMu9Anr/amegT87M9Z6w==",
      "dev": true,
      "requires": {
        "path-parse": "^1.0.6"
      }
    },
    "rimraf": {
      "version": "2.6.3",
      "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.3.tgz",
      "integrity": "sha512-mwqeW5XsA2qAejG46gYdENaxXjx9onRNCfn7L0duuP4hCuTIi/QO7PDK07KJfp1d+izWPrzEJDcSqBa0OZQriA==",
      "version": "3.0.0",
      "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.0.tgz",
      "integrity": "sha512-NDGVxTsjqfunkds7CqsOiEnxln4Bo7Nddl3XhS4pXg5OzwkLqJ971ZVAAnB+DDLnF76N+VnDEiBHaVV8I06SUg==",
      "dev": true,
      "requires": {
        "glob": "^7.1.3"
      }
    },
    "rollup": {
      "version": "1.27.10",
      "resolved": "https://registry.npmjs.org/rollup/-/rollup-1.27.10.tgz",
      "integrity": "sha512-5PjBSKney8zLu7tTn/y4iVBL3OyK+G9rA/wfkcY78bZ9kAMtgNqb8nOfR5KpoDYyt8Vs5o2o8DyDjf9RpwYbAg==",
      "dev": true,
      "requires": {
        "@types/estree": "*",
        "@types/node": "*",
        "acorn": "^7.1.0"
      }
    },
    "shelljs": {
      "version": "0.8.3",
      "resolved": "https://registry.npmjs.org/shelljs/-/shelljs-0.8.3.tgz",
@@ -309,53 +293,59 @@
      "dev": true
    },
    "typedoc": {
      "version": "0.14.2",
      "resolved": "https://registry.npmjs.org/typedoc/-/typedoc-0.14.2.tgz",
      "integrity": "sha512-aEbgJXV8/KqaVhcedT7xG6d2r+mOvB5ep3eIz1KuB5sc4fDYXcepEEMdU7XSqLFO5hVPu0nllHi1QxX2h/QlpQ==",
      "version": "0.15.4",
      "resolved": "https://registry.npmjs.org/typedoc/-/typedoc-0.15.4.tgz",
      "integrity": "sha512-XzrV8sM44j4nXGSKt99VOkFCPGLUH9DHGGvcgZJbvqdSG7/iR3HztNjpsLyTu1nybZLLjcClLRuWJDO3icXzYA==",
      "dev": true,
      "requires": {
        "@types/fs-extra": "^5.0.3",
        "@types/handlebars": "^4.0.38",
        "@types/highlight.js": "^9.12.3",
        "@types/lodash": "^4.14.110",
        "@types/marked": "^0.4.0",
        "@types/minimatch": "3.0.3",
        "@types/shelljs": "^0.8.0",
        "fs-extra": "^7.0.0",
        "handlebars": "^4.0.6",
        "highlight.js": "^9.13.1",
        "lodash": "^4.17.10",
        "marked": "^0.4.0",
        "fs-extra": "^8.1.0",
        "handlebars": "^4.5.3",
        "highlight.js": "^9.16.2",
        "lodash": "^4.17.15",
        "marked": "^0.7.0",
        "minimatch": "^3.0.0",
        "progress": "^2.0.0",
        "shelljs": "^0.8.2",
        "typedoc-default-themes": "^0.5.0",
        "typescript": "3.2.x"
        "progress": "^2.0.3",
        "shelljs": "^0.8.3",
        "typedoc-default-themes": "^0.6.1",
        "typescript": "3.7.x"
      }
    },
    "typedoc-default-themes": {
      "version": "0.5.0",
      "resolved": "https://registry.npmjs.org/typedoc-default-themes/-/typedoc-default-themes-0.5.0.tgz",
      "integrity": "sha1-bcJDPnjti+qOiHo6zeLzF4W9Yic=",
      "dev": true
      "version": "0.6.1",
      "resolved": "https://registry.npmjs.org/typedoc-default-themes/-/typedoc-default-themes-0.6.1.tgz",
      "integrity": "sha512-z5AWKqQDz7igl9WkUuafx8cEm4MPVQGMpbWE+3lwVOaq+U4UoLKBMnpFQWh/4fqQ3bGysXpOstMxy2OOzHezyw==",
      "dev": true,
      "requires": {
        "backbone": "^1.4.0",
        "jquery": "^3.4.1",
        "lunr": "^2.3.8",
        "underscore": "^1.9.1"
      }
    },
    "typescript": {
      "version": "3.2.4",
      "resolved": "https://registry.npmjs.org/typescript/-/typescript-3.2.4.tgz",
      "integrity": "sha512-0RNDbSdEokBeEAkgNbxJ+BLwSManFy9TeXz8uW+48j/xhEXv1ePME60olyzw2XzUqUBNAYFeJadIqAgNqIACwg==",
      "version": "3.7.3",
      "resolved": "https://registry.npmjs.org/typescript/-/typescript-3.7.3.tgz",
      "integrity": "sha512-Mcr/Qk7hXqFBXMN7p7Lusj1ktCBydylfQM/FZCk5glCNQJrCUKPkMHdo9R0MTFWsC/4kPFvDS0fDPvukfCkFsw==",
      "dev": true
    },
    "uglify-js": {
      "version": "3.6.0",
      "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.6.0.tgz",
      "integrity": "sha512-W+jrUHJr3DXKhrsS7NUVxn3zqMOFn0hL/Ei6v0anCIMoKC93TjcflTagwIHLW7SfMFfiQuktQyFVCFHGUE0+yg==",
      "version": "3.7.2",
      "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.7.2.tgz",
      "integrity": "sha512-uhRwZcANNWVLrxLfNFEdltoPNhECUR3lc+UdJoG9CBpMcSnKyWA94tc3eAujB1GcMY5Uwq8ZMp4qWpxWYDQmaA==",
      "dev": true,
      "optional": true,
      "requires": {
        "commander": "~2.20.0",
        "commander": "~2.20.3",
        "source-map": "~0.6.1"
      }
    },
    "underscore": {
      "version": "1.9.1",
      "resolved": "https://registry.npmjs.org/underscore/-/underscore-1.9.1.tgz",
      "integrity": "sha512-5/4etnCkd9c8gwgowi5/om/mYO5ajCaOgdzj/oW+0eQV9WxKBDZw5+ycmKmeaTXjInS/W0BzpGLo2xR2aBwZdg==",
      "dev": true
    },
    "universalify": {
      "version": "0.1.2",
      "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz",
package.json
@@ -7,14 +7,16 @@
    "example": "examples"
  },
  "devDependencies": {
    "rimraf": "^2.6.3",
    "typedoc": "^0.14.2"
    "rimraf": "^3.0.0",
    "rollup": "^1.27.10",
    "typedoc": "^0.15.4"
  },
  "scripts": {
    "clean": "rimraf dist/ && rimraf docs/",
    "build": "npm run clean  && npm run build-docs && npm run build-utils",
    "build-utils": "tsc",
    "build-docs": "typedoc mathcoach-api.d.ts src/ --out docs/ --mode file --theme minimal --includeDeclarations --excludeExternals --media ./media"
    "clean": "rimraf dist/",
    "build": "npm run clean  && npm run build-api-docs && npm run build-utils-docs && npm run build-utils",
    "build-utils": "tsc && rollup dist/es6/index.js --file dist/es5/ide-tool-utils.js --sourcemap  --format iife --name MC.IdeUtils",
    "build-api-docs": "typedoc src/mathcoach-api.d.ts   --out dist/docs/ide-api/        --mode file --readme IDE-API.md --theme minimal --includeDeclarations --excludeExternals --media ./media",
    "build-utils-docs": "typedoc src/                   --out dist/docs/ide-tool-utils/ --mode file --readme IDE-TOOL-UTILS.md --theme minimal --includeDeclarations --excludeExternals --media ./media"
  },
  "author": "jsteuer",
  "license": ""
src/index.ts
@@ -1,4 +1,4 @@
/// <reference path="../mathcoach-api.d.ts"/>
/// <reference path="./mathcoach-api.d.ts"/>
/**
 * Offline MathCoach-API falls notwendig bereitstellen. Dabei wird das Dateisystem durch den
src/mathcoach-api.d.ts
tsconfig.json
@@ -1,9 +1,11 @@
{
  "compilerOptions": {
    "module": "es6",
    "target": "es5",
    "target": "es6",
    "declaration": true,
    "outDir": "./dist"
    "outDir": "./dist/es6",
    "lib": ["DOM","ES2016"],
    "sourceMap": true
  },
  "include": [
    "src/**/*"