diff --git a/angular.json b/angular.json index a8a8012d3751286ac7422a4a4486449b2247e5a1..1e2976c20f2a68cba97dfa4dd2599d8b68b9a41f 100644 --- a/angular.json +++ b/angular.json @@ -13,6 +13,7 @@ "build": { "builder": "@angular-devkit/build-angular:browser", "options": { + "aot": true, "outputPath": "dist/itc-ng", "index": "src/index.html", "main": "src/main.ts", @@ -50,6 +51,12 @@ }, "configurations": { "production": { + "budgets": [ + { + "type": "anyComponentStyle", + "maximumWarning": "6kb" + } + ], "fileReplacements": [ { "replace": "src/environments/environment.ts", @@ -67,6 +74,12 @@ "buildOptimizer": true }, "build": { + "budgets": [ + { + "type": "anyComponentStyle", + "maximumWarning": "6kb" + } + ], "fileReplacements": [ { "replace": "src/environments/environment.ts", diff --git a/docs/booklet-config.md b/docs/booklet-config.md new file mode 100644 index 0000000000000000000000000000000000000000..45c171e26814e0d5bbb0634392798af981c4c041 --- /dev/null +++ b/docs/booklet-config.md @@ -0,0 +1,92 @@ +# Booklet config +There are some configuration parameters for adjusting the behaviour during the test.This +document describes the ways to bring the parameters to the application and lists +all possible keys. + +### Configuration file on the server +There is one file on the server where the application looks for booklet definitions: +``` +/config/bookletDefintions.json +``` +This configuration is loaded at (re)start of the application and is applied for +all booklets, if no other configuration is found. This is a simple JSON file with +key value pairs. Example: +``` +{ + "force_responses_complete": "OFF", + "unit_navibuttons": "ARROWS_ONLY", +... +} +``` +The adminstrator of the server can upload this file. We aim at providing an +administration feature of the super-admin section of the application to manage +this configuration. + +### Configuration via booklet XML +The configuration can be set for every single booklet. You need to add one XML-Element +into the booklet-file. Example: +``` +... +</Metadata> +<BookletConfig> + <Config key="force_responses_complete">OFF</CustomText> + <Config key="unit_navibuttons">ARROWS_ONLY</CustomText> +... +</BookletConfig> +``` + +### List of parameters + +#### `loading_mode` +Ladeverhalten beim Start + * "LAZY" (default): Start sobald wie möglich, Laden im Hintergrund fortsetzen + * "EAGER": Testheft erst dann starten, wenn alle Inhalte geladen sind + +#### `log_mode` +Erfassen und Speichern von Log-Daten + * "OFF": Ausgeschaltet + * "LEAN": Nur wichtige Meldungen + * "RICH" (default): Alles + +#### `page_navibuttons` +Navigationsbuttons für die Seitennavigation (innerhalb einer Aufgabe) + * "OFF": Keine Seitennavigation unterstützen (übernimmt ggf. die Aufgabe selbst) + * "MERGED": Die Seitennavigation wird durch die Aufgabennavigation mit übernommen + * "SEPARATE_TOP": Seitennavigation über getrennte Button-Leiste - oben + * "SEPARATE_BOTTOM" (default): Seitennavigation über getrennte Button-Leiste - unten + +#### `unit_navibuttons` +Navigationsbuttons für die Navigation zwischen den Aufgaben + * "OFF": Keine Buttons für Aufgabennavigation anzeigen (übernimmt ggf. die Aufgabe selbst) + * "ARROWS_ONLY": Nur die Buttons für 'Weiter' und 'Zurück' anzeigen + * "FULL" (default): Buttons für 'Weiter' und 'Zurück' und dazwischen kleine Buttons für jede Aufgabe anzeigen + +#### `unit_menu` +Extra-Seite mit großen Buttons für Aufgaben zum direkten Springen + * "OFF": Ausgeschaltet + * "ENABLED_ONLY" (default): Eingeschaltet - nur die Aufgaben anzeigen, die noch freigegeben sind + * "FULL": Eingeschaltet - auch die Aufgaben anzeigen, die nicht mehr freigegeben sind (gegraut) + +#### `force_presentation_complete` +Verhalten, wenn noch nicht alle Elemente der Aufgabe angezeigt wurden + * "OFF" (default): Ignorieren - Weiterblättern möglich + * "ON": Weiterblättern verhindern, bis Anzeige vollständig + +#### `force_responses_complete` +Verhalten, wenn noch nicht alle Antworten der Aufgabe vollständig gegeben wurden + * "OFF" (default): Ignorieren - Weiterblättern möglich + * "SOME": Weiterblättern erst möglich, wenn einige Antworten gegeben wurden + * "COMPLETE": Weiterblättern erst möglich, wenn alle Antworten gegeben wurden + * "COMPLETE_AND_VALID": Weiterblättern erst möglich, wenn alle Antworten gegeben wurden und als gültig eingeschätzt wurden + +#### `unit_screenheader` +Legt fest, ob im obersten Seitenbereich Platz für Logo, Navigations-Buttons u. ä. gelassen wird. + * "OFF": Kein Seitenkopf. Achtung: Logo bleibt sichtbar (überlappt). + * "WITH_UNIT_TITLE": Seitenkopf wird angezeigt mit Titel der Unit (s. Booklet-XML) + * "WITH_BOOKLET_TITLE": Seitenkopf wird angezeigt mit Titel des Booklets (s. Booklet-XML) + * "EMPTY" (default): Seitenkopf wird angezeigt (leer) + +#### `unit_title` +Festlegung, ob oberhalb des Unitbereiches eine Zeile mit dem Unit-Titel gezeigt werden soll + * "OFF": Keine Titelzeile + * "ON" (default): Eine Zeile wird eingeblendet mit dem Unit-Titel (s. Booklet-XML). diff --git a/docs/custom-texts.md b/docs/custom-texts.md new file mode 100644 index 0000000000000000000000000000000000000000..2d289d1b6675944aea1eaf5738ef2dbe8c9f72f6 --- /dev/null +++ b/docs/custom-texts.md @@ -0,0 +1,94 @@ +# CustomTexts +This application enables changes of texts during runtime. It's an implementation +of the CustomTextPipe/CustomTextService +of [iqb-components](https://github.com/iqb-berlin/iqb-components). The idea is, that +there might be some cases where the standard titles, prompts or explanations are not +suitable for the specific environment the iqb-testcenter application is run in. One +could change the source code and rebuild the application, but for minor changes we +use this text replacement feature 'custom texts'. + +This document +describes the ways to bring the custom texts to the application and lists +all possible keys. + +### Configuration file on the server +There is one file on the server where the application looks for custom texts: +``` +/config/customTexts.json +``` +These custom texts are loaded at (re)start of the application and the replacement starts +as soon as possible. This is a simple JSON file with key value pairs. Example: +``` +{ + "login_testEndButtonText": "Test beenden", + "login_bookletSelectPrompt": "Bitte wählen", +... +} +``` +The adminstrator of the server can upload this file. We aim at providing an +administration feature of the super-admin section of the application to manage +these texts. + +### Configuration via login configuration +For some tests, the test authority might like to change standard titles, prompts or explanations +furthermore depending on the testtaker. For example, the questionnaire for teachers +will use 'Please contact the administrator of the survey' and the booklet for students +will prompt 'Please ask the test proctor'. + +The login configuration goes with the XML file for the longin(s). There is one optional +section 'CustomTexts' in every login file. Text replacements in this section will apply +for every login of this file. Example: +``` +<CustomTexts> + <CustomText key="login_testEndButtonText">Test beenden</CustomText> + <CustomText key="login_bookletSelectPrompt">Bitte wählen</CustomText> +... +</CustomTexts> +``` +### Configuration of System check +In the definition file for system checks, there is also one place to define text +replacements: +``` +<Config> + <UploadSpeed ... + <DownloadSpeed ... + <CustomText key="syscheck_questionsintro">...</CustomText> + <CustomText key="app_intro1">...</CustomText> +... +</Config> +``` + +### List of possible replacements +| Key | Used for | Default | +| :------------- | :---------- | :----------- | +|`app_title`|Titel der Hauptanwendung|IQB-Testcenter| +|`app_intro1`|Begrüßungstext auf der Startseite (Text nach IQB-Link)|betreibt auf diesen Seiten eine Anwendung für das computerbasierte Leistungstesten von Schülerinnen und Schülern. Der Zugang zu einem Test ist nur möglich, wenn Sie von Testverantwortlichen Zugangsdaten erhalten haben. Es sind keine weiteren Seiten öffentlich verfügbar.| +|`login_testRunningText`|Kurznachricht, dass ein Test (Booklet) gestartet ist|Ein Testheft ist gestartet| +|`login_testRunningTextAndClick`|Nachricht, dass ein Test (Booklet) gestartet ist, mit Aufforderung zum Klicken|Es wird gerade ein Test ausgeführt. Bitte durch Klicken auf eine der beiden Schaltflächen links wählen, ob der Test fortgesetzt oder beendet werden soll!| +|`login_testEndButtonLabel`|Schalterbeschriftung für 'Test beenden'|Test beenden| +|`booklet_warningLeaveTimerBlockTextPrompt`|Schalterbeschriftung für 'Zurück zum Test'|Du verlässt einen zeitbeschränkten Bereich und kannst nicht zurückkehren. Trotzdem weiterblättern?| +|`login_testReturnButtonLabel`|Schalterbeschriftung für 'Zurück zum Test'|Zum Test zurückkehren| +|`login_bookletSelectPromptNull`|Nachricht für den Fall, dass Booklet(s) beendet wurden und keine weiteren zur Verfügung stehen|Beendet. Es können keine weiteren Testhefte gestartet werden.| +|`login_bookletSelectPromptOne`|Aufforderung, den einen gefundenen Test anzuklicken (auf Schalter klicken)|Bitte klicke auf die Schaltfläche auf der linken Seite, um den Test zu starten!| +|`login_bookletSelectPromptMany`|Aufforderung, aus der Liste der gefundenen Tests einen auszusuchen (auf Schalter klicken)|Bitte klicke auf eine der Schaltflächen auf der linken Seite, um einen Test zu starten!| +|`login_codeInputPrompt`|Aufforderung, Code einzugeben (bei einem zweistufigen Login-Prozess)|Bitte Log-in eingeben, der auf dem Zettel steht!| +|`login_codeInputTitle`|Titel des Eingabeformulares für den Code|Log-in eingeben| +|`booklet_msgPresentationNotCompleteTitleNext`|Titel der Nachricht (Dialogbox), dass nicht weitergeblättert werden kann, solange die Präsentation des Aufgabeninhaltes nicht abgeschlossen ist|Weiterblättern nicht möglich!| +|`booklet_msgPresentationNotCompleteTextNext`|Nachrichttext, dass nicht weitergeblättert werden kann, solange die Präsentation des Aufgabeninhaltes nicht abgeschlossen ist|Du kannst erst weiterblättern, wenn Audio-Dateien vollständig abgespielt wurden und wenn du in allen Fenstern bis ganz nach unten gescrollt hast.| +|`booklet_msgPresentationNotCompleteTitlePrev`|Titel der Nachricht (Dialogbox), dass nicht zurückgeblättert werden kann, solange die Präsentation des Aufgabeninhaltes nicht abgeschlossen ist|Zurückblättern - Warnung| +|`booklet_msgPresentationNotCompleteTextPrev`|Nachrichttext, dass nicht zurückgeblättert werden kann, solange die Präsentation des Aufgabeninhaltes nicht abgeschlossen ist|Eine Audio-Datei ist noch nicht bis zu Ende abgespielt oder Seiten wurden noch nicht vollständig gezeigt. Wenn du jetzt zurückblätterst, kannst Du später Audio-Dateien nicht nocheinmal starten.| +|`booklet_codeToEnterTitle`|Titel der Dialogbox für die Eingabe eines Freigabewortes|Freigabewort| +|`booklet_codeToEnterPrompt`|Aufforderung für die Eingabe eines Freigabewortes (Dialog-Box)|Bitte gib das Freigabewort ein, das angesagt wurde!| +|`booklet_msgSoonTimeOver5Minutes`|Nachricht, dass für die Bearbeitung eines Abschnittes noch 5 min Zeit sind|Du hast noch 5 Minuten Zeit für die Bearbeitung der Aufgaben in diesem Abschnitt.| +|`booklet_msgSoonTimeOver1Minute`|Nachricht, dass für die Bearbeitung eines Abschnittes noch 1 min Zeit ist|Du hast noch 1 Minute Zeit für die Bearbeitung der Aufgaben in diesem Abschnitt.| +|`booklet_msgTimerStarted`|Nachricht, dass der Timer für die Bearbeitung eines Abschnittes gestartet wurde|Die Bearbeitungszeit für diesen Abschnitt hat begonnen: | +|`booklet_msgTimerCancelled`|Nachricht, dass die Bearbeitung eines Abschnittes mit Timer abgebrochen wurde|Die Bearbeitung des Abschnittes wurde abgebrochen.| +|`booklet_msgTimeOver`|Nachricht, dass die Bearbeitungszeit für einen Abschnitt abgelaufen ist.|Die Bearbeitung des Abschnittes ist beendet.| +|`booklet_warningLeaveTimerBlockTitle`|Titel für Warnung (Dialogbox) vor dem vorzeitigen Verlassen eines Abschnittes mit Timer|Aufgabenabschnitt verlassen?| +|`booklet_warningLeaveTimerBlockPrompt`|Warnung vor dem vorzeitigen Verlassen eines Abschnittes mit Timer|Wenn du jetzt weiterblätterst, beendest du vorzeitig die Bearbeitung dieses Aufgabenabschnitts und du kannst nicht mehr zurück.| +|`booklet_tasklisttitle`|Titel für die Auflistung der Aufgaben (Schalter)|Aufgaben| +|`booklet_warningLeaveTestTitle`|Titel für Warnung (Dialogbox) vor dem vorzeitigen Verlassen des Tests|Test verlassen?| +|`booklet_warningLeaveTestPrompt`|Warnung vor dem vorzeitigen Verlassen des Tests|Der Test ist noch nicht beendet. Möchtest Du den Test trotzdem verlassen?| +|`syscheck_questionsintro`|Aufforderung, die Fragen (Questionnaire) zu beantworten|Bitte bearbeiten Sie die nachfolgenden Fragen.| +|`booklet_errormessage`|Nachricht an die Testperson, wenn ein schwerer Fehler aufgetreten ist|Es ist ein schwerer Fehler aufgetreten. Bitte rufe die Aufsichtsperson und beschreibe das Problem!| +|`booklet_pausedmessage`|Nachricht an die Testperson, wenn der Test vom System unterbrochen wurde|Der Test wurde kurz angehalten.| diff --git a/docs/test-mode.md b/docs/test-mode.md new file mode 100644 index 0000000000000000000000000000000000000000..2895d07ec97c550042c250f666579cbb84397013 --- /dev/null +++ b/docs/test-mode.md @@ -0,0 +1,30 @@ +# Modes for test execution + +For the test or the survey, all execution parameters are given by +the XML definition files. But before the test starts in production (hot) mode, there is +the need to evaluate the test content and configuration. Then, some restrictions of the +test may make it really hard to evaluate. For example, it would take too much time if +you have to wait for the completion of all audio sequences. One could adapt the +test definition for the evaluation period, but this is dangerous: After evaluation, you +will change the test definition again and then risk new errors. + +Our system allows multiple modes to run the test. Every login carries a token that declares +this mode. You can first review only the design of the units and its arrangement, +then switch on some restrictions and store responses, and finally evaluate the +test like a testtaker. + +* `DEMO` (default): Nur Ansicht (Demo) +* `HOT`: Durchführung Test/Befragung +* `REVIEW`: Prüfdurchgang ohne Speichern +* `TRIAL`: Prüfdurchgang mit Speichern + + +| | `DEMO` | `HOT` | `REVIEW` | `TRIAL` | +| :------------- | :-------------: | :-------------: | :-------------: | :-------------: | +|Es können Reviews abgegeben werden (Kommentare/Einschätzungen zur Unit bzw. zum Test)| | |X | | +|Es werden Antworten und Logs gespeichert.| |X | |X | +|Alle Zeitbeschränkungen für Testabschnitte werden angewendet.| |X | |X | +|Alle Navigationsbeschränkungen des Booklets werden angewendet (z. B. erst weiter, wenn vollständig angezeigt).| |X | |X | +|Sollte ein Testabschnitt mit einem Freigabewort geschützt sein, wird dieses bei der Eingabebox schon eingetragen.|X | |X |X | +|Sollte eine Maximalzeit für einen Testabschnitt festgelegt sein, wird die verbleibende Zeit angezeigt, auch wenn die Booklet-Konfiguration dies unterbindet.|X | |X | | +|Die Seite mit der Aufgaben-Übersicht wird erlaubt, auch wenn das Booklet dies unterbindet.| | |X | | diff --git a/e2e/user-stories/README.md b/e2e/user-stories/README.md new file mode 100644 index 0000000000000000000000000000000000000000..e7f2859418a793544ca474041ccee861a45e8ada --- /dev/null +++ b/e2e/user-stories/README.md @@ -0,0 +1,15 @@ +# User Stories +These documents will be the basis for +* manually testing process +* E2E-tests programming + +It will describe a set of basic paths through the application, +including crucial edge-cases. It aims to ensure a basic set of +functionality but cannot exhaust every possible path. Testers +should use this as a minimal guideline what is to test, but +should try out all edge-cases and variations they can imagine. +The goal for E2E-tests is to *at least* test those user stories, +other E2E-tests will follow. + +New functionality should never be implemented without test +E2E-Tests but must *at least* be described here. diff --git a/e2e/user-stories/about.md b/e2e/user-stories/about.md new file mode 100644 index 0000000000000000000000000000000000000000..78ca32494eda6f3d726406b482c99d45ceec243c --- /dev/null +++ b/e2e/user-stories/about.md @@ -0,0 +1,11 @@ +# about page +## is accessible +On the start page, + +* click "imprint" + + * imprint-page appears + +* click "back" + + * start page appears again diff --git a/e2e/user-stories/admin.md b/e2e/user-stories/admin.md new file mode 100644 index 0000000000000000000000000000000000000000..ebb0e788421d50ebd73bd934d618ac1aac995a6f --- /dev/null +++ b/e2e/user-stories/admin.md @@ -0,0 +1,172 @@ +# Admin +## Login +### with valid credentials of super-user +On the start page, + +* insert credentials of admin-user (`super:user123`) + + * "select workspace"-page appears + +### with invalid credentials +On the start page, + +* insert credentials of super-user (`super:user123`) + +# select workspace +On "select workspace"-page + +* click on workspace + + * "workspace overview"-page appears + * "files"-tab is open + * "sys-check-report"-tab available if sys-check in this workspace + * "results/answers"-tab available if booklet exists + * in headline: name of workspace and rights + +# files tab + +On "files"-tab in "workspace overview"-page + + * all files from workspace are listed. + + +## validate button + +On "files"-tab in "workspace overview"-page + +* click on "validate workspace"-button + + * validation results appear below the buttons. + +## upload button shall upload XML File + +On "files"-tab in "workspace overview"-page + +* click on "upload"-button +* select Unit-File from your hard drive + + * the new file appears in filelist. + + +## upload button shall not upload invalid XML File + +On "files"-tab in "workspace overview"-page + +* click on "upload"-button +* select broken Unit-File from your hard drive + + * XMl-error description appears below the buttons + * OK-button appears below error-text + +* click OK-button + + * XMl-error description disappears. + +## upload button shall accept multiple files + +On "files"-tab in "workspace overview"-page + +* click on "upload"-button +* select (use shift key) a broken and a valid unit file from your hard drive + + * XMl-error description for the broken file appears below the buttons + * OK-button appears below error-text + * valid file appears in file-list. + +* click OK-button + + * XMl-error description disappears. + +## upload button shall accept zipped archive + +On "files"-tab in "workspace overview"-page + +* click on "upload"-button +* select zip-archive with two valid files + + * both files appears in file-list. + +## delete button shall delete files + +On "files"-tab in "workspace overview"-page + +* check the boxes left to the names of two files +* click the "delete file"-button + + * "confirm deletion"-modal appears + +* click "ok"-button + + * the two files disappear from file-list + +# sys-check tab + +On "SysCheck"-tab in "workspace overview"-page + + * sys-check-report(s) appear in list + +## get report-data CSV + +* select sys-check-report(s) by checking the boxes left to the names +* click the "download reports"-button + + * download modal appears or downloads starts (browser dependant) + * download contains valid CSV + +## delete reports + +* select a sys-check-report-set by checking the boxes left to the names +* click the delete-button + + * "confirm deletion"-modal appears + +* click "ok"-button + + * the list-entry of this report-set disappears from list. + +# results tab + +On "Results"-tab in "workspace overview"-page + + * result-sets for groups appear in list + +## "download-answers"-button + +On "Results"-tab in "workspace overview"-page + +* select a result-set by checking the boxes left to the names +* click the "download-answers"-button + + * download modal appears or downloads starts (browser dependant) + * download contains valid CSV + +## "download-logs"-button + +On "Results"-tab in "workspace overview"-page + +* select a result-set by checking the boxes left to the names +* click the "download-logs"-button + + * download modal appears or downloads starts (browser dependant) + * download contains valid CSV + +## "download-comments"-button + +On "Results"-tab in "workspace overview"-page + +* select a result-set by checking the boxes left to the names +* click the "download-comments"-button + + * download modal appears or downloads starts (browser dependant) + * download contains valid CSV + +## delete results + +* select a result-set by checking the boxes left to the names +* click the "delete"-button + + * "confirm deletion"-modal appears + +* click "ok"-button + + * the list-entry of this report-set disappears from list. diff --git a/e2e/user-stories/super-admin.md b/e2e/user-stories/super-admin.md new file mode 100644 index 0000000000000000000000000000000000000000..5f9ca754fe68e1d1b0d712415d909f61951c7218 --- /dev/null +++ b/e2e/user-stories/super-admin.md @@ -0,0 +1,163 @@ +# Super-Admin +## Login +### with valid credentials of super-user +On the start page, + +* insert credentials of super-user (`super:user123`) + + * "select workspace"-page appears + * "super-admin"-button appears + +* click "super-admin"-button + + * "super-user"-page appears + * tab "users" is selected + * tab "workspaces" exists + +## "users"-tab + +### "create user"-button + +On "users"-tab on "super-user"-page + +* click the "add user"-button (+) + + * "new user"-modal appears. + * "save" button is disabled + +* insert name and password + + * save button is enabled + +* click "save"-button + + * new user appears in list. + + +### change user's rights + +On "users"-tab on "super-user"-page + +* select a user *by clicking on his name* + + * all workspaces an this user's (`expired_user`) rights appear on the right side + +* change/give rights by clicking one of the checkboxes +* click the save-button. + + * save confirmation appears. + +* select another user *by clicking on his name* +* select the first user again + + * rights are still changed + +### delete user + +* select a user *by clicking on his name or on the box left to his name* + + * "confirm deletion"-modal appears + +* click "ok"-button + + * user vanishes from list. + + +### change user's password + +On "users"-tab on "super-user"-page + +* select a user *by clicking on his name* +* click on the "change-password"-button (the left of the two pen-icons) + + * "change password"-modal appears + + * insert new password + +* "password changed" confirmation appears. + +### change user's super-admin status + +On "users"-tab on "super-user"-page + +* select a user *by clicking on his name* (not to be confused with selection +by the checkbox left to the name) +* click on the "change-super-admin-status"-button (the right of the +two pen-icons) + + * "change-super-admin-status"-modal appears + +* click OK + + * "insert password" modal appears + +* insert password + + * user's super-admin status is gone (the asterisk behind his name vanished). + + +### don't change user's super-admin status without password + +On "users"-tab on "super-user"-page + +* select a user *by clicking on his name* (not to be confused with selection +by the checkbox left to the name) +* click on the "change-super-admin-status"-button (the right of the +two pen-icons) + + * "change-super-admin-status"-modal appears + +* click OK + + * "insert password" modal appears + +* insert incorrect password + + * warning appears. + +## "workspaces"-tab + +### add workspace + +On "workspaces"-tab on "super-user"-page + +* click the "add workspace"-button (+) + + * "new workspace"-modal appears. + * "save" button is disabled + +* insert name + + * save button is enabled + +* click "save"-button + + * new workspace of this name appears in list. + +### delete workspace + +* select a user *by clicking on the box left to it's name or the box left to it* + + * "confirm deletion"-modal appears + +* click "ok"-button + + * workspace vanishes from list. + +### change user's rights on workspace + +On "users"-tab on "super-user"-page + +* select a workspace *by clicking on it's name* + + * all users appear on the right side with their rights on this workspace + +* change/give rights by clicking one of the checkboxes +* click the save-button. + + * save confirmation appears + +* select another user *by clicking on his name* +* select the first user again + + * rights are still changed. diff --git a/e2e/user-stories/sys-check.md b/e2e/user-stories/sys-check.md new file mode 100644 index 0000000000000000000000000000000000000000..058611961460442ca017e655ddea800b5807533e --- /dev/null +++ b/e2e/user-stories/sys-check.md @@ -0,0 +1,37 @@ +# SysCheck +## overview +### with valid credentials +On Start-Page, + +* click on SysCheck-Button + + * SysCheck.Page-Appears with available SysChecks (`example SysCheck`) + +## starts + +On Sys-Check-Overview + +* click on the Sys-check + + * computer enviroment is visible in the top-right corner + * test starts with speedtest + * after speedtest test unit gets loaded + * right of that a questionaire + +## send report + +On ready Sys-Check + +* click on "send report" + + * "send-report"-modal appears + * send-button is disabled + +* insert password and title (`sendme`, `sometitle`) +* click on "save" + +* check required questions + + + + diff --git a/e2e/user-stories/test-login.md b/e2e/user-stories/test-login.md new file mode 100644 index 0000000000000000000000000000000000000000..17676ceb4292e7e8afb6a8131ce53c079ceed00d --- /dev/null +++ b/e2e/user-stories/test-login.md @@ -0,0 +1,132 @@ +# Test +## Login +### with valid credentials +On the start page, + +* insert credentials (`test:user123`) + + * "Insert Code" modal appears + +* insert correct code: (`xxx`) + + * booklet overview appears and contains booklets: `Sample booklet`. + +### with invalid credentials + +On the start page, + +* insert invalid credentials (`test:blah`) + + * "Invalid credentials"-message appears. + +### with correct credentials but wrong code +On the start page, + +* insert credentials (`test:user123`) + + * "Insert Code" modal appears + +* insert code: (`zzz`) + + * booklet overview appears and contains booklets: `Sample booklet`. + + * "Invalid code"-message appears. + +* insert correct code (`xxx`) +* click "continue" + + * booklet overview appears and contains booklets: `Sample booklet`. + +## login with codeless-login + +On the start page, + +* insert credentials of codeless login (`test-review:user123`) + + * booklet overview appears and contains booklets: `Sample booklet`. + +## login with passwordless-login + +On the start page, + +* insert credentials of a login that does not require a password (`test-no-pw:`) + + * booklet overview appears and contains booklets: `Sample booklet`. + +## login with expired login + +On the start page, + +* insert credentials of an expired login (`test-expired:`) + + * "login expired"-warning appears + * login form stays + +* re-enter correct credentials (`test:user123`) + + * booklet overview appears and contains booklets: `Sample booklet`. + +Known Bug: https://github.com/iqb-berlin/testcenter-iqb-ng/issues/107 + +## login with login, that is no active right now + +On the start page, + +* insert credentials of a login, which is not active right now (`test-future:`) + + * "login invalid"-warning appears + * login form stays + +* re-enter correct credentials (`test:user123`) + + * booklet overview appears and contains booklets: `Sample booklet`. + +Known Bug: https://github.com/iqb-berlin/testcenter-iqb-ng/issues/108 + +## login survives reload + +On the start page, + +* insert credentials (`test:user123`) + + * "Insert Code" modal appears + +* reload page by pressing [F5] + + * "Insert Code" modal appears again + +* insert correct code: (`xxx`) + + * booklet overview appears and contains booklets: `Sample booklet` + +* reload page by pressing [F5] + + * booklet overview appears again. + +## Forward/Back Buttons while login do their job + +Not implemented yet: https://github.com/iqb-berlin/testcenter-iqb-ng/issues/109 + +## "login again"-button restarts login-process + +On the start page, + +* insert credentials (`test:user123`) + + * "Insert Code" modal appears again + +* click "login again" + + * start page appears + +* insert credentials again (`test:user123`) + + * "Insert Code" modal appears again + +* insert correct code: (`xxx`) + + * booklet overview appears + +* click "login again" + + * start page appears diff --git a/e2e/user-stories/test-run.md b/e2e/user-stories/test-run.md new file mode 100644 index 0000000000000000000000000000000000000000..3e001ca242900817b86bcc74664de954a401b9c1 --- /dev/null +++ b/e2e/user-stories/test-run.md @@ -0,0 +1,36 @@ +# Test +## Run +### starts with release word + +On Test-Overview-Page, + +* click on test + + * "please insert release word" + +* insert correct release word (`sample`) + + * click "continue" + +TODO, has to be defined + +https://github.com/iqb-berlin/testcenter-iqb-ng/issues/112 + +### starts with first unit + +From there, + +* first unit appears + +* unit navigation works TODO + +* return to overview-button + + +... + +### review modus + +* snackbar mMldungen im review modus + +* send comment diff --git a/package-lock.json b/package-lock.json index a5ceab8e3aa5f68fcfc5d10d60274291ed6dc5ec..da197bbedb307aa1e1602cea3a9cfaa2623a6bf6 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,23 +1,23 @@ { "name": "itc-ng", - "version": "2.0.0-alpha", + "version": "3.1.0", "lockfileVersion": 1, "requires": true, "dependencies": { "@angular-devkit/architect": { - "version": "0.803.25", - "resolved": "https://registry.npmjs.org/@angular-devkit/architect/-/architect-0.803.25.tgz", - "integrity": "sha512-usV/zEncKCKQuF6AD3pRU6N5i5fbaAux/qZb+nbOz9/2G5jrXwe5sH+y3vxbgqB83e3LqusEQCTu7/tfg6LwZg==", + "version": "0.900.7", + "resolved": "https://registry.npmjs.org/@angular-devkit/architect/-/architect-0.900.7.tgz", + "integrity": "sha512-hfiTVYc72kzbXrzK4tea6jnTDnSKpE1D+vEptBXN2tdXEVNEAQI5Qm5L1zVDtt16UdqoUTUypIgUc9jcNH1mUQ==", "dev": true, "requires": { - "@angular-devkit/core": "8.3.25", - "rxjs": "6.4.0" + "@angular-devkit/core": "9.0.7", + "rxjs": "6.5.3" }, "dependencies": { "rxjs": { - "version": "6.4.0", - "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.4.0.tgz", - "integrity": "sha512-Z9Yfa11F6B9Sg/BK9MnqnQ+aQYicPLtilXBp2yUtDt2JRCE0h26d33EnfO3ZxoNxG0T92OUucP3Ct7cpfkdFfw==", + "version": "6.5.3", + "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.5.3.tgz", + "integrity": "sha512-wuYsAYYFdWTAnAaPoKGNhfpWwKZbJW+HgAJ+mImp+Epl7BG8oNWBCTyRM8gba9k4lk8BgWdoYm21Mo/RYhhbgA==", "dev": true, "requires": { "tslib": "^1.9.0" @@ -26,96 +26,205 @@ } }, "@angular-devkit/build-angular": { - "version": "0.803.25", - "resolved": "https://registry.npmjs.org/@angular-devkit/build-angular/-/build-angular-0.803.25.tgz", - "integrity": "sha512-WY0E7NgXuog3phhz5ZdutZPWQ9nbOr+omGN5KI1e8MZs1sJO4xkyaGRT8zOulkogkqJ2NboTBq3j9uSbZkcYeg==", - "dev": true, - "requires": { - "@angular-devkit/architect": "0.803.25", - "@angular-devkit/build-optimizer": "0.803.25", - "@angular-devkit/build-webpack": "0.803.25", - "@angular-devkit/core": "8.3.25", - "@babel/core": "7.8.3", - "@babel/preset-env": "7.8.3", - "@ngtools/webpack": "8.3.25", + "version": "0.900.7", + "resolved": "https://registry.npmjs.org/@angular-devkit/build-angular/-/build-angular-0.900.7.tgz", + "integrity": "sha512-Yv2y3OEaYEd0fE0pKvtqBpmkQYs9xJws7thHnJYCwIfYO55RfolYsXkJgAXke/4NPLrD3EsIDqoPxF7l+uw2/Q==", + "dev": true, + "requires": { + "@angular-devkit/architect": "0.900.7", + "@angular-devkit/build-optimizer": "0.900.7", + "@angular-devkit/build-webpack": "0.900.7", + "@angular-devkit/core": "9.0.7", + "@babel/core": "7.7.7", + "@babel/generator": "7.7.7", + "@babel/preset-env": "7.7.7", + "@ngtools/webpack": "9.0.7", "ajv": "6.10.2", - "autoprefixer": "9.6.1", - "browserslist": "4.8.6", - "cacache": "12.0.2", - "caniuse-lite": "1.0.30001024", + "autoprefixer": "9.7.1", + "babel-loader": "8.0.6", + "browserslist": "^4.9.1", + "cacache": "13.0.1", + "caniuse-lite": "^1.0.30001032", "circular-dependency-plugin": "5.2.0", - "clean-css": "4.2.1", "copy-webpack-plugin": "5.1.1", "core-js": "3.6.4", "coverage-istanbul-loader": "2.0.3", + "cssnano": "4.1.10", "file-loader": "4.2.0", "find-cache-dir": "3.0.0", - "glob": "7.1.4", + "glob": "7.1.5", "jest-worker": "24.9.0", "karma-source-map-support": "1.4.0", - "less": "3.9.0", + "less": "3.10.3", "less-loader": "5.0.0", - "license-webpack-plugin": "2.1.2", + "license-webpack-plugin": "2.1.3", "loader-utils": "1.2.3", + "magic-string": "0.25.4", "mini-css-extract-plugin": "0.8.0", "minimatch": "3.0.4", - "open": "6.4.0", + "open": "7.0.0", "parse5": "4.0.0", - "postcss": "7.0.17", + "postcss": "7.0.21", "postcss-import": "12.0.1", "postcss-loader": "3.0.0", "raw-loader": "3.1.0", "regenerator-runtime": "0.13.3", - "rxjs": "6.4.0", - "sass": "1.22.9", - "sass-loader": "7.2.0", + "rimraf": "3.0.0", + "rollup": "1.25.2", + "rxjs": "6.5.3", + "sass": "1.23.3", + "sass-loader": "8.0.0", "semver": "6.3.0", "source-map": "0.7.3", "source-map-loader": "0.2.4", - "source-map-support": "0.5.13", + "source-map-support": "0.5.16", "speed-measure-webpack-plugin": "1.3.1", "style-loader": "1.0.0", - "stylus": "0.54.5", + "stylus": "0.54.7", "stylus-loader": "3.0.2", - "terser": "4.6.3", - "terser-webpack-plugin": "1.4.3", + "terser": "4.5.1", + "terser-webpack-plugin": "2.3.3", "tree-kill": "1.2.2", - "webpack": "4.39.2", + "webpack": "4.41.2", "webpack-dev-middleware": "3.7.2", "webpack-dev-server": "3.9.0", - "webpack-merge": "4.2.1", + "webpack-merge": "4.2.2", "webpack-sources": "1.4.3", - "webpack-subresource-integrity": "1.1.0-rc.6", + "webpack-subresource-integrity": "1.3.4", "worker-plugin": "3.2.0" }, "dependencies": { + "@babel/generator": { + "version": "7.7.7", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.7.7.tgz", + "integrity": "sha512-/AOIBpHh/JU1l0ZFS4kiRCBnLi6OTHzh0RPk3h9isBxkkqELtQNFi1Vr/tiG9p1yfoUdKVwISuXWQR+hwwM4VQ==", + "dev": true, + "requires": { + "@babel/types": "^7.7.4", + "jsesc": "^2.5.1", + "lodash": "^4.17.13", + "source-map": "^0.5.0" + }, + "dependencies": { + "source-map": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", + "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", + "dev": true + } + } + }, + "fast-deep-equal": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.1.tgz", + "integrity": "sha512-8UEa58QDLauDNfpbrX55Q9jrGHThw2ZMdOky5Gl1CDtVeJDPVrG4Jxx1N8jw2gkWaff5UUuX1KJd+9zGe2B+ZA==", + "dev": true + }, + "glob": { + "version": "7.1.5", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.5.tgz", + "integrity": "sha512-J9dlskqUXK1OeTOYBEn5s8aMukWMwWfs+rPTn/jn50Ux4MNXVhubL1wu/j2t+H4NVI+cXEcCaYellqaPVGXNqQ==", + "dev": true, + "requires": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.0.4", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + } + }, "parse5": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/parse5/-/parse5-4.0.0.tgz", "integrity": "sha512-VrZ7eOd3T1Fk4XWNXMgiGBK/z0MG48BWG2uQNU4I72fkQuKUTZpl+u9k+CxEG0twMVzSmXEEz12z5Fnw1jIQFA==", "dev": true }, + "rimraf": { + "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" + } + }, "rxjs": { - "version": "6.4.0", - "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.4.0.tgz", - "integrity": "sha512-Z9Yfa11F6B9Sg/BK9MnqnQ+aQYicPLtilXBp2yUtDt2JRCE0h26d33EnfO3ZxoNxG0T92OUucP3Ct7cpfkdFfw==", + "version": "6.5.3", + "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.5.3.tgz", + "integrity": "sha512-wuYsAYYFdWTAnAaPoKGNhfpWwKZbJW+HgAJ+mImp+Epl7BG8oNWBCTyRM8gba9k4lk8BgWdoYm21Mo/RYhhbgA==", "dev": true, "requires": { "tslib": "^1.9.0" } + }, + "sass-loader": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/sass-loader/-/sass-loader-8.0.0.tgz", + "integrity": "sha512-+qeMu563PN7rPdit2+n5uuYVR0SSVwm0JsOUsaJXzgYcClWSlmX0iHDnmeOobPkf5kUglVot3QS6SyLyaQoJ4w==", + "dev": true, + "requires": { + "clone-deep": "^4.0.1", + "loader-utils": "^1.2.3", + "neo-async": "^2.6.1", + "schema-utils": "^2.1.0", + "semver": "^6.3.0" + } + }, + "schema-utils": { + "version": "2.6.5", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-2.6.5.tgz", + "integrity": "sha512-5KXuwKziQrTVHh8j/Uxz+QUbxkaLW9X/86NBlx/gnKgtsZA2GIVMUn17qWhRFwF8jdYb3Dig5hRO/W5mZqy6SQ==", + "dev": true, + "requires": { + "ajv": "^6.12.0", + "ajv-keywords": "^3.4.1" + }, + "dependencies": { + "ajv": { + "version": "6.12.0", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.0.tgz", + "integrity": "sha512-D6gFiFA0RRLyUbvijN74DWAjXSFxWKaWP7mldxkVhyhAV3+SWA9HEJPHQ2c9soIeTFJqcSdFDGFgdqs1iUU2Hw==", + "dev": true, + "requires": { + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + } + } + } + }, + "source-map-support": { + "version": "0.5.16", + "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.16.tgz", + "integrity": "sha512-efyLRJDr68D9hBBNIPWFjhpFzURh+KJykQwvMyW5UiZzYwoF6l4YMMDIJJEyFWxWCqfyxLzz6tSfUFR+kXXsVQ==", + "dev": true, + "requires": { + "buffer-from": "^1.0.0", + "source-map": "^0.6.0" + }, + "dependencies": { + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true + } + } } } }, "@angular-devkit/build-optimizer": { - "version": "0.803.25", - "resolved": "https://registry.npmjs.org/@angular-devkit/build-optimizer/-/build-optimizer-0.803.25.tgz", - "integrity": "sha512-MiQimuEs8QeM3xo7bR3Yk1OWHHlp2pGCc2GLUMIcWhKqM+QjoRky0HoGoBazbznx292l+xjFjANvPEKbqJ2v7Q==", + "version": "0.900.7", + "resolved": "https://registry.npmjs.org/@angular-devkit/build-optimizer/-/build-optimizer-0.900.7.tgz", + "integrity": "sha512-gxin2oPNMN+PYo82At2JP1Q+uxnvwyDFWA1Wl+Ufuc5zHGhjKqxdQjkdMF7OT0ihtmkllN+t/NTB7rcx/Sx9Wg==", "dev": true, "requires": { "loader-utils": "1.2.3", "source-map": "0.7.3", "tslib": "1.10.0", - "typescript": "3.5.3", + "typescript": "3.6.4", "webpack-sources": "1.4.3" }, "dependencies": { @@ -124,24 +233,30 @@ "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.10.0.tgz", "integrity": "sha512-qOebF53frne81cf0S9B41ByenJ3/IuH8yJKngAX35CmiZySA0khhkovshKK+jGCaMnVomla7gVlIcc3EvKPbTQ==", "dev": true + }, + "typescript": { + "version": "3.6.4", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-3.6.4.tgz", + "integrity": "sha512-unoCll1+l+YK4i4F8f22TaNVPRHcD9PA3yCuZ8g5e0qGqlVlJ/8FSateOLLSagn+Yg5+ZwuPkL8LFUc0Jcvksg==", + "dev": true } } }, "@angular-devkit/build-webpack": { - "version": "0.803.25", - "resolved": "https://registry.npmjs.org/@angular-devkit/build-webpack/-/build-webpack-0.803.25.tgz", - "integrity": "sha512-WR7HWJIWL6TB3WHG7ZFn8s0z3WlojeQlod75UIKl5i+f4OU90kp8kxcoH5G6OCXu56x5w40oIi1ve5ljjWSJkw==", + "version": "0.900.7", + "resolved": "https://registry.npmjs.org/@angular-devkit/build-webpack/-/build-webpack-0.900.7.tgz", + "integrity": "sha512-Nwwqjo1ZpHFLavN+nXOmuBgGjhoMBZGelDCvHtiQlQ9N6i7k9cKnP7eU5pY7jbalBguS+gWg5wJIGnbqk1K9Rg==", "dev": true, "requires": { - "@angular-devkit/architect": "0.803.25", - "@angular-devkit/core": "8.3.25", - "rxjs": "6.4.0" + "@angular-devkit/architect": "0.900.7", + "@angular-devkit/core": "9.0.7", + "rxjs": "6.5.3" }, "dependencies": { "rxjs": { - "version": "6.4.0", - "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.4.0.tgz", - "integrity": "sha512-Z9Yfa11F6B9Sg/BK9MnqnQ+aQYicPLtilXBp2yUtDt2JRCE0h26d33EnfO3ZxoNxG0T92OUucP3Ct7cpfkdFfw==", + "version": "6.5.3", + "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.5.3.tgz", + "integrity": "sha512-wuYsAYYFdWTAnAaPoKGNhfpWwKZbJW+HgAJ+mImp+Epl7BG8oNWBCTyRM8gba9k4lk8BgWdoYm21Mo/RYhhbgA==", "dev": true, "requires": { "tslib": "^1.9.0" @@ -150,22 +265,22 @@ } }, "@angular-devkit/core": { - "version": "8.3.25", - "resolved": "https://registry.npmjs.org/@angular-devkit/core/-/core-8.3.25.tgz", - "integrity": "sha512-l7Gqy1tMrTpRmPVlovcFX8UA3mtXRlgO8kcSsbJ9MKRKNTCcxlfsWEYY5igyDBUVh6ADkgSIu0nuk31ZGTe0lw==", + "version": "9.0.7", + "resolved": "https://registry.npmjs.org/@angular-devkit/core/-/core-9.0.7.tgz", + "integrity": "sha512-tMrz36sM1xrwvFf9Qm59GwALscVlMP7rQBjtd0fIR/QbsiOAIX4AQbV+vN6Vtwnzo5NIRZY1IXJUhesWms+h5w==", "dev": true, "requires": { "ajv": "6.10.2", "fast-json-stable-stringify": "2.0.0", - "magic-string": "0.25.3", - "rxjs": "6.4.0", + "magic-string": "0.25.4", + "rxjs": "6.5.3", "source-map": "0.7.3" }, "dependencies": { "rxjs": { - "version": "6.4.0", - "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.4.0.tgz", - "integrity": "sha512-Z9Yfa11F6B9Sg/BK9MnqnQ+aQYicPLtilXBp2yUtDt2JRCE0h26d33EnfO3ZxoNxG0T92OUucP3Ct7cpfkdFfw==", + "version": "6.5.3", + "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.5.3.tgz", + "integrity": "sha512-wuYsAYYFdWTAnAaPoKGNhfpWwKZbJW+HgAJ+mImp+Epl7BG8oNWBCTyRM8gba9k4lk8BgWdoYm21Mo/RYhhbgA==", "dev": true, "requires": { "tslib": "^1.9.0" @@ -174,19 +289,20 @@ } }, "@angular-devkit/schematics": { - "version": "8.3.25", - "resolved": "https://registry.npmjs.org/@angular-devkit/schematics/-/schematics-8.3.25.tgz", - "integrity": "sha512-/p1MkfursfLy+JRGXlJGPEmX55lrFCsR/2khWAVXZcMaFR3QlR/b6/zvB8I2pHFfr0/XWnYTT/BsF7rJjO3RmA==", + "version": "9.0.7", + "resolved": "https://registry.npmjs.org/@angular-devkit/schematics/-/schematics-9.0.7.tgz", + "integrity": "sha512-ryPC+l24f3gX5DFMTLkDM/q2Kp6LPzBn6400k7j4qVdb1cIrZx+JUQd7F4iAksTTkX15EQPanptQXeztUrl9Ng==", "dev": true, "requires": { - "@angular-devkit/core": "8.3.25", - "rxjs": "6.4.0" + "@angular-devkit/core": "9.0.7", + "ora": "4.0.2", + "rxjs": "6.5.3" }, "dependencies": { "rxjs": { - "version": "6.4.0", - "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.4.0.tgz", - "integrity": "sha512-Z9Yfa11F6B9Sg/BK9MnqnQ+aQYicPLtilXBp2yUtDt2JRCE0h26d33EnfO3ZxoNxG0T92OUucP3Ct7cpfkdFfw==", + "version": "6.5.3", + "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.5.3.tgz", + "integrity": "sha512-wuYsAYYFdWTAnAaPoKGNhfpWwKZbJW+HgAJ+mImp+Epl7BG8oNWBCTyRM8gba9k4lk8BgWdoYm21Mo/RYhhbgA==", "dev": true, "requires": { "tslib": "^1.9.0" @@ -195,42 +311,38 @@ } }, "@angular/animations": { - "version": "8.2.14", - "resolved": "https://registry.npmjs.org/@angular/animations/-/animations-8.2.14.tgz", - "integrity": "sha512-3Vc9TnNpKdtvKIXcWDFINSsnwgEMiDmLzjceWg1iYKwpeZGQahUXPoesLwQazBMmxJzQiA4HOMj0TTXKZ+Jzkg==", - "requires": { - "tslib": "^1.9.0" - } + "version": "9.0.7", + "resolved": "https://registry.npmjs.org/@angular/animations/-/animations-9.0.7.tgz", + "integrity": "sha512-74gY7onajmmnksy5E0/32bFv3B9NuWxV64kqD15YjGrh8AWe1BHt5enQI+rJ2tO8m2DKnwZsctis6k0Kcy+YKQ==" }, "@angular/cdk": { - "version": "8.2.3", - "resolved": "https://registry.npmjs.org/@angular/cdk/-/cdk-8.2.3.tgz", - "integrity": "sha512-ZwO5Sn720RA2YvBqud0JAHkZXjmjxM0yNzCO8RVtRE9i8Gl26Wk0j0nQeJkVm4zwv2QO8MwbKUKGTMt8evsokA==", + "version": "9.1.3", + "resolved": "https://registry.npmjs.org/@angular/cdk/-/cdk-9.1.3.tgz", + "integrity": "sha512-K6XJzfqP+PE0ahyBUYrnoW+3ocwDpPN3dE9a+XRtZ0vM4P/FElweWj5zjNwWktb+uF9yal6oMPWXJNOAfonpPw==", "requires": { - "parse5": "^5.0.0", - "tslib": "^1.7.1" + "parse5": "^5.0.0" } }, "@angular/cli": { - "version": "8.3.25", - "resolved": "https://registry.npmjs.org/@angular/cli/-/cli-8.3.25.tgz", - "integrity": "sha512-CPJI5nnbBvvyBUFwOHfRXy/KVwsiYlcbDAeIk1klcjQjbVFYZbnY0iAhNupy9j7rPQhb7jle5oslU3TLfbqOTQ==", + "version": "9.0.7", + "resolved": "https://registry.npmjs.org/@angular/cli/-/cli-9.0.7.tgz", + "integrity": "sha512-/9CUNSSVyTtTNUADZ/VXJDEdhineMN/rfd35w6VsHiob49tKkeOTggaoiSne3RY4VCTqlo7GGf4KhhVXEMGnDQ==", "dev": true, "requires": { - "@angular-devkit/architect": "0.803.25", - "@angular-devkit/core": "8.3.25", - "@angular-devkit/schematics": "8.3.25", - "@schematics/angular": "8.3.25", - "@schematics/update": "0.803.25", + "@angular-devkit/architect": "0.900.7", + "@angular-devkit/core": "9.0.7", + "@angular-devkit/schematics": "9.0.7", + "@schematics/angular": "9.0.7", + "@schematics/update": "0.900.7", "@yarnpkg/lockfile": "1.1.0", "ansi-colors": "4.1.1", "debug": "^4.1.1", "ini": "1.3.5", - "inquirer": "6.5.1", - "npm-package-arg": "6.1.0", + "inquirer": "7.0.0", + "npm-package-arg": "6.1.1", "npm-pick-manifest": "3.0.2", - "open": "6.4.0", - "pacote": "9.5.5", + "open": "7.0.0", + "pacote": "9.5.8", "read-package-tree": "5.3.1", "rimraf": "3.0.0", "semver": "6.3.0", @@ -257,36 +369,32 @@ } }, "@angular/common": { - "version": "8.2.14", - "resolved": "https://registry.npmjs.org/@angular/common/-/common-8.2.14.tgz", - "integrity": "sha512-Qmt+aX2quUW54kaNT7QH7WGXnFxr/cC2C6sf5SW5SdkZfDQSiz8IaItvieZfXVQUbBOQKFRJ7TlSkt0jI/yjvw==", - "requires": { - "tslib": "^1.9.0" - } + "version": "9.0.7", + "resolved": "https://registry.npmjs.org/@angular/common/-/common-9.0.7.tgz", + "integrity": "sha512-B58YgxZva1DBaeayOBsaUOOkoyR+GRibuNC3gfOMm2vXeW9eCNX+jvDtw767GnKm2yGzIq8wB3x6GHojN00dPw==" }, "@angular/compiler": { - "version": "8.2.14", - "resolved": "https://registry.npmjs.org/@angular/compiler/-/compiler-8.2.14.tgz", - "integrity": "sha512-ABZO4E7eeFA1QyJ2trDezxeQM5ZFa1dXw1Mpl/+1vuXDKNjJgNyWYwKp/NwRkLmrsuV0yv4UDCDe4kJOGbPKnw==", - "requires": { - "tslib": "^1.9.0" - } + "version": "9.0.7", + "resolved": "https://registry.npmjs.org/@angular/compiler/-/compiler-9.0.7.tgz", + "integrity": "sha512-hFpkuGpzxpK5h59LHHAjTFWsY6DCXZwgJFqvCuTPxWi/srvLGZRXrpC6Z1SlgHI9xxXaPfoa4uWw2VfA3BnqEg==" }, "@angular/compiler-cli": { - "version": "8.2.14", - "resolved": "https://registry.npmjs.org/@angular/compiler-cli/-/compiler-cli-8.2.14.tgz", - "integrity": "sha512-XDrTyrlIZM+0NquVT+Kbg5bn48AaWFT+B3bAT288PENrTdkuxuF9AhjFRZj8jnMdmaE4O2rioEkXBtl6z3zptA==", + "version": "9.0.7", + "resolved": "https://registry.npmjs.org/@angular/compiler-cli/-/compiler-cli-9.0.7.tgz", + "integrity": "sha512-+RXghex63v0Vi8vpQtDpWiqpAAnrTaN3bHT5fntRenq5+Ok5vL1MJ1mzbTmBXs2tuwTqNlwMm2AlZB7G/xcDMQ==", "dev": true, "requires": { "canonical-path": "1.0.0", - "chokidar": "^2.1.1", + "chokidar": "^3.0.0", "convert-source-map": "^1.5.1", "dependency-graph": "^0.7.2", + "fs-extra": "4.0.2", "magic-string": "^0.25.0", "minimist": "^1.2.0", "reflect-metadata": "^0.1.2", + "semver": "^6.3.0", "source-map": "^0.6.1", - "tslib": "^1.9.0", + "sourcemap-codec": "^1.4.8", "yargs": "13.1.0" }, "dependencies": { @@ -296,3839 +404,4245 @@ "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", "dev": true }, - "anymatch": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-2.0.0.tgz", - "integrity": "sha512-5teOsQWABXHHBFP9y3skS5P3d/WfWXpv3FUpy+LorMrNYaT9pI4oLMQX7jzQ2KklNpGpWHzdCXTDT2Y3XGlZBw==", + "emoji-regex": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz", + "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==", + "dev": true + }, + "fs-extra": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-4.0.2.tgz", + "integrity": "sha1-+RcExT0bRh+JNFKwwwfZmXZHq2s=", "dev": true, "requires": { - "micromatch": "^3.1.4", - "normalize-path": "^2.1.1" - }, - "dependencies": { - "normalize-path": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-2.1.1.tgz", - "integrity": "sha1-GrKLVW4Zg2Oowab35vogE3/mrtk=", - "dev": true, - "requires": { - "remove-trailing-separator": "^1.0.1" - } - } + "graceful-fs": "^4.1.2", + "jsonfile": "^4.0.0", + "universalify": "^0.1.0" } }, - "binary-extensions": { - "version": "1.13.1", - "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-1.13.1.tgz", - "integrity": "sha512-Un7MIEDdUC5gNpcGDV97op1Ywk748MpHcFTHoYs6qnj1Z3j7I53VG3nwZhKzoBZmbdRNnb6WRdFlwl7tSDuZGw==", + "get-caller-file": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", + "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", "dev": true }, - "braces": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz", - "integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==", + "require-main-filename": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-2.0.0.tgz", + "integrity": "sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==", + "dev": true + }, + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true + }, + "string-width": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", + "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", "dev": true, "requires": { - "arr-flatten": "^1.1.0", - "array-unique": "^0.3.2", - "extend-shallow": "^2.0.1", - "fill-range": "^4.0.0", - "isobject": "^3.0.1", - "repeat-element": "^1.1.2", - "snapdragon": "^0.8.1", - "snapdragon-node": "^2.0.1", - "split-string": "^3.0.2", - "to-regex": "^3.0.1" + "emoji-regex": "^7.0.1", + "is-fullwidth-code-point": "^2.0.0", + "strip-ansi": "^5.1.0" } }, - "chokidar": { - "version": "2.1.8", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-2.1.8.tgz", - "integrity": "sha512-ZmZUazfOzf0Nve7duiCKD23PFSCs4JPoYyccjUFF3aQkQadqBhfzhjkwBH2mNOG9cTBwhamM37EIsIkZw3nRgg==", + "strip-ansi": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", + "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", "dev": true, "requires": { - "anymatch": "^2.0.0", - "async-each": "^1.0.1", - "braces": "^2.3.2", - "fsevents": "^1.2.7", - "glob-parent": "^3.1.0", - "inherits": "^2.0.3", - "is-binary-path": "^1.0.0", - "is-glob": "^4.0.0", - "normalize-path": "^3.0.0", - "path-is-absolute": "^1.0.0", - "readdirp": "^2.2.1", - "upath": "^1.1.1" + "ansi-regex": "^4.1.0" } }, - "emoji-regex": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz", - "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==", - "dev": true - }, - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "yargs": { + "version": "13.1.0", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-13.1.0.tgz", + "integrity": "sha512-1UhJbXfzHiPqkfXNHYhiz79qM/kZqjTE8yGlEjZa85Q+3+OwcV6NRkV7XOV1W2Eom2bzILeUn55pQYffjVOLAg==", "dev": true, "requires": { - "is-extendable": "^0.1.0" + "cliui": "^4.0.0", + "find-up": "^3.0.0", + "get-caller-file": "^2.0.1", + "os-locale": "^3.1.0", + "require-directory": "^2.1.1", + "require-main-filename": "^2.0.0", + "set-blocking": "^2.0.0", + "string-width": "^3.0.0", + "which-module": "^2.0.0", + "y18n": "^4.0.0", + "yargs-parser": "^13.0.0" } }, - "fill-range": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz", - "integrity": "sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc=", + "yargs-parser": { + "version": "13.1.2", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-13.1.2.tgz", + "integrity": "sha512-3lbsNRf/j+A4QuSZfDRA7HRSfWrzO0YjqTJd5kjAq37Zep1CEgaYmrH9Q3GwPiB9cHyd1Y1UwggGhJGoxipbzg==", "dev": true, "requires": { - "extend-shallow": "^2.0.1", - "is-number": "^3.0.0", - "repeat-string": "^1.6.1", - "to-regex-range": "^2.1.0" + "camelcase": "^5.0.0", + "decamelize": "^1.2.0" } - }, - "fsevents": { - "version": "1.2.11", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-1.2.11.tgz", - "integrity": "sha512-+ux3lx6peh0BpvY0JebGyZoiR4D+oYzdPZMKJwkZ+sFkNJzpL7tXc/wehS49gUAxg3tmMHPHZkA8JU2rhhgDHw==", + } + } + }, + "@angular/core": { + "version": "9.0.7", + "resolved": "https://registry.npmjs.org/@angular/core/-/core-9.0.7.tgz", + "integrity": "sha512-E9XZH5Dl+9MWG3MDC6wrKllhA8Rljpz66HOIeqKv2fHPed8kzuJZU3WJWLtbhDAXFwtGTyTZ4c82ZLSmqwTorg==" + }, + "@angular/flex-layout": { + "version": "9.0.0-beta.29", + "resolved": "https://registry.npmjs.org/@angular/flex-layout/-/flex-layout-9.0.0-beta.29.tgz", + "integrity": "sha512-93sxR+kYfYMOdnlWL0Q77FZ428gg8XnBu0YZm6GsCdkw/vLggIT/G1ZAqHlCPIODt6pxmCJ5KXh4ShvniIYDsA==" + }, + "@angular/forms": { + "version": "9.0.7", + "resolved": "https://registry.npmjs.org/@angular/forms/-/forms-9.0.7.tgz", + "integrity": "sha512-PaHAmjMJDtg/3aGCPuq5BCRC1eZ/DBCpva9f7NrA1kqk0LcLdebm0v2uHwTOBtiz/VEgPvxiS4tXC4rjvUtfEg==" + }, + "@angular/language-service": { + "version": "9.0.7", + "resolved": "https://registry.npmjs.org/@angular/language-service/-/language-service-9.0.7.tgz", + "integrity": "sha512-IZG1kvw48JyFRy7bfMHqBixWrEHZmXmkP5DWsi5Tw6KusaczkMghI20BevCkodPcajXWHAUHNKyp1tlE3OnH0w==", + "dev": true + }, + "@angular/material": { + "version": "9.1.3", + "resolved": "https://registry.npmjs.org/@angular/material/-/material-9.1.3.tgz", + "integrity": "sha512-tRdd5+z9XwsbN+4WCuH3goyEjqw1Q6vKeURCdas8bh5AVOrCt8pcFlj3yA3P/u4fdhfTeFc67PJRz8Zm0n3moQ==" + }, + "@angular/platform-browser": { + "version": "9.0.7", + "resolved": "https://registry.npmjs.org/@angular/platform-browser/-/platform-browser-9.0.7.tgz", + "integrity": "sha512-Por8omrEiSV2U/K2mm/Kuv+2R2rJkbAZ3ctEM6CWj9Y4Gz2akjOCxmEgWhhBeqdigcC3T1v707f52osf9jWBkg==" + }, + "@angular/platform-browser-dynamic": { + "version": "9.0.7", + "resolved": "https://registry.npmjs.org/@angular/platform-browser-dynamic/-/platform-browser-dynamic-9.0.7.tgz", + "integrity": "sha512-jwpyd93ofcRtchbayKD5v4GN4Lc7vbPe6dMUiwfnVnVAql0bOD/3YRI7w5qJ0Xx0sgQT+9Xo6jTXYnyUsZpEww==" + }, + "@angular/router": { + "version": "9.0.7", + "resolved": "https://registry.npmjs.org/@angular/router/-/router-9.0.7.tgz", + "integrity": "sha512-uKru9F/Zju//gg6INl54abnlpLdEUUO/GpCfMk4zqu8LCZGNFta6OY7VT+9DK9Vdrh/XUD70oE9WoelcRwwTYA==" + }, + "@babel/code-frame": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.8.3.tgz", + "integrity": "sha512-a9gxpmdXtZEInkCSHUJDLHZVBgb1QS0jhss4cPP93EW7s+uC5bikET2twEF3KV+7rDblJcmNvTR7VJejqd2C2g==", + "dev": true, + "requires": { + "@babel/highlight": "^7.8.3" + } + }, + "@babel/core": { + "version": "7.7.7", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.7.7.tgz", + "integrity": "sha512-jlSjuj/7z138NLZALxVgrx13AOtqip42ATZP7+kYl53GvDV6+4dCek1mVUo8z8c8Xnw/mx2q3d9HWh3griuesQ==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.5.5", + "@babel/generator": "^7.7.7", + "@babel/helpers": "^7.7.4", + "@babel/parser": "^7.7.7", + "@babel/template": "^7.7.4", + "@babel/traverse": "^7.7.4", + "@babel/types": "^7.7.4", + "convert-source-map": "^1.7.0", + "debug": "^4.1.0", + "json5": "^2.1.0", + "lodash": "^4.17.13", + "resolve": "^1.3.2", + "semver": "^5.4.1", + "source-map": "^0.5.0" + }, + "dependencies": { + "json5": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/json5/-/json5-2.1.2.tgz", + "integrity": "sha512-MoUOQ4WdiN3yxhm7NEVJSJrieAo5hNSLQ5sj05OTRHPL9HOBy8u4Bu88jsC1jvqAdN+E1bJmsUcZH+1HQxliqQ==", "dev": true, - "optional": true, "requires": { - "bindings": "^1.5.0", - "nan": "^2.12.1", - "node-pre-gyp": "*" - }, - "dependencies": { - "abbrev": { - "version": "1.1.1", - "bundled": true, - "dev": true, - "optional": true - }, - "ansi-regex": { - "version": "2.1.1", - "bundled": true, - "dev": true, - "optional": true - }, - "aproba": { - "version": "1.2.0", - "bundled": true, - "dev": true, - "optional": true - }, - "are-we-there-yet": { - "version": "1.1.5", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "delegates": "^1.0.0", - "readable-stream": "^2.0.6" - } - }, - "balanced-match": { - "version": "1.0.0", - "bundled": true, - "dev": true, - "optional": true - }, - "brace-expansion": { - "version": "1.1.11", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, - "chownr": { - "version": "1.1.3", - "bundled": true, - "dev": true, - "optional": true - }, - "code-point-at": { - "version": "1.1.0", - "bundled": true, - "dev": true, - "optional": true - }, - "concat-map": { - "version": "0.0.1", - "bundled": true, - "dev": true, - "optional": true - }, - "console-control-strings": { - "version": "1.1.0", - "bundled": true, - "dev": true, - "optional": true - }, - "core-util-is": { - "version": "1.0.2", - "bundled": true, - "dev": true, - "optional": true - }, - "debug": { - "version": "3.2.6", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "ms": "^2.1.1" - } - }, - "deep-extend": { - "version": "0.6.0", - "bundled": true, - "dev": true, - "optional": true - }, - "delegates": { - "version": "1.0.0", - "bundled": true, - "dev": true, - "optional": true - }, - "detect-libc": { - "version": "1.0.3", - "bundled": true, - "dev": true, - "optional": true - }, - "fs-minipass": { - "version": "1.2.7", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "minipass": "^2.6.0" - } - }, - "fs.realpath": { - "version": "1.0.0", - "bundled": true, - "dev": true, - "optional": true - }, - "gauge": { - "version": "2.7.4", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "aproba": "^1.0.3", - "console-control-strings": "^1.0.0", - "has-unicode": "^2.0.0", - "object-assign": "^4.1.0", - "signal-exit": "^3.0.0", - "string-width": "^1.0.1", - "strip-ansi": "^3.0.1", - "wide-align": "^1.1.0" - } - }, - "glob": { - "version": "7.1.6", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.0.4", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - } - }, - "has-unicode": { - "version": "2.0.1", - "bundled": true, - "dev": true, - "optional": true - }, - "iconv-lite": { - "version": "0.4.24", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "safer-buffer": ">= 2.1.2 < 3" - } - }, - "ignore-walk": { - "version": "3.0.3", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "minimatch": "^3.0.4" - } - }, - "inflight": { - "version": "1.0.6", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "once": "^1.3.0", - "wrappy": "1" - } - }, - "inherits": { - "version": "2.0.4", - "bundled": true, - "dev": true, - "optional": true - }, - "ini": { - "version": "1.3.5", - "bundled": true, - "dev": true, - "optional": true - }, - "is-fullwidth-code-point": { - "version": "1.0.0", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "number-is-nan": "^1.0.0" - } - }, - "isarray": { - "version": "1.0.0", - "bundled": true, - "dev": true, - "optional": true - }, - "minimatch": { - "version": "3.0.4", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "brace-expansion": "^1.1.7" - } - }, - "minimist": { - "version": "0.0.8", - "bundled": true, - "dev": true, - "optional": true - }, - "minipass": { - "version": "2.9.0", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "safe-buffer": "^5.1.2", - "yallist": "^3.0.0" - } - }, - "minizlib": { - "version": "1.3.3", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "minipass": "^2.9.0" - } - }, - "mkdirp": { - "version": "0.5.1", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "minimist": "0.0.8" - } - }, - "ms": { - "version": "2.1.2", - "bundled": true, - "dev": true, - "optional": true - }, - "needle": { - "version": "2.4.0", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "debug": "^3.2.6", - "iconv-lite": "^0.4.4", - "sax": "^1.2.4" - } - }, - "node-pre-gyp": { - "version": "0.14.0", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "detect-libc": "^1.0.2", - "mkdirp": "^0.5.1", - "needle": "^2.2.1", - "nopt": "^4.0.1", - "npm-packlist": "^1.1.6", - "npmlog": "^4.0.2", - "rc": "^1.2.7", - "rimraf": "^2.6.1", - "semver": "^5.3.0", - "tar": "^4.4.2" - } - }, - "nopt": { - "version": "4.0.1", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "abbrev": "1", - "osenv": "^0.1.4" - } - }, - "npm-bundled": { - "version": "1.1.1", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "npm-normalize-package-bin": "^1.0.1" - } - }, - "npm-normalize-package-bin": { - "version": "1.0.1", - "bundled": true, - "dev": true, - "optional": true - }, - "npm-packlist": { - "version": "1.4.7", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "ignore-walk": "^3.0.1", - "npm-bundled": "^1.0.1" - } - }, - "npmlog": { - "version": "4.1.2", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "are-we-there-yet": "~1.1.2", - "console-control-strings": "~1.1.0", - "gauge": "~2.7.3", - "set-blocking": "~2.0.0" - } - }, - "number-is-nan": { - "version": "1.0.1", - "bundled": true, - "dev": true, - "optional": true - }, - "object-assign": { - "version": "4.1.1", - "bundled": true, - "dev": true, - "optional": true - }, - "once": { - "version": "1.4.0", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "wrappy": "1" - } - }, - "os-homedir": { - "version": "1.0.2", - "bundled": true, - "dev": true, - "optional": true - }, - "os-tmpdir": { - "version": "1.0.2", - "bundled": true, - "dev": true, - "optional": true - }, - "osenv": { - "version": "0.1.5", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "os-homedir": "^1.0.0", - "os-tmpdir": "^1.0.0" - } - }, - "path-is-absolute": { - "version": "1.0.1", - "bundled": true, - "dev": true, - "optional": true - }, - "process-nextick-args": { - "version": "2.0.1", - "bundled": true, - "dev": true, - "optional": true - }, - "rc": { - "version": "1.2.8", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "deep-extend": "^0.6.0", - "ini": "~1.3.0", - "minimist": "^1.2.0", - "strip-json-comments": "~2.0.1" - }, - "dependencies": { - "minimist": { - "version": "1.2.0", - "bundled": true, - "dev": true, - "optional": true - } - } - }, - "readable-stream": { - "version": "2.3.6", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "rimraf": { - "version": "2.7.1", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "glob": "^7.1.3" - } - }, - "safe-buffer": { - "version": "5.1.2", - "bundled": true, - "dev": true, - "optional": true - }, - "safer-buffer": { - "version": "2.1.2", - "bundled": true, - "dev": true, - "optional": true - }, - "sax": { - "version": "1.2.4", - "bundled": true, - "dev": true, - "optional": true - }, - "semver": { - "version": "5.7.1", - "bundled": true, - "dev": true, - "optional": true - }, - "set-blocking": { - "version": "2.0.0", - "bundled": true, - "dev": true, - "optional": true - }, - "signal-exit": { - "version": "3.0.2", - "bundled": true, - "dev": true, - "optional": true - }, - "string-width": { - "version": "1.0.2", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "code-point-at": "^1.0.0", - "is-fullwidth-code-point": "^1.0.0", - "strip-ansi": "^3.0.0" - } - }, - "string_decoder": { - "version": "1.1.1", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "safe-buffer": "~5.1.0" - } - }, - "strip-ansi": { - "version": "3.0.1", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "ansi-regex": "^2.0.0" - } - }, - "strip-json-comments": { - "version": "2.0.1", - "bundled": true, - "dev": true, - "optional": true - }, - "tar": { - "version": "4.4.13", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "chownr": "^1.1.1", - "fs-minipass": "^1.2.5", - "minipass": "^2.8.6", - "minizlib": "^1.2.1", - "mkdirp": "^0.5.0", - "safe-buffer": "^5.1.2", - "yallist": "^3.0.3" - } - }, - "util-deprecate": { - "version": "1.0.2", - "bundled": true, - "dev": true, - "optional": true - }, - "wide-align": { - "version": "1.1.3", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "string-width": "^1.0.2 || 2" - } - }, - "wrappy": { - "version": "1.0.2", - "bundled": true, - "dev": true, - "optional": true - }, - "yallist": { - "version": "3.1.1", - "bundled": true, - "dev": true, - "optional": true - } + "minimist": "^1.2.5" } }, - "get-caller-file": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", - "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", + "semver": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", "dev": true }, - "is-binary-path": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-1.0.1.tgz", - "integrity": "sha1-dfFmQrSA8YenEcgUFh/TpKdlWJg=", - "dev": true, - "requires": { - "binary-extensions": "^1.0.0" - } - }, - "is-number": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", - "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - } - }, - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - }, - "readdirp": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-2.2.1.tgz", - "integrity": "sha512-1JU/8q+VgFZyxwrJ+SVIOsh+KywWGpds3NTqikiKpDMZWScmAYyKIgqkO+ARvNWJfXeXR1zxz7aHF4u4CyH6vQ==", - "dev": true, - "requires": { - "graceful-fs": "^4.1.11", - "micromatch": "^3.1.10", - "readable-stream": "^2.0.2" - } - }, - "require-main-filename": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-2.0.0.tgz", - "integrity": "sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==", + "source-map": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", + "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", "dev": true - }, + } + } + }, + "@babel/generator": { + "version": "7.8.8", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.8.8.tgz", + "integrity": "sha512-HKyUVu69cZoclptr8t8U5b6sx6zoWjh8jiUhnuj3MpZuKT2dJ8zPTuiy31luq32swhI0SpwItCIlU8XW7BZeJg==", + "dev": true, + "requires": { + "@babel/types": "^7.8.7", + "jsesc": "^2.5.1", + "lodash": "^4.17.13", + "source-map": "^0.5.0" + }, + "dependencies": { "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", + "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", "dev": true - }, - "string-width": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", - "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", - "dev": true, - "requires": { - "emoji-regex": "^7.0.1", - "is-fullwidth-code-point": "^2.0.0", - "strip-ansi": "^5.1.0" - } - }, - "strip-ansi": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", - "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", - "dev": true, - "requires": { - "ansi-regex": "^4.1.0" - } - }, - "to-regex-range": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-2.1.1.tgz", - "integrity": "sha1-fIDBe53+vlmeJzZ+DU3VWQFB2zg=", - "dev": true, - "requires": { - "is-number": "^3.0.0", - "repeat-string": "^1.6.1" - } - }, - "yargs": { - "version": "13.1.0", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-13.1.0.tgz", - "integrity": "sha512-1UhJbXfzHiPqkfXNHYhiz79qM/kZqjTE8yGlEjZa85Q+3+OwcV6NRkV7XOV1W2Eom2bzILeUn55pQYffjVOLAg==", - "dev": true, - "requires": { - "cliui": "^4.0.0", - "find-up": "^3.0.0", - "get-caller-file": "^2.0.1", - "os-locale": "^3.1.0", - "require-directory": "^2.1.1", - "require-main-filename": "^2.0.0", - "set-blocking": "^2.0.0", - "string-width": "^3.0.0", - "which-module": "^2.0.0", - "y18n": "^4.0.0", - "yargs-parser": "^13.0.0" - } - }, - "yargs-parser": { - "version": "13.1.2", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-13.1.2.tgz", - "integrity": "sha512-3lbsNRf/j+A4QuSZfDRA7HRSfWrzO0YjqTJd5kjAq37Zep1CEgaYmrH9Q3GwPiB9cHyd1Y1UwggGhJGoxipbzg==", - "dev": true, - "requires": { - "camelcase": "^5.0.0", - "decamelize": "^1.2.0" - } } } }, - "@angular/core": { - "version": "8.2.14", - "resolved": "https://registry.npmjs.org/@angular/core/-/core-8.2.14.tgz", - "integrity": "sha512-zeePkigi+hPh3rN7yoNENG/YUBUsIvUXdxx+AZq+QPaFeKEA2FBSrKn36ojHFrdJUjKzl0lPMEiGC2b6a6bo6g==", + "@babel/helper-annotate-as-pure": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.8.3.tgz", + "integrity": "sha512-6o+mJrZBxOoEX77Ezv9zwW7WV8DdluouRKNY/IR5u/YTMuKHgugHOzYWlYvYLpLA9nPsQCAAASpCIbjI9Mv+Uw==", + "dev": true, + "requires": { + "@babel/types": "^7.8.3" + } + }, + "@babel/helper-builder-binary-assignment-operator-visitor": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/helper-builder-binary-assignment-operator-visitor/-/helper-builder-binary-assignment-operator-visitor-7.8.3.tgz", + "integrity": "sha512-5eFOm2SyFPK4Rh3XMMRDjN7lBH0orh3ss0g3rTYZnBQ+r6YPj7lgDyCvPphynHvUrobJmeMignBr6Acw9mAPlw==", + "dev": true, + "requires": { + "@babel/helper-explode-assignable-expression": "^7.8.3", + "@babel/types": "^7.8.3" + } + }, + "@babel/helper-call-delegate": { + "version": "7.8.7", + "resolved": "https://registry.npmjs.org/@babel/helper-call-delegate/-/helper-call-delegate-7.8.7.tgz", + "integrity": "sha512-doAA5LAKhsFCR0LAFIf+r2RSMmC+m8f/oQ+URnUET/rWeEzC0yTRmAGyWkD4sSu3xwbS7MYQ2u+xlt1V5R56KQ==", + "dev": true, + "requires": { + "@babel/helper-hoist-variables": "^7.8.3", + "@babel/traverse": "^7.8.3", + "@babel/types": "^7.8.7" + } + }, + "@babel/helper-create-regexp-features-plugin": { + "version": "7.8.8", + "resolved": "https://registry.npmjs.org/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.8.8.tgz", + "integrity": "sha512-LYVPdwkrQEiX9+1R29Ld/wTrmQu1SSKYnuOk3g0CkcZMA1p0gsNxJFj/3gBdaJ7Cg0Fnek5z0DsMULePP7Lrqg==", + "dev": true, + "requires": { + "@babel/helper-annotate-as-pure": "^7.8.3", + "@babel/helper-regex": "^7.8.3", + "regexpu-core": "^4.7.0" + } + }, + "@babel/helper-define-map": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/helper-define-map/-/helper-define-map-7.8.3.tgz", + "integrity": "sha512-PoeBYtxoZGtct3md6xZOCWPcKuMuk3IHhgxsRRNtnNShebf4C8YonTSblsK4tvDbm+eJAw2HAPOfCr+Q/YRG/g==", + "dev": true, + "requires": { + "@babel/helper-function-name": "^7.8.3", + "@babel/types": "^7.8.3", + "lodash": "^4.17.13" + } + }, + "@babel/helper-explode-assignable-expression": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/helper-explode-assignable-expression/-/helper-explode-assignable-expression-7.8.3.tgz", + "integrity": "sha512-N+8eW86/Kj147bO9G2uclsg5pwfs/fqqY5rwgIL7eTBklgXjcOJ3btzS5iM6AitJcftnY7pm2lGsrJVYLGjzIw==", + "dev": true, + "requires": { + "@babel/traverse": "^7.8.3", + "@babel/types": "^7.8.3" + } + }, + "@babel/helper-function-name": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.8.3.tgz", + "integrity": "sha512-BCxgX1BC2hD/oBlIFUgOCQDOPV8nSINxCwM3o93xP4P9Fq6aV5sgv2cOOITDMtCfQ+3PvHp3l689XZvAM9QyOA==", + "dev": true, + "requires": { + "@babel/helper-get-function-arity": "^7.8.3", + "@babel/template": "^7.8.3", + "@babel/types": "^7.8.3" + } + }, + "@babel/helper-get-function-arity": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.8.3.tgz", + "integrity": "sha512-FVDR+Gd9iLjUMY1fzE2SR0IuaJToR4RkCDARVfsBBPSP53GEqSFjD8gNyxg246VUyc/ALRxFaAK8rVG7UT7xRA==", + "dev": true, + "requires": { + "@babel/types": "^7.8.3" + } + }, + "@babel/helper-hoist-variables": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.8.3.tgz", + "integrity": "sha512-ky1JLOjcDUtSc+xkt0xhYff7Z6ILTAHKmZLHPxAhOP0Nd77O+3nCsd6uSVYur6nJnCI029CrNbYlc0LoPfAPQg==", + "dev": true, + "requires": { + "@babel/types": "^7.8.3" + } + }, + "@babel/helper-member-expression-to-functions": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.8.3.tgz", + "integrity": "sha512-fO4Egq88utkQFjbPrSHGmGLFqmrshs11d46WI+WZDESt7Wu7wN2G2Iu+NMMZJFDOVRHAMIkB5SNh30NtwCA7RA==", + "dev": true, + "requires": { + "@babel/types": "^7.8.3" + } + }, + "@babel/helper-module-imports": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.8.3.tgz", + "integrity": "sha512-R0Bx3jippsbAEtzkpZ/6FIiuzOURPcMjHp+Z6xPe6DtApDJx+w7UYyOLanZqO8+wKR9G10s/FmHXvxaMd9s6Kg==", + "dev": true, + "requires": { + "@babel/types": "^7.8.3" + } + }, + "@babel/helper-module-transforms": { + "version": "7.8.6", + "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.8.6.tgz", + "integrity": "sha512-RDnGJSR5EFBJjG3deY0NiL0K9TO8SXxS9n/MPsbPK/s9LbQymuLNtlzvDiNS7IpecuL45cMeLVkA+HfmlrnkRg==", + "dev": true, + "requires": { + "@babel/helper-module-imports": "^7.8.3", + "@babel/helper-replace-supers": "^7.8.6", + "@babel/helper-simple-access": "^7.8.3", + "@babel/helper-split-export-declaration": "^7.8.3", + "@babel/template": "^7.8.6", + "@babel/types": "^7.8.6", + "lodash": "^4.17.13" + } + }, + "@babel/helper-optimise-call-expression": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.8.3.tgz", + "integrity": "sha512-Kag20n86cbO2AvHca6EJsvqAd82gc6VMGule4HwebwMlwkpXuVqrNRj6CkCV2sKxgi9MyAUnZVnZ6lJ1/vKhHQ==", + "dev": true, "requires": { - "tslib": "^1.9.0" + "@babel/types": "^7.8.3" } }, - "@angular/flex-layout": { - "version": "8.0.0-beta.27", - "resolved": "https://registry.npmjs.org/@angular/flex-layout/-/flex-layout-8.0.0-beta.27.tgz", - "integrity": "sha512-qmpvQPesU4ZQ56IscwgmVRpK2UnyV+gwvXUql7TMv0QV215hLcHczjGsrKkLfW2By5E7XEyDat9br72uVXcPMw==", + "@babel/helper-plugin-utils": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.8.3.tgz", + "integrity": "sha512-j+fq49Xds2smCUNYmEHF9kGNkhbet6yVIBp4e6oeQpH1RUs/Ir06xUKzDjDkGcaaokPiTNs2JBWHjaE4csUkZQ==", + "dev": true + }, + "@babel/helper-regex": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/helper-regex/-/helper-regex-7.8.3.tgz", + "integrity": "sha512-BWt0QtYv/cg/NecOAZMdcn/waj/5P26DR4mVLXfFtDokSR6fyuG0Pj+e2FqtSME+MqED1khnSMulkmGl8qWiUQ==", + "dev": true, "requires": { - "tslib": "^1.7.1" + "lodash": "^4.17.13" } }, - "@angular/forms": { - "version": "8.2.14", - "resolved": "https://registry.npmjs.org/@angular/forms/-/forms-8.2.14.tgz", - "integrity": "sha512-zhyKL3CFIqcyHJ/TQF/h1OZztK611a6rxuPHCrt/5Sn1SuBTJJQ1pPTkOYIDy6IrCrtyANc8qB6P17Mao71DNQ==", + "@babel/helper-remap-async-to-generator": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.8.3.tgz", + "integrity": "sha512-kgwDmw4fCg7AVgS4DukQR/roGp+jP+XluJE5hsRZwxCYGg+Rv9wSGErDWhlI90FODdYfd4xG4AQRiMDjjN0GzA==", + "dev": true, "requires": { - "tslib": "^1.9.0" + "@babel/helper-annotate-as-pure": "^7.8.3", + "@babel/helper-wrap-function": "^7.8.3", + "@babel/template": "^7.8.3", + "@babel/traverse": "^7.8.3", + "@babel/types": "^7.8.3" } }, - "@angular/language-service": { - "version": "8.2.14", - "resolved": "https://registry.npmjs.org/@angular/language-service/-/language-service-8.2.14.tgz", - "integrity": "sha512-7EhN9JJbAJcH2xCa+rIOmekjiEuB0qwPdHuD5qn/wwMfRzMZo+Db4hHbR9KHrLH6H82PTwYKye/LLpDaZqoHOA==", + "@babel/helper-replace-supers": { + "version": "7.8.6", + "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.8.6.tgz", + "integrity": "sha512-PeMArdA4Sv/Wf4zXwBKPqVj7n9UF/xg6slNRtZW84FM7JpE1CbG8B612FyM4cxrf4fMAMGO0kR7voy1ForHHFA==", + "dev": true, + "requires": { + "@babel/helper-member-expression-to-functions": "^7.8.3", + "@babel/helper-optimise-call-expression": "^7.8.3", + "@babel/traverse": "^7.8.6", + "@babel/types": "^7.8.6" + } + }, + "@babel/helper-simple-access": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.8.3.tgz", + "integrity": "sha512-VNGUDjx5cCWg4vvCTR8qQ7YJYZ+HBjxOgXEl7ounz+4Sn7+LMD3CFrCTEU6/qXKbA2nKg21CwhhBzO0RpRbdCw==", + "dev": true, + "requires": { + "@babel/template": "^7.8.3", + "@babel/types": "^7.8.3" + } + }, + "@babel/helper-split-export-declaration": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.8.3.tgz", + "integrity": "sha512-3x3yOeyBhW851hroze7ElzdkeRXQYQbFIb7gLK1WQYsw2GWDay5gAJNw1sWJ0VFP6z5J1whqeXH/WCdCjZv6dA==", + "dev": true, + "requires": { + "@babel/types": "^7.8.3" + } + }, + "@babel/helper-wrap-function": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/helper-wrap-function/-/helper-wrap-function-7.8.3.tgz", + "integrity": "sha512-LACJrbUET9cQDzb6kG7EeD7+7doC3JNvUgTEQOx2qaO1fKlzE/Bf05qs9w1oXQMmXlPO65lC3Tq9S6gZpTErEQ==", + "dev": true, + "requires": { + "@babel/helper-function-name": "^7.8.3", + "@babel/template": "^7.8.3", + "@babel/traverse": "^7.8.3", + "@babel/types": "^7.8.3" + } + }, + "@babel/helpers": { + "version": "7.8.4", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.8.4.tgz", + "integrity": "sha512-VPbe7wcQ4chu4TDQjimHv/5tj73qz88o12EPkO2ValS2QiQS/1F2SsjyIGNnAD0vF/nZS6Cf9i+vW6HIlnaR8w==", + "dev": true, + "requires": { + "@babel/template": "^7.8.3", + "@babel/traverse": "^7.8.4", + "@babel/types": "^7.8.3" + } + }, + "@babel/highlight": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.8.3.tgz", + "integrity": "sha512-PX4y5xQUvy0fnEVHrYOarRPXVWafSjTW9T0Hab8gVIawpl2Sj0ORyrygANq+KjcNlSSTw0YCLSNA8OyZ1I4yEg==", + "dev": true, + "requires": { + "chalk": "^2.0.0", + "esutils": "^2.0.2", + "js-tokens": "^4.0.0" + } + }, + "@babel/parser": { + "version": "7.8.8", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.8.8.tgz", + "integrity": "sha512-mO5GWzBPsPf6865iIbzNE0AvkKF3NE+2S3eRUpE+FE07BOAkXh6G+GW/Pj01hhXjve1WScbaIO4UlY1JKeqCcA==", "dev": true }, - "@angular/material": { - "version": "8.2.3", - "resolved": "https://registry.npmjs.org/@angular/material/-/material-8.2.3.tgz", - "integrity": "sha512-SOczkIaqes+r+9XF/UUiokidfFKBpHkOPIaFK857sFD0FBNPvPEpOr5oHKCG3feERRwAFqHS7Wo2ohVEWypb5A==", + "@babel/plugin-proposal-async-generator-functions": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-async-generator-functions/-/plugin-proposal-async-generator-functions-7.8.3.tgz", + "integrity": "sha512-NZ9zLv848JsV3hs8ryEh7Uaz/0KsmPLqv0+PdkDJL1cJy0K4kOCFa8zc1E3mp+RHPQcpdfb/6GovEsW4VDrOMw==", + "dev": true, "requires": { - "tslib": "^1.7.1" + "@babel/helper-plugin-utils": "^7.8.3", + "@babel/helper-remap-async-to-generator": "^7.8.3", + "@babel/plugin-syntax-async-generators": "^7.8.0" } }, - "@angular/platform-browser": { - "version": "8.2.14", - "resolved": "https://registry.npmjs.org/@angular/platform-browser/-/platform-browser-8.2.14.tgz", - "integrity": "sha512-MtJptptyKzsE37JZ2VB/tI4cvMrdAH+cT9pMBYZd66YSZfKjIj5s+AZo7z8ncoskQSB1o3HMfDjSK7QXGx1mLQ==", + "@babel/plugin-proposal-dynamic-import": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-dynamic-import/-/plugin-proposal-dynamic-import-7.8.3.tgz", + "integrity": "sha512-NyaBbyLFXFLT9FP+zk0kYlUlA8XtCUbehs67F0nnEg7KICgMc2mNkIeu9TYhKzyXMkrapZFwAhXLdnt4IYHy1w==", + "dev": true, "requires": { - "tslib": "^1.9.0" + "@babel/helper-plugin-utils": "^7.8.3", + "@babel/plugin-syntax-dynamic-import": "^7.8.0" } }, - "@angular/platform-browser-dynamic": { - "version": "8.2.14", - "resolved": "https://registry.npmjs.org/@angular/platform-browser-dynamic/-/platform-browser-dynamic-8.2.14.tgz", - "integrity": "sha512-mO2JPR5kLU/A3AQngy9+R/Q5gaF9csMStBQjwsCRI0wNtlItOIGL6+wTYpiTuh/ux+WVN1F2sLcEYU4Zf1ud9A==", + "@babel/plugin-proposal-json-strings": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-json-strings/-/plugin-proposal-json-strings-7.8.3.tgz", + "integrity": "sha512-KGhQNZ3TVCQG/MjRbAUwuH+14y9q0tpxs1nWWs3pbSleRdDro9SAMMDyye8HhY1gqZ7/NqIc8SKhya0wRDgP1Q==", + "dev": true, "requires": { - "tslib": "^1.9.0" + "@babel/helper-plugin-utils": "^7.8.3", + "@babel/plugin-syntax-json-strings": "^7.8.0" } }, - "@angular/router": { - "version": "8.2.14", - "resolved": "https://registry.npmjs.org/@angular/router/-/router-8.2.14.tgz", - "integrity": "sha512-DHA2BhODqV7F0g6ZKgFaZgbsqzHHWRcfWchCOrOVKu2rYiKUTwwHVLBgZAhrpNeinq2pWanVYSIhMr7wy+LfEA==", + "@babel/plugin-proposal-object-rest-spread": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-object-rest-spread/-/plugin-proposal-object-rest-spread-7.8.3.tgz", + "integrity": "sha512-8qvuPwU/xxUCt78HocNlv0mXXo0wdh9VT1R04WU8HGOfaOob26pF+9P5/lYjN/q7DHOX1bvX60hnhOvuQUJdbA==", + "dev": true, "requires": { - "tslib": "^1.9.0" + "@babel/helper-plugin-utils": "^7.8.3", + "@babel/plugin-syntax-object-rest-spread": "^7.8.0" } }, - "@babel/code-frame": { + "@babel/plugin-proposal-optional-catch-binding": { "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.8.3.tgz", - "integrity": "sha512-a9gxpmdXtZEInkCSHUJDLHZVBgb1QS0jhss4cPP93EW7s+uC5bikET2twEF3KV+7rDblJcmNvTR7VJejqd2C2g==", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-optional-catch-binding/-/plugin-proposal-optional-catch-binding-7.8.3.tgz", + "integrity": "sha512-0gkX7J7E+AtAw9fcwlVQj8peP61qhdg/89D5swOkjYbkboA2CVckn3kiyum1DE0wskGb7KJJxBdyEBApDLLVdw==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.8.3", + "@babel/plugin-syntax-optional-catch-binding": "^7.8.0" + } + }, + "@babel/plugin-proposal-unicode-property-regex": { + "version": "7.8.8", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-unicode-property-regex/-/plugin-proposal-unicode-property-regex-7.8.8.tgz", + "integrity": "sha512-EVhjVsMpbhLw9ZfHWSx2iy13Q8Z/eg8e8ccVWt23sWQK5l1UdkoLJPN5w69UA4uITGBnEZD2JOe4QOHycYKv8A==", + "dev": true, + "requires": { + "@babel/helper-create-regexp-features-plugin": "^7.8.8", + "@babel/helper-plugin-utils": "^7.8.3" + } + }, + "@babel/plugin-syntax-async-generators": { + "version": "7.8.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-async-generators/-/plugin-syntax-async-generators-7.8.4.tgz", + "integrity": "sha512-tycmZxkGfZaxhMRbXlPXuVFpdWlXpir2W4AMhSJgRKzk/eDlIXOhb2LHWoLpDF7TEHylV5zNhykX6KAgHJmTNw==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.8.0" + } + }, + "@babel/plugin-syntax-dynamic-import": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-dynamic-import/-/plugin-syntax-dynamic-import-7.8.3.tgz", + "integrity": "sha512-5gdGbFon+PszYzqs83S3E5mpi7/y/8M9eC90MRTZfduQOYW76ig6SOSPNe41IG5LoP3FGBn2N0RjVDSQiS94kQ==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.8.0" + } + }, + "@babel/plugin-syntax-json-strings": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-json-strings/-/plugin-syntax-json-strings-7.8.3.tgz", + "integrity": "sha512-lY6kdGpWHvjoe2vk4WrAapEuBR69EMxZl+RoGRhrFGNYVK8mOPAW8VfbT/ZgrFbXlDNiiaxQnAtgVCZ6jv30EA==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.8.0" + } + }, + "@babel/plugin-syntax-object-rest-spread": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-object-rest-spread/-/plugin-syntax-object-rest-spread-7.8.3.tgz", + "integrity": "sha512-XoqMijGZb9y3y2XskN+P1wUGiVwWZ5JmoDRwx5+3GmEplNyVM2s2Dg8ILFQm8rWM48orGy5YpI5Bl8U1y7ydlA==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.8.0" + } + }, + "@babel/plugin-syntax-optional-catch-binding": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-optional-catch-binding/-/plugin-syntax-optional-catch-binding-7.8.3.tgz", + "integrity": "sha512-6VPD0Pc1lpTqw0aKoeRTMiB+kWhAoT24PA+ksWSBrFtl5SIRVpZlwN3NNPQjehA2E/91FV3RjLWoVTglWcSV3Q==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.8.0" + } + }, + "@babel/plugin-syntax-top-level-await": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-top-level-await/-/plugin-syntax-top-level-await-7.8.3.tgz", + "integrity": "sha512-kwj1j9lL/6Wd0hROD3b/OZZ7MSrZLqqn9RAZ5+cYYsflQ9HZBIKCUkr3+uL1MEJ1NePiUbf98jjiMQSv0NMR9g==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.8.3" + } + }, + "@babel/plugin-transform-arrow-functions": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.8.3.tgz", + "integrity": "sha512-0MRF+KC8EqH4dbuITCWwPSzsyO3HIWWlm30v8BbbpOrS1B++isGxPnnuq/IZvOX5J2D/p7DQalQm+/2PnlKGxg==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.8.3" + } + }, + "@babel/plugin-transform-async-to-generator": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.8.3.tgz", + "integrity": "sha512-imt9tFLD9ogt56Dd5CI/6XgpukMwd/fLGSrix2httihVe7LOGVPhyhMh1BU5kDM7iHD08i8uUtmV2sWaBFlHVQ==", + "dev": true, + "requires": { + "@babel/helper-module-imports": "^7.8.3", + "@babel/helper-plugin-utils": "^7.8.3", + "@babel/helper-remap-async-to-generator": "^7.8.3" + } + }, + "@babel/plugin-transform-block-scoped-functions": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoped-functions/-/plugin-transform-block-scoped-functions-7.8.3.tgz", + "integrity": "sha512-vo4F2OewqjbB1+yaJ7k2EJFHlTP3jR634Z9Cj9itpqNjuLXvhlVxgnjsHsdRgASR8xYDrx6onw4vW5H6We0Jmg==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.8.3" + } + }, + "@babel/plugin-transform-block-scoping": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.8.3.tgz", + "integrity": "sha512-pGnYfm7RNRgYRi7bids5bHluENHqJhrV4bCZRwc5GamaWIIs07N4rZECcmJL6ZClwjDz1GbdMZFtPs27hTB06w==", "dev": true, "requires": { - "@babel/highlight": "^7.8.3" + "@babel/helper-plugin-utils": "^7.8.3", + "lodash": "^4.17.13" } }, - "@babel/compat-data": { + "@babel/plugin-transform-classes": { "version": "7.8.6", - "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.8.6.tgz", - "integrity": "sha512-CurCIKPTkS25Mb8mz267vU95vy+TyUpnctEX2lV33xWNmHAfjruztgiPBbXZRh3xZZy1CYvGx6XfxyTVS+sk7Q==", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-classes/-/plugin-transform-classes-7.8.6.tgz", + "integrity": "sha512-k9r8qRay/R6v5aWZkrEclEhKO6mc1CCQr2dLsVHBmOQiMpN6I2bpjX3vgnldUWeEI1GHVNByULVxZ4BdP4Hmdg==", "dev": true, "requires": { - "browserslist": "^4.8.5", - "invariant": "^2.2.4", - "semver": "^5.5.0" - }, - "dependencies": { - "semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", - "dev": true - } + "@babel/helper-annotate-as-pure": "^7.8.3", + "@babel/helper-define-map": "^7.8.3", + "@babel/helper-function-name": "^7.8.3", + "@babel/helper-optimise-call-expression": "^7.8.3", + "@babel/helper-plugin-utils": "^7.8.3", + "@babel/helper-replace-supers": "^7.8.6", + "@babel/helper-split-export-declaration": "^7.8.3", + "globals": "^11.1.0" } }, - "@babel/core": { + "@babel/plugin-transform-computed-properties": { "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.8.3.tgz", - "integrity": "sha512-4XFkf8AwyrEG7Ziu3L2L0Cv+WyY47Tcsp70JFmpftbAA1K7YL/sgE9jh9HyNj08Y/U50ItUchpN0w6HxAoX1rA==", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.8.3.tgz", + "integrity": "sha512-O5hiIpSyOGdrQZRQ2ccwtTVkgUDBBiCuK//4RJ6UfePllUTCENOzKxfh6ulckXKc0DixTFLCfb2HVkNA7aDpzA==", "dev": true, "requires": { - "@babel/code-frame": "^7.8.3", - "@babel/generator": "^7.8.3", - "@babel/helpers": "^7.8.3", - "@babel/parser": "^7.8.3", - "@babel/template": "^7.8.3", - "@babel/traverse": "^7.8.3", - "@babel/types": "^7.8.3", - "convert-source-map": "^1.7.0", - "debug": "^4.1.0", - "gensync": "^1.0.0-beta.1", - "json5": "^2.1.0", - "lodash": "^4.17.13", - "resolve": "^1.3.2", - "semver": "^5.4.1", - "source-map": "^0.5.0" - }, - "dependencies": { - "json5": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/json5/-/json5-2.1.2.tgz", - "integrity": "sha512-MoUOQ4WdiN3yxhm7NEVJSJrieAo5hNSLQ5sj05OTRHPL9HOBy8u4Bu88jsC1jvqAdN+E1bJmsUcZH+1HQxliqQ==", - "dev": true, - "requires": { - "minimist": "^1.2.5" - } - }, - "semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", - "dev": true - }, - "source-map": { - "version": "0.5.7", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", - "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", - "dev": true - } + "@babel/helper-plugin-utils": "^7.8.3" } }, - "@babel/generator": { + "@babel/plugin-transform-destructuring": { "version": "7.8.8", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.8.8.tgz", - "integrity": "sha512-HKyUVu69cZoclptr8t8U5b6sx6zoWjh8jiUhnuj3MpZuKT2dJ8zPTuiy31luq32swhI0SpwItCIlU8XW7BZeJg==", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.8.8.tgz", + "integrity": "sha512-eRJu4Vs2rmttFCdhPUM3bV0Yo/xPSdPw6ML9KHs/bjB4bLA5HXlbvYXPOD5yASodGod+krjYx21xm1QmL8dCJQ==", "dev": true, "requires": { - "@babel/types": "^7.8.7", - "jsesc": "^2.5.1", - "lodash": "^4.17.13", - "source-map": "^0.5.0" - }, - "dependencies": { - "source-map": { - "version": "0.5.7", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", - "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", - "dev": true - } + "@babel/helper-plugin-utils": "^7.8.3" } }, - "@babel/helper-annotate-as-pure": { + "@babel/plugin-transform-dotall-regex": { "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.8.3.tgz", - "integrity": "sha512-6o+mJrZBxOoEX77Ezv9zwW7WV8DdluouRKNY/IR5u/YTMuKHgugHOzYWlYvYLpLA9nPsQCAAASpCIbjI9Mv+Uw==", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-dotall-regex/-/plugin-transform-dotall-regex-7.8.3.tgz", + "integrity": "sha512-kLs1j9Nn4MQoBYdRXH6AeaXMbEJFaFu/v1nQkvib6QzTj8MZI5OQzqmD83/2jEM1z0DLilra5aWO5YpyC0ALIw==", "dev": true, "requires": { - "@babel/types": "^7.8.3" + "@babel/helper-create-regexp-features-plugin": "^7.8.3", + "@babel/helper-plugin-utils": "^7.8.3" } }, - "@babel/helper-builder-binary-assignment-operator-visitor": { + "@babel/plugin-transform-duplicate-keys": { "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/helper-builder-binary-assignment-operator-visitor/-/helper-builder-binary-assignment-operator-visitor-7.8.3.tgz", - "integrity": "sha512-5eFOm2SyFPK4Rh3XMMRDjN7lBH0orh3ss0g3rTYZnBQ+r6YPj7lgDyCvPphynHvUrobJmeMignBr6Acw9mAPlw==", - "dev": true, - "requires": { - "@babel/helper-explode-assignable-expression": "^7.8.3", - "@babel/types": "^7.8.3" - } - }, - "@babel/helper-call-delegate": { - "version": "7.8.7", - "resolved": "https://registry.npmjs.org/@babel/helper-call-delegate/-/helper-call-delegate-7.8.7.tgz", - "integrity": "sha512-doAA5LAKhsFCR0LAFIf+r2RSMmC+m8f/oQ+URnUET/rWeEzC0yTRmAGyWkD4sSu3xwbS7MYQ2u+xlt1V5R56KQ==", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-duplicate-keys/-/plugin-transform-duplicate-keys-7.8.3.tgz", + "integrity": "sha512-s8dHiBUbcbSgipS4SMFuWGqCvyge5V2ZeAWzR6INTVC3Ltjig/Vw1G2Gztv0vU/hRG9X8IvKvYdoksnUfgXOEQ==", "dev": true, "requires": { - "@babel/helper-hoist-variables": "^7.8.3", - "@babel/traverse": "^7.8.3", - "@babel/types": "^7.8.7" + "@babel/helper-plugin-utils": "^7.8.3" } }, - "@babel/helper-compilation-targets": { - "version": "7.8.7", - "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.8.7.tgz", - "integrity": "sha512-4mWm8DCK2LugIS+p1yArqvG1Pf162upsIsjE7cNBjez+NjliQpVhj20obE520nao0o14DaTnFJv+Fw5a0JpoUw==", + "@babel/plugin-transform-exponentiation-operator": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-exponentiation-operator/-/plugin-transform-exponentiation-operator-7.8.3.tgz", + "integrity": "sha512-zwIpuIymb3ACcInbksHaNcR12S++0MDLKkiqXHl3AzpgdKlFNhog+z/K0+TGW+b0w5pgTq4H6IwV/WhxbGYSjQ==", "dev": true, "requires": { - "@babel/compat-data": "^7.8.6", - "browserslist": "^4.9.1", - "invariant": "^2.2.4", - "levenary": "^1.1.1", - "semver": "^5.5.0" - }, - "dependencies": { - "browserslist": { - "version": "4.9.1", - "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.9.1.tgz", - "integrity": "sha512-Q0DnKq20End3raFulq6Vfp1ecB9fh8yUNV55s8sekaDDeqBaCtWlRHCUdaWyUeSSBJM7IbM6HcsyaeYqgeDhnw==", - "dev": true, - "requires": { - "caniuse-lite": "^1.0.30001030", - "electron-to-chromium": "^1.3.363", - "node-releases": "^1.1.50" - } - }, - "caniuse-lite": { - "version": "1.0.30001035", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001035.tgz", - "integrity": "sha512-C1ZxgkuA4/bUEdMbU5WrGY4+UhMFFiXrgNAfxiMIqWgFTWfv/xsZCS2xEHT2LMq7xAZfuAnu6mcqyDl0ZR6wLQ==", - "dev": true - }, - "semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", - "dev": true - } + "@babel/helper-builder-binary-assignment-operator-visitor": "^7.8.3", + "@babel/helper-plugin-utils": "^7.8.3" } }, - "@babel/helper-create-regexp-features-plugin": { - "version": "7.8.8", - "resolved": "https://registry.npmjs.org/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.8.8.tgz", - "integrity": "sha512-LYVPdwkrQEiX9+1R29Ld/wTrmQu1SSKYnuOk3g0CkcZMA1p0gsNxJFj/3gBdaJ7Cg0Fnek5z0DsMULePP7Lrqg==", + "@babel/plugin-transform-for-of": { + "version": "7.8.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.8.6.tgz", + "integrity": "sha512-M0pw4/1/KI5WAxPsdcUL/w2LJ7o89YHN3yLkzNjg7Yl15GlVGgzHyCU+FMeAxevHGsLVmUqbirlUIKTafPmzdw==", "dev": true, "requires": { - "@babel/helper-annotate-as-pure": "^7.8.3", - "@babel/helper-regex": "^7.8.3", - "regexpu-core": "^4.7.0" + "@babel/helper-plugin-utils": "^7.8.3" } }, - "@babel/helper-define-map": { + "@babel/plugin-transform-function-name": { "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/helper-define-map/-/helper-define-map-7.8.3.tgz", - "integrity": "sha512-PoeBYtxoZGtct3md6xZOCWPcKuMuk3IHhgxsRRNtnNShebf4C8YonTSblsK4tvDbm+eJAw2HAPOfCr+Q/YRG/g==", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-function-name/-/plugin-transform-function-name-7.8.3.tgz", + "integrity": "sha512-rO/OnDS78Eifbjn5Py9v8y0aR+aSYhDhqAwVfsTl0ERuMZyr05L1aFSCJnbv2mmsLkit/4ReeQ9N2BgLnOcPCQ==", "dev": true, "requires": { "@babel/helper-function-name": "^7.8.3", - "@babel/types": "^7.8.3", - "lodash": "^4.17.13" + "@babel/helper-plugin-utils": "^7.8.3" } }, - "@babel/helper-explode-assignable-expression": { + "@babel/plugin-transform-literals": { "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/helper-explode-assignable-expression/-/helper-explode-assignable-expression-7.8.3.tgz", - "integrity": "sha512-N+8eW86/Kj147bO9G2uclsg5pwfs/fqqY5rwgIL7eTBklgXjcOJ3btzS5iM6AitJcftnY7pm2lGsrJVYLGjzIw==", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-literals/-/plugin-transform-literals-7.8.3.tgz", + "integrity": "sha512-3Tqf8JJ/qB7TeldGl+TT55+uQei9JfYaregDcEAyBZ7akutriFrt6C/wLYIer6OYhleVQvH/ntEhjE/xMmy10A==", "dev": true, "requires": { - "@babel/traverse": "^7.8.3", - "@babel/types": "^7.8.3" + "@babel/helper-plugin-utils": "^7.8.3" } }, - "@babel/helper-function-name": { + "@babel/plugin-transform-member-expression-literals": { "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.8.3.tgz", - "integrity": "sha512-BCxgX1BC2hD/oBlIFUgOCQDOPV8nSINxCwM3o93xP4P9Fq6aV5sgv2cOOITDMtCfQ+3PvHp3l689XZvAM9QyOA==", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-member-expression-literals/-/plugin-transform-member-expression-literals-7.8.3.tgz", + "integrity": "sha512-3Wk2EXhnw+rP+IDkK6BdtPKsUE5IeZ6QOGrPYvw52NwBStw9V1ZVzxgK6fSKSxqUvH9eQPR3tm3cOq79HlsKYA==", "dev": true, "requires": { - "@babel/helper-get-function-arity": "^7.8.3", - "@babel/template": "^7.8.3", - "@babel/types": "^7.8.3" + "@babel/helper-plugin-utils": "^7.8.3" } }, - "@babel/helper-get-function-arity": { + "@babel/plugin-transform-modules-amd": { "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.8.3.tgz", - "integrity": "sha512-FVDR+Gd9iLjUMY1fzE2SR0IuaJToR4RkCDARVfsBBPSP53GEqSFjD8gNyxg246VUyc/ALRxFaAK8rVG7UT7xRA==", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-amd/-/plugin-transform-modules-amd-7.8.3.tgz", + "integrity": "sha512-MadJiU3rLKclzT5kBH4yxdry96odTUwuqrZM+GllFI/VhxfPz+k9MshJM+MwhfkCdxxclSbSBbUGciBngR+kEQ==", "dev": true, "requires": { - "@babel/types": "^7.8.3" + "@babel/helper-module-transforms": "^7.8.3", + "@babel/helper-plugin-utils": "^7.8.3", + "babel-plugin-dynamic-import-node": "^2.3.0" } }, - "@babel/helper-hoist-variables": { + "@babel/plugin-transform-modules-commonjs": { "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.8.3.tgz", - "integrity": "sha512-ky1JLOjcDUtSc+xkt0xhYff7Z6ILTAHKmZLHPxAhOP0Nd77O+3nCsd6uSVYur6nJnCI029CrNbYlc0LoPfAPQg==", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.8.3.tgz", + "integrity": "sha512-JpdMEfA15HZ/1gNuB9XEDlZM1h/gF/YOH7zaZzQu2xCFRfwc01NXBMHHSTT6hRjlXJJs5x/bfODM3LiCk94Sxg==", "dev": true, "requires": { - "@babel/types": "^7.8.3" + "@babel/helper-module-transforms": "^7.8.3", + "@babel/helper-plugin-utils": "^7.8.3", + "@babel/helper-simple-access": "^7.8.3", + "babel-plugin-dynamic-import-node": "^2.3.0" } }, - "@babel/helper-member-expression-to-functions": { + "@babel/plugin-transform-modules-systemjs": { "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.8.3.tgz", - "integrity": "sha512-fO4Egq88utkQFjbPrSHGmGLFqmrshs11d46WI+WZDESt7Wu7wN2G2Iu+NMMZJFDOVRHAMIkB5SNh30NtwCA7RA==", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.8.3.tgz", + "integrity": "sha512-8cESMCJjmArMYqa9AO5YuMEkE4ds28tMpZcGZB/jl3n0ZzlsxOAi3mC+SKypTfT8gjMupCnd3YiXCkMjj2jfOg==", "dev": true, "requires": { - "@babel/types": "^7.8.3" + "@babel/helper-hoist-variables": "^7.8.3", + "@babel/helper-module-transforms": "^7.8.3", + "@babel/helper-plugin-utils": "^7.8.3", + "babel-plugin-dynamic-import-node": "^2.3.0" } }, - "@babel/helper-module-imports": { + "@babel/plugin-transform-modules-umd": { "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.8.3.tgz", - "integrity": "sha512-R0Bx3jippsbAEtzkpZ/6FIiuzOURPcMjHp+Z6xPe6DtApDJx+w7UYyOLanZqO8+wKR9G10s/FmHXvxaMd9s6Kg==", - "dev": true, - "requires": { - "@babel/types": "^7.8.3" - } - }, - "@babel/helper-module-transforms": { - "version": "7.8.6", - "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.8.6.tgz", - "integrity": "sha512-RDnGJSR5EFBJjG3deY0NiL0K9TO8SXxS9n/MPsbPK/s9LbQymuLNtlzvDiNS7IpecuL45cMeLVkA+HfmlrnkRg==", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-umd/-/plugin-transform-modules-umd-7.8.3.tgz", + "integrity": "sha512-evhTyWhbwbI3/U6dZAnx/ePoV7H6OUG+OjiJFHmhr9FPn0VShjwC2kdxqIuQ/+1P50TMrneGzMeyMTFOjKSnAw==", "dev": true, "requires": { - "@babel/helper-module-imports": "^7.8.3", - "@babel/helper-replace-supers": "^7.8.6", - "@babel/helper-simple-access": "^7.8.3", - "@babel/helper-split-export-declaration": "^7.8.3", - "@babel/template": "^7.8.6", - "@babel/types": "^7.8.6", - "lodash": "^4.17.13" + "@babel/helper-module-transforms": "^7.8.3", + "@babel/helper-plugin-utils": "^7.8.3" } }, - "@babel/helper-optimise-call-expression": { + "@babel/plugin-transform-named-capturing-groups-regex": { "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.8.3.tgz", - "integrity": "sha512-Kag20n86cbO2AvHca6EJsvqAd82gc6VMGule4HwebwMlwkpXuVqrNRj6CkCV2sKxgi9MyAUnZVnZ6lJ1/vKhHQ==", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-named-capturing-groups-regex/-/plugin-transform-named-capturing-groups-regex-7.8.3.tgz", + "integrity": "sha512-f+tF/8UVPU86TrCb06JoPWIdDpTNSGGcAtaD9mLP0aYGA0OS0j7j7DHJR0GTFrUZPUU6loZhbsVZgTh0N+Qdnw==", "dev": true, "requires": { - "@babel/types": "^7.8.3" + "@babel/helper-create-regexp-features-plugin": "^7.8.3" } }, - "@babel/helper-plugin-utils": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.8.3.tgz", - "integrity": "sha512-j+fq49Xds2smCUNYmEHF9kGNkhbet6yVIBp4e6oeQpH1RUs/Ir06xUKzDjDkGcaaokPiTNs2JBWHjaE4csUkZQ==", - "dev": true - }, - "@babel/helper-regex": { + "@babel/plugin-transform-new-target": { "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/helper-regex/-/helper-regex-7.8.3.tgz", - "integrity": "sha512-BWt0QtYv/cg/NecOAZMdcn/waj/5P26DR4mVLXfFtDokSR6fyuG0Pj+e2FqtSME+MqED1khnSMulkmGl8qWiUQ==", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-new-target/-/plugin-transform-new-target-7.8.3.tgz", + "integrity": "sha512-QuSGysibQpyxexRyui2vca+Cmbljo8bcRckgzYV4kRIsHpVeyeC3JDO63pY+xFZ6bWOBn7pfKZTqV4o/ix9sFw==", "dev": true, "requires": { - "lodash": "^4.17.13" + "@babel/helper-plugin-utils": "^7.8.3" } }, - "@babel/helper-remap-async-to-generator": { + "@babel/plugin-transform-object-super": { "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.8.3.tgz", - "integrity": "sha512-kgwDmw4fCg7AVgS4DukQR/roGp+jP+XluJE5hsRZwxCYGg+Rv9wSGErDWhlI90FODdYfd4xG4AQRiMDjjN0GzA==", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-object-super/-/plugin-transform-object-super-7.8.3.tgz", + "integrity": "sha512-57FXk+gItG/GejofIyLIgBKTas4+pEU47IXKDBWFTxdPd7F80H8zybyAY7UoblVfBhBGs2EKM+bJUu2+iUYPDQ==", "dev": true, "requires": { - "@babel/helper-annotate-as-pure": "^7.8.3", - "@babel/helper-wrap-function": "^7.8.3", - "@babel/template": "^7.8.3", - "@babel/traverse": "^7.8.3", - "@babel/types": "^7.8.3" + "@babel/helper-plugin-utils": "^7.8.3", + "@babel/helper-replace-supers": "^7.8.3" } }, - "@babel/helper-replace-supers": { - "version": "7.8.6", - "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.8.6.tgz", - "integrity": "sha512-PeMArdA4Sv/Wf4zXwBKPqVj7n9UF/xg6slNRtZW84FM7JpE1CbG8B612FyM4cxrf4fMAMGO0kR7voy1ForHHFA==", + "@babel/plugin-transform-parameters": { + "version": "7.8.8", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.8.8.tgz", + "integrity": "sha512-hC4Ld/Ulpf1psQciWWwdnUspQoQco2bMzSrwU6TmzRlvoYQe4rQFy9vnCZDTlVeCQj0JPfL+1RX0V8hCJvkgBA==", "dev": true, "requires": { - "@babel/helper-member-expression-to-functions": "^7.8.3", - "@babel/helper-optimise-call-expression": "^7.8.3", - "@babel/traverse": "^7.8.6", - "@babel/types": "^7.8.6" + "@babel/helper-call-delegate": "^7.8.7", + "@babel/helper-get-function-arity": "^7.8.3", + "@babel/helper-plugin-utils": "^7.8.3" } }, - "@babel/helper-simple-access": { + "@babel/plugin-transform-property-literals": { "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.8.3.tgz", - "integrity": "sha512-VNGUDjx5cCWg4vvCTR8qQ7YJYZ+HBjxOgXEl7ounz+4Sn7+LMD3CFrCTEU6/qXKbA2nKg21CwhhBzO0RpRbdCw==", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-property-literals/-/plugin-transform-property-literals-7.8.3.tgz", + "integrity": "sha512-uGiiXAZMqEoQhRWMK17VospMZh5sXWg+dlh2soffpkAl96KAm+WZuJfa6lcELotSRmooLqg0MWdH6UUq85nmmg==", "dev": true, "requires": { - "@babel/template": "^7.8.3", - "@babel/types": "^7.8.3" + "@babel/helper-plugin-utils": "^7.8.3" } }, - "@babel/helper-split-export-declaration": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.8.3.tgz", - "integrity": "sha512-3x3yOeyBhW851hroze7ElzdkeRXQYQbFIb7gLK1WQYsw2GWDay5gAJNw1sWJ0VFP6z5J1whqeXH/WCdCjZv6dA==", + "@babel/plugin-transform-regenerator": { + "version": "7.8.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.8.7.tgz", + "integrity": "sha512-TIg+gAl4Z0a3WmD3mbYSk+J9ZUH6n/Yc57rtKRnlA/7rcCvpekHXe0CMZHP1gYp7/KLe9GHTuIba0vXmls6drA==", "dev": true, "requires": { - "@babel/types": "^7.8.3" + "regenerator-transform": "^0.14.2" } }, - "@babel/helper-wrap-function": { + "@babel/plugin-transform-reserved-words": { "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/helper-wrap-function/-/helper-wrap-function-7.8.3.tgz", - "integrity": "sha512-LACJrbUET9cQDzb6kG7EeD7+7doC3JNvUgTEQOx2qaO1fKlzE/Bf05qs9w1oXQMmXlPO65lC3Tq9S6gZpTErEQ==", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-reserved-words/-/plugin-transform-reserved-words-7.8.3.tgz", + "integrity": "sha512-mwMxcycN3omKFDjDQUl+8zyMsBfjRFr0Zn/64I41pmjv4NJuqcYlEtezwYtw9TFd9WR1vN5kiM+O0gMZzO6L0A==", "dev": true, "requires": { - "@babel/helper-function-name": "^7.8.3", - "@babel/template": "^7.8.3", - "@babel/traverse": "^7.8.3", - "@babel/types": "^7.8.3" + "@babel/helper-plugin-utils": "^7.8.3" } }, - "@babel/helpers": { - "version": "7.8.4", - "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.8.4.tgz", - "integrity": "sha512-VPbe7wcQ4chu4TDQjimHv/5tj73qz88o12EPkO2ValS2QiQS/1F2SsjyIGNnAD0vF/nZS6Cf9i+vW6HIlnaR8w==", + "@babel/plugin-transform-shorthand-properties": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-shorthand-properties/-/plugin-transform-shorthand-properties-7.8.3.tgz", + "integrity": "sha512-I9DI6Odg0JJwxCHzbzW08ggMdCezoWcuQRz3ptdudgwaHxTjxw5HgdFJmZIkIMlRymL6YiZcped4TTCB0JcC8w==", "dev": true, "requires": { - "@babel/template": "^7.8.3", - "@babel/traverse": "^7.8.4", - "@babel/types": "^7.8.3" + "@babel/helper-plugin-utils": "^7.8.3" } }, - "@babel/highlight": { + "@babel/plugin-transform-spread": { "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.8.3.tgz", - "integrity": "sha512-PX4y5xQUvy0fnEVHrYOarRPXVWafSjTW9T0Hab8gVIawpl2Sj0ORyrygANq+KjcNlSSTw0YCLSNA8OyZ1I4yEg==", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-spread/-/plugin-transform-spread-7.8.3.tgz", + "integrity": "sha512-CkuTU9mbmAoFOI1tklFWYYbzX5qCIZVXPVy0jpXgGwkplCndQAa58s2jr66fTeQnA64bDox0HL4U56CFYoyC7g==", "dev": true, "requires": { - "chalk": "^2.0.0", - "esutils": "^2.0.2", - "js-tokens": "^4.0.0" + "@babel/helper-plugin-utils": "^7.8.3" } }, - "@babel/parser": { - "version": "7.8.8", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.8.8.tgz", - "integrity": "sha512-mO5GWzBPsPf6865iIbzNE0AvkKF3NE+2S3eRUpE+FE07BOAkXh6G+GW/Pj01hhXjve1WScbaIO4UlY1JKeqCcA==", - "dev": true - }, - "@babel/plugin-proposal-async-generator-functions": { + "@babel/plugin-transform-sticky-regex": { "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-async-generator-functions/-/plugin-proposal-async-generator-functions-7.8.3.tgz", - "integrity": "sha512-NZ9zLv848JsV3hs8ryEh7Uaz/0KsmPLqv0+PdkDJL1cJy0K4kOCFa8zc1E3mp+RHPQcpdfb/6GovEsW4VDrOMw==", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-sticky-regex/-/plugin-transform-sticky-regex-7.8.3.tgz", + "integrity": "sha512-9Spq0vGCD5Bb4Z/ZXXSK5wbbLFMG085qd2vhL1JYu1WcQ5bXqZBAYRzU1d+p79GcHs2szYv5pVQCX13QgldaWw==", "dev": true, "requires": { "@babel/helper-plugin-utils": "^7.8.3", - "@babel/helper-remap-async-to-generator": "^7.8.3", - "@babel/plugin-syntax-async-generators": "^7.8.0" + "@babel/helper-regex": "^7.8.3" } }, - "@babel/plugin-proposal-dynamic-import": { + "@babel/plugin-transform-template-literals": { "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-dynamic-import/-/plugin-proposal-dynamic-import-7.8.3.tgz", - "integrity": "sha512-NyaBbyLFXFLT9FP+zk0kYlUlA8XtCUbehs67F0nnEg7KICgMc2mNkIeu9TYhKzyXMkrapZFwAhXLdnt4IYHy1w==", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-template-literals/-/plugin-transform-template-literals-7.8.3.tgz", + "integrity": "sha512-820QBtykIQOLFT8NZOcTRJ1UNuztIELe4p9DCgvj4NK+PwluSJ49we7s9FB1HIGNIYT7wFUJ0ar2QpCDj0escQ==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "^7.8.3", - "@babel/plugin-syntax-dynamic-import": "^7.8.0" + "@babel/helper-annotate-as-pure": "^7.8.3", + "@babel/helper-plugin-utils": "^7.8.3" } }, - "@babel/plugin-proposal-json-strings": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-json-strings/-/plugin-proposal-json-strings-7.8.3.tgz", - "integrity": "sha512-KGhQNZ3TVCQG/MjRbAUwuH+14y9q0tpxs1nWWs3pbSleRdDro9SAMMDyye8HhY1gqZ7/NqIc8SKhya0wRDgP1Q==", + "@babel/plugin-transform-typeof-symbol": { + "version": "7.8.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-typeof-symbol/-/plugin-transform-typeof-symbol-7.8.4.tgz", + "integrity": "sha512-2QKyfjGdvuNfHsb7qnBBlKclbD4CfshH2KvDabiijLMGXPHJXGxtDzwIF7bQP+T0ysw8fYTtxPafgfs/c1Lrqg==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "^7.8.3", - "@babel/plugin-syntax-json-strings": "^7.8.0" + "@babel/helper-plugin-utils": "^7.8.3" } }, - "@babel/plugin-proposal-nullish-coalescing-operator": { + "@babel/plugin-transform-unicode-regex": { "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-nullish-coalescing-operator/-/plugin-proposal-nullish-coalescing-operator-7.8.3.tgz", - "integrity": "sha512-TS9MlfzXpXKt6YYomudb/KU7nQI6/xnapG6in1uZxoxDghuSMZsPb6D2fyUwNYSAp4l1iR7QtFOjkqcRYcUsfw==", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-regex/-/plugin-transform-unicode-regex-7.8.3.tgz", + "integrity": "sha512-+ufgJjYdmWfSQ+6NS9VGUR2ns8cjJjYbrbi11mZBTaWm+Fui/ncTLFF28Ei1okavY+xkojGr1eJxNsWYeA5aZw==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "^7.8.3", - "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.0" + "@babel/helper-create-regexp-features-plugin": "^7.8.3", + "@babel/helper-plugin-utils": "^7.8.3" } }, - "@babel/plugin-proposal-object-rest-spread": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-object-rest-spread/-/plugin-proposal-object-rest-spread-7.8.3.tgz", - "integrity": "sha512-8qvuPwU/xxUCt78HocNlv0mXXo0wdh9VT1R04WU8HGOfaOob26pF+9P5/lYjN/q7DHOX1bvX60hnhOvuQUJdbA==", + "@babel/preset-env": { + "version": "7.7.7", + "resolved": "https://registry.npmjs.org/@babel/preset-env/-/preset-env-7.7.7.tgz", + "integrity": "sha512-pCu0hrSSDVI7kCVUOdcMNQEbOPJ52E+LrQ14sN8uL2ALfSqePZQlKrOy+tM4uhEdYlCHi4imr8Zz2cZe9oSdIg==", + "dev": true, + "requires": { + "@babel/helper-module-imports": "^7.7.4", + "@babel/helper-plugin-utils": "^7.0.0", + "@babel/plugin-proposal-async-generator-functions": "^7.7.4", + "@babel/plugin-proposal-dynamic-import": "^7.7.4", + "@babel/plugin-proposal-json-strings": "^7.7.4", + "@babel/plugin-proposal-object-rest-spread": "^7.7.7", + "@babel/plugin-proposal-optional-catch-binding": "^7.7.4", + "@babel/plugin-proposal-unicode-property-regex": "^7.7.7", + "@babel/plugin-syntax-async-generators": "^7.7.4", + "@babel/plugin-syntax-dynamic-import": "^7.7.4", + "@babel/plugin-syntax-json-strings": "^7.7.4", + "@babel/plugin-syntax-object-rest-spread": "^7.7.4", + "@babel/plugin-syntax-optional-catch-binding": "^7.7.4", + "@babel/plugin-syntax-top-level-await": "^7.7.4", + "@babel/plugin-transform-arrow-functions": "^7.7.4", + "@babel/plugin-transform-async-to-generator": "^7.7.4", + "@babel/plugin-transform-block-scoped-functions": "^7.7.4", + "@babel/plugin-transform-block-scoping": "^7.7.4", + "@babel/plugin-transform-classes": "^7.7.4", + "@babel/plugin-transform-computed-properties": "^7.7.4", + "@babel/plugin-transform-destructuring": "^7.7.4", + "@babel/plugin-transform-dotall-regex": "^7.7.7", + "@babel/plugin-transform-duplicate-keys": "^7.7.4", + "@babel/plugin-transform-exponentiation-operator": "^7.7.4", + "@babel/plugin-transform-for-of": "^7.7.4", + "@babel/plugin-transform-function-name": "^7.7.4", + "@babel/plugin-transform-literals": "^7.7.4", + "@babel/plugin-transform-member-expression-literals": "^7.7.4", + "@babel/plugin-transform-modules-amd": "^7.7.5", + "@babel/plugin-transform-modules-commonjs": "^7.7.5", + "@babel/plugin-transform-modules-systemjs": "^7.7.4", + "@babel/plugin-transform-modules-umd": "^7.7.4", + "@babel/plugin-transform-named-capturing-groups-regex": "^7.7.4", + "@babel/plugin-transform-new-target": "^7.7.4", + "@babel/plugin-transform-object-super": "^7.7.4", + "@babel/plugin-transform-parameters": "^7.7.7", + "@babel/plugin-transform-property-literals": "^7.7.4", + "@babel/plugin-transform-regenerator": "^7.7.5", + "@babel/plugin-transform-reserved-words": "^7.7.4", + "@babel/plugin-transform-shorthand-properties": "^7.7.4", + "@babel/plugin-transform-spread": "^7.7.4", + "@babel/plugin-transform-sticky-regex": "^7.7.4", + "@babel/plugin-transform-template-literals": "^7.7.4", + "@babel/plugin-transform-typeof-symbol": "^7.7.4", + "@babel/plugin-transform-unicode-regex": "^7.7.4", + "@babel/types": "^7.7.4", + "browserslist": "^4.6.0", + "core-js-compat": "^3.6.0", + "invariant": "^2.2.2", + "js-levenshtein": "^1.1.3", + "semver": "^5.5.0" + }, + "dependencies": { + "semver": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", + "dev": true + } + } + }, + "@babel/runtime": { + "version": "7.8.7", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.8.7.tgz", + "integrity": "sha512-+AATMUFppJDw6aiR5NVPHqIQBlV/Pj8wY/EZH+lmvRdUo9xBaz/rF3alAwFJQavvKfeOlPE7oaaDHVbcySbCsg==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "^7.8.3", - "@babel/plugin-syntax-object-rest-spread": "^7.8.0" + "regenerator-runtime": "^0.13.4" + }, + "dependencies": { + "regenerator-runtime": { + "version": "0.13.5", + "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.5.tgz", + "integrity": "sha512-ZS5w8CpKFinUzOwW3c83oPeVXoNsrLsaCoLtJvAClH135j/R77RuymhiSErhm2lKcwSCIpmvIWSbDkIfAqKQlA==", + "dev": true + } } }, - "@babel/plugin-proposal-optional-catch-binding": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-optional-catch-binding/-/plugin-proposal-optional-catch-binding-7.8.3.tgz", - "integrity": "sha512-0gkX7J7E+AtAw9fcwlVQj8peP61qhdg/89D5swOkjYbkboA2CVckn3kiyum1DE0wskGb7KJJxBdyEBApDLLVdw==", + "@babel/template": { + "version": "7.8.6", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.8.6.tgz", + "integrity": "sha512-zbMsPMy/v0PWFZEhQJ66bqjhH+z0JgMoBWuikXybgG3Gkd/3t5oQ1Rw2WQhnSrsOmsKXnZOx15tkC4qON/+JPg==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "^7.8.3", - "@babel/plugin-syntax-optional-catch-binding": "^7.8.0" + "@babel/code-frame": "^7.8.3", + "@babel/parser": "^7.8.6", + "@babel/types": "^7.8.6" } }, - "@babel/plugin-proposal-optional-chaining": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-optional-chaining/-/plugin-proposal-optional-chaining-7.8.3.tgz", - "integrity": "sha512-QIoIR9abkVn+seDE3OjA08jWcs3eZ9+wJCKSRgo3WdEU2csFYgdScb+8qHB3+WXsGJD55u+5hWCISI7ejXS+kg==", + "@babel/traverse": { + "version": "7.8.6", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.8.6.tgz", + "integrity": "sha512-2B8l0db/DPi8iinITKuo7cbPznLCEk0kCxDoB9/N6gGNg/gxOXiR/IcymAFPiBwk5w6TtQ27w4wpElgp9btR9A==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "^7.8.3", - "@babel/plugin-syntax-optional-chaining": "^7.8.0" + "@babel/code-frame": "^7.8.3", + "@babel/generator": "^7.8.6", + "@babel/helper-function-name": "^7.8.3", + "@babel/helper-split-export-declaration": "^7.8.3", + "@babel/parser": "^7.8.6", + "@babel/types": "^7.8.6", + "debug": "^4.1.0", + "globals": "^11.1.0", + "lodash": "^4.17.13" } }, - "@babel/plugin-proposal-unicode-property-regex": { - "version": "7.8.8", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-unicode-property-regex/-/plugin-proposal-unicode-property-regex-7.8.8.tgz", - "integrity": "sha512-EVhjVsMpbhLw9ZfHWSx2iy13Q8Z/eg8e8ccVWt23sWQK5l1UdkoLJPN5w69UA4uITGBnEZD2JOe4QOHycYKv8A==", + "@babel/types": { + "version": "7.8.7", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.8.7.tgz", + "integrity": "sha512-k2TreEHxFA4CjGkL+GYjRyx35W0Mr7DP5+9q6WMkyKXB+904bYmG40syjMFV0oLlhhFCwWl0vA0DyzTDkwAiJw==", "dev": true, "requires": { - "@babel/helper-create-regexp-features-plugin": "^7.8.8", - "@babel/helper-plugin-utils": "^7.8.3" + "esutils": "^2.0.2", + "lodash": "^4.17.13", + "to-fast-properties": "^2.0.0" } }, - "@babel/plugin-syntax-async-generators": { - "version": "7.8.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-async-generators/-/plugin-syntax-async-generators-7.8.4.tgz", - "integrity": "sha512-tycmZxkGfZaxhMRbXlPXuVFpdWlXpir2W4AMhSJgRKzk/eDlIXOhb2LHWoLpDF7TEHylV5zNhykX6KAgHJmTNw==", + "@istanbuljs/schema": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/@istanbuljs/schema/-/schema-0.1.2.tgz", + "integrity": "sha512-tsAQNx32a8CoFhjhijUIhI4kccIAgmGhy8LZMZgGfmXcpMbPRUqn5LWmgRttILi6yeGmBJd2xsPkFMs0PzgPCw==", + "dev": true + }, + "@ngtools/webpack": { + "version": "9.0.7", + "resolved": "https://registry.npmjs.org/@ngtools/webpack/-/webpack-9.0.7.tgz", + "integrity": "sha512-MvoMaErkjESefoIrbt8F2RpKDr9KavwvH4v3hwSAKooVNFdFKNsjJ7m3gCQehumEfsYFq2mrEK2sTW4/CpFlMQ==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "^7.8.0" + "@angular-devkit/core": "9.0.7", + "enhanced-resolve": "4.1.1", + "rxjs": "6.5.3", + "webpack-sources": "1.4.3" + }, + "dependencies": { + "rxjs": { + "version": "6.5.3", + "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.5.3.tgz", + "integrity": "sha512-wuYsAYYFdWTAnAaPoKGNhfpWwKZbJW+HgAJ+mImp+Epl7BG8oNWBCTyRM8gba9k4lk8BgWdoYm21Mo/RYhhbgA==", + "dev": true, + "requires": { + "tslib": "^1.9.0" + } + } } }, - "@babel/plugin-syntax-dynamic-import": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-dynamic-import/-/plugin-syntax-dynamic-import-7.8.3.tgz", - "integrity": "sha512-5gdGbFon+PszYzqs83S3E5mpi7/y/8M9eC90MRTZfduQOYW76ig6SOSPNe41IG5LoP3FGBn2N0RjVDSQiS94kQ==", + "@schematics/angular": { + "version": "9.0.7", + "resolved": "https://registry.npmjs.org/@schematics/angular/-/angular-9.0.7.tgz", + "integrity": "sha512-3UCeexYx/YVo3kboyPZ8KgqBTduMA18AAm3s2yrC0qj41fBFVVZAZLa74uouTf4RYVgy9kR7J3uv6VLxrJPOnQ==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "^7.8.0" + "@angular-devkit/core": "9.0.7", + "@angular-devkit/schematics": "9.0.7" } }, - "@babel/plugin-syntax-json-strings": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-json-strings/-/plugin-syntax-json-strings-7.8.3.tgz", - "integrity": "sha512-lY6kdGpWHvjoe2vk4WrAapEuBR69EMxZl+RoGRhrFGNYVK8mOPAW8VfbT/ZgrFbXlDNiiaxQnAtgVCZ6jv30EA==", + "@schematics/update": { + "version": "0.900.7", + "resolved": "https://registry.npmjs.org/@schematics/update/-/update-0.900.7.tgz", + "integrity": "sha512-e9tX2DGNYfj/k9mVICpQt2bWIYyD92dlsip7LzPeZGt+R9zCp5w19uBLa8Z00OgEGzFR1krhRvkQE5OxkkAnVw==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "^7.8.0" + "@angular-devkit/core": "9.0.7", + "@angular-devkit/schematics": "9.0.7", + "@yarnpkg/lockfile": "1.1.0", + "ini": "1.3.5", + "npm-package-arg": "^7.0.0", + "pacote": "9.5.8", + "rxjs": "6.5.3", + "semver": "6.3.0", + "semver-intersect": "1.4.0" + }, + "dependencies": { + "npm-package-arg": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/npm-package-arg/-/npm-package-arg-7.0.0.tgz", + "integrity": "sha512-xXxr8y5U0kl8dVkz2oK7yZjPBvqM2fwaO5l3Yg13p03v8+E3qQcD0JNhHzjL1vyGgxcKkD0cco+NLR72iuPk3g==", + "dev": true, + "requires": { + "hosted-git-info": "^3.0.2", + "osenv": "^0.1.5", + "semver": "^5.6.0", + "validate-npm-package-name": "^3.0.0" + }, + "dependencies": { + "semver": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", + "dev": true + } + } + }, + "rxjs": { + "version": "6.5.3", + "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.5.3.tgz", + "integrity": "sha512-wuYsAYYFdWTAnAaPoKGNhfpWwKZbJW+HgAJ+mImp+Epl7BG8oNWBCTyRM8gba9k4lk8BgWdoYm21Mo/RYhhbgA==", + "dev": true, + "requires": { + "tslib": "^1.9.0" + } + } } }, - "@babel/plugin-syntax-nullish-coalescing-operator": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-nullish-coalescing-operator/-/plugin-syntax-nullish-coalescing-operator-7.8.3.tgz", - "integrity": "sha512-aSff4zPII1u2QD7y+F8oDsz19ew4IGEJg9SVW+bqwpwtfFleiQDMdzA/R+UlWDzfnHFCxxleFT0PMIrR36XLNQ==", + "@types/estree": { + "version": "0.0.43", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-0.0.43.tgz", + "integrity": "sha512-WfOySUnBpyKXbkC9QuZguwOGhGnugDXT2f2P6X8EIis7qlnd5NI1Nr4kRi357NtguxezyizIcaFlQe0wx23XnA==", + "dev": true + }, + "@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/file-saver": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/@types/file-saver/-/file-saver-2.0.1.tgz", + "integrity": "sha512-g1QUuhYVVAamfCifK7oB7G3aIl4BbOyzDOqVyUfEr4tfBKrXfeH+M+Tg7HKCXSrbzxYdhyCP7z9WbKo0R2hBCw==" + }, + "@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": { - "@babel/helper-plugin-utils": "^7.8.0" + "@types/events": "*", + "@types/minimatch": "*", + "@types/node": "*" } }, - "@babel/plugin-syntax-object-rest-spread": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-object-rest-spread/-/plugin-syntax-object-rest-spread-7.8.3.tgz", - "integrity": "sha512-XoqMijGZb9y3y2XskN+P1wUGiVwWZ5JmoDRwx5+3GmEplNyVM2s2Dg8ILFQm8rWM48orGy5YpI5Bl8U1y7ydlA==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.8.0" - } + "@types/jasmine": { + "version": "3.5.9", + "resolved": "https://registry.npmjs.org/@types/jasmine/-/jasmine-3.5.9.tgz", + "integrity": "sha512-KNL2Fq6GRmty2j6+ZmueT/Z/dkctLNH+5DFoGHNDtcgt7yME9NZd8x2p81Yuea1Xux/qAryDd3zVLUoKpDz1TA==", + "dev": true }, - "@babel/plugin-syntax-optional-catch-binding": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-optional-catch-binding/-/plugin-syntax-optional-catch-binding-7.8.3.tgz", - "integrity": "sha512-6VPD0Pc1lpTqw0aKoeRTMiB+kWhAoT24PA+ksWSBrFtl5SIRVpZlwN3NNPQjehA2E/91FV3RjLWoVTglWcSV3Q==", + "@types/jasminewd2": { + "version": "2.0.8", + "resolved": "https://registry.npmjs.org/@types/jasminewd2/-/jasminewd2-2.0.8.tgz", + "integrity": "sha512-d9p31r7Nxk0ZH0U39PTH0hiDlJ+qNVGjlt1ucOoTUptxb2v+Y5VMnsxfwN+i3hK4yQnqBi3FMmoMFcd1JHDxdg==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "^7.8.0" + "@types/jasmine": "*" } }, - "@babel/plugin-syntax-optional-chaining": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-optional-chaining/-/plugin-syntax-optional-chaining-7.8.3.tgz", - "integrity": "sha512-KoK9ErH1MBlCPxV0VANkXW2/dw4vlbGDrFgz8bmUsBGYkFRcbRwMh6cIJubdPrkxRwuGdtCk0v/wPTKbQgBjkg==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.8.0" - } + "@types/minimatch": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/@types/minimatch/-/minimatch-3.0.3.tgz", + "integrity": "sha512-tHq6qdbT9U1IRSGf14CL0pUlULksvY9OZ+5eEgl1N7t+OA3tGvNpxJCzuKQlsNgCVwbAs670L1vcVQi8j9HjnA==", + "dev": true }, - "@babel/plugin-syntax-top-level-await": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-top-level-await/-/plugin-syntax-top-level-await-7.8.3.tgz", - "integrity": "sha512-kwj1j9lL/6Wd0hROD3b/OZZ7MSrZLqqn9RAZ5+cYYsflQ9HZBIKCUkr3+uL1MEJ1NePiUbf98jjiMQSv0NMR9g==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.8.3" - } + "@types/node": { + "version": "13.9.2", + "resolved": "https://registry.npmjs.org/@types/node/-/node-13.9.2.tgz", + "integrity": "sha512-bnoqK579sAYrQbp73wwglccjJ4sfRdKU7WNEZ5FW4K2U6Kc0/eZ5kvXG0JKsEKFB50zrFmfFt52/cvBbZa7eXg==", + "dev": true }, - "@babel/plugin-transform-arrow-functions": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.8.3.tgz", - "integrity": "sha512-0MRF+KC8EqH4dbuITCWwPSzsyO3HIWWlm30v8BbbpOrS1B++isGxPnnuq/IZvOX5J2D/p7DQalQm+/2PnlKGxg==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.8.3" - } + "@types/q": { + "version": "0.0.32", + "resolved": "https://registry.npmjs.org/@types/q/-/q-0.0.32.tgz", + "integrity": "sha1-vShOV8hPEyXacCur/IKlMoGQwMU=", + "dev": true }, - "@babel/plugin-transform-async-to-generator": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.8.3.tgz", - "integrity": "sha512-imt9tFLD9ogt56Dd5CI/6XgpukMwd/fLGSrix2httihVe7LOGVPhyhMh1BU5kDM7iHD08i8uUtmV2sWaBFlHVQ==", - "dev": true, - "requires": { - "@babel/helper-module-imports": "^7.8.3", - "@babel/helper-plugin-utils": "^7.8.3", - "@babel/helper-remap-async-to-generator": "^7.8.3" - } + "@types/selenium-webdriver": { + "version": "3.0.17", + "resolved": "https://registry.npmjs.org/@types/selenium-webdriver/-/selenium-webdriver-3.0.17.tgz", + "integrity": "sha512-tGomyEuzSC1H28y2zlW6XPCaDaXFaD6soTdb4GNdmte2qfHtrKqhy0ZFs4r/1hpazCfEZqeTSRLvSasmEx89uw==", + "dev": true }, - "@babel/plugin-transform-block-scoped-functions": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoped-functions/-/plugin-transform-block-scoped-functions-7.8.3.tgz", - "integrity": "sha512-vo4F2OewqjbB1+yaJ7k2EJFHlTP3jR634Z9Cj9itpqNjuLXvhlVxgnjsHsdRgASR8xYDrx6onw4vW5H6We0Jmg==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.8.3" - } + "@types/source-list-map": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/@types/source-list-map/-/source-list-map-0.1.2.tgz", + "integrity": "sha512-K5K+yml8LTo9bWJI/rECfIPrGgxdpeNbj+d53lwN4QjW1MCwlkhUms+gtdzigTeUyBr09+u8BwOIY3MXvHdcsA==", + "dev": true }, - "@babel/plugin-transform-block-scoping": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.8.3.tgz", - "integrity": "sha512-pGnYfm7RNRgYRi7bids5bHluENHqJhrV4bCZRwc5GamaWIIs07N4rZECcmJL6ZClwjDz1GbdMZFtPs27hTB06w==", + "@types/webpack-sources": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/@types/webpack-sources/-/webpack-sources-0.1.6.tgz", + "integrity": "sha512-FtAWR7wR5ocJ9+nP137DV81tveD/ZgB1sadnJ/axUGM3BUVfRPx8oQNMtv3JNfTeHx3VP7cXiyfR/jmtEsVHsQ==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "^7.8.3", - "lodash": "^4.17.13" + "@types/node": "*", + "@types/source-list-map": "*", + "source-map": "^0.6.1" + }, + "dependencies": { + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true + } } }, - "@babel/plugin-transform-classes": { - "version": "7.8.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-classes/-/plugin-transform-classes-7.8.6.tgz", - "integrity": "sha512-k9r8qRay/R6v5aWZkrEclEhKO6mc1CCQr2dLsVHBmOQiMpN6I2bpjX3vgnldUWeEI1GHVNByULVxZ4BdP4Hmdg==", + "@webassemblyjs/ast": { + "version": "1.8.5", + "resolved": "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.8.5.tgz", + "integrity": "sha512-aJMfngIZ65+t71C3y2nBBg5FFG0Okt9m0XEgWZ7Ywgn1oMAT8cNwx00Uv1cQyHtidq0Xn94R4TAywO+LCQ+ZAQ==", "dev": true, "requires": { - "@babel/helper-annotate-as-pure": "^7.8.3", - "@babel/helper-define-map": "^7.8.3", - "@babel/helper-function-name": "^7.8.3", - "@babel/helper-optimise-call-expression": "^7.8.3", - "@babel/helper-plugin-utils": "^7.8.3", - "@babel/helper-replace-supers": "^7.8.6", - "@babel/helper-split-export-declaration": "^7.8.3", - "globals": "^11.1.0" + "@webassemblyjs/helper-module-context": "1.8.5", + "@webassemblyjs/helper-wasm-bytecode": "1.8.5", + "@webassemblyjs/wast-parser": "1.8.5" } }, - "@babel/plugin-transform-computed-properties": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.8.3.tgz", - "integrity": "sha512-O5hiIpSyOGdrQZRQ2ccwtTVkgUDBBiCuK//4RJ6UfePllUTCENOzKxfh6ulckXKc0DixTFLCfb2HVkNA7aDpzA==", + "@webassemblyjs/floating-point-hex-parser": { + "version": "1.8.5", + "resolved": "https://registry.npmjs.org/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.8.5.tgz", + "integrity": "sha512-9p+79WHru1oqBh9ewP9zW95E3XAo+90oth7S5Re3eQnECGq59ly1Ri5tsIipKGpiStHsUYmY3zMLqtk3gTcOtQ==", + "dev": true + }, + "@webassemblyjs/helper-api-error": { + "version": "1.8.5", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-api-error/-/helper-api-error-1.8.5.tgz", + "integrity": "sha512-Za/tnzsvnqdaSPOUXHyKJ2XI7PDX64kWtURyGiJJZKVEdFOsdKUCPTNEVFZq3zJ2R0G5wc2PZ5gvdTRFgm81zA==", + "dev": true + }, + "@webassemblyjs/helper-buffer": { + "version": "1.8.5", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-buffer/-/helper-buffer-1.8.5.tgz", + "integrity": "sha512-Ri2R8nOS0U6G49Q86goFIPNgjyl6+oE1abW1pS84BuhP1Qcr5JqMwRFT3Ah3ADDDYGEgGs1iyb1DGX+kAi/c/Q==", + "dev": true + }, + "@webassemblyjs/helper-code-frame": { + "version": "1.8.5", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-code-frame/-/helper-code-frame-1.8.5.tgz", + "integrity": "sha512-VQAadSubZIhNpH46IR3yWO4kZZjMxN1opDrzePLdVKAZ+DFjkGD/rf4v1jap744uPVU6yjL/smZbRIIJTOUnKQ==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "^7.8.3" + "@webassemblyjs/wast-printer": "1.8.5" } }, - "@babel/plugin-transform-destructuring": { - "version": "7.8.8", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.8.8.tgz", - "integrity": "sha512-eRJu4Vs2rmttFCdhPUM3bV0Yo/xPSdPw6ML9KHs/bjB4bLA5HXlbvYXPOD5yASodGod+krjYx21xm1QmL8dCJQ==", + "@webassemblyjs/helper-fsm": { + "version": "1.8.5", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-fsm/-/helper-fsm-1.8.5.tgz", + "integrity": "sha512-kRuX/saORcg8se/ft6Q2UbRpZwP4y7YrWsLXPbbmtepKr22i8Z4O3V5QE9DbZK908dh5Xya4Un57SDIKwB9eow==", + "dev": true + }, + "@webassemblyjs/helper-module-context": { + "version": "1.8.5", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-module-context/-/helper-module-context-1.8.5.tgz", + "integrity": "sha512-/O1B236mN7UNEU4t9X7Pj38i4VoU8CcMHyy3l2cV/kIF4U5KoHXDVqcDuOs1ltkac90IM4vZdHc52t1x8Yfs3g==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "^7.8.3" + "@webassemblyjs/ast": "1.8.5", + "mamacro": "^0.0.3" } }, - "@babel/plugin-transform-dotall-regex": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-dotall-regex/-/plugin-transform-dotall-regex-7.8.3.tgz", - "integrity": "sha512-kLs1j9Nn4MQoBYdRXH6AeaXMbEJFaFu/v1nQkvib6QzTj8MZI5OQzqmD83/2jEM1z0DLilra5aWO5YpyC0ALIw==", + "@webassemblyjs/helper-wasm-bytecode": { + "version": "1.8.5", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.8.5.tgz", + "integrity": "sha512-Cu4YMYG3Ddl72CbmpjU/wbP6SACcOPVbHN1dI4VJNJVgFwaKf1ppeFJrwydOG3NDHxVGuCfPlLZNyEdIYlQ6QQ==", + "dev": true + }, + "@webassemblyjs/helper-wasm-section": { + "version": "1.8.5", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.8.5.tgz", + "integrity": "sha512-VV083zwR+VTrIWWtgIUpqfvVdK4ff38loRmrdDBgBT8ADXYsEZ5mPQ4Nde90N3UYatHdYoDIFb7oHzMncI02tA==", "dev": true, "requires": { - "@babel/helper-create-regexp-features-plugin": "^7.8.3", - "@babel/helper-plugin-utils": "^7.8.3" + "@webassemblyjs/ast": "1.8.5", + "@webassemblyjs/helper-buffer": "1.8.5", + "@webassemblyjs/helper-wasm-bytecode": "1.8.5", + "@webassemblyjs/wasm-gen": "1.8.5" } }, - "@babel/plugin-transform-duplicate-keys": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-duplicate-keys/-/plugin-transform-duplicate-keys-7.8.3.tgz", - "integrity": "sha512-s8dHiBUbcbSgipS4SMFuWGqCvyge5V2ZeAWzR6INTVC3Ltjig/Vw1G2Gztv0vU/hRG9X8IvKvYdoksnUfgXOEQ==", + "@webassemblyjs/ieee754": { + "version": "1.8.5", + "resolved": "https://registry.npmjs.org/@webassemblyjs/ieee754/-/ieee754-1.8.5.tgz", + "integrity": "sha512-aaCvQYrvKbY/n6wKHb/ylAJr27GglahUO89CcGXMItrOBqRarUMxWLJgxm9PJNuKULwN5n1csT9bYoMeZOGF3g==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "^7.8.3" + "@xtuc/ieee754": "^1.2.0" } }, - "@babel/plugin-transform-exponentiation-operator": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-exponentiation-operator/-/plugin-transform-exponentiation-operator-7.8.3.tgz", - "integrity": "sha512-zwIpuIymb3ACcInbksHaNcR12S++0MDLKkiqXHl3AzpgdKlFNhog+z/K0+TGW+b0w5pgTq4H6IwV/WhxbGYSjQ==", + "@webassemblyjs/leb128": { + "version": "1.8.5", + "resolved": "https://registry.npmjs.org/@webassemblyjs/leb128/-/leb128-1.8.5.tgz", + "integrity": "sha512-plYUuUwleLIziknvlP8VpTgO4kqNaH57Y3JnNa6DLpu/sGcP6hbVdfdX5aHAV716pQBKrfuU26BJK29qY37J7A==", "dev": true, "requires": { - "@babel/helper-builder-binary-assignment-operator-visitor": "^7.8.3", - "@babel/helper-plugin-utils": "^7.8.3" + "@xtuc/long": "4.2.2" } }, - "@babel/plugin-transform-for-of": { - "version": "7.8.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.8.6.tgz", - "integrity": "sha512-M0pw4/1/KI5WAxPsdcUL/w2LJ7o89YHN3yLkzNjg7Yl15GlVGgzHyCU+FMeAxevHGsLVmUqbirlUIKTafPmzdw==", + "@webassemblyjs/utf8": { + "version": "1.8.5", + "resolved": "https://registry.npmjs.org/@webassemblyjs/utf8/-/utf8-1.8.5.tgz", + "integrity": "sha512-U7zgftmQriw37tfD934UNInokz6yTmn29inT2cAetAsaU9YeVCveWEwhKL1Mg4yS7q//NGdzy79nlXh3bT8Kjw==", + "dev": true + }, + "@webassemblyjs/wasm-edit": { + "version": "1.8.5", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-edit/-/wasm-edit-1.8.5.tgz", + "integrity": "sha512-A41EMy8MWw5yvqj7MQzkDjU29K7UJq1VrX2vWLzfpRHt3ISftOXqrtojn7nlPsZ9Ijhp5NwuODuycSvfAO/26Q==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "^7.8.3" + "@webassemblyjs/ast": "1.8.5", + "@webassemblyjs/helper-buffer": "1.8.5", + "@webassemblyjs/helper-wasm-bytecode": "1.8.5", + "@webassemblyjs/helper-wasm-section": "1.8.5", + "@webassemblyjs/wasm-gen": "1.8.5", + "@webassemblyjs/wasm-opt": "1.8.5", + "@webassemblyjs/wasm-parser": "1.8.5", + "@webassemblyjs/wast-printer": "1.8.5" } }, - "@babel/plugin-transform-function-name": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-function-name/-/plugin-transform-function-name-7.8.3.tgz", - "integrity": "sha512-rO/OnDS78Eifbjn5Py9v8y0aR+aSYhDhqAwVfsTl0ERuMZyr05L1aFSCJnbv2mmsLkit/4ReeQ9N2BgLnOcPCQ==", + "@webassemblyjs/wasm-gen": { + "version": "1.8.5", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-gen/-/wasm-gen-1.8.5.tgz", + "integrity": "sha512-BCZBT0LURC0CXDzj5FXSc2FPTsxwp3nWcqXQdOZE4U7h7i8FqtFK5Egia6f9raQLpEKT1VL7zr4r3+QX6zArWg==", "dev": true, "requires": { - "@babel/helper-function-name": "^7.8.3", - "@babel/helper-plugin-utils": "^7.8.3" + "@webassemblyjs/ast": "1.8.5", + "@webassemblyjs/helper-wasm-bytecode": "1.8.5", + "@webassemblyjs/ieee754": "1.8.5", + "@webassemblyjs/leb128": "1.8.5", + "@webassemblyjs/utf8": "1.8.5" } }, - "@babel/plugin-transform-literals": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-literals/-/plugin-transform-literals-7.8.3.tgz", - "integrity": "sha512-3Tqf8JJ/qB7TeldGl+TT55+uQei9JfYaregDcEAyBZ7akutriFrt6C/wLYIer6OYhleVQvH/ntEhjE/xMmy10A==", + "@webassemblyjs/wasm-opt": { + "version": "1.8.5", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-opt/-/wasm-opt-1.8.5.tgz", + "integrity": "sha512-HKo2mO/Uh9A6ojzu7cjslGaHaUU14LdLbGEKqTR7PBKwT6LdPtLLh9fPY33rmr5wcOMrsWDbbdCHq4hQUdd37Q==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "^7.8.3" + "@webassemblyjs/ast": "1.8.5", + "@webassemblyjs/helper-buffer": "1.8.5", + "@webassemblyjs/wasm-gen": "1.8.5", + "@webassemblyjs/wasm-parser": "1.8.5" } }, - "@babel/plugin-transform-member-expression-literals": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-member-expression-literals/-/plugin-transform-member-expression-literals-7.8.3.tgz", - "integrity": "sha512-3Wk2EXhnw+rP+IDkK6BdtPKsUE5IeZ6QOGrPYvw52NwBStw9V1ZVzxgK6fSKSxqUvH9eQPR3tm3cOq79HlsKYA==", + "@webassemblyjs/wasm-parser": { + "version": "1.8.5", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-parser/-/wasm-parser-1.8.5.tgz", + "integrity": "sha512-pi0SYE9T6tfcMkthwcgCpL0cM9nRYr6/6fjgDtL6q/ZqKHdMWvxitRi5JcZ7RI4SNJJYnYNaWy5UUrHQy998lw==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "^7.8.3" + "@webassemblyjs/ast": "1.8.5", + "@webassemblyjs/helper-api-error": "1.8.5", + "@webassemblyjs/helper-wasm-bytecode": "1.8.5", + "@webassemblyjs/ieee754": "1.8.5", + "@webassemblyjs/leb128": "1.8.5", + "@webassemblyjs/utf8": "1.8.5" } }, - "@babel/plugin-transform-modules-amd": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-amd/-/plugin-transform-modules-amd-7.8.3.tgz", - "integrity": "sha512-MadJiU3rLKclzT5kBH4yxdry96odTUwuqrZM+GllFI/VhxfPz+k9MshJM+MwhfkCdxxclSbSBbUGciBngR+kEQ==", + "@webassemblyjs/wast-parser": { + "version": "1.8.5", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wast-parser/-/wast-parser-1.8.5.tgz", + "integrity": "sha512-daXC1FyKWHF1i11obK086QRlsMsY4+tIOKgBqI1lxAnkp9xe9YMcgOxm9kLe+ttjs5aWV2KKE1TWJCN57/Btsg==", "dev": true, "requires": { - "@babel/helper-module-transforms": "^7.8.3", - "@babel/helper-plugin-utils": "^7.8.3", - "babel-plugin-dynamic-import-node": "^2.3.0" + "@webassemblyjs/ast": "1.8.5", + "@webassemblyjs/floating-point-hex-parser": "1.8.5", + "@webassemblyjs/helper-api-error": "1.8.5", + "@webassemblyjs/helper-code-frame": "1.8.5", + "@webassemblyjs/helper-fsm": "1.8.5", + "@xtuc/long": "4.2.2" } }, - "@babel/plugin-transform-modules-commonjs": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.8.3.tgz", - "integrity": "sha512-JpdMEfA15HZ/1gNuB9XEDlZM1h/gF/YOH7zaZzQu2xCFRfwc01NXBMHHSTT6hRjlXJJs5x/bfODM3LiCk94Sxg==", + "@webassemblyjs/wast-printer": { + "version": "1.8.5", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wast-printer/-/wast-printer-1.8.5.tgz", + "integrity": "sha512-w0U0pD4EhlnvRyeJzBqaVSJAo9w/ce7/WPogeXLzGkO6hzhr4GnQIZ4W4uUt5b9ooAaXPtnXlj0gzsXEOUNYMg==", "dev": true, "requires": { - "@babel/helper-module-transforms": "^7.8.3", - "@babel/helper-plugin-utils": "^7.8.3", - "@babel/helper-simple-access": "^7.8.3", - "babel-plugin-dynamic-import-node": "^2.3.0" + "@webassemblyjs/ast": "1.8.5", + "@webassemblyjs/wast-parser": "1.8.5", + "@xtuc/long": "4.2.2" } }, - "@babel/plugin-transform-modules-systemjs": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.8.3.tgz", - "integrity": "sha512-8cESMCJjmArMYqa9AO5YuMEkE4ds28tMpZcGZB/jl3n0ZzlsxOAi3mC+SKypTfT8gjMupCnd3YiXCkMjj2jfOg==", + "@xtuc/ieee754": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@xtuc/ieee754/-/ieee754-1.2.0.tgz", + "integrity": "sha512-DX8nKgqcGwsc0eJSqYt5lwP4DH5FlHnmuWWBRy7X0NcaGR0ZtuyeESgMwTYVEtxmsNGY+qit4QYT/MIYTOTPeA==", + "dev": true + }, + "@xtuc/long": { + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/@xtuc/long/-/long-4.2.2.tgz", + "integrity": "sha512-NuHqBY1PB/D8xU6s/thBgOAiAP7HOYDQ32+BFZILJ8ivkUkAHQnWfn6WhL79Owj1qmUnoN/YPhktdIoucipkAQ==", + "dev": true + }, + "@yarnpkg/lockfile": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@yarnpkg/lockfile/-/lockfile-1.1.0.tgz", + "integrity": "sha512-GpSwvyXOcOOlV70vbnzjj4fW5xW/FdUF6nQEt1ENy7m4ZCczi1+/buVUPAqmGfqznsORNFzUMjctTIp8a9tuCQ==", + "dev": true + }, + "JSONStream": { + "version": "1.3.5", + "resolved": "https://registry.npmjs.org/JSONStream/-/JSONStream-1.3.5.tgz", + "integrity": "sha512-E+iruNOY8VV9s4JEbe1aNEm6MiszPRr/UfcHMz0TQh1BXSxHK+ASV1R6W4HpjBhSeS+54PIsAMCBmwD06LLsqQ==", "dev": true, "requires": { - "@babel/helper-hoist-variables": "^7.8.3", - "@babel/helper-module-transforms": "^7.8.3", - "@babel/helper-plugin-utils": "^7.8.3", - "babel-plugin-dynamic-import-node": "^2.3.0" + "jsonparse": "^1.2.0", + "through": ">=2.2.7 <3" } }, - "@babel/plugin-transform-modules-umd": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-umd/-/plugin-transform-modules-umd-7.8.3.tgz", - "integrity": "sha512-evhTyWhbwbI3/U6dZAnx/ePoV7H6OUG+OjiJFHmhr9FPn0VShjwC2kdxqIuQ/+1P50TMrneGzMeyMTFOjKSnAw==", + "abbrev": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.1.1.tgz", + "integrity": "sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==" + }, + "accepts": { + "version": "1.3.7", + "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.7.tgz", + "integrity": "sha512-Il80Qs2WjYlJIBNzNkK6KYqlVMTbZLXgHx2oT0pU/fjRHyEp+PEfEPY0R3WCwAGVOtauxh1hOxNgIf5bv7dQpA==", "dev": true, "requires": { - "@babel/helper-module-transforms": "^7.8.3", - "@babel/helper-plugin-utils": "^7.8.3" + "mime-types": "~2.1.24", + "negotiator": "0.6.2" } }, - "@babel/plugin-transform-named-capturing-groups-regex": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-named-capturing-groups-regex/-/plugin-transform-named-capturing-groups-regex-7.8.3.tgz", - "integrity": "sha512-f+tF/8UVPU86TrCb06JoPWIdDpTNSGGcAtaD9mLP0aYGA0OS0j7j7DHJR0GTFrUZPUU6loZhbsVZgTh0N+Qdnw==", + "acorn": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.1.1.tgz", + "integrity": "sha512-add7dgA5ppRPxCFJoAGfMDi7PIBXq1RtGo7BhbLaxwrXPOmw8gq48Y9ozT01hUKy9byMjlR20EJhu5zlkErEkg==", + "dev": true + }, + "adm-zip": { + "version": "0.4.14", + "resolved": "https://registry.npmjs.org/adm-zip/-/adm-zip-0.4.14.tgz", + "integrity": "sha512-/9aQCnQHF+0IiCl0qhXoK7qs//SwYE7zX8lsr/DNk1BRAHYxeLZPL4pguwK29gUEqasYQjqPtEpDRSWEkdHn9g==", + "dev": true + }, + "after": { + "version": "0.8.2", + "resolved": "https://registry.npmjs.org/after/-/after-0.8.2.tgz", + "integrity": "sha1-/ts5T58OAqqXaOcCvaI7UF+ufh8=", + "dev": true + }, + "agent-base": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-4.3.0.tgz", + "integrity": "sha512-salcGninV0nPrwpGNn4VTXBb1SOuXQBiqbrNXoeizJsHrsL6ERFM2Ne3JUSBWRE6aeNJI2ROP/WEEIDUiDe3cg==", "dev": true, "requires": { - "@babel/helper-create-regexp-features-plugin": "^7.8.3" + "es6-promisify": "^5.0.0" } }, - "@babel/plugin-transform-new-target": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-new-target/-/plugin-transform-new-target-7.8.3.tgz", - "integrity": "sha512-QuSGysibQpyxexRyui2vca+Cmbljo8bcRckgzYV4kRIsHpVeyeC3JDO63pY+xFZ6bWOBn7pfKZTqV4o/ix9sFw==", + "agentkeepalive": { + "version": "3.5.2", + "resolved": "https://registry.npmjs.org/agentkeepalive/-/agentkeepalive-3.5.2.tgz", + "integrity": "sha512-e0L/HNe6qkQ7H19kTlRRqUibEAwDK5AFk6y3PtMsuut2VAH6+Q4xZml1tNDJD7kSAyqmbG/K08K5WEJYtUrSlQ==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "^7.8.3" + "humanize-ms": "^1.2.1" } }, - "@babel/plugin-transform-object-super": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-object-super/-/plugin-transform-object-super-7.8.3.tgz", - "integrity": "sha512-57FXk+gItG/GejofIyLIgBKTas4+pEU47IXKDBWFTxdPd7F80H8zybyAY7UoblVfBhBGs2EKM+bJUu2+iUYPDQ==", + "aggregate-error": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/aggregate-error/-/aggregate-error-3.0.1.tgz", + "integrity": "sha512-quoaXsZ9/BLNae5yiNoUz+Nhkwz83GhWwtYFglcjEQB2NDHCIpApbqXxIFnm4Pq/Nvhrsq5sYJFyohrrxnTGAA==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "^7.8.3", - "@babel/helper-replace-supers": "^7.8.3" + "clean-stack": "^2.0.0", + "indent-string": "^4.0.0" } }, - "@babel/plugin-transform-parameters": { - "version": "7.8.8", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.8.8.tgz", - "integrity": "sha512-hC4Ld/Ulpf1psQciWWwdnUspQoQco2bMzSrwU6TmzRlvoYQe4rQFy9vnCZDTlVeCQj0JPfL+1RX0V8hCJvkgBA==", - "dev": true, + "ajv": { + "version": "6.10.2", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.10.2.tgz", + "integrity": "sha512-TXtUUEYHuaTEbLZWIKUr5pmBuhDLy+8KYtPYdcV8qC+pOZL+NKqYwvWSRrVXHn+ZmRRAu8vJTAznH7Oag6RVRw==", "requires": { - "@babel/helper-call-delegate": "^7.8.7", - "@babel/helper-get-function-arity": "^7.8.3", - "@babel/helper-plugin-utils": "^7.8.3" + "fast-deep-equal": "^2.0.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" } }, - "@babel/plugin-transform-property-literals": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-property-literals/-/plugin-transform-property-literals-7.8.3.tgz", - "integrity": "sha512-uGiiXAZMqEoQhRWMK17VospMZh5sXWg+dlh2soffpkAl96KAm+WZuJfa6lcELotSRmooLqg0MWdH6UUq85nmmg==", + "ajv-errors": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/ajv-errors/-/ajv-errors-1.0.1.tgz", + "integrity": "sha512-DCRfO/4nQ+89p/RK43i8Ezd41EqdGIU4ld7nGF8OQ14oc/we5rEntLCUa7+jrn3nn83BosfwZA0wb4pon2o8iQ==", + "dev": true + }, + "ajv-keywords": { + "version": "3.4.1", + "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.4.1.tgz", + "integrity": "sha512-RO1ibKvd27e6FEShVFfPALuHI3WjSVNeK5FIsmme/LYRNxjKuNj+Dt7bucLa6NdSv3JcVTyMlm9kGR84z1XpaQ==" + }, + "alphanum-sort": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/alphanum-sort/-/alphanum-sort-1.0.2.tgz", + "integrity": "sha1-l6ERlkmyEa0zaR2fn0hqjsn74KM=", + "dev": true + }, + "amdefine": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/amdefine/-/amdefine-1.0.1.tgz", + "integrity": "sha1-SlKCrBZHKek2Gbz9OtFR+BfOkfU=" + }, + "ansi-colors": { + "version": "3.2.4", + "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-3.2.4.tgz", + "integrity": "sha512-hHUXGagefjN2iRrID63xckIvotOXOojhQKWIPUZ4mNUZ9nLZW+7FMNoE1lOkEhNWYsx/7ysGIuJYCiMAA9FnrA==", + "dev": true + }, + "ansi-escapes": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.1.tgz", + "integrity": "sha512-JWF7ocqNrp8u9oqpgV+wH5ftbt+cfvv+PTjOvKLT3AdYly/LmORARfEVT1iyjwN+4MqE5UmVKoAdIBqeoCHgLA==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "^7.8.3" + "type-fest": "^0.11.0" } }, - "@babel/plugin-transform-regenerator": { - "version": "7.8.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.8.7.tgz", - "integrity": "sha512-TIg+gAl4Z0a3WmD3mbYSk+J9ZUH6n/Yc57rtKRnlA/7rcCvpekHXe0CMZHP1gYp7/KLe9GHTuIba0vXmls6drA==", + "ansi-html": { + "version": "0.0.7", + "resolved": "https://registry.npmjs.org/ansi-html/-/ansi-html-0.0.7.tgz", + "integrity": "sha1-gTWEAhliqenm/QOflA0S9WynhZ4=", + "dev": true + }, + "ansi-regex": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", + "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=" + }, + "ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", "dev": true, "requires": { - "regenerator-transform": "^0.14.2" + "color-convert": "^1.9.0" } }, - "@babel/plugin-transform-reserved-words": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-reserved-words/-/plugin-transform-reserved-words-7.8.3.tgz", - "integrity": "sha512-mwMxcycN3omKFDjDQUl+8zyMsBfjRFr0Zn/64I41pmjv4NJuqcYlEtezwYtw9TFd9WR1vN5kiM+O0gMZzO6L0A==", + "anymatch": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.1.tgz", + "integrity": "sha512-mM8522psRCqzV+6LhomX5wgp25YVibjh8Wj23I5RPkPppSVSjyKD2A2mBJmWGa+KN7f2D6LNh9jkBCeyLktzjg==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "^7.8.3" + "normalize-path": "^3.0.0", + "picomatch": "^2.0.4" } }, - "@babel/plugin-transform-shorthand-properties": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-shorthand-properties/-/plugin-transform-shorthand-properties-7.8.3.tgz", - "integrity": "sha512-I9DI6Odg0JJwxCHzbzW08ggMdCezoWcuQRz3ptdudgwaHxTjxw5HgdFJmZIkIMlRymL6YiZcped4TTCB0JcC8w==", + "app-root-path": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/app-root-path/-/app-root-path-2.2.1.tgz", + "integrity": "sha512-91IFKeKk7FjfmezPKkwtaRvSpnUc4gDwPAjA1YZ9Gn0q0PPeW+vbeUsZuyDwjI7+QTHhcLen2v25fi/AmhvbJA==", + "dev": true + }, + "append-transform": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/append-transform/-/append-transform-1.0.0.tgz", + "integrity": "sha512-P009oYkeHyU742iSZJzZZywj4QRJdnTWffaKuJQLablCZ1uz6/cW4yaRgcDaoQ+uwOxxnt0gRUcwfsNP2ri0gw==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "^7.8.3" + "default-require-extensions": "^2.0.0" } }, - "@babel/plugin-transform-spread": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-spread/-/plugin-transform-spread-7.8.3.tgz", - "integrity": "sha512-CkuTU9mbmAoFOI1tklFWYYbzX5qCIZVXPVy0jpXgGwkplCndQAa58s2jr66fTeQnA64bDox0HL4U56CFYoyC7g==", - "dev": true, + "aproba": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/aproba/-/aproba-1.2.0.tgz", + "integrity": "sha512-Y9J6ZjXtoYh8RnXVCMOU/ttDmk1aBjunq9vO0ta5x85WDQiQfUF9sIPBITdbiiIVcBo03Hi3jMxigBtsddlXRw==" + }, + "are-we-there-yet": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/are-we-there-yet/-/are-we-there-yet-1.1.5.tgz", + "integrity": "sha512-5hYdAkZlcG8tOLujVDTgCT+uPX0VnpAH28gWsLfzpXYm7wP6mp5Q/gYyR7YQ0cKVJcXJnl3j2kpBan13PtQf6w==", "requires": { - "@babel/helper-plugin-utils": "^7.8.3" + "delegates": "^1.0.0", + "readable-stream": "^2.0.6" } }, - "@babel/plugin-transform-sticky-regex": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-sticky-regex/-/plugin-transform-sticky-regex-7.8.3.tgz", - "integrity": "sha512-9Spq0vGCD5Bb4Z/ZXXSK5wbbLFMG085qd2vhL1JYu1WcQ5bXqZBAYRzU1d+p79GcHs2szYv5pVQCX13QgldaWw==", + "arg": { + "version": "4.1.3", + "resolved": "https://registry.npmjs.org/arg/-/arg-4.1.3.tgz", + "integrity": "sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==", + "dev": true + }, + "argparse": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", + "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "^7.8.3", - "@babel/helper-regex": "^7.8.3" + "sprintf-js": "~1.0.2" } }, - "@babel/plugin-transform-template-literals": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-template-literals/-/plugin-transform-template-literals-7.8.3.tgz", - "integrity": "sha512-820QBtykIQOLFT8NZOcTRJ1UNuztIELe4p9DCgvj4NK+PwluSJ49we7s9FB1HIGNIYT7wFUJ0ar2QpCDj0escQ==", + "aria-query": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/aria-query/-/aria-query-3.0.0.tgz", + "integrity": "sha1-ZbP8wcoRVajJrmTW7uKX8V1RM8w=", "dev": true, "requires": { - "@babel/helper-annotate-as-pure": "^7.8.3", - "@babel/helper-plugin-utils": "^7.8.3" + "ast-types-flow": "0.0.7", + "commander": "^2.11.0" } }, - "@babel/plugin-transform-typeof-symbol": { - "version": "7.8.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-typeof-symbol/-/plugin-transform-typeof-symbol-7.8.4.tgz", - "integrity": "sha512-2QKyfjGdvuNfHsb7qnBBlKclbD4CfshH2KvDabiijLMGXPHJXGxtDzwIF7bQP+T0ysw8fYTtxPafgfs/c1Lrqg==", + "arr-diff": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-4.0.0.tgz", + "integrity": "sha1-1kYQdP6/7HHn4VI1dhoyml3HxSA=", + "dev": true + }, + "arr-flatten": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/arr-flatten/-/arr-flatten-1.1.0.tgz", + "integrity": "sha512-L3hKV5R/p5o81R7O02IGnwpDmkp6E982XhtbuwSe3O4qOtMMMtodicASA1Cny2U+aCXcNpml+m4dPsvsJ3jatg==", + "dev": true + }, + "arr-union": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/arr-union/-/arr-union-3.1.0.tgz", + "integrity": "sha1-45sJrqne+Gao8gbiiK9jkZuuOcQ=", + "dev": true + }, + "array-find-index": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/array-find-index/-/array-find-index-1.0.2.tgz", + "integrity": "sha1-3wEKoSh+Fku9pvlyOwqWoexBh6E=" + }, + "array-flatten": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-2.1.2.tgz", + "integrity": "sha512-hNfzcOV8W4NdualtqBFPyVO+54DSJuZGY9qT4pRroB6S9e3iiido2ISIC5h9R2sPJ8H3FHCIiEnsv1lPXO3KtQ==", + "dev": true + }, + "array-union": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/array-union/-/array-union-1.0.2.tgz", + "integrity": "sha1-mjRBDk9OPaI96jdb5b5w8kd47Dk=", "dev": true, "requires": { - "@babel/helper-plugin-utils": "^7.8.3" + "array-uniq": "^1.0.1" } }, - "@babel/plugin-transform-unicode-regex": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-regex/-/plugin-transform-unicode-regex-7.8.3.tgz", - "integrity": "sha512-+ufgJjYdmWfSQ+6NS9VGUR2ns8cjJjYbrbi11mZBTaWm+Fui/ncTLFF28Ei1okavY+xkojGr1eJxNsWYeA5aZw==", - "dev": true, + "array-uniq": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/array-uniq/-/array-uniq-1.0.3.tgz", + "integrity": "sha1-r2rId6Jcx/dOBYiUdThY39sk/bY=", + "dev": true + }, + "array-unique": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.3.2.tgz", + "integrity": "sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg=", + "dev": true + }, + "arraybuffer.slice": { + "version": "0.0.7", + "resolved": "https://registry.npmjs.org/arraybuffer.slice/-/arraybuffer.slice-0.0.7.tgz", + "integrity": "sha512-wGUIVQXuehL5TCqQun8OW81jGzAWycqzFF8lFp+GOM5BXLYj3bKNsYC4daB7n6XjCqxQA/qgTJ+8ANR3acjrog==", + "dev": true + }, + "arrify": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/arrify/-/arrify-1.0.1.tgz", + "integrity": "sha1-iYUI2iIm84DfkEcoRWhJwVAaSw0=", + "dev": true + }, + "asap": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/asap/-/asap-2.0.6.tgz", + "integrity": "sha1-5QNHYR1+aQlDIIu9r+vLwvuGbUY=", + "dev": true + }, + "asn1": { + "version": "0.2.4", + "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.4.tgz", + "integrity": "sha512-jxwzQpLQjSmWXgwaCZE9Nz+glAG01yF1QnWgbhGwHI5A6FRIEY6IVqtHhIepHqI7/kyEyQEagBC5mBEFlIYvdg==", "requires": { - "@babel/helper-create-regexp-features-plugin": "^7.8.3", - "@babel/helper-plugin-utils": "^7.8.3" + "safer-buffer": "~2.1.0" } }, - "@babel/preset-env": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/preset-env/-/preset-env-7.8.3.tgz", - "integrity": "sha512-Rs4RPL2KjSLSE2mWAx5/iCH+GC1ikKdxPrhnRS6PfFVaiZeom22VFKN4X8ZthyN61kAaR05tfXTbCvatl9WIQg==", + "asn1.js": { + "version": "4.10.1", + "resolved": "https://registry.npmjs.org/asn1.js/-/asn1.js-4.10.1.tgz", + "integrity": "sha512-p32cOF5q0Zqs9uBiONKYLm6BClCoBCM5O9JfeUSlnQLBTxYdTK+pW+nXflm8UkKd2UYlEbYz5qEi0JuZR9ckSw==", "dev": true, "requires": { - "@babel/compat-data": "^7.8.0", - "@babel/helper-compilation-targets": "^7.8.3", - "@babel/helper-module-imports": "^7.8.3", - "@babel/helper-plugin-utils": "^7.8.3", - "@babel/plugin-proposal-async-generator-functions": "^7.8.3", - "@babel/plugin-proposal-dynamic-import": "^7.8.3", - "@babel/plugin-proposal-json-strings": "^7.8.3", - "@babel/plugin-proposal-nullish-coalescing-operator": "^7.8.3", - "@babel/plugin-proposal-object-rest-spread": "^7.8.3", - "@babel/plugin-proposal-optional-catch-binding": "^7.8.3", - "@babel/plugin-proposal-optional-chaining": "^7.8.3", - "@babel/plugin-proposal-unicode-property-regex": "^7.8.3", - "@babel/plugin-syntax-async-generators": "^7.8.0", - "@babel/plugin-syntax-dynamic-import": "^7.8.0", - "@babel/plugin-syntax-json-strings": "^7.8.0", - "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.0", - "@babel/plugin-syntax-object-rest-spread": "^7.8.0", - "@babel/plugin-syntax-optional-catch-binding": "^7.8.0", - "@babel/plugin-syntax-optional-chaining": "^7.8.0", - "@babel/plugin-syntax-top-level-await": "^7.8.3", - "@babel/plugin-transform-arrow-functions": "^7.8.3", - "@babel/plugin-transform-async-to-generator": "^7.8.3", - "@babel/plugin-transform-block-scoped-functions": "^7.8.3", - "@babel/plugin-transform-block-scoping": "^7.8.3", - "@babel/plugin-transform-classes": "^7.8.3", - "@babel/plugin-transform-computed-properties": "^7.8.3", - "@babel/plugin-transform-destructuring": "^7.8.3", - "@babel/plugin-transform-dotall-regex": "^7.8.3", - "@babel/plugin-transform-duplicate-keys": "^7.8.3", - "@babel/plugin-transform-exponentiation-operator": "^7.8.3", - "@babel/plugin-transform-for-of": "^7.8.3", - "@babel/plugin-transform-function-name": "^7.8.3", - "@babel/plugin-transform-literals": "^7.8.3", - "@babel/plugin-transform-member-expression-literals": "^7.8.3", - "@babel/plugin-transform-modules-amd": "^7.8.3", - "@babel/plugin-transform-modules-commonjs": "^7.8.3", - "@babel/plugin-transform-modules-systemjs": "^7.8.3", - "@babel/plugin-transform-modules-umd": "^7.8.3", - "@babel/plugin-transform-named-capturing-groups-regex": "^7.8.3", - "@babel/plugin-transform-new-target": "^7.8.3", - "@babel/plugin-transform-object-super": "^7.8.3", - "@babel/plugin-transform-parameters": "^7.8.3", - "@babel/plugin-transform-property-literals": "^7.8.3", - "@babel/plugin-transform-regenerator": "^7.8.3", - "@babel/plugin-transform-reserved-words": "^7.8.3", - "@babel/plugin-transform-shorthand-properties": "^7.8.3", - "@babel/plugin-transform-spread": "^7.8.3", - "@babel/plugin-transform-sticky-regex": "^7.8.3", - "@babel/plugin-transform-template-literals": "^7.8.3", - "@babel/plugin-transform-typeof-symbol": "^7.8.3", - "@babel/plugin-transform-unicode-regex": "^7.8.3", - "@babel/types": "^7.8.3", - "browserslist": "^4.8.2", - "core-js-compat": "^3.6.2", - "invariant": "^2.2.2", - "levenary": "^1.1.0", - "semver": "^5.5.0" - }, - "dependencies": { - "semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", - "dev": true - } + "bn.js": "^4.0.0", + "inherits": "^2.0.1", + "minimalistic-assert": "^1.0.0" } }, - "@babel/runtime": { - "version": "7.8.7", - "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.8.7.tgz", - "integrity": "sha512-+AATMUFppJDw6aiR5NVPHqIQBlV/Pj8wY/EZH+lmvRdUo9xBaz/rF3alAwFJQavvKfeOlPE7oaaDHVbcySbCsg==", + "assert": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/assert/-/assert-1.5.0.tgz", + "integrity": "sha512-EDsgawzwoun2CZkCgtxJbv392v4nbk9XDD06zI+kQYoBM/3RBWLlEyJARDOmhAAosBjWACEkKL6S+lIZtcAubA==", "dev": true, "requires": { - "regenerator-runtime": "^0.13.4" + "object-assign": "^4.1.1", + "util": "0.10.3" }, "dependencies": { - "regenerator-runtime": { - "version": "0.13.5", - "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.5.tgz", - "integrity": "sha512-ZS5w8CpKFinUzOwW3c83oPeVXoNsrLsaCoLtJvAClH135j/R77RuymhiSErhm2lKcwSCIpmvIWSbDkIfAqKQlA==", + "inherits": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.1.tgz", + "integrity": "sha1-sX0I0ya0Qj5Wjv9xn5GwscvfafE=", "dev": true + }, + "util": { + "version": "0.10.3", + "resolved": "https://registry.npmjs.org/util/-/util-0.10.3.tgz", + "integrity": "sha1-evsa/lCAUkZInj23/g7TeTNqwPk=", + "dev": true, + "requires": { + "inherits": "2.0.1" + } } } }, - "@babel/template": { - "version": "7.8.6", - "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.8.6.tgz", - "integrity": "sha512-zbMsPMy/v0PWFZEhQJ66bqjhH+z0JgMoBWuikXybgG3Gkd/3t5oQ1Rw2WQhnSrsOmsKXnZOx15tkC4qON/+JPg==", + "assert-plus": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", + "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=" + }, + "assign-symbols": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/assign-symbols/-/assign-symbols-1.0.0.tgz", + "integrity": "sha1-WWZ/QfrdTyDMvCu5a41Pf3jsA2c=", + "dev": true + }, + "ast-types-flow": { + "version": "0.0.7", + "resolved": "https://registry.npmjs.org/ast-types-flow/-/ast-types-flow-0.0.7.tgz", + "integrity": "sha1-9wtzXGvKGlycItmCw+Oef+ujva0=", + "dev": true + }, + "async": { + "version": "2.6.3", + "resolved": "https://registry.npmjs.org/async/-/async-2.6.3.tgz", + "integrity": "sha512-zflvls11DCy+dQWzTW2dzuilv8Z5X/pjfmZOWba6TNIVDm+2UDaJmXSOXlasHKfNBs8oo3M0aT50fDEWfKZjXg==", "dev": true, "requires": { - "@babel/code-frame": "^7.8.3", - "@babel/parser": "^7.8.6", - "@babel/types": "^7.8.6" + "lodash": "^4.17.14" } }, - "@babel/traverse": { - "version": "7.8.6", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.8.6.tgz", - "integrity": "sha512-2B8l0db/DPi8iinITKuo7cbPznLCEk0kCxDoB9/N6gGNg/gxOXiR/IcymAFPiBwk5w6TtQ27w4wpElgp9btR9A==", + "async-each": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/async-each/-/async-each-1.0.3.tgz", + "integrity": "sha512-z/WhQ5FPySLdvREByI2vZiTWwCnF0moMJ1hK9YQwDTHKh6I7/uSckMetoRGb5UBZPC1z0jlw+n/XCgjeH7y1AQ==", + "dev": true + }, + "async-foreach": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/async-foreach/-/async-foreach-0.1.3.tgz", + "integrity": "sha1-NhIfhFwFeBct5Bmpfb6x0W7DRUI=" + }, + "async-limiter": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/async-limiter/-/async-limiter-1.0.1.tgz", + "integrity": "sha512-csOlWGAcRFJaI6m+F2WKdnMKr4HhdhFVBk0H/QbJFMCr+uO2kwohwXQPxw/9OCxp05r5ghVBFSyioixx3gfkNQ==", + "dev": true + }, + "asynckit": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", + "integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k=" + }, + "atob": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/atob/-/atob-2.1.2.tgz", + "integrity": "sha512-Wm6ukoaOGJi/73p/cl2GvLjTI5JM1k/O14isD73YML8StrH/7/lRFgmg8nICZgD3bZZvjwCGxtMOD3wWNAu8cg==", + "dev": true + }, + "autoprefixer": { + "version": "9.7.1", + "resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-9.7.1.tgz", + "integrity": "sha512-w3b5y1PXWlhYulevrTJ0lizkQ5CyqfeU6BIRDbuhsMupstHQOeb1Ur80tcB1zxSu7AwyY/qCQ7Vvqklh31ZBFw==", "dev": true, "requires": { - "@babel/code-frame": "^7.8.3", - "@babel/generator": "^7.8.6", - "@babel/helper-function-name": "^7.8.3", - "@babel/helper-split-export-declaration": "^7.8.3", - "@babel/parser": "^7.8.6", - "@babel/types": "^7.8.6", - "debug": "^4.1.0", - "globals": "^11.1.0", - "lodash": "^4.17.13" + "browserslist": "^4.7.2", + "caniuse-lite": "^1.0.30001006", + "chalk": "^2.4.2", + "normalize-range": "^0.1.2", + "num2fraction": "^1.2.2", + "postcss": "^7.0.21", + "postcss-value-parser": "^4.0.2" } }, - "@babel/types": { - "version": "7.8.7", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.8.7.tgz", - "integrity": "sha512-k2TreEHxFA4CjGkL+GYjRyx35W0Mr7DP5+9q6WMkyKXB+904bYmG40syjMFV0oLlhhFCwWl0vA0DyzTDkwAiJw==", + "aws-sign2": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.7.0.tgz", + "integrity": "sha1-tG6JCTSpWR8tL2+G1+ap8bP+dqg=" + }, + "aws4": { + "version": "1.9.1", + "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.9.1.tgz", + "integrity": "sha512-wMHVg2EOHaMRxbzgFJ9gtjOOCrI80OHLG14rxi28XwOW8ux6IiEbRCGGGqCtdAIg4FQCbW20k9RsT4y3gJlFug==" + }, + "axobject-query": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/axobject-query/-/axobject-query-2.0.2.tgz", + "integrity": "sha512-MCeek8ZH7hKyO1rWUbKNQBbl4l2eY0ntk7OGi+q0RlafrCnfPxC06WZA+uebCfmYp4mNU9jRBP1AhGyf8+W3ww==", "dev": true, "requires": { - "esutils": "^2.0.2", - "lodash": "^4.17.13", - "to-fast-properties": "^2.0.0" + "ast-types-flow": "0.0.7" } }, - "@istanbuljs/schema": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/@istanbuljs/schema/-/schema-0.1.2.tgz", - "integrity": "sha512-tsAQNx32a8CoFhjhijUIhI4kccIAgmGhy8LZMZgGfmXcpMbPRUqn5LWmgRttILi6yeGmBJd2xsPkFMs0PzgPCw==", - "dev": true - }, - "@ngtools/webpack": { - "version": "8.3.25", - "resolved": "https://registry.npmjs.org/@ngtools/webpack/-/webpack-8.3.25.tgz", - "integrity": "sha512-yHvgxXUXlgdWijtzcRjTaUqzK+6TVK/8p7PreBR00GsLxhl4U1jQSC6yDaZUCjOaEkiczFWl4hEuC4wTU/hLdg==", + "babel-loader": { + "version": "8.0.6", + "resolved": "https://registry.npmjs.org/babel-loader/-/babel-loader-8.0.6.tgz", + "integrity": "sha512-4BmWKtBOBm13uoUwd08UwjZlaw3O9GWf456R9j+5YykFZ6LUIjIKLc0zEZf+hauxPOJs96C8k6FvYD09vWzhYw==", "dev": true, "requires": { - "@angular-devkit/core": "8.3.25", - "enhanced-resolve": "4.1.0", - "rxjs": "6.4.0", - "tree-kill": "1.2.2", - "webpack-sources": "1.4.3" + "find-cache-dir": "^2.0.0", + "loader-utils": "^1.0.2", + "mkdirp": "^0.5.1", + "pify": "^4.0.1" }, "dependencies": { - "rxjs": { - "version": "6.4.0", - "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.4.0.tgz", - "integrity": "sha512-Z9Yfa11F6B9Sg/BK9MnqnQ+aQYicPLtilXBp2yUtDt2JRCE0h26d33EnfO3ZxoNxG0T92OUucP3Ct7cpfkdFfw==", + "find-cache-dir": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/find-cache-dir/-/find-cache-dir-2.1.0.tgz", + "integrity": "sha512-Tq6PixE0w/VMFfCgbONnkiQIVol/JJL7nRMi20fqzA4NRs9AfeqMGeRdPi3wIhYkxjeBaWh2rxwapn5Tu3IqOQ==", "dev": true, "requires": { - "tslib": "^1.9.0" + "commondir": "^1.0.1", + "make-dir": "^2.0.0", + "pkg-dir": "^3.0.0" } } } }, - "@schematics/angular": { - "version": "8.3.25", - "resolved": "https://registry.npmjs.org/@schematics/angular/-/angular-8.3.25.tgz", - "integrity": "sha512-/vEPtE+fvgsWPml/MVqzmlGPBujadPPNwaTuuj5Uz1aVcKeEYzLkbN8YQOpml4vxZHCF8RDwNdGiU4SZg63Jfg==", + "babel-plugin-dynamic-import-node": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/babel-plugin-dynamic-import-node/-/babel-plugin-dynamic-import-node-2.3.0.tgz", + "integrity": "sha512-o6qFkpeQEBxcqt0XYlWzAVxNCSCZdUgcR8IRlhD/8DylxjjO4foPcvTW0GGKa/cVt3rvxZ7o5ippJ+/0nvLhlQ==", "dev": true, "requires": { - "@angular-devkit/core": "8.3.25", - "@angular-devkit/schematics": "8.3.25" + "object.assign": "^4.1.0" } }, - "@schematics/update": { - "version": "0.803.25", - "resolved": "https://registry.npmjs.org/@schematics/update/-/update-0.803.25.tgz", - "integrity": "sha512-VIlqhJsCStA3aO4llxZ7lAOvQUqppyZdrEO7f/ApIJmuofPQTkO5Hx21tnv0dyExwoqPCSIHzEu4Tmc0/TWM1A==", + "backo2": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/backo2/-/backo2-1.0.2.tgz", + "integrity": "sha1-MasayLEpNjRj41s+u2n038+6eUc=", + "dev": true + }, + "balanced-match": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", + "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=" + }, + "base": { + "version": "0.11.2", + "resolved": "https://registry.npmjs.org/base/-/base-0.11.2.tgz", + "integrity": "sha512-5T6P4xPgpp0YDFvSWwEZ4NoE3aM4QBQXDzmVbraCkFj8zHM+mba8SyqB5DbZWyR7mYHo6Y7BdQo3MoA4m0TeQg==", "dev": true, "requires": { - "@angular-devkit/core": "8.3.25", - "@angular-devkit/schematics": "8.3.25", - "@yarnpkg/lockfile": "1.1.0", - "ini": "1.3.5", - "pacote": "9.5.5", - "rxjs": "6.4.0", - "semver": "6.3.0", - "semver-intersect": "1.4.0" + "cache-base": "^1.0.1", + "class-utils": "^0.3.5", + "component-emitter": "^1.2.1", + "define-property": "^1.0.0", + "isobject": "^3.0.1", + "mixin-deep": "^1.2.0", + "pascalcase": "^0.1.1" }, "dependencies": { - "rxjs": { - "version": "6.4.0", - "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.4.0.tgz", - "integrity": "sha512-Z9Yfa11F6B9Sg/BK9MnqnQ+aQYicPLtilXBp2yUtDt2JRCE0h26d33EnfO3ZxoNxG0T92OUucP3Ct7cpfkdFfw==", + "define-property": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", + "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", "dev": true, "requires": { - "tslib": "^1.9.0" + "is-descriptor": "^1.0.0" + } + }, + "is-accessor-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", + "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", + "dev": true, + "requires": { + "kind-of": "^6.0.0" + } + }, + "is-data-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", + "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", + "dev": true, + "requires": { + "kind-of": "^6.0.0" + } + }, + "is-descriptor": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", + "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", + "dev": true, + "requires": { + "is-accessor-descriptor": "^1.0.0", + "is-data-descriptor": "^1.0.0", + "kind-of": "^6.0.2" } } } }, - "@types/events": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@types/events/-/events-3.0.0.tgz", - "integrity": "sha512-EaObqwIvayI5a8dCzhFrjKzVwKLxjoG9T6Ppd5CEo07LRKfQ8Yokw54r5+Wq7FaBQ+yXRvQAYPrHwya1/UFt9g==", + "base64-arraybuffer": { + "version": "0.1.5", + "resolved": "https://registry.npmjs.org/base64-arraybuffer/-/base64-arraybuffer-0.1.5.tgz", + "integrity": "sha1-c5JncZI7Whl0etZmqlzUv5xunOg=", "dev": true }, - "@types/file-saver": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/@types/file-saver/-/file-saver-2.0.1.tgz", - "integrity": "sha512-g1QUuhYVVAamfCifK7oB7G3aIl4BbOyzDOqVyUfEr4tfBKrXfeH+M+Tg7HKCXSrbzxYdhyCP7z9WbKo0R2hBCw==" + "base64-js": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.3.1.tgz", + "integrity": "sha512-mLQ4i2QO1ytvGWFWmcngKO//JXAQueZvwEKtjgQFM4jIK0kU+ytMfplL8j+n5mspOfjHwoAg+9yhb7BwAHm36g==", + "dev": true }, - "@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": "*" - } + "base64id": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/base64id/-/base64id-1.0.0.tgz", + "integrity": "sha1-R2iMuZu2gE8OBtPnY7HDLlfY5rY=", + "dev": true }, - "@types/jasmine": { - "version": "3.5.9", - "resolved": "https://registry.npmjs.org/@types/jasmine/-/jasmine-3.5.9.tgz", - "integrity": "sha512-KNL2Fq6GRmty2j6+ZmueT/Z/dkctLNH+5DFoGHNDtcgt7yME9NZd8x2p81Yuea1Xux/qAryDd3zVLUoKpDz1TA==", + "batch": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/batch/-/batch-0.6.1.tgz", + "integrity": "sha1-3DQxT05nkxgJP8dgJyUl+UvyXBY=", "dev": true }, - "@types/jasminewd2": { - "version": "2.0.8", - "resolved": "https://registry.npmjs.org/@types/jasminewd2/-/jasminewd2-2.0.8.tgz", - "integrity": "sha512-d9p31r7Nxk0ZH0U39PTH0hiDlJ+qNVGjlt1ucOoTUptxb2v+Y5VMnsxfwN+i3hK4yQnqBi3FMmoMFcd1JHDxdg==", + "bcrypt-pbkdf": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz", + "integrity": "sha1-pDAdOJtqQ/m2f/PKEaP2Y342Dp4=", + "requires": { + "tweetnacl": "^0.14.3" + } + }, + "better-assert": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/better-assert/-/better-assert-1.0.2.tgz", + "integrity": "sha1-QIZrnhueC1W0gYlDEeaPr/rrxSI=", "dev": true, "requires": { - "@types/jasmine": "*" + "callsite": "1.0.0" } }, - "@types/minimatch": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/@types/minimatch/-/minimatch-3.0.3.tgz", - "integrity": "sha512-tHq6qdbT9U1IRSGf14CL0pUlULksvY9OZ+5eEgl1N7t+OA3tGvNpxJCzuKQlsNgCVwbAs670L1vcVQi8j9HjnA==", - "dev": true + "big.js": { + "version": "5.2.2", + "resolved": "https://registry.npmjs.org/big.js/-/big.js-5.2.2.tgz", + "integrity": "sha512-vyL2OymJxmarO8gxMr0mhChsO9QGwhynfuu4+MHTAW6czfq9humCB7rKpUjDd9YUiDPU4mzpyupFSvOClAwbmQ==" }, - "@types/node": { - "version": "13.9.1", - "resolved": "https://registry.npmjs.org/@types/node/-/node-13.9.1.tgz", - "integrity": "sha512-E6M6N0blf/jiZx8Q3nb0vNaswQeEyn0XlupO+xN6DtJ6r6IT4nXrTry7zhIfYvFCl3/8Cu6WIysmUBKiqV0bqQ==", + "binary-extensions": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.0.0.tgz", + "integrity": "sha512-Phlt0plgpIIBOGTT/ehfFnbNlfsDEiqmzE2KRXoX1bLIlir4X/MR+zSyBEkL05ffWgnRSf/DXv+WrUAVr93/ow==", "dev": true }, - "@types/q": { - "version": "0.0.32", - "resolved": "https://registry.npmjs.org/@types/q/-/q-0.0.32.tgz", - "integrity": "sha1-vShOV8hPEyXacCur/IKlMoGQwMU=", + "blob": { + "version": "0.0.5", + "resolved": "https://registry.npmjs.org/blob/-/blob-0.0.5.tgz", + "integrity": "sha512-gaqbzQPqOoamawKg0LGVd7SzLgXS+JH61oWprSLH+P+abTczqJbhTR8CmJ2u9/bUYNmHTGJx/UEmn6doAvvuig==", "dev": true }, - "@types/selenium-webdriver": { - "version": "3.0.17", - "resolved": "https://registry.npmjs.org/@types/selenium-webdriver/-/selenium-webdriver-3.0.17.tgz", - "integrity": "sha512-tGomyEuzSC1H28y2zlW6XPCaDaXFaD6soTdb4GNdmte2qfHtrKqhy0ZFs4r/1hpazCfEZqeTSRLvSasmEx89uw==", + "block-stream": { + "version": "0.0.9", + "resolved": "https://registry.npmjs.org/block-stream/-/block-stream-0.0.9.tgz", + "integrity": "sha1-E+v+d4oDIFz+A3UUgeu0szAMEmo=", + "requires": { + "inherits": "~2.0.0" + } + }, + "blocking-proxy": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/blocking-proxy/-/blocking-proxy-1.0.1.tgz", + "integrity": "sha512-KE8NFMZr3mN2E0HcvCgRtX7DjhiIQrwle+nSVJVC/yqFb9+xznHl2ZcoBp2L9qzkI4t4cBFJ1efXF8Dwi132RA==", + "dev": true, + "requires": { + "minimist": "^1.2.0" + } + }, + "bluebird": { + "version": "3.7.2", + "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.7.2.tgz", + "integrity": "sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg==", "dev": true }, - "@types/source-list-map": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/@types/source-list-map/-/source-list-map-0.1.2.tgz", - "integrity": "sha512-K5K+yml8LTo9bWJI/rECfIPrGgxdpeNbj+d53lwN4QjW1MCwlkhUms+gtdzigTeUyBr09+u8BwOIY3MXvHdcsA==", + "bn.js": { + "version": "4.11.8", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.8.tgz", + "integrity": "sha512-ItfYfPLkWHUjckQCk8xC+LwxgK8NYcXywGigJgSwOP8Y2iyWT4f2vsZnoOXTTbo+o5yXmIUJ4gn5538SO5S3gA==", "dev": true }, - "@types/webpack-sources": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/@types/webpack-sources/-/webpack-sources-0.1.6.tgz", - "integrity": "sha512-FtAWR7wR5ocJ9+nP137DV81tveD/ZgB1sadnJ/axUGM3BUVfRPx8oQNMtv3JNfTeHx3VP7cXiyfR/jmtEsVHsQ==", + "body-parser": { + "version": "1.19.0", + "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.19.0.tgz", + "integrity": "sha512-dhEPs72UPbDnAQJ9ZKMNTP6ptJaionhP5cBb541nXPlW60Jepo9RV/a4fX4XWW9CuFNK22krhrj1+rgzifNCsw==", "dev": true, "requires": { - "@types/node": "*", - "@types/source-list-map": "*", - "source-map": "^0.6.1" + "bytes": "3.1.0", + "content-type": "~1.0.4", + "debug": "2.6.9", + "depd": "~1.1.2", + "http-errors": "1.7.2", + "iconv-lite": "0.4.24", + "on-finished": "~2.3.0", + "qs": "6.7.0", + "raw-body": "2.4.0", + "type-is": "~1.6.17" }, "dependencies": { - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "bytes": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.0.tgz", + "integrity": "sha512-zauLjrfCG+xvoyaqLoV8bLVXXNGC4JqlxFCutSDWA6fJrTo2ZuvLYTqZ7aHBLZSMOopbzwv8f+wZcVzfVTI2Dg==", + "dev": true + }, + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "requires": { + "ms": "2.0.0" + } + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", + "dev": true + }, + "qs": { + "version": "6.7.0", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.7.0.tgz", + "integrity": "sha512-VCdBRNFTX1fyE7Nb6FYoURo/SPe62QCaAyzJvUjwRaIsc+NePBEniHlvxFmmX56+HZphIGtV0XeCirBtpDrTyQ==", "dev": true } } }, - "@webassemblyjs/ast": { - "version": "1.8.5", - "resolved": "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.8.5.tgz", - "integrity": "sha512-aJMfngIZ65+t71C3y2nBBg5FFG0Okt9m0XEgWZ7Ywgn1oMAT8cNwx00Uv1cQyHtidq0Xn94R4TAywO+LCQ+ZAQ==", + "bonjour": { + "version": "3.5.0", + "resolved": "https://registry.npmjs.org/bonjour/-/bonjour-3.5.0.tgz", + "integrity": "sha1-jokKGD2O6aI5OzhExpGkK897yfU=", + "dev": true, + "requires": { + "array-flatten": "^2.1.0", + "deep-equal": "^1.0.1", + "dns-equal": "^1.0.0", + "dns-txt": "^2.0.2", + "multicast-dns": "^6.0.1", + "multicast-dns-service-types": "^1.1.0" + } + }, + "boolbase": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/boolbase/-/boolbase-1.0.0.tgz", + "integrity": "sha1-aN/1++YMUes3cl6p4+0xDcwed24=" + }, + "brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "requires": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "braces": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", + "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", "dev": true, "requires": { - "@webassemblyjs/helper-module-context": "1.8.5", - "@webassemblyjs/helper-wasm-bytecode": "1.8.5", - "@webassemblyjs/wast-parser": "1.8.5" + "fill-range": "^7.0.1" } }, - "@webassemblyjs/floating-point-hex-parser": { - "version": "1.8.5", - "resolved": "https://registry.npmjs.org/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.8.5.tgz", - "integrity": "sha512-9p+79WHru1oqBh9ewP9zW95E3XAo+90oth7S5Re3eQnECGq59ly1Ri5tsIipKGpiStHsUYmY3zMLqtk3gTcOtQ==", - "dev": true - }, - "@webassemblyjs/helper-api-error": { - "version": "1.8.5", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-api-error/-/helper-api-error-1.8.5.tgz", - "integrity": "sha512-Za/tnzsvnqdaSPOUXHyKJ2XI7PDX64kWtURyGiJJZKVEdFOsdKUCPTNEVFZq3zJ2R0G5wc2PZ5gvdTRFgm81zA==", - "dev": true - }, - "@webassemblyjs/helper-buffer": { - "version": "1.8.5", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-buffer/-/helper-buffer-1.8.5.tgz", - "integrity": "sha512-Ri2R8nOS0U6G49Q86goFIPNgjyl6+oE1abW1pS84BuhP1Qcr5JqMwRFT3Ah3ADDDYGEgGs1iyb1DGX+kAi/c/Q==", + "brorand": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/brorand/-/brorand-1.1.0.tgz", + "integrity": "sha1-EsJe/kCkXjwyPrhnWgoM5XsiNx8=", "dev": true }, - "@webassemblyjs/helper-code-frame": { - "version": "1.8.5", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-code-frame/-/helper-code-frame-1.8.5.tgz", - "integrity": "sha512-VQAadSubZIhNpH46IR3yWO4kZZjMxN1opDrzePLdVKAZ+DFjkGD/rf4v1jap744uPVU6yjL/smZbRIIJTOUnKQ==", + "browserify-aes": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/browserify-aes/-/browserify-aes-1.2.0.tgz", + "integrity": "sha512-+7CHXqGuspUn/Sl5aO7Ea0xWGAtETPXNSAjHo48JfLdPWcMng33Xe4znFvQweqc/uzk5zSOI3H52CYnjCfb5hA==", "dev": true, "requires": { - "@webassemblyjs/wast-printer": "1.8.5" + "buffer-xor": "^1.0.3", + "cipher-base": "^1.0.0", + "create-hash": "^1.1.0", + "evp_bytestokey": "^1.0.3", + "inherits": "^2.0.1", + "safe-buffer": "^5.0.1" } }, - "@webassemblyjs/helper-fsm": { - "version": "1.8.5", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-fsm/-/helper-fsm-1.8.5.tgz", - "integrity": "sha512-kRuX/saORcg8se/ft6Q2UbRpZwP4y7YrWsLXPbbmtepKr22i8Z4O3V5QE9DbZK908dh5Xya4Un57SDIKwB9eow==", - "dev": true - }, - "@webassemblyjs/helper-module-context": { - "version": "1.8.5", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-module-context/-/helper-module-context-1.8.5.tgz", - "integrity": "sha512-/O1B236mN7UNEU4t9X7Pj38i4VoU8CcMHyy3l2cV/kIF4U5KoHXDVqcDuOs1ltkac90IM4vZdHc52t1x8Yfs3g==", + "browserify-cipher": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/browserify-cipher/-/browserify-cipher-1.0.1.tgz", + "integrity": "sha512-sPhkz0ARKbf4rRQt2hTpAHqn47X3llLkUGn+xEJzLjwY8LRs2p0v7ljvI5EyoRO/mexrNunNECisZs+gw2zz1w==", "dev": true, "requires": { - "@webassemblyjs/ast": "1.8.5", - "mamacro": "^0.0.3" + "browserify-aes": "^1.0.4", + "browserify-des": "^1.0.0", + "evp_bytestokey": "^1.0.0" } }, - "@webassemblyjs/helper-wasm-bytecode": { - "version": "1.8.5", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.8.5.tgz", - "integrity": "sha512-Cu4YMYG3Ddl72CbmpjU/wbP6SACcOPVbHN1dI4VJNJVgFwaKf1ppeFJrwydOG3NDHxVGuCfPlLZNyEdIYlQ6QQ==", - "dev": true + "browserify-des": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/browserify-des/-/browserify-des-1.0.2.tgz", + "integrity": "sha512-BioO1xf3hFwz4kc6iBhI3ieDFompMhrMlnDFC4/0/vd5MokpuAc3R+LYbwTA9A5Yc9pq9UYPqffKpW2ObuwX5A==", + "dev": true, + "requires": { + "cipher-base": "^1.0.1", + "des.js": "^1.0.0", + "inherits": "^2.0.1", + "safe-buffer": "^5.1.2" + } }, - "@webassemblyjs/helper-wasm-section": { - "version": "1.8.5", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.8.5.tgz", - "integrity": "sha512-VV083zwR+VTrIWWtgIUpqfvVdK4ff38loRmrdDBgBT8ADXYsEZ5mPQ4Nde90N3UYatHdYoDIFb7oHzMncI02tA==", + "browserify-rsa": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/browserify-rsa/-/browserify-rsa-4.0.1.tgz", + "integrity": "sha1-IeCr+vbyApzy+vsTNWenAdQTVSQ=", "dev": true, "requires": { - "@webassemblyjs/ast": "1.8.5", - "@webassemblyjs/helper-buffer": "1.8.5", - "@webassemblyjs/helper-wasm-bytecode": "1.8.5", - "@webassemblyjs/wasm-gen": "1.8.5" + "bn.js": "^4.1.0", + "randombytes": "^2.0.1" } }, - "@webassemblyjs/ieee754": { - "version": "1.8.5", - "resolved": "https://registry.npmjs.org/@webassemblyjs/ieee754/-/ieee754-1.8.5.tgz", - "integrity": "sha512-aaCvQYrvKbY/n6wKHb/ylAJr27GglahUO89CcGXMItrOBqRarUMxWLJgxm9PJNuKULwN5n1csT9bYoMeZOGF3g==", + "browserify-sign": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/browserify-sign/-/browserify-sign-4.0.4.tgz", + "integrity": "sha1-qk62jl17ZYuqa/alfmMMvXqT0pg=", "dev": true, "requires": { - "@xtuc/ieee754": "^1.2.0" + "bn.js": "^4.1.1", + "browserify-rsa": "^4.0.0", + "create-hash": "^1.1.0", + "create-hmac": "^1.1.2", + "elliptic": "^6.0.0", + "inherits": "^2.0.1", + "parse-asn1": "^5.0.0" } }, - "@webassemblyjs/leb128": { - "version": "1.8.5", - "resolved": "https://registry.npmjs.org/@webassemblyjs/leb128/-/leb128-1.8.5.tgz", - "integrity": "sha512-plYUuUwleLIziknvlP8VpTgO4kqNaH57Y3JnNa6DLpu/sGcP6hbVdfdX5aHAV716pQBKrfuU26BJK29qY37J7A==", + "browserify-zlib": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/browserify-zlib/-/browserify-zlib-0.2.0.tgz", + "integrity": "sha512-Z942RysHXmJrhqk88FmKBVq/v5tqmSkDz7p54G/MGyjMnCFFnC79XWNbg+Vta8W6Wb2qtSZTSxIGkJrRpCFEiA==", "dev": true, "requires": { - "@xtuc/long": "4.2.2" + "pako": "~1.0.5" } }, - "@webassemblyjs/utf8": { - "version": "1.8.5", - "resolved": "https://registry.npmjs.org/@webassemblyjs/utf8/-/utf8-1.8.5.tgz", - "integrity": "sha512-U7zgftmQriw37tfD934UNInokz6yTmn29inT2cAetAsaU9YeVCveWEwhKL1Mg4yS7q//NGdzy79nlXh3bT8Kjw==", - "dev": true + "browserslist": { + "version": "4.10.0", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.10.0.tgz", + "integrity": "sha512-TpfK0TDgv71dzuTsEAlQiHeWQ/tiPqgNZVdv046fvNtBZrjbv2O3TsWCDU0AWGJJKCF/KsjNdLzR9hXOsh/CfA==", + "dev": true, + "requires": { + "caniuse-lite": "^1.0.30001035", + "electron-to-chromium": "^1.3.378", + "node-releases": "^1.1.52", + "pkg-up": "^3.1.0" + } }, - "@webassemblyjs/wasm-edit": { - "version": "1.8.5", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-edit/-/wasm-edit-1.8.5.tgz", - "integrity": "sha512-A41EMy8MWw5yvqj7MQzkDjU29K7UJq1VrX2vWLzfpRHt3ISftOXqrtojn7nlPsZ9Ijhp5NwuODuycSvfAO/26Q==", + "browserstack": { + "version": "1.5.3", + "resolved": "https://registry.npmjs.org/browserstack/-/browserstack-1.5.3.tgz", + "integrity": "sha512-AO+mECXsW4QcqC9bxwM29O7qWa7bJT94uBFzeb5brylIQwawuEziwq20dPYbins95GlWzOawgyDNdjYAo32EKg==", "dev": true, "requires": { - "@webassemblyjs/ast": "1.8.5", - "@webassemblyjs/helper-buffer": "1.8.5", - "@webassemblyjs/helper-wasm-bytecode": "1.8.5", - "@webassemblyjs/helper-wasm-section": "1.8.5", - "@webassemblyjs/wasm-gen": "1.8.5", - "@webassemblyjs/wasm-opt": "1.8.5", - "@webassemblyjs/wasm-parser": "1.8.5", - "@webassemblyjs/wast-printer": "1.8.5" + "https-proxy-agent": "^2.2.1" } }, - "@webassemblyjs/wasm-gen": { - "version": "1.8.5", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-gen/-/wasm-gen-1.8.5.tgz", - "integrity": "sha512-BCZBT0LURC0CXDzj5FXSc2FPTsxwp3nWcqXQdOZE4U7h7i8FqtFK5Egia6f9raQLpEKT1VL7zr4r3+QX6zArWg==", + "buffer": { + "version": "4.9.2", + "resolved": "https://registry.npmjs.org/buffer/-/buffer-4.9.2.tgz", + "integrity": "sha512-xq+q3SRMOxGivLhBNaUdC64hDTQwejJ+H0T/NB1XMtTVEwNTrfFF3gAxiyW0Bu/xWEGhjVKgUcMhCrUy2+uCWg==", "dev": true, "requires": { - "@webassemblyjs/ast": "1.8.5", - "@webassemblyjs/helper-wasm-bytecode": "1.8.5", - "@webassemblyjs/ieee754": "1.8.5", - "@webassemblyjs/leb128": "1.8.5", - "@webassemblyjs/utf8": "1.8.5" + "base64-js": "^1.0.2", + "ieee754": "^1.1.4", + "isarray": "^1.0.0" } }, - "@webassemblyjs/wasm-opt": { - "version": "1.8.5", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-opt/-/wasm-opt-1.8.5.tgz", - "integrity": "sha512-HKo2mO/Uh9A6ojzu7cjslGaHaUU14LdLbGEKqTR7PBKwT6LdPtLLh9fPY33rmr5wcOMrsWDbbdCHq4hQUdd37Q==", + "buffer-alloc": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/buffer-alloc/-/buffer-alloc-1.2.0.tgz", + "integrity": "sha512-CFsHQgjtW1UChdXgbyJGtnm+O/uLQeZdtbDo8mfUgYXCHSM1wgrVxXm6bSyrUuErEb+4sYVGCzASBRot7zyrow==", "dev": true, "requires": { - "@webassemblyjs/ast": "1.8.5", - "@webassemblyjs/helper-buffer": "1.8.5", - "@webassemblyjs/wasm-gen": "1.8.5", - "@webassemblyjs/wasm-parser": "1.8.5" + "buffer-alloc-unsafe": "^1.1.0", + "buffer-fill": "^1.0.0" } }, - "@webassemblyjs/wasm-parser": { - "version": "1.8.5", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-parser/-/wasm-parser-1.8.5.tgz", - "integrity": "sha512-pi0SYE9T6tfcMkthwcgCpL0cM9nRYr6/6fjgDtL6q/ZqKHdMWvxitRi5JcZ7RI4SNJJYnYNaWy5UUrHQy998lw==", + "buffer-alloc-unsafe": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/buffer-alloc-unsafe/-/buffer-alloc-unsafe-1.1.0.tgz", + "integrity": "sha512-TEM2iMIEQdJ2yjPJoSIsldnleVaAk1oW3DBVUykyOLsEsFmEc9kn+SFFPz+gl54KQNxlDnAwCXosOS9Okx2xAg==", + "dev": true + }, + "buffer-fill": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/buffer-fill/-/buffer-fill-1.0.0.tgz", + "integrity": "sha1-+PeLdniYiO858gXNY39o5wISKyw=", + "dev": true + }, + "buffer-from": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.1.tgz", + "integrity": "sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A==", + "dev": true + }, + "buffer-indexof": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/buffer-indexof/-/buffer-indexof-1.1.1.tgz", + "integrity": "sha512-4/rOEg86jivtPTeOUUT61jJO1Ya1TrR/OkqCSZDyq84WJh3LuuiphBYJN+fm5xufIk4XAFcEwte/8WzC8If/1g==", + "dev": true + }, + "buffer-xor": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/buffer-xor/-/buffer-xor-1.0.3.tgz", + "integrity": "sha1-JuYe0UIvtw3ULm42cp7VHYVf6Nk=", + "dev": true + }, + "builtin-modules": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/builtin-modules/-/builtin-modules-1.1.1.tgz", + "integrity": "sha1-Jw8HbFpywC9bZaR9+Uxf46J4iS8=", + "dev": true + }, + "builtin-status-codes": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/builtin-status-codes/-/builtin-status-codes-3.0.0.tgz", + "integrity": "sha1-hZgoeOIbmOHGZCXgPQF0eI9Wnug=", + "dev": true + }, + "builtins": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/builtins/-/builtins-1.0.3.tgz", + "integrity": "sha1-y5T662HIaWRR2zZTThQi+U8K7og=", + "dev": true + }, + "bytes": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.0.0.tgz", + "integrity": "sha1-0ygVQE1olpn4Wk6k+odV3ROpYEg=", + "dev": true + }, + "cacache": { + "version": "13.0.1", + "resolved": "https://registry.npmjs.org/cacache/-/cacache-13.0.1.tgz", + "integrity": "sha512-5ZvAxd05HDDU+y9BVvcqYu2LLXmPnQ0hW62h32g4xBTgL/MppR4/04NHfj/ycM2y6lmTnbw6HVi+1eN0Psba6w==", + "dev": true, + "requires": { + "chownr": "^1.1.2", + "figgy-pudding": "^3.5.1", + "fs-minipass": "^2.0.0", + "glob": "^7.1.4", + "graceful-fs": "^4.2.2", + "infer-owner": "^1.0.4", + "lru-cache": "^5.1.1", + "minipass": "^3.0.0", + "minipass-collect": "^1.0.2", + "minipass-flush": "^1.0.5", + "minipass-pipeline": "^1.2.2", + "mkdirp": "^0.5.1", + "move-concurrently": "^1.0.1", + "p-map": "^3.0.0", + "promise-inflight": "^1.0.1", + "rimraf": "^2.7.1", + "ssri": "^7.0.0", + "unique-filename": "^1.1.1" + } + }, + "cache-base": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/cache-base/-/cache-base-1.0.1.tgz", + "integrity": "sha512-AKcdTnFSWATd5/GCPRxr2ChwIJ85CeyrEyjRHlKxQ56d4XJMGym0uAiKn0xbLOGOl3+yRpOTi484dVCEc5AUzQ==", "dev": true, "requires": { - "@webassemblyjs/ast": "1.8.5", - "@webassemblyjs/helper-api-error": "1.8.5", - "@webassemblyjs/helper-wasm-bytecode": "1.8.5", - "@webassemblyjs/ieee754": "1.8.5", - "@webassemblyjs/leb128": "1.8.5", - "@webassemblyjs/utf8": "1.8.5" + "collection-visit": "^1.0.0", + "component-emitter": "^1.2.1", + "get-value": "^2.0.6", + "has-value": "^1.0.0", + "isobject": "^3.0.1", + "set-value": "^2.0.0", + "to-object-path": "^0.3.0", + "union-value": "^1.0.0", + "unset-value": "^1.0.0" } }, - "@webassemblyjs/wast-parser": { - "version": "1.8.5", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wast-parser/-/wast-parser-1.8.5.tgz", - "integrity": "sha512-daXC1FyKWHF1i11obK086QRlsMsY4+tIOKgBqI1lxAnkp9xe9YMcgOxm9kLe+ttjs5aWV2KKE1TWJCN57/Btsg==", + "caller-callsite": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/caller-callsite/-/caller-callsite-2.0.0.tgz", + "integrity": "sha1-hH4PzgoiN1CpoCfFSzNzGtMVQTQ=", "dev": true, "requires": { - "@webassemblyjs/ast": "1.8.5", - "@webassemblyjs/floating-point-hex-parser": "1.8.5", - "@webassemblyjs/helper-api-error": "1.8.5", - "@webassemblyjs/helper-code-frame": "1.8.5", - "@webassemblyjs/helper-fsm": "1.8.5", - "@xtuc/long": "4.2.2" + "callsites": "^2.0.0" } }, - "@webassemblyjs/wast-printer": { - "version": "1.8.5", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wast-printer/-/wast-printer-1.8.5.tgz", - "integrity": "sha512-w0U0pD4EhlnvRyeJzBqaVSJAo9w/ce7/WPogeXLzGkO6hzhr4GnQIZ4W4uUt5b9ooAaXPtnXlj0gzsXEOUNYMg==", + "caller-path": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/caller-path/-/caller-path-2.0.0.tgz", + "integrity": "sha1-Ro+DBE42mrIBD6xfBs7uFbsssfQ=", "dev": true, "requires": { - "@webassemblyjs/ast": "1.8.5", - "@webassemblyjs/wast-parser": "1.8.5", - "@xtuc/long": "4.2.2" + "caller-callsite": "^2.0.0" } }, - "@xtuc/ieee754": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/@xtuc/ieee754/-/ieee754-1.2.0.tgz", - "integrity": "sha512-DX8nKgqcGwsc0eJSqYt5lwP4DH5FlHnmuWWBRy7X0NcaGR0ZtuyeESgMwTYVEtxmsNGY+qit4QYT/MIYTOTPeA==", + "callsite": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/callsite/-/callsite-1.0.0.tgz", + "integrity": "sha1-KAOY5dZkvXQDi28JBRU+borxvCA=", "dev": true }, - "@xtuc/long": { - "version": "4.2.2", - "resolved": "https://registry.npmjs.org/@xtuc/long/-/long-4.2.2.tgz", - "integrity": "sha512-NuHqBY1PB/D8xU6s/thBgOAiAP7HOYDQ32+BFZILJ8ivkUkAHQnWfn6WhL79Owj1qmUnoN/YPhktdIoucipkAQ==", + "callsites": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/callsites/-/callsites-2.0.0.tgz", + "integrity": "sha1-BuuE8A7qQT2oav/vrL/7Ngk7PFA=", "dev": true }, - "@yarnpkg/lockfile": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@yarnpkg/lockfile/-/lockfile-1.1.0.tgz", - "integrity": "sha512-GpSwvyXOcOOlV70vbnzjj4fW5xW/FdUF6nQEt1ENy7m4ZCczi1+/buVUPAqmGfqznsORNFzUMjctTIp8a9tuCQ==", + "camel-case": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/camel-case/-/camel-case-3.0.0.tgz", + "integrity": "sha1-yjw2iKTpzzpM2nd9xNy8cTJJz3M=", + "requires": { + "no-case": "^2.2.0", + "upper-case": "^1.1.1" + } + }, + "camelcase": { + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", + "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", "dev": true }, - "JSONStream": { - "version": "1.3.5", - "resolved": "https://registry.npmjs.org/JSONStream/-/JSONStream-1.3.5.tgz", - "integrity": "sha512-E+iruNOY8VV9s4JEbe1aNEm6MiszPRr/UfcHMz0TQh1BXSxHK+ASV1R6W4HpjBhSeS+54PIsAMCBmwD06LLsqQ==", - "dev": true, + "camelcase-keys": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/camelcase-keys/-/camelcase-keys-2.1.0.tgz", + "integrity": "sha1-MIvur/3ygRkFHvodkyITyRuPkuc=", "requires": { - "jsonparse": "^1.2.0", - "through": ">=2.2.7 <3" + "camelcase": "^2.0.0", + "map-obj": "^1.0.0" + }, + "dependencies": { + "camelcase": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-2.1.1.tgz", + "integrity": "sha1-fB0W1nmhu+WcoCys7PsBHiAfWh8=" + } } }, - "accepts": { - "version": "1.3.7", - "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.7.tgz", - "integrity": "sha512-Il80Qs2WjYlJIBNzNkK6KYqlVMTbZLXgHx2oT0pU/fjRHyEp+PEfEPY0R3WCwAGVOtauxh1hOxNgIf5bv7dQpA==", + "caniuse-api": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/caniuse-api/-/caniuse-api-3.0.0.tgz", + "integrity": "sha512-bsTwuIg/BZZK/vreVTYYbSWoe2F+71P7K5QGEX+pT250DZbfU1MQ5prOKpPR+LL6uWKK3KMwMCAS74QB3Um1uw==", "dev": true, "requires": { - "mime-types": "~2.1.24", - "negotiator": "0.6.2" + "browserslist": "^4.0.0", + "caniuse-lite": "^1.0.0", + "lodash.memoize": "^4.1.2", + "lodash.uniq": "^4.5.0" } }, - "acorn": { - "version": "6.4.1", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-6.4.1.tgz", - "integrity": "sha512-ZVA9k326Nwrj3Cj9jlh3wGFutC2ZornPNARZwsNYqQYgN0EsV2d53w5RN/co65Ohn4sUAUtb1rSUAOD6XN9idA==", + "caniuse-lite": { + "version": "1.0.30001035", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001035.tgz", + "integrity": "sha512-C1ZxgkuA4/bUEdMbU5WrGY4+UhMFFiXrgNAfxiMIqWgFTWfv/xsZCS2xEHT2LMq7xAZfuAnu6mcqyDl0ZR6wLQ==", "dev": true }, - "adm-zip": { - "version": "0.4.14", - "resolved": "https://registry.npmjs.org/adm-zip/-/adm-zip-0.4.14.tgz", - "integrity": "sha512-/9aQCnQHF+0IiCl0qhXoK7qs//SwYE7zX8lsr/DNk1BRAHYxeLZPL4pguwK29gUEqasYQjqPtEpDRSWEkdHn9g==", + "canonical-path": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/canonical-path/-/canonical-path-1.0.0.tgz", + "integrity": "sha512-feylzsbDxi1gPZ1IjystzIQZagYYLvfKrSuygUCgf7z6x790VEzze5QEkdSV1U58RA7Hi0+v6fv4K54atOzATg==", "dev": true }, - "after": { - "version": "0.8.2", - "resolved": "https://registry.npmjs.org/after/-/after-0.8.2.tgz", - "integrity": "sha1-/ts5T58OAqqXaOcCvaI7UF+ufh8=", + "caseless": { + "version": "0.12.0", + "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz", + "integrity": "sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw=" + }, + "chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dev": true, + "requires": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + } + }, + "chardet": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/chardet/-/chardet-0.7.0.tgz", + "integrity": "sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA==", "dev": true }, - "agent-base": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-4.3.0.tgz", - "integrity": "sha512-salcGninV0nPrwpGNn4VTXBb1SOuXQBiqbrNXoeizJsHrsL6ERFM2Ne3JUSBWRE6aeNJI2ROP/WEEIDUiDe3cg==", + "chokidar": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.3.1.tgz", + "integrity": "sha512-4QYCEWOcK3OJrxwvyyAOxFuhpvOVCYkr33LPfFNBjAD/w3sEzWsp2BUOkI4l9bHvWioAd0rc6NlHUOEaWkTeqg==", "dev": true, "requires": { - "es6-promisify": "^5.0.0" + "anymatch": "~3.1.1", + "braces": "~3.0.2", + "fsevents": "~2.1.2", + "glob-parent": "~5.1.0", + "is-binary-path": "~2.1.0", + "is-glob": "~4.0.1", + "normalize-path": "~3.0.0", + "readdirp": "~3.3.0" + }, + "dependencies": { + "glob-parent": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.0.tgz", + "integrity": "sha512-qjtRgnIVmOfnKUE3NJAQEdk+lKrxfw8t5ke7SXtfMTHcjsBfOfWXCQfdb30zfDoZQ2IRSIiidmjtbHZPZ++Ihw==", + "dev": true, + "requires": { + "is-glob": "^4.0.1" + } + } } }, - "agentkeepalive": { - "version": "3.5.2", - "resolved": "https://registry.npmjs.org/agentkeepalive/-/agentkeepalive-3.5.2.tgz", - "integrity": "sha512-e0L/HNe6qkQ7H19kTlRRqUibEAwDK5AFk6y3PtMsuut2VAH6+Q4xZml1tNDJD7kSAyqmbG/K08K5WEJYtUrSlQ==", + "chownr": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/chownr/-/chownr-1.1.4.tgz", + "integrity": "sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg==", + "dev": true + }, + "chrome-trace-event": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/chrome-trace-event/-/chrome-trace-event-1.0.2.tgz", + "integrity": "sha512-9e/zx1jw7B4CO+c/RXoCsfg/x1AfUBioy4owYH0bJprEYAx5hRFLRhWBqHAG57D0ZM4H7vxbP7bPe0VwhQRYDQ==", "dev": true, "requires": { - "humanize-ms": "^1.2.1" + "tslib": "^1.9.0" } }, - "ajv": { - "version": "6.10.2", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.10.2.tgz", - "integrity": "sha512-TXtUUEYHuaTEbLZWIKUr5pmBuhDLy+8KYtPYdcV8qC+pOZL+NKqYwvWSRrVXHn+ZmRRAu8vJTAznH7Oag6RVRw==", + "cipher-base": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/cipher-base/-/cipher-base-1.0.4.tgz", + "integrity": "sha512-Kkht5ye6ZGmwv40uUDZztayT2ThLQGfnj/T71N/XzeZeo3nf8foyW7zGTsPYkEya3m5f3cAypH+qe7YOrM1U2Q==", "dev": true, "requires": { - "fast-deep-equal": "^2.0.1", - "fast-json-stable-stringify": "^2.0.0", - "json-schema-traverse": "^0.4.1", - "uri-js": "^4.2.2" + "inherits": "^2.0.1", + "safe-buffer": "^5.0.1" } }, - "ajv-errors": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/ajv-errors/-/ajv-errors-1.0.1.tgz", - "integrity": "sha512-DCRfO/4nQ+89p/RK43i8Ezd41EqdGIU4ld7nGF8OQ14oc/we5rEntLCUa7+jrn3nn83BosfwZA0wb4pon2o8iQ==", + "circular-dependency-plugin": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/circular-dependency-plugin/-/circular-dependency-plugin-5.2.0.tgz", + "integrity": "sha512-7p4Kn/gffhQaavNfyDFg7LS5S/UT1JAjyGd4UqR2+jzoYF02eDkj0Ec3+48TsIa4zghjLY87nQHIh/ecK9qLdw==", "dev": true }, - "ajv-keywords": { - "version": "3.4.1", - "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.4.1.tgz", - "integrity": "sha512-RO1ibKvd27e6FEShVFfPALuHI3WjSVNeK5FIsmme/LYRNxjKuNj+Dt7bucLa6NdSv3JcVTyMlm9kGR84z1XpaQ==", + "class-utils": { + "version": "0.3.6", + "resolved": "https://registry.npmjs.org/class-utils/-/class-utils-0.3.6.tgz", + "integrity": "sha512-qOhPa/Fj7s6TY8H8esGu5QNpMMQxz79h+urzrNYN6mn+9BnxlDGf5QZ+XeCDsxSjPqsSR56XOZOJmpeurnLMeg==", + "dev": true, + "requires": { + "arr-union": "^3.1.0", + "define-property": "^0.2.5", + "isobject": "^3.0.0", + "static-extend": "^0.1.1" + }, + "dependencies": { + "define-property": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", + "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", + "dev": true, + "requires": { + "is-descriptor": "^0.1.0" + } + } + } + }, + "classlist.js": { + "version": "1.1.20150312", + "resolved": "https://registry.npmjs.org/classlist.js/-/classlist.js-1.1.20150312.tgz", + "integrity": "sha1-HXCEL3Ai8I2awIbOaeWyUPLFd4k=" + }, + "clean-css": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/clean-css/-/clean-css-4.2.3.tgz", + "integrity": "sha512-VcMWDN54ZN/DS+g58HYL5/n4Zrqe8vHJpGA8KdgUXFU4fuP/aHNw8eld9SyEIyabIMJX/0RaY/fplOo5hYLSFA==", + "requires": { + "source-map": "~0.6.0" + }, + "dependencies": { + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==" + } + } + }, + "clean-stack": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/clean-stack/-/clean-stack-2.2.0.tgz", + "integrity": "sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A==", "dev": true }, - "amdefine": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/amdefine/-/amdefine-1.0.1.tgz", - "integrity": "sha1-SlKCrBZHKek2Gbz9OtFR+BfOkfU=", + "cli-cursor": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-3.1.0.tgz", + "integrity": "sha512-I/zHAwsKf9FqGoXM4WWRACob9+SNukZTd94DWF57E4toouRulbCxcUh6RKUEOQlYTHJnzkPMySvPNaaSLNfLZw==", + "dev": true, + "requires": { + "restore-cursor": "^3.1.0" + } + }, + "cli-spinners": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/cli-spinners/-/cli-spinners-2.2.0.tgz", + "integrity": "sha512-tgU3fKwzYjiLEQgPMD9Jt+JjHVL9kW93FiIMX/l7rivvOD4/LL0Mf7gda3+4U2KJBloybwgj5KEoQgGRioMiKQ==", "dev": true }, - "ansi-colors": { - "version": "3.2.4", - "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-3.2.4.tgz", - "integrity": "sha512-hHUXGagefjN2iRrID63xckIvotOXOojhQKWIPUZ4mNUZ9nLZW+7FMNoE1lOkEhNWYsx/7ysGIuJYCiMAA9FnrA==", + "cli-width": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/cli-width/-/cli-width-2.2.0.tgz", + "integrity": "sha1-/xnt6Kml5XkyQUewwR8PvLq+1jk=", "dev": true }, - "ansi-escapes": { - "version": "4.3.1", - "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.1.tgz", - "integrity": "sha512-JWF7ocqNrp8u9oqpgV+wH5ftbt+cfvv+PTjOvKLT3AdYly/LmORARfEVT1iyjwN+4MqE5UmVKoAdIBqeoCHgLA==", + "cliui": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-4.1.0.tgz", + "integrity": "sha512-4FG+RSG9DL7uEwRUZXZn3SS34DiDPfzP0VOiEwtUWlE+AR2EIg+hSyvrIgUUfhdgR/UkAeW2QHgeP+hWrXs7jQ==", "dev": true, "requires": { - "type-fest": "^0.11.0" + "string-width": "^2.1.1", + "strip-ansi": "^4.0.0", + "wrap-ansi": "^2.0.0" + }, + "dependencies": { + "ansi-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", + "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=", + "dev": true + }, + "strip-ansi": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", + "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", + "dev": true, + "requires": { + "ansi-regex": "^3.0.0" + } + } } }, - "ansi-html": { - "version": "0.0.7", - "resolved": "https://registry.npmjs.org/ansi-html/-/ansi-html-0.0.7.tgz", - "integrity": "sha1-gTWEAhliqenm/QOflA0S9WynhZ4=", + "clone": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/clone/-/clone-2.1.2.tgz", + "integrity": "sha1-G39Ln1kfHo+DZwQBYANFoCiHQ18=", "dev": true }, - "ansi-regex": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", - "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=", - "dev": true + "clone-deep": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/clone-deep/-/clone-deep-4.0.1.tgz", + "integrity": "sha512-neHB9xuzh/wk0dIHweyAXv2aPGZIVk3pLMe+/RNzINf17fe0OG96QroktYAUm7SM1PBnzTabaLboqqxDyMU+SQ==", + "requires": { + "is-plain-object": "^2.0.4", + "kind-of": "^6.0.2", + "shallow-clone": "^3.0.0" + } }, - "ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "coa": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/coa/-/coa-2.0.2.tgz", + "integrity": "sha512-q5/jG+YQnSy4nRTV4F7lPepBJZ8qBNJJDBuJdoejDyLXgmL7IEo+Le2JDZudFTFt7mrCqIRaSjws4ygRCTCAXA==", "dev": true, "requires": { - "color-convert": "^1.9.0" + "@types/q": "^1.5.1", + "chalk": "^2.4.1", + "q": "^1.1.2" + }, + "dependencies": { + "@types/q": { + "version": "1.5.2", + "resolved": "https://registry.npmjs.org/@types/q/-/q-1.5.2.tgz", + "integrity": "sha512-ce5d3q03Ex0sy4R14722Rmt6MT07Ua+k4FwDfdcToYJcMKNtRVQvJ6JCAPdAmAnbRb6CsX6aYb9m96NGod9uTw==", + "dev": true + } } }, - "anymatch": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.1.tgz", - "integrity": "sha512-mM8522psRCqzV+6LhomX5wgp25YVibjh8Wj23I5RPkPppSVSjyKD2A2mBJmWGa+KN7f2D6LNh9jkBCeyLktzjg==", + "code-point-at": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/code-point-at/-/code-point-at-1.1.0.tgz", + "integrity": "sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c=" + }, + "codelyzer": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/codelyzer/-/codelyzer-5.2.1.tgz", + "integrity": "sha512-awBZXFcJUyC5HMYXiHzjr3D24tww2l1D1OqtfA9vUhEtYr32a65A+Gblm/OvsO+HuKLYzn8EDMw1inSM3VbxWA==", "dev": true, "requires": { - "normalize-path": "^3.0.0", - "picomatch": "^2.0.4" + "app-root-path": "^2.2.1", + "aria-query": "^3.0.0", + "axobject-query": "2.0.2", + "css-selector-tokenizer": "^0.7.1", + "cssauron": "^1.4.0", + "damerau-levenshtein": "^1.0.4", + "semver-dsl": "^1.0.1", + "source-map": "^0.5.7", + "sprintf-js": "^1.1.2" + }, + "dependencies": { + "source-map": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", + "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", + "dev": true + }, + "sprintf-js": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.1.2.tgz", + "integrity": "sha512-VE0SOVEHCk7Qc8ulkWw3ntAzXuqf7S2lvwQaDLRnUeIEaKNQJzV6BwmLKhOqT61aGhfUMrXeaBk+oDGCzvhcug==", + "dev": true + } } }, - "app-root-path": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/app-root-path/-/app-root-path-2.2.1.tgz", - "integrity": "sha512-91IFKeKk7FjfmezPKkwtaRvSpnUc4gDwPAjA1YZ9Gn0q0PPeW+vbeUsZuyDwjI7+QTHhcLen2v25fi/AmhvbJA==", - "dev": true - }, - "append-transform": { + "collection-visit": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/append-transform/-/append-transform-1.0.0.tgz", - "integrity": "sha512-P009oYkeHyU742iSZJzZZywj4QRJdnTWffaKuJQLablCZ1uz6/cW4yaRgcDaoQ+uwOxxnt0gRUcwfsNP2ri0gw==", + "resolved": "https://registry.npmjs.org/collection-visit/-/collection-visit-1.0.0.tgz", + "integrity": "sha1-S8A3PBZLwykbTTaMgpzxqApZ3KA=", "dev": true, "requires": { - "default-require-extensions": "^2.0.0" + "map-visit": "^1.0.0", + "object-visit": "^1.0.0" } }, - "aproba": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/aproba/-/aproba-1.2.0.tgz", - "integrity": "sha512-Y9J6ZjXtoYh8RnXVCMOU/ttDmk1aBjunq9vO0ta5x85WDQiQfUF9sIPBITdbiiIVcBo03Hi3jMxigBtsddlXRw==", - "dev": true - }, - "arg": { - "version": "4.1.3", - "resolved": "https://registry.npmjs.org/arg/-/arg-4.1.3.tgz", - "integrity": "sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==", - "dev": true - }, - "argparse": { - "version": "1.0.10", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", - "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", + "color": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/color/-/color-3.1.2.tgz", + "integrity": "sha512-vXTJhHebByxZn3lDvDJYw4lR5+uB3vuoHsuYA5AKuxRVn5wzzIfQKGLBmgdVRHKTJYeK5rvJcHnrd0Li49CFpg==", "dev": true, "requires": { - "sprintf-js": "~1.0.2" + "color-convert": "^1.9.1", + "color-string": "^1.5.2" } }, - "aria-query": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/aria-query/-/aria-query-3.0.0.tgz", - "integrity": "sha1-ZbP8wcoRVajJrmTW7uKX8V1RM8w=", + "color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", "dev": true, "requires": { - "ast-types-flow": "0.0.7", - "commander": "^2.11.0" + "color-name": "1.1.3" } }, - "arr-diff": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-4.0.0.tgz", - "integrity": "sha1-1kYQdP6/7HHn4VI1dhoyml3HxSA=", - "dev": true - }, - "arr-flatten": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/arr-flatten/-/arr-flatten-1.1.0.tgz", - "integrity": "sha512-L3hKV5R/p5o81R7O02IGnwpDmkp6E982XhtbuwSe3O4qOtMMMtodicASA1Cny2U+aCXcNpml+m4dPsvsJ3jatg==", + "color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", "dev": true }, - "arr-union": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/arr-union/-/arr-union-3.1.0.tgz", - "integrity": "sha1-45sJrqne+Gao8gbiiK9jkZuuOcQ=", - "dev": true + "color-string": { + "version": "1.5.3", + "resolved": "https://registry.npmjs.org/color-string/-/color-string-1.5.3.tgz", + "integrity": "sha512-dC2C5qeWoYkxki5UAXapdjqO672AM4vZuPGRQfO8b5HKuKGBbKWpITyDYN7TOFKvRW7kOgAn3746clDBMDJyQw==", + "dev": true, + "requires": { + "color-name": "^1.0.0", + "simple-swizzle": "^0.2.2" + } }, - "array-flatten": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-2.1.2.tgz", - "integrity": "sha512-hNfzcOV8W4NdualtqBFPyVO+54DSJuZGY9qT4pRroB6S9e3iiido2ISIC5h9R2sPJ8H3FHCIiEnsv1lPXO3KtQ==", + "colors": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/colors/-/colors-1.1.2.tgz", + "integrity": "sha1-FopHAXVran9RoSzgyXv6KMCE7WM=", "dev": true }, - "array-union": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/array-union/-/array-union-1.0.2.tgz", - "integrity": "sha1-mjRBDk9OPaI96jdb5b5w8kd47Dk=", - "dev": true, + "combined-stream": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", + "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", "requires": { - "array-uniq": "^1.0.1" + "delayed-stream": "~1.0.0" } }, - "array-uniq": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/array-uniq/-/array-uniq-1.0.3.tgz", - "integrity": "sha1-r2rId6Jcx/dOBYiUdThY39sk/bY=", + "commander": { + "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 }, - "array-unique": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.3.2.tgz", - "integrity": "sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg=", + "commondir": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/commondir/-/commondir-1.0.1.tgz", + "integrity": "sha1-3dgA2gxmEnOTzKWVDqloo6rxJTs=", "dev": true }, - "arraybuffer.slice": { - "version": "0.0.7", - "resolved": "https://registry.npmjs.org/arraybuffer.slice/-/arraybuffer.slice-0.0.7.tgz", - "integrity": "sha512-wGUIVQXuehL5TCqQun8OW81jGzAWycqzFF8lFp+GOM5BXLYj3bKNsYC4daB7n6XjCqxQA/qgTJ+8ANR3acjrog==", + "compare-versions": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/compare-versions/-/compare-versions-3.6.0.tgz", + "integrity": "sha512-W6Af2Iw1z4CB7q4uU4hv646dW9GQuBM+YpC0UvUCWSD8w90SJjp+ujJuXaEMtAXBtSqGfMPuFOVn4/+FlaqfBA==", "dev": true }, - "arrify": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/arrify/-/arrify-1.0.1.tgz", - "integrity": "sha1-iYUI2iIm84DfkEcoRWhJwVAaSw0=", + "component-bind": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/component-bind/-/component-bind-1.0.0.tgz", + "integrity": "sha1-AMYIq33Nk4l8AAllGx06jh5zu9E=", "dev": true }, - "asap": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/asap/-/asap-2.0.6.tgz", - "integrity": "sha1-5QNHYR1+aQlDIIu9r+vLwvuGbUY=", + "component-emitter": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.3.0.tgz", + "integrity": "sha512-Rd3se6QB+sO1TwqZjscQrurpEPIfO0/yYnSin6Q/rD3mOutHvUrCAhJub3r90uNb+SESBuE0QYoB90YdfatsRg==", "dev": true }, - "asn1": { - "version": "0.2.4", - "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.4.tgz", - "integrity": "sha512-jxwzQpLQjSmWXgwaCZE9Nz+glAG01yF1QnWgbhGwHI5A6FRIEY6IVqtHhIepHqI7/kyEyQEagBC5mBEFlIYvdg==", + "component-inherit": { + "version": "0.0.3", + "resolved": "https://registry.npmjs.org/component-inherit/-/component-inherit-0.0.3.tgz", + "integrity": "sha1-ZF/ErfWLcrZJ1crmUTVhnbJv8UM=", + "dev": true + }, + "compressible": { + "version": "2.0.18", + "resolved": "https://registry.npmjs.org/compressible/-/compressible-2.0.18.tgz", + "integrity": "sha512-AF3r7P5dWxL8MxyITRMlORQNaOA2IkAFaTr4k7BUumjPtRpGDTZpl0Pb1XCO6JeDCBdp126Cgs9sMxqSjgYyRg==", "dev": true, "requires": { - "safer-buffer": "~2.1.0" + "mime-db": ">= 1.43.0 < 2" + } + }, + "compression": { + "version": "1.7.4", + "resolved": "https://registry.npmjs.org/compression/-/compression-1.7.4.tgz", + "integrity": "sha512-jaSIDzP9pZVS4ZfQ+TzvtiWhdpFhE2RDHz8QJkpX9SIpLq88VueF5jJw6t+6CUQcAoA6t+x89MLrWAqpfDE8iQ==", + "dev": true, + "requires": { + "accepts": "~1.3.5", + "bytes": "3.0.0", + "compressible": "~2.0.16", + "debug": "2.6.9", + "on-headers": "~1.0.2", + "safe-buffer": "5.1.2", + "vary": "~1.1.2" + }, + "dependencies": { + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "requires": { + "ms": "2.0.0" + } + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", + "dev": true + } } }, - "asn1.js": { - "version": "4.10.1", - "resolved": "https://registry.npmjs.org/asn1.js/-/asn1.js-4.10.1.tgz", - "integrity": "sha512-p32cOF5q0Zqs9uBiONKYLm6BClCoBCM5O9JfeUSlnQLBTxYdTK+pW+nXflm8UkKd2UYlEbYz5qEi0JuZR9ckSw==", + "concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=" + }, + "concat-stream": { + "version": "1.6.2", + "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-1.6.2.tgz", + "integrity": "sha512-27HBghJxjiZtIk3Ycvn/4kbJk/1uZuJFfuPEns6LaEvpvG1f0hTea8lilrouyo9mVc2GWdcEZ8OLoGmSADlrCw==", "dev": true, "requires": { - "bn.js": "^4.0.0", - "inherits": "^2.0.1", - "minimalistic-assert": "^1.0.0" + "buffer-from": "^1.0.0", + "inherits": "^2.0.3", + "readable-stream": "^2.2.2", + "typedarray": "^0.0.6" } }, - "assert": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/assert/-/assert-1.5.0.tgz", - "integrity": "sha512-EDsgawzwoun2CZkCgtxJbv392v4nbk9XDD06zI+kQYoBM/3RBWLlEyJARDOmhAAosBjWACEkKL6S+lIZtcAubA==", + "connect": { + "version": "3.7.0", + "resolved": "https://registry.npmjs.org/connect/-/connect-3.7.0.tgz", + "integrity": "sha512-ZqRXc+tZukToSNmh5C2iWMSoV3X1YUcPbqEM4DkEG5tNQXrQUZCNVGGv3IuicnkMtPfGf3Xtp8WCXs295iQ1pQ==", "dev": true, "requires": { - "object-assign": "^4.1.1", - "util": "0.10.3" + "debug": "2.6.9", + "finalhandler": "1.1.2", + "parseurl": "~1.3.3", + "utils-merge": "1.0.1" }, "dependencies": { - "inherits": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.1.tgz", - "integrity": "sha1-sX0I0ya0Qj5Wjv9xn5GwscvfafE=", - "dev": true - }, - "util": { - "version": "0.10.3", - "resolved": "https://registry.npmjs.org/util/-/util-0.10.3.tgz", - "integrity": "sha1-evsa/lCAUkZInj23/g7TeTNqwPk=", + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", "dev": true, "requires": { - "inherits": "2.0.1" + "ms": "2.0.0" } + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", + "dev": true } } }, - "assert-plus": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", - "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=", + "connect-history-api-fallback": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/connect-history-api-fallback/-/connect-history-api-fallback-1.6.0.tgz", + "integrity": "sha512-e54B99q/OUoH64zYYRf3HBP5z24G38h5D3qXu23JGRoigpX5Ss4r9ZnDk3g0Z8uQC2x2lPaJ+UlWBc1ZWBWdLg==", "dev": true }, - "assign-symbols": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/assign-symbols/-/assign-symbols-1.0.0.tgz", - "integrity": "sha1-WWZ/QfrdTyDMvCu5a41Pf3jsA2c=", + "console-browserify": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/console-browserify/-/console-browserify-1.2.0.tgz", + "integrity": "sha512-ZMkYO/LkF17QvCPqM0gxw8yUzigAOZOSWSHg91FH6orS7vcEj5dVZTidN2fQ14yBSdg97RqhSNwLUXInd52OTA==", "dev": true }, - "ast-types-flow": { - "version": "0.0.7", - "resolved": "https://registry.npmjs.org/ast-types-flow/-/ast-types-flow-0.0.7.tgz", - "integrity": "sha1-9wtzXGvKGlycItmCw+Oef+ujva0=", + "console-control-strings": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/console-control-strings/-/console-control-strings-1.1.0.tgz", + "integrity": "sha1-PXz0Rk22RG6mRL9LOVB/mFEAjo4=" + }, + "constants-browserify": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/constants-browserify/-/constants-browserify-1.0.0.tgz", + "integrity": "sha1-wguW2MYXdIqvHBYCF2DNJ/y4y3U=", "dev": true }, - "async": { - "version": "2.6.3", - "resolved": "https://registry.npmjs.org/async/-/async-2.6.3.tgz", - "integrity": "sha512-zflvls11DCy+dQWzTW2dzuilv8Z5X/pjfmZOWba6TNIVDm+2UDaJmXSOXlasHKfNBs8oo3M0aT50fDEWfKZjXg==", + "content-disposition": { + "version": "0.5.3", + "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.3.tgz", + "integrity": "sha512-ExO0774ikEObIAEV9kDo50o+79VCUdEB6n6lzKgGwupcVeRlhrj3qGAfwq8G6uBJjkqLrhT0qEYFcWng8z1z0g==", "dev": true, "requires": { - "lodash": "^4.17.14" + "safe-buffer": "5.1.2" } }, - "async-each": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/async-each/-/async-each-1.0.3.tgz", - "integrity": "sha512-z/WhQ5FPySLdvREByI2vZiTWwCnF0moMJ1hK9YQwDTHKh6I7/uSckMetoRGb5UBZPC1z0jlw+n/XCgjeH7y1AQ==", - "dev": true - }, - "async-limiter": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/async-limiter/-/async-limiter-1.0.1.tgz", - "integrity": "sha512-csOlWGAcRFJaI6m+F2WKdnMKr4HhdhFVBk0H/QbJFMCr+uO2kwohwXQPxw/9OCxp05r5ghVBFSyioixx3gfkNQ==", - "dev": true - }, - "asynckit": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", - "integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k=", - "dev": true - }, - "atob": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/atob/-/atob-2.1.2.tgz", - "integrity": "sha512-Wm6ukoaOGJi/73p/cl2GvLjTI5JM1k/O14isD73YML8StrH/7/lRFgmg8nICZgD3bZZvjwCGxtMOD3wWNAu8cg==", + "content-type": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.4.tgz", + "integrity": "sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA==", "dev": true }, - "autoprefixer": { - "version": "9.6.1", - "resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-9.6.1.tgz", - "integrity": "sha512-aVo5WxR3VyvyJxcJC3h4FKfwCQvQWb1tSI5VHNibddCVWrcD1NvlxEweg3TSgiPztMnWfjpy2FURKA2kvDE+Tw==", + "convert-source-map": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.7.0.tgz", + "integrity": "sha512-4FJkXzKXEDB1snCFZlLP4gpC3JILicCpGbzG9f9G7tGqGCzETQ2hWPrcinA9oU4wtf2biUaEH5065UnMeR33oA==", "dev": true, "requires": { - "browserslist": "^4.6.3", - "caniuse-lite": "^1.0.30000980", - "chalk": "^2.4.2", - "normalize-range": "^0.1.2", - "num2fraction": "^1.2.2", - "postcss": "^7.0.17", - "postcss-value-parser": "^4.0.0" + "safe-buffer": "~5.1.1" } }, - "aws-sign2": { - "version": "0.7.0", - "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.7.0.tgz", - "integrity": "sha1-tG6JCTSpWR8tL2+G1+ap8bP+dqg=", + "cookie": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.4.0.tgz", + "integrity": "sha512-+Hp8fLp57wnUSt0tY0tHEXh4voZRDnoIrZPqlo3DPiI4y9lwg/jqx+1Om94/W6ZaPDOUbnjOt/99w66zk+l1Xg==", "dev": true }, - "aws4": { - "version": "1.9.1", - "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.9.1.tgz", - "integrity": "sha512-wMHVg2EOHaMRxbzgFJ9gtjOOCrI80OHLG14rxi28XwOW8ux6IiEbRCGGGqCtdAIg4FQCbW20k9RsT4y3gJlFug==", + "cookie-signature": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz", + "integrity": "sha1-4wOogrNCzD7oylE6eZmXNNqzriw=", "dev": true }, - "axobject-query": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/axobject-query/-/axobject-query-2.0.2.tgz", - "integrity": "sha512-MCeek8ZH7hKyO1rWUbKNQBbl4l2eY0ntk7OGi+q0RlafrCnfPxC06WZA+uebCfmYp4mNU9jRBP1AhGyf8+W3ww==", - "dev": true, - "requires": { - "ast-types-flow": "0.0.7" - } - }, - "babel-plugin-dynamic-import-node": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/babel-plugin-dynamic-import-node/-/babel-plugin-dynamic-import-node-2.3.0.tgz", - "integrity": "sha512-o6qFkpeQEBxcqt0XYlWzAVxNCSCZdUgcR8IRlhD/8DylxjjO4foPcvTW0GGKa/cVt3rvxZ7o5ippJ+/0nvLhlQ==", + "copy-concurrently": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/copy-concurrently/-/copy-concurrently-1.0.5.tgz", + "integrity": "sha512-f2domd9fsVDFtaFcbaRZuYXwtdmnzqbADSwhSWYxYB/Q8zsdUUFMXVRwXGDMWmbEzAn1kdRrtI1T/KTFOL4X2A==", "dev": true, "requires": { - "object.assign": "^4.1.0" + "aproba": "^1.1.1", + "fs-write-stream-atomic": "^1.0.8", + "iferr": "^0.1.5", + "mkdirp": "^0.5.1", + "rimraf": "^2.5.4", + "run-queue": "^1.0.0" } }, - "backo2": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/backo2/-/backo2-1.0.2.tgz", - "integrity": "sha1-MasayLEpNjRj41s+u2n038+6eUc=", - "dev": true - }, - "balanced-match": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", - "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=", + "copy-descriptor": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/copy-descriptor/-/copy-descriptor-0.1.1.tgz", + "integrity": "sha1-Z29us8OZl8LuGsOpJP1hJHSPV40=", "dev": true }, - "base": { - "version": "0.11.2", - "resolved": "https://registry.npmjs.org/base/-/base-0.11.2.tgz", - "integrity": "sha512-5T6P4xPgpp0YDFvSWwEZ4NoE3aM4QBQXDzmVbraCkFj8zHM+mba8SyqB5DbZWyR7mYHo6Y7BdQo3MoA4m0TeQg==", + "copy-webpack-plugin": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/copy-webpack-plugin/-/copy-webpack-plugin-5.1.1.tgz", + "integrity": "sha512-P15M5ZC8dyCjQHWwd4Ia/dm0SgVvZJMYeykVIVYXbGyqO4dWB5oyPHp9i7wjwo5LhtlhKbiBCdS2NvM07Wlybg==", "dev": true, "requires": { - "cache-base": "^1.0.1", - "class-utils": "^0.3.5", - "component-emitter": "^1.2.1", - "define-property": "^1.0.0", - "isobject": "^3.0.1", - "mixin-deep": "^1.2.0", - "pascalcase": "^0.1.1" + "cacache": "^12.0.3", + "find-cache-dir": "^2.1.0", + "glob-parent": "^3.1.0", + "globby": "^7.1.1", + "is-glob": "^4.0.1", + "loader-utils": "^1.2.3", + "minimatch": "^3.0.4", + "normalize-path": "^3.0.0", + "p-limit": "^2.2.1", + "schema-utils": "^1.0.0", + "serialize-javascript": "^2.1.2", + "webpack-log": "^2.0.0" }, "dependencies": { - "define-property": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", - "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", - "dev": true, - "requires": { - "is-descriptor": "^1.0.0" - } - }, - "is-accessor-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", - "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", + "cacache": { + "version": "12.0.3", + "resolved": "https://registry.npmjs.org/cacache/-/cacache-12.0.3.tgz", + "integrity": "sha512-kqdmfXEGFepesTuROHMs3MpFLWrPkSSpRqOw80RCflZXy/khxaArvFrQ7uJxSUduzAufc6G0g1VUCOZXxWavPw==", "dev": true, "requires": { - "kind-of": "^6.0.0" - } - }, - "is-data-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", - "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", + "bluebird": "^3.5.5", + "chownr": "^1.1.1", + "figgy-pudding": "^3.5.1", + "glob": "^7.1.4", + "graceful-fs": "^4.1.15", + "infer-owner": "^1.0.3", + "lru-cache": "^5.1.1", + "mississippi": "^3.0.0", + "mkdirp": "^0.5.1", + "move-concurrently": "^1.0.1", + "promise-inflight": "^1.0.1", + "rimraf": "^2.6.3", + "ssri": "^6.0.1", + "unique-filename": "^1.1.1", + "y18n": "^4.0.0" + } + }, + "find-cache-dir": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/find-cache-dir/-/find-cache-dir-2.1.0.tgz", + "integrity": "sha512-Tq6PixE0w/VMFfCgbONnkiQIVol/JJL7nRMi20fqzA4NRs9AfeqMGeRdPi3wIhYkxjeBaWh2rxwapn5Tu3IqOQ==", "dev": true, "requires": { - "kind-of": "^6.0.0" + "commondir": "^1.0.1", + "make-dir": "^2.0.0", + "pkg-dir": "^3.0.0" } }, - "is-descriptor": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", - "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", + "ssri": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/ssri/-/ssri-6.0.1.tgz", + "integrity": "sha512-3Wge10hNcT1Kur4PDFwEieXSCMCJs/7WvSACcrMYrNp+b8kDL1/0wJch5Ni2WrtwEa2IO8OsVfeKIciKCDx/QA==", "dev": true, "requires": { - "is-accessor-descriptor": "^1.0.0", - "is-data-descriptor": "^1.0.0", - "kind-of": "^6.0.2" + "figgy-pudding": "^3.5.1" } } } }, - "base64-arraybuffer": { - "version": "0.1.5", - "resolved": "https://registry.npmjs.org/base64-arraybuffer/-/base64-arraybuffer-0.1.5.tgz", - "integrity": "sha1-c5JncZI7Whl0etZmqlzUv5xunOg=", - "dev": true - }, - "base64-js": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.3.1.tgz", - "integrity": "sha512-mLQ4i2QO1ytvGWFWmcngKO//JXAQueZvwEKtjgQFM4jIK0kU+ytMfplL8j+n5mspOfjHwoAg+9yhb7BwAHm36g==", - "dev": true - }, - "base64id": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/base64id/-/base64id-1.0.0.tgz", - "integrity": "sha1-R2iMuZu2gE8OBtPnY7HDLlfY5rY=", - "dev": true - }, - "batch": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/batch/-/batch-0.6.1.tgz", - "integrity": "sha1-3DQxT05nkxgJP8dgJyUl+UvyXBY=", - "dev": true + "core-js": { + "version": "3.6.4", + "resolved": "https://registry.npmjs.org/core-js/-/core-js-3.6.4.tgz", + "integrity": "sha512-4paDGScNgZP2IXXilaffL9X7968RuvwlkK3xWtZRVqgd8SYNiVKRJvkFd1aqqEuPfN7E68ZHEp9hDj6lHj4Hyw==" }, - "bcrypt-pbkdf": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz", - "integrity": "sha1-pDAdOJtqQ/m2f/PKEaP2Y342Dp4=", + "core-js-compat": { + "version": "3.6.4", + "resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.6.4.tgz", + "integrity": "sha512-zAa3IZPvsJ0slViBQ2z+vgyyTuhd3MFn1rBQjZSKVEgB0UMYhUkCj9jJUVPgGTGqWvsBVmfnruXgTcNyTlEiSA==", "dev": true, "requires": { - "tweetnacl": "^0.14.3" + "browserslist": "^4.8.3", + "semver": "7.0.0" + }, + "dependencies": { + "semver": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.0.0.tgz", + "integrity": "sha512-+GB6zVA9LWh6zovYQLALHwv5rb2PHGlJi3lfiqIHxR0uuwCgefcOJc59v9fv1w8GbStwxuuqqAjI9NMAOOgq1A==", + "dev": true + } } }, - "better-assert": { + "core-util-is": { "version": "1.0.2", - "resolved": "https://registry.npmjs.org/better-assert/-/better-assert-1.0.2.tgz", - "integrity": "sha1-QIZrnhueC1W0gYlDEeaPr/rrxSI=", - "dev": true, - "requires": { - "callsite": "1.0.0" - } - }, - "big.js": { - "version": "5.2.2", - "resolved": "https://registry.npmjs.org/big.js/-/big.js-5.2.2.tgz", - "integrity": "sha512-vyL2OymJxmarO8gxMr0mhChsO9QGwhynfuu4+MHTAW6czfq9humCB7rKpUjDd9YUiDPU4mzpyupFSvOClAwbmQ==", - "dev": true - }, - "binary-extensions": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.0.0.tgz", - "integrity": "sha512-Phlt0plgpIIBOGTT/ehfFnbNlfsDEiqmzE2KRXoX1bLIlir4X/MR+zSyBEkL05ffWgnRSf/DXv+WrUAVr93/ow==", - "dev": true - }, - "bindings": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/bindings/-/bindings-1.5.0.tgz", - "integrity": "sha512-p2q/t/mhvuOj/UeLlV6566GD/guowlr0hHxClI0W9m7MWYkL1F0hLo+0Aexs9HSPCtR1SXQ0TD3MMKrXZajbiQ==", - "dev": true, - "optional": true, - "requires": { - "file-uri-to-path": "1.0.0" - } - }, - "blob": { - "version": "0.0.5", - "resolved": "https://registry.npmjs.org/blob/-/blob-0.0.5.tgz", - "integrity": "sha512-gaqbzQPqOoamawKg0LGVd7SzLgXS+JH61oWprSLH+P+abTczqJbhTR8CmJ2u9/bUYNmHTGJx/UEmn6doAvvuig==", - "dev": true + "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", + "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=" }, - "blocking-proxy": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/blocking-proxy/-/blocking-proxy-1.0.1.tgz", - "integrity": "sha512-KE8NFMZr3mN2E0HcvCgRtX7DjhiIQrwle+nSVJVC/yqFb9+xznHl2ZcoBp2L9qzkI4t4cBFJ1efXF8Dwi132RA==", + "cosmiconfig": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-5.2.1.tgz", + "integrity": "sha512-H65gsXo1SKjf8zmrJ67eJk8aIRKV5ff2D4uKZIBZShbhGSpEmsQOPW/SKMKYhSTrqR7ufy6RP69rPogdaPh/kA==", "dev": true, "requires": { - "minimist": "^1.2.0" + "import-fresh": "^2.0.0", + "is-directory": "^0.3.1", + "js-yaml": "^3.13.1", + "parse-json": "^4.0.0" } }, - "bluebird": { - "version": "3.7.2", - "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.7.2.tgz", - "integrity": "sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg==", - "dev": true - }, - "bn.js": { - "version": "4.11.8", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.8.tgz", - "integrity": "sha512-ItfYfPLkWHUjckQCk8xC+LwxgK8NYcXywGigJgSwOP8Y2iyWT4f2vsZnoOXTTbo+o5yXmIUJ4gn5538SO5S3gA==", - "dev": true - }, - "body-parser": { - "version": "1.19.0", - "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.19.0.tgz", - "integrity": "sha512-dhEPs72UPbDnAQJ9ZKMNTP6ptJaionhP5cBb541nXPlW60Jepo9RV/a4fX4XWW9CuFNK22krhrj1+rgzifNCsw==", + "coverage-istanbul-loader": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/coverage-istanbul-loader/-/coverage-istanbul-loader-2.0.3.tgz", + "integrity": "sha512-LiGRvyIuzVYs3M1ZYK1tF0HekjH0DJ8zFdUwAZq378EJzqOgToyb1690dp3TAUlP6Y+82uu42LRjuROVeJ54CA==", "dev": true, "requires": { - "bytes": "3.1.0", - "content-type": "~1.0.4", - "debug": "2.6.9", - "depd": "~1.1.2", - "http-errors": "1.7.2", - "iconv-lite": "0.4.24", - "on-finished": "~2.3.0", - "qs": "6.7.0", - "raw-body": "2.4.0", - "type-is": "~1.6.17" + "convert-source-map": "^1.7.0", + "istanbul-lib-instrument": "^4.0.0", + "loader-utils": "^1.2.3", + "merge-source-map": "^1.1.0", + "schema-utils": "^2.6.1" }, "dependencies": { - "bytes": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.0.tgz", - "integrity": "sha512-zauLjrfCG+xvoyaqLoV8bLVXXNGC4JqlxFCutSDWA6fJrTo2ZuvLYTqZ7aHBLZSMOopbzwv8f+wZcVzfVTI2Dg==", - "dev": true - }, - "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "ajv": { + "version": "6.12.0", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.0.tgz", + "integrity": "sha512-D6gFiFA0RRLyUbvijN74DWAjXSFxWKaWP7mldxkVhyhAV3+SWA9HEJPHQ2c9soIeTFJqcSdFDGFgdqs1iUU2Hw==", "dev": true, "requires": { - "ms": "2.0.0" + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" } }, - "ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", + "fast-deep-equal": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.1.tgz", + "integrity": "sha512-8UEa58QDLauDNfpbrX55Q9jrGHThw2ZMdOky5Gl1CDtVeJDPVrG4Jxx1N8jw2gkWaff5UUuX1KJd+9zGe2B+ZA==", "dev": true }, - "qs": { - "version": "6.7.0", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.7.0.tgz", - "integrity": "sha512-VCdBRNFTX1fyE7Nb6FYoURo/SPe62QCaAyzJvUjwRaIsc+NePBEniHlvxFmmX56+HZphIGtV0XeCirBtpDrTyQ==", - "dev": true + "schema-utils": { + "version": "2.6.5", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-2.6.5.tgz", + "integrity": "sha512-5KXuwKziQrTVHh8j/Uxz+QUbxkaLW9X/86NBlx/gnKgtsZA2GIVMUn17qWhRFwF8jdYb3Dig5hRO/W5mZqy6SQ==", + "dev": true, + "requires": { + "ajv": "^6.12.0", + "ajv-keywords": "^3.4.1" + } } } }, - "bonjour": { - "version": "3.5.0", - "resolved": "https://registry.npmjs.org/bonjour/-/bonjour-3.5.0.tgz", - "integrity": "sha1-jokKGD2O6aI5OzhExpGkK897yfU=", - "dev": true, - "requires": { - "array-flatten": "^2.1.0", - "deep-equal": "^1.0.1", - "dns-equal": "^1.0.0", - "dns-txt": "^2.0.2", - "multicast-dns": "^6.0.1", - "multicast-dns-service-types": "^1.1.0" - } - }, - "brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", - "dev": true, - "requires": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, - "braces": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", - "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", + "create-ecdh": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/create-ecdh/-/create-ecdh-4.0.3.tgz", + "integrity": "sha512-GbEHQPMOswGpKXM9kCWVrremUcBmjteUaQ01T9rkKCPDXfUHX0IoP9LpHYo2NPFampa4e+/pFDc3jQdxrxQLaw==", "dev": true, "requires": { - "fill-range": "^7.0.1" + "bn.js": "^4.1.0", + "elliptic": "^6.0.0" } }, - "brorand": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/brorand/-/brorand-1.1.0.tgz", - "integrity": "sha1-EsJe/kCkXjwyPrhnWgoM5XsiNx8=", - "dev": true - }, - "browserify-aes": { + "create-hash": { "version": "1.2.0", - "resolved": "https://registry.npmjs.org/browserify-aes/-/browserify-aes-1.2.0.tgz", - "integrity": "sha512-+7CHXqGuspUn/Sl5aO7Ea0xWGAtETPXNSAjHo48JfLdPWcMng33Xe4znFvQweqc/uzk5zSOI3H52CYnjCfb5hA==", + "resolved": "https://registry.npmjs.org/create-hash/-/create-hash-1.2.0.tgz", + "integrity": "sha512-z00bCGNHDG8mHAkP7CtT1qVu+bFQUPjYq/4Iv3C3kWjTFV10zIjfSoeqXo9Asws8gwSHDGj/hl2u4OGIjapeCg==", "dev": true, "requires": { - "buffer-xor": "^1.0.3", - "cipher-base": "^1.0.0", - "create-hash": "^1.1.0", - "evp_bytestokey": "^1.0.3", + "cipher-base": "^1.0.1", "inherits": "^2.0.1", - "safe-buffer": "^5.0.1" - } - }, - "browserify-cipher": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/browserify-cipher/-/browserify-cipher-1.0.1.tgz", - "integrity": "sha512-sPhkz0ARKbf4rRQt2hTpAHqn47X3llLkUGn+xEJzLjwY8LRs2p0v7ljvI5EyoRO/mexrNunNECisZs+gw2zz1w==", - "dev": true, - "requires": { - "browserify-aes": "^1.0.4", - "browserify-des": "^1.0.0", - "evp_bytestokey": "^1.0.0" - } - }, - "browserify-des": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/browserify-des/-/browserify-des-1.0.2.tgz", - "integrity": "sha512-BioO1xf3hFwz4kc6iBhI3ieDFompMhrMlnDFC4/0/vd5MokpuAc3R+LYbwTA9A5Yc9pq9UYPqffKpW2ObuwX5A==", + "md5.js": "^1.3.4", + "ripemd160": "^2.0.1", + "sha.js": "^2.4.0" + } + }, + "create-hmac": { + "version": "1.1.7", + "resolved": "https://registry.npmjs.org/create-hmac/-/create-hmac-1.1.7.tgz", + "integrity": "sha512-MJG9liiZ+ogc4TzUwuvbER1JRdgvUFSB5+VR/g5h82fGaIRWMWddtKBHi7/sVhfjQZ6SehlyhvQYrcYkaUIpLg==", "dev": true, "requires": { - "cipher-base": "^1.0.1", - "des.js": "^1.0.0", + "cipher-base": "^1.0.3", + "create-hash": "^1.1.0", "inherits": "^2.0.1", - "safe-buffer": "^5.1.2" + "ripemd160": "^2.0.0", + "safe-buffer": "^5.0.1", + "sha.js": "^2.4.8" } }, - "browserify-rsa": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/browserify-rsa/-/browserify-rsa-4.0.1.tgz", - "integrity": "sha1-IeCr+vbyApzy+vsTNWenAdQTVSQ=", + "cross-spawn": { + "version": "6.0.5", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz", + "integrity": "sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==", "dev": true, "requires": { - "bn.js": "^4.1.0", - "randombytes": "^2.0.1" + "nice-try": "^1.0.4", + "path-key": "^2.0.1", + "semver": "^5.5.0", + "shebang-command": "^1.2.0", + "which": "^1.2.9" + }, + "dependencies": { + "semver": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", + "dev": true + } } }, - "browserify-sign": { - "version": "4.0.4", - "resolved": "https://registry.npmjs.org/browserify-sign/-/browserify-sign-4.0.4.tgz", - "integrity": "sha1-qk62jl17ZYuqa/alfmMMvXqT0pg=", + "crypto-browserify": { + "version": "3.12.0", + "resolved": "https://registry.npmjs.org/crypto-browserify/-/crypto-browserify-3.12.0.tgz", + "integrity": "sha512-fz4spIh+znjO2VjL+IdhEpRJ3YN6sMzITSBijk6FK2UvTqruSQW+/cCZTSNsMiZNvUeq0CqurF+dAbyiGOY6Wg==", "dev": true, "requires": { - "bn.js": "^4.1.1", - "browserify-rsa": "^4.0.0", + "browserify-cipher": "^1.0.0", + "browserify-sign": "^4.0.0", + "create-ecdh": "^4.0.0", "create-hash": "^1.1.0", - "create-hmac": "^1.1.2", - "elliptic": "^6.0.0", + "create-hmac": "^1.1.0", + "diffie-hellman": "^5.0.0", "inherits": "^2.0.1", - "parse-asn1": "^5.0.0" + "pbkdf2": "^3.0.3", + "public-encrypt": "^4.0.0", + "randombytes": "^2.0.0", + "randomfill": "^1.0.3" } }, - "browserify-zlib": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/browserify-zlib/-/browserify-zlib-0.2.0.tgz", - "integrity": "sha512-Z942RysHXmJrhqk88FmKBVq/v5tqmSkDz7p54G/MGyjMnCFFnC79XWNbg+Vta8W6Wb2qtSZTSxIGkJrRpCFEiA==", + "css": { + "version": "2.2.4", + "resolved": "https://registry.npmjs.org/css/-/css-2.2.4.tgz", + "integrity": "sha512-oUnjmWpy0niI3x/mPL8dVEI1l7MnG3+HHyRPHf+YFSbK+svOhXpmSOcDURUh2aOCgl2grzrOPt1nHLuCVFULLw==", "dev": true, "requires": { - "pako": "~1.0.5" + "inherits": "^2.0.3", + "source-map": "^0.6.1", + "source-map-resolve": "^0.5.2", + "urix": "^0.1.0" + }, + "dependencies": { + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true + } } }, - "browserslist": { - "version": "4.8.6", - "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.8.6.tgz", - "integrity": "sha512-ZHao85gf0eZ0ESxLfCp73GG9O/VTytYDIkIiZDlURppLTI9wErSM/5yAKEq6rcUdxBLjMELmrYUJGg5sxGKMHg==", - "dev": true, - "requires": { - "caniuse-lite": "^1.0.30001023", - "electron-to-chromium": "^1.3.341", - "node-releases": "^1.1.47" - } + "css-color-names": { + "version": "0.0.4", + "resolved": "https://registry.npmjs.org/css-color-names/-/css-color-names-0.0.4.tgz", + "integrity": "sha1-gIrcLnnPhHOAabZGyyDsJ762KeA=", + "dev": true }, - "browserstack": { - "version": "1.5.3", - "resolved": "https://registry.npmjs.org/browserstack/-/browserstack-1.5.3.tgz", - "integrity": "sha512-AO+mECXsW4QcqC9bxwM29O7qWa7bJT94uBFzeb5brylIQwawuEziwq20dPYbins95GlWzOawgyDNdjYAo32EKg==", + "css-declaration-sorter": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/css-declaration-sorter/-/css-declaration-sorter-4.0.1.tgz", + "integrity": "sha512-BcxQSKTSEEQUftYpBVnsH4SF05NTuBokb19/sBt6asXGKZ/6VP7PLG1CBCkFDYOnhXhPh0jMhO6xZ71oYHXHBA==", "dev": true, "requires": { - "https-proxy-agent": "^2.2.1" + "postcss": "^7.0.1", + "timsort": "^0.3.0" } }, - "buffer": { - "version": "4.9.2", - "resolved": "https://registry.npmjs.org/buffer/-/buffer-4.9.2.tgz", - "integrity": "sha512-xq+q3SRMOxGivLhBNaUdC64hDTQwejJ+H0T/NB1XMtTVEwNTrfFF3gAxiyW0Bu/xWEGhjVKgUcMhCrUy2+uCWg==", + "css-parse": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/css-parse/-/css-parse-2.0.0.tgz", + "integrity": "sha1-pGjuZnwW2BzPBcWMONKpfHgNv9Q=", "dev": true, "requires": { - "base64-js": "^1.0.2", - "ieee754": "^1.1.4", - "isarray": "^1.0.0" + "css": "^2.0.0" } }, - "buffer-alloc": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/buffer-alloc/-/buffer-alloc-1.2.0.tgz", - "integrity": "sha512-CFsHQgjtW1UChdXgbyJGtnm+O/uLQeZdtbDo8mfUgYXCHSM1wgrVxXm6bSyrUuErEb+4sYVGCzASBRot7zyrow==", + "css-select": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/css-select/-/css-select-2.1.0.tgz", + "integrity": "sha512-Dqk7LQKpwLoH3VovzZnkzegqNSuAziQyNZUcrdDM401iY+R5NkGBXGmtO05/yaXQziALuPogeG0b7UAgjnTJTQ==", "dev": true, "requires": { - "buffer-alloc-unsafe": "^1.1.0", - "buffer-fill": "^1.0.0" + "boolbase": "^1.0.0", + "css-what": "^3.2.1", + "domutils": "^1.7.0", + "nth-check": "^1.0.2" } }, - "buffer-alloc-unsafe": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/buffer-alloc-unsafe/-/buffer-alloc-unsafe-1.1.0.tgz", - "integrity": "sha512-TEM2iMIEQdJ2yjPJoSIsldnleVaAk1oW3DBVUykyOLsEsFmEc9kn+SFFPz+gl54KQNxlDnAwCXosOS9Okx2xAg==", - "dev": true - }, - "buffer-fill": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/buffer-fill/-/buffer-fill-1.0.0.tgz", - "integrity": "sha1-+PeLdniYiO858gXNY39o5wISKyw=", - "dev": true - }, - "buffer-from": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.1.tgz", - "integrity": "sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A==", - "dev": true - }, - "buffer-indexof": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/buffer-indexof/-/buffer-indexof-1.1.1.tgz", - "integrity": "sha512-4/rOEg86jivtPTeOUUT61jJO1Ya1TrR/OkqCSZDyq84WJh3LuuiphBYJN+fm5xufIk4XAFcEwte/8WzC8If/1g==", + "css-select-base-adapter": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/css-select-base-adapter/-/css-select-base-adapter-0.1.1.tgz", + "integrity": "sha512-jQVeeRG70QI08vSTwf1jHxp74JoZsr2XSgETae8/xC8ovSnL2WF87GTLO86Sbwdt2lK4Umg4HnnwMO4YF3Ce7w==", "dev": true }, - "buffer-xor": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/buffer-xor/-/buffer-xor-1.0.3.tgz", - "integrity": "sha1-JuYe0UIvtw3ULm42cp7VHYVf6Nk=", - "dev": true + "css-selector-tokenizer": { + "version": "0.7.2", + "resolved": "https://registry.npmjs.org/css-selector-tokenizer/-/css-selector-tokenizer-0.7.2.tgz", + "integrity": "sha512-yj856NGuAymN6r8bn8/Jl46pR+OC3eEvAhfGYDUe7YPtTPAYrSSw4oAniZ9Y8T5B92hjhwTBLUen0/vKPxf6pw==", + "dev": true, + "requires": { + "cssesc": "^3.0.0", + "fastparse": "^1.1.2", + "regexpu-core": "^4.6.0" + } }, - "builtin-modules": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/builtin-modules/-/builtin-modules-1.1.1.tgz", - "integrity": "sha1-Jw8HbFpywC9bZaR9+Uxf46J4iS8=", - "dev": true + "css-tree": { + "version": "1.0.0-alpha.37", + "resolved": "https://registry.npmjs.org/css-tree/-/css-tree-1.0.0-alpha.37.tgz", + "integrity": "sha512-DMxWJg0rnz7UgxKT0Q1HU/L9BeJI0M6ksor0OgqOnF+aRCDWg/N2641HmVyU9KVIu0OVVWOb2IpC9A+BJRnejg==", + "dev": true, + "requires": { + "mdn-data": "2.0.4", + "source-map": "^0.6.1" + }, + "dependencies": { + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true + } + } }, - "builtin-status-codes": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/builtin-status-codes/-/builtin-status-codes-3.0.0.tgz", - "integrity": "sha1-hZgoeOIbmOHGZCXgPQF0eI9Wnug=", + "css-what": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/css-what/-/css-what-3.2.1.tgz", + "integrity": "sha512-WwOrosiQTvyms+Ti5ZC5vGEK0Vod3FTt1ca+payZqvKuGJF+dq7bG63DstxtN0dpm6FxY27a/zS3Wten+gEtGw==", "dev": true }, - "builtins": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/builtins/-/builtins-1.0.3.tgz", - "integrity": "sha1-y5T662HIaWRR2zZTThQi+U8K7og=", - "dev": true + "cssauron": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/cssauron/-/cssauron-1.4.0.tgz", + "integrity": "sha1-pmAt/34EqDBtwNuaVR6S6LVmKtg=", + "dev": true, + "requires": { + "through": "X.X.X" + } }, - "bytes": { + "cssesc": { "version": "3.0.0", - "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.0.0.tgz", - "integrity": "sha1-0ygVQE1olpn4Wk6k+odV3ROpYEg=", + "resolved": "https://registry.npmjs.org/cssesc/-/cssesc-3.0.0.tgz", + "integrity": "sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==", "dev": true }, - "cacache": { - "version": "12.0.2", - "resolved": "https://registry.npmjs.org/cacache/-/cacache-12.0.2.tgz", - "integrity": "sha512-ifKgxH2CKhJEg6tNdAwziu6Q33EvuG26tYcda6PT3WKisZcYDXsnEdnRv67Po3yCzFfaSoMjGZzJyD2c3DT1dg==", + "cssnano": { + "version": "4.1.10", + "resolved": "https://registry.npmjs.org/cssnano/-/cssnano-4.1.10.tgz", + "integrity": "sha512-5wny+F6H4/8RgNlaqab4ktc3e0/blKutmq8yNlBFXA//nSFFAqAngjNVRzUvCgYROULmZZUoosL/KSoZo5aUaQ==", "dev": true, "requires": { - "bluebird": "^3.5.5", - "chownr": "^1.1.1", - "figgy-pudding": "^3.5.1", - "glob": "^7.1.4", - "graceful-fs": "^4.1.15", - "infer-owner": "^1.0.3", - "lru-cache": "^5.1.1", - "mississippi": "^3.0.0", - "mkdirp": "^0.5.1", - "move-concurrently": "^1.0.1", - "promise-inflight": "^1.0.1", - "rimraf": "^2.6.3", - "ssri": "^6.0.1", - "unique-filename": "^1.1.1", - "y18n": "^4.0.0" + "cosmiconfig": "^5.0.0", + "cssnano-preset-default": "^4.0.7", + "is-resolvable": "^1.0.0", + "postcss": "^7.0.0" } }, - "cache-base": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/cache-base/-/cache-base-1.0.1.tgz", - "integrity": "sha512-AKcdTnFSWATd5/GCPRxr2ChwIJ85CeyrEyjRHlKxQ56d4XJMGym0uAiKn0xbLOGOl3+yRpOTi484dVCEc5AUzQ==", + "cssnano-preset-default": { + "version": "4.0.7", + "resolved": "https://registry.npmjs.org/cssnano-preset-default/-/cssnano-preset-default-4.0.7.tgz", + "integrity": "sha512-x0YHHx2h6p0fCl1zY9L9roD7rnlltugGu7zXSKQx6k2rYw0Hi3IqxcoAGF7u9Q5w1nt7vK0ulxV8Lo+EvllGsA==", "dev": true, "requires": { - "collection-visit": "^1.0.0", - "component-emitter": "^1.2.1", - "get-value": "^2.0.6", - "has-value": "^1.0.0", - "isobject": "^3.0.1", - "set-value": "^2.0.0", - "to-object-path": "^0.3.0", - "union-value": "^1.0.0", - "unset-value": "^1.0.0" - } + "css-declaration-sorter": "^4.0.1", + "cssnano-util-raw-cache": "^4.0.1", + "postcss": "^7.0.0", + "postcss-calc": "^7.0.1", + "postcss-colormin": "^4.0.3", + "postcss-convert-values": "^4.0.1", + "postcss-discard-comments": "^4.0.2", + "postcss-discard-duplicates": "^4.0.2", + "postcss-discard-empty": "^4.0.1", + "postcss-discard-overridden": "^4.0.1", + "postcss-merge-longhand": "^4.0.11", + "postcss-merge-rules": "^4.0.3", + "postcss-minify-font-values": "^4.0.2", + "postcss-minify-gradients": "^4.0.2", + "postcss-minify-params": "^4.0.2", + "postcss-minify-selectors": "^4.0.2", + "postcss-normalize-charset": "^4.0.1", + "postcss-normalize-display-values": "^4.0.2", + "postcss-normalize-positions": "^4.0.2", + "postcss-normalize-repeat-style": "^4.0.2", + "postcss-normalize-string": "^4.0.2", + "postcss-normalize-timing-functions": "^4.0.2", + "postcss-normalize-unicode": "^4.0.1", + "postcss-normalize-url": "^4.0.1", + "postcss-normalize-whitespace": "^4.0.2", + "postcss-ordered-values": "^4.1.2", + "postcss-reduce-initial": "^4.0.3", + "postcss-reduce-transforms": "^4.0.2", + "postcss-svgo": "^4.0.2", + "postcss-unique-selectors": "^4.0.1" + } + }, + "cssnano-util-get-arguments": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/cssnano-util-get-arguments/-/cssnano-util-get-arguments-4.0.0.tgz", + "integrity": "sha1-7ToIKZ8h11dBsg87gfGU7UnMFQ8=", + "dev": true }, - "caller-callsite": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/caller-callsite/-/caller-callsite-2.0.0.tgz", - "integrity": "sha1-hH4PzgoiN1CpoCfFSzNzGtMVQTQ=", - "dev": true, - "requires": { - "callsites": "^2.0.0" - } + "cssnano-util-get-match": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/cssnano-util-get-match/-/cssnano-util-get-match-4.0.0.tgz", + "integrity": "sha1-wOTKB/U4a7F+xeUiULT1lhNlFW0=", + "dev": true }, - "caller-path": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/caller-path/-/caller-path-2.0.0.tgz", - "integrity": "sha1-Ro+DBE42mrIBD6xfBs7uFbsssfQ=", + "cssnano-util-raw-cache": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/cssnano-util-raw-cache/-/cssnano-util-raw-cache-4.0.1.tgz", + "integrity": "sha512-qLuYtWK2b2Dy55I8ZX3ky1Z16WYsx544Q0UWViebptpwn/xDBmog2TLg4f+DBMg1rJ6JDWtn96WHbOKDWt1WQA==", "dev": true, "requires": { - "caller-callsite": "^2.0.0" + "postcss": "^7.0.0" } }, - "callsite": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/callsite/-/callsite-1.0.0.tgz", - "integrity": "sha1-KAOY5dZkvXQDi28JBRU+borxvCA=", + "cssnano-util-same-parent": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/cssnano-util-same-parent/-/cssnano-util-same-parent-4.0.1.tgz", + "integrity": "sha512-WcKx5OY+KoSIAxBW6UBBRay1U6vkYheCdjyVNDm85zt5K9mHoGOfsOsqIszfAqrQQFIIKgjh2+FDgIj/zsl21Q==", "dev": true }, - "callsites": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/callsites/-/callsites-2.0.0.tgz", - "integrity": "sha1-BuuE8A7qQT2oav/vrL/7Ngk7PFA=", - "dev": true + "csso": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/csso/-/csso-4.0.2.tgz", + "integrity": "sha512-kS7/oeNVXkHWxby5tHVxlhjizRCSv8QdU7hB2FpdAibDU8FjTAolhNjKNTiLzXtUrKT6HwClE81yXwEk1309wg==", + "dev": true, + "requires": { + "css-tree": "1.0.0-alpha.37" + } }, - "camelcase": { - "version": "5.3.1", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", - "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", - "dev": true + "currently-unhandled": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/currently-unhandled/-/currently-unhandled-0.4.1.tgz", + "integrity": "sha1-mI3zP+qxke95mmE2nddsF635V+o=", + "requires": { + "array-find-index": "^1.0.1" + } }, - "caniuse-lite": { - "version": "1.0.30001024", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001024.tgz", - "integrity": "sha512-LubRSEPpOlKlhZw9wGlLHo8ZVj6ugGU3xGUfLPneNBledSd9lIM5cCGZ9Mz/mMCJUhEt4jZpYteZNVRdJw5FRA==", + "custom-event": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/custom-event/-/custom-event-1.0.1.tgz", + "integrity": "sha1-XQKkaFCt8bSjF5RqOSj8y1v9BCU=", "dev": true }, - "canonical-path": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/canonical-path/-/canonical-path-1.0.0.tgz", - "integrity": "sha512-feylzsbDxi1gPZ1IjystzIQZagYYLvfKrSuygUCgf7z6x790VEzze5QEkdSV1U58RA7Hi0+v6fv4K54atOzATg==", + "cyclist": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/cyclist/-/cyclist-1.0.1.tgz", + "integrity": "sha1-WW6WmP0MgOEgOMK4LW6xs1tiJNk=", "dev": true }, - "caseless": { - "version": "0.12.0", - "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz", - "integrity": "sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw=", + "damerau-levenshtein": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/damerau-levenshtein/-/damerau-levenshtein-1.0.6.tgz", + "integrity": "sha512-JVrozIeElnj3QzfUIt8tB8YMluBJom4Vw9qTPpjGYQ9fYlB3D/rb6OordUxf3xeFB35LKWs0xqcO5U6ySvBtug==", "dev": true }, - "chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", - "dev": true, + "dashdash": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz", + "integrity": "sha1-hTz6D3y+L+1d4gMmuN1YEDX24vA=", "requires": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" + "assert-plus": "^1.0.0" } }, - "chardet": { - "version": "0.7.0", - "resolved": "https://registry.npmjs.org/chardet/-/chardet-0.7.0.tgz", - "integrity": "sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA==", + "date-format": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/date-format/-/date-format-2.1.0.tgz", + "integrity": "sha512-bYQuGLeFxhkxNOF3rcMtiZxvCBAquGzZm6oWA1oZ0g2THUzivaRhv8uOhdr19LmoobSOLoIAxeUK2RdbM8IFTA==", "dev": true }, - "chokidar": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.3.1.tgz", - "integrity": "sha512-4QYCEWOcK3OJrxwvyyAOxFuhpvOVCYkr33LPfFNBjAD/w3sEzWsp2BUOkI4l9bHvWioAd0rc6NlHUOEaWkTeqg==", + "debug": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", + "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", "dev": true, "requires": { - "anymatch": "~3.1.1", - "braces": "~3.0.2", - "fsevents": "~2.1.2", - "glob-parent": "~5.1.0", - "is-binary-path": "~2.1.0", - "is-glob": "~4.0.1", - "normalize-path": "~3.0.0", - "readdirp": "~3.3.0" - }, - "dependencies": { - "glob-parent": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.0.tgz", - "integrity": "sha512-qjtRgnIVmOfnKUE3NJAQEdk+lKrxfw8t5ke7SXtfMTHcjsBfOfWXCQfdb30zfDoZQ2IRSIiidmjtbHZPZ++Ihw==", - "dev": true, - "requires": { - "is-glob": "^4.0.1" - } - } + "ms": "^2.1.1" } }, - "chownr": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/chownr/-/chownr-1.1.4.tgz", - "integrity": "sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg==", + "debuglog": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/debuglog/-/debuglog-1.0.1.tgz", + "integrity": "sha1-qiT/uaw9+aI1GDfPstJ5NgzXhJI=", "dev": true }, - "chrome-trace-event": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/chrome-trace-event/-/chrome-trace-event-1.0.2.tgz", - "integrity": "sha512-9e/zx1jw7B4CO+c/RXoCsfg/x1AfUBioy4owYH0bJprEYAx5hRFLRhWBqHAG57D0ZM4H7vxbP7bPe0VwhQRYDQ==", + "decamelize": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", + "integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=" + }, + "decode-uri-component": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/decode-uri-component/-/decode-uri-component-0.2.0.tgz", + "integrity": "sha1-6zkTMzRYd1y4TNGh+uBiEGu4dUU=", + "dev": true + }, + "deep-equal": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/deep-equal/-/deep-equal-1.1.1.tgz", + "integrity": "sha512-yd9c5AdiqVcR+JjcwUQb9DkhJc8ngNr0MahEBGvDiJw8puWab2yZlh+nkasOnZP+EGTAP6rRp2JzJhJZzvNF8g==", "dev": true, "requires": { - "tslib": "^1.9.0" + "is-arguments": "^1.0.4", + "is-date-object": "^1.0.1", + "is-regex": "^1.0.4", + "object-is": "^1.0.1", + "object-keys": "^1.1.1", + "regexp.prototype.flags": "^1.2.0" } }, - "cipher-base": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/cipher-base/-/cipher-base-1.0.4.tgz", - "integrity": "sha512-Kkht5ye6ZGmwv40uUDZztayT2ThLQGfnj/T71N/XzeZeo3nf8foyW7zGTsPYkEya3m5f3cAypH+qe7YOrM1U2Q==", + "default-gateway": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/default-gateway/-/default-gateway-4.2.0.tgz", + "integrity": "sha512-h6sMrVB1VMWVrW13mSc6ia/DwYYw5MN6+exNu1OaJeFac5aSAvwM7lZ0NVfTABuSkQelr4h5oebg3KB1XPdjgA==", "dev": true, "requires": { - "inherits": "^2.0.1", - "safe-buffer": "^5.0.1" + "execa": "^1.0.0", + "ip-regex": "^2.1.0" } }, - "circular-dependency-plugin": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/circular-dependency-plugin/-/circular-dependency-plugin-5.2.0.tgz", - "integrity": "sha512-7p4Kn/gffhQaavNfyDFg7LS5S/UT1JAjyGd4UqR2+jzoYF02eDkj0Ec3+48TsIa4zghjLY87nQHIh/ecK9qLdw==", - "dev": true - }, - "class-utils": { - "version": "0.3.6", - "resolved": "https://registry.npmjs.org/class-utils/-/class-utils-0.3.6.tgz", - "integrity": "sha512-qOhPa/Fj7s6TY8H8esGu5QNpMMQxz79h+urzrNYN6mn+9BnxlDGf5QZ+XeCDsxSjPqsSR56XOZOJmpeurnLMeg==", + "default-require-extensions": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/default-require-extensions/-/default-require-extensions-2.0.0.tgz", + "integrity": "sha1-9fj7sYp9bVCyH2QfZJ67Uiz+JPc=", "dev": true, "requires": { - "arr-union": "^3.1.0", - "define-property": "^0.2.5", - "isobject": "^3.0.0", - "static-extend": "^0.1.1" - }, - "dependencies": { - "define-property": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", - "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", - "dev": true, - "requires": { - "is-descriptor": "^0.1.0" - } - } + "strip-bom": "^3.0.0" } }, - "classlist.js": { - "version": "1.1.20150312", - "resolved": "https://registry.npmjs.org/classlist.js/-/classlist.js-1.1.20150312.tgz", - "integrity": "sha1-HXCEL3Ai8I2awIbOaeWyUPLFd4k=" - }, - "clean-css": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/clean-css/-/clean-css-4.2.1.tgz", - "integrity": "sha512-4ZxI6dy4lrY6FHzfiy1aEOXgu4LIsW2MhwG0VBKdcoGoH/XLFgaHSdLTGr4O8Be6A8r3MOphEiI8Gc1n0ecf3g==", + "defaults": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/defaults/-/defaults-1.0.3.tgz", + "integrity": "sha1-xlYFHpgX2f8I7YgUd/P+QBnz730=", "dev": true, "requires": { - "source-map": "~0.6.0" + "clone": "^1.0.2" }, "dependencies": { - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "clone": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/clone/-/clone-1.0.4.tgz", + "integrity": "sha1-2jCcwmPfFZlMaIypAheco8fNfH4=", "dev": true } } }, - "cli-cursor": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-3.1.0.tgz", - "integrity": "sha512-I/zHAwsKf9FqGoXM4WWRACob9+SNukZTd94DWF57E4toouRulbCxcUh6RKUEOQlYTHJnzkPMySvPNaaSLNfLZw==", - "dev": true, + "define-properties": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.3.tgz", + "integrity": "sha512-3MqfYKj2lLzdMSf8ZIZE/V+Zuy+BgD6f164e8K2w7dgnpKArBDerGYpM46IYYcjnkdPNMjPk9A6VFB8+3SKlXQ==", "requires": { - "restore-cursor": "^3.1.0" + "object-keys": "^1.0.12" } }, - "cli-width": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/cli-width/-/cli-width-2.2.0.tgz", - "integrity": "sha1-/xnt6Kml5XkyQUewwR8PvLq+1jk=", - "dev": true - }, - "cliui": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-4.1.0.tgz", - "integrity": "sha512-4FG+RSG9DL7uEwRUZXZn3SS34DiDPfzP0VOiEwtUWlE+AR2EIg+hSyvrIgUUfhdgR/UkAeW2QHgeP+hWrXs7jQ==", + "define-property": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-2.0.2.tgz", + "integrity": "sha512-jwK2UV4cnPpbcG7+VRARKTZPUWowwXA8bzH5NP6ud0oeAxyYPuGZUAC7hMugpCdz4BeSZl2Dl9k66CHJ/46ZYQ==", "dev": true, "requires": { - "string-width": "^2.1.1", - "strip-ansi": "^4.0.0", - "wrap-ansi": "^2.0.0" + "is-descriptor": "^1.0.2", + "isobject": "^3.0.1" }, "dependencies": { - "ansi-regex": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", - "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=", - "dev": true + "is-accessor-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", + "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", + "dev": true, + "requires": { + "kind-of": "^6.0.0" + } }, - "strip-ansi": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", - "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", + "is-data-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", + "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", "dev": true, "requires": { - "ansi-regex": "^3.0.0" + "kind-of": "^6.0.0" + } + }, + "is-descriptor": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", + "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", + "dev": true, + "requires": { + "is-accessor-descriptor": "^1.0.0", + "is-data-descriptor": "^1.0.0", + "kind-of": "^6.0.2" } } } }, - "clone": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/clone/-/clone-2.1.2.tgz", - "integrity": "sha1-G39Ln1kfHo+DZwQBYANFoCiHQ18=", - "dev": true - }, - "clone-deep": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/clone-deep/-/clone-deep-4.0.1.tgz", - "integrity": "sha512-neHB9xuzh/wk0dIHweyAXv2aPGZIVk3pLMe+/RNzINf17fe0OG96QroktYAUm7SM1PBnzTabaLboqqxDyMU+SQ==", - "dev": true, - "requires": { - "is-plain-object": "^2.0.4", - "kind-of": "^6.0.2", - "shallow-clone": "^3.0.0" - } - }, - "code-point-at": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/code-point-at/-/code-point-at-1.1.0.tgz", - "integrity": "sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c=", - "dev": true - }, - "codelyzer": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/codelyzer/-/codelyzer-5.2.1.tgz", - "integrity": "sha512-awBZXFcJUyC5HMYXiHzjr3D24tww2l1D1OqtfA9vUhEtYr32a65A+Gblm/OvsO+HuKLYzn8EDMw1inSM3VbxWA==", + "del": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/del/-/del-4.1.1.tgz", + "integrity": "sha512-QwGuEUouP2kVwQenAsOof5Fv8K9t3D8Ca8NxcXKrIpEHjTXK5J2nXLdP+ALI1cgv8wj7KuwBhTwBkOZSJKM5XQ==", "dev": true, "requires": { - "app-root-path": "^2.2.1", - "aria-query": "^3.0.0", - "axobject-query": "2.0.2", - "css-selector-tokenizer": "^0.7.1", - "cssauron": "^1.4.0", - "damerau-levenshtein": "^1.0.4", - "semver-dsl": "^1.0.1", - "source-map": "^0.5.7", - "sprintf-js": "^1.1.2" + "@types/glob": "^7.1.1", + "globby": "^6.1.0", + "is-path-cwd": "^2.0.0", + "is-path-in-cwd": "^2.0.0", + "p-map": "^2.0.0", + "pify": "^4.0.1", + "rimraf": "^2.6.3" }, "dependencies": { - "source-map": { - "version": "0.5.7", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", - "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", - "dev": true + "globby": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/globby/-/globby-6.1.0.tgz", + "integrity": "sha1-9abXDoOV4hyFj7BInWTfAkJNUGw=", + "dev": true, + "requires": { + "array-union": "^1.0.1", + "glob": "^7.0.3", + "object-assign": "^4.0.1", + "pify": "^2.0.0", + "pinkie-promise": "^2.0.0" + }, + "dependencies": { + "pify": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", + "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=", + "dev": true + } + } }, - "sprintf-js": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.1.2.tgz", - "integrity": "sha512-VE0SOVEHCk7Qc8ulkWw3ntAzXuqf7S2lvwQaDLRnUeIEaKNQJzV6BwmLKhOqT61aGhfUMrXeaBk+oDGCzvhcug==", + "p-map": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/p-map/-/p-map-2.1.0.tgz", + "integrity": "sha512-y3b8Kpd8OAN444hxfBbFfj1FY/RjtTd8tzYwhUqNYXx0fXx2iX4maP4Qr6qhIKbQXI02wTLAda4fYUbDagTUFw==", "dev": true } } }, - "collection-visit": { + "delayed-stream": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/collection-visit/-/collection-visit-1.0.0.tgz", - "integrity": "sha1-S8A3PBZLwykbTTaMgpzxqApZ3KA=", - "dev": true, - "requires": { - "map-visit": "^1.0.0", - "object-visit": "^1.0.0" - } + "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", + "integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk=" }, - "color-convert": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", - "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", - "dev": true, - "requires": { - "color-name": "1.1.3" - } + "delegates": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/delegates/-/delegates-1.0.0.tgz", + "integrity": "sha1-hMbhWbgZBP3KWaDvRM2HDTElD5o=" }, - "color-name": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", + "depd": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz", + "integrity": "sha1-m81S4UwJd2PnSbJ0xDRu0uVgtak=", "dev": true }, - "colors": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/colors/-/colors-1.1.2.tgz", - "integrity": "sha1-FopHAXVran9RoSzgyXv6KMCE7WM=", + "dependency-graph": { + "version": "0.7.2", + "resolved": "https://registry.npmjs.org/dependency-graph/-/dependency-graph-0.7.2.tgz", + "integrity": "sha512-KqtH4/EZdtdfWX0p6MGP9jljvxSY6msy/pRUD4jgNwVpv3v1QmNLlsB3LDSSUg79BRVSn7jI1QPRtArGABovAQ==", "dev": true }, - "combined-stream": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", - "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", + "des.js": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/des.js/-/des.js-1.0.1.tgz", + "integrity": "sha512-Q0I4pfFrv2VPd34/vfLrFOoRmlYj3OV50i7fskps1jZWK1kApMWWT9G6RRUeYedLcBDIhnSDaUvJMb3AhUlaEA==", "dev": true, "requires": { - "delayed-stream": "~1.0.0" + "inherits": "^2.0.1", + "minimalistic-assert": "^1.0.0" } }, - "commander": { - "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==", + "destroy": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.0.4.tgz", + "integrity": "sha1-l4hXRCxEdJ5CBmE+N5RiBYJqvYA=", "dev": true }, - "commondir": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/commondir/-/commondir-1.0.1.tgz", - "integrity": "sha1-3dgA2gxmEnOTzKWVDqloo6rxJTs=", - "dev": true + "detect-libc": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-1.0.3.tgz", + "integrity": "sha1-+hN8S9aY7fVc1c0CrFWfkaTEups=" }, - "compare-versions": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/compare-versions/-/compare-versions-3.6.0.tgz", - "integrity": "sha512-W6Af2Iw1z4CB7q4uU4hv646dW9GQuBM+YpC0UvUCWSD8w90SJjp+ujJuXaEMtAXBtSqGfMPuFOVn4/+FlaqfBA==", + "detect-node": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/detect-node/-/detect-node-2.0.4.tgz", + "integrity": "sha512-ZIzRpLJrOj7jjP2miAtgqIfmzbxa4ZOr5jJc601zklsfEx9oTzmmj2nVpIPRpNlRTIh8lc1kyViIY7BWSGNmKw==", "dev": true }, - "component-bind": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/component-bind/-/component-bind-1.0.0.tgz", - "integrity": "sha1-AMYIq33Nk4l8AAllGx06jh5zu9E=", - "dev": true + "dezalgo": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/dezalgo/-/dezalgo-1.0.3.tgz", + "integrity": "sha1-f3Qt4Gb8dIvI24IFad3c5Jvw1FY=", + "dev": true, + "requires": { + "asap": "^2.0.0", + "wrappy": "1" + } }, - "component-emitter": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.3.0.tgz", - "integrity": "sha512-Rd3se6QB+sO1TwqZjscQrurpEPIfO0/yYnSin6Q/rD3mOutHvUrCAhJub3r90uNb+SESBuE0QYoB90YdfatsRg==", + "di": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/di/-/di-0.0.1.tgz", + "integrity": "sha1-gGZJMmzqp8qjMG112YXqJ0i6kTw=", "dev": true }, - "component-inherit": { - "version": "0.0.3", - "resolved": "https://registry.npmjs.org/component-inherit/-/component-inherit-0.0.3.tgz", - "integrity": "sha1-ZF/ErfWLcrZJ1crmUTVhnbJv8UM=", + "diff": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz", + "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==", "dev": true }, - "compressible": { - "version": "2.0.18", - "resolved": "https://registry.npmjs.org/compressible/-/compressible-2.0.18.tgz", - "integrity": "sha512-AF3r7P5dWxL8MxyITRMlORQNaOA2IkAFaTr4k7BUumjPtRpGDTZpl0Pb1XCO6JeDCBdp126Cgs9sMxqSjgYyRg==", + "diffie-hellman": { + "version": "5.0.3", + "resolved": "https://registry.npmjs.org/diffie-hellman/-/diffie-hellman-5.0.3.tgz", + "integrity": "sha512-kqag/Nl+f3GwyK25fhUMYj81BUOrZ9IuJsjIcDE5icNM9FJHAVm3VcUDxdLPoQtTuUylWm6ZIknYJwwaPxsUzg==", "dev": true, "requires": { - "mime-db": ">= 1.43.0 < 2" + "bn.js": "^4.1.0", + "miller-rabin": "^4.0.0", + "randombytes": "^2.0.0" } }, - "compression": { - "version": "1.7.4", - "resolved": "https://registry.npmjs.org/compression/-/compression-1.7.4.tgz", - "integrity": "sha512-jaSIDzP9pZVS4ZfQ+TzvtiWhdpFhE2RDHz8QJkpX9SIpLq88VueF5jJw6t+6CUQcAoA6t+x89MLrWAqpfDE8iQ==", + "dir-glob": { + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-2.2.2.tgz", + "integrity": "sha512-f9LBi5QWzIW3I6e//uxZoLBlUt9kcp66qo0sSCxL6YZKc75R1c4MFCoe/LaZiBGmgujvQdxc5Bn3QhfyvK5Hsw==", "dev": true, "requires": { - "accepts": "~1.3.5", - "bytes": "3.0.0", - "compressible": "~2.0.16", - "debug": "2.6.9", - "on-headers": "~1.0.2", - "safe-buffer": "5.1.2", - "vary": "~1.1.2" - }, - "dependencies": { - "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dev": true, - "requires": { - "ms": "2.0.0" - } - }, - "ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", - "dev": true - } + "path-type": "^3.0.0" } }, - "concat-map": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", - "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=", + "dns-equal": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/dns-equal/-/dns-equal-1.0.0.tgz", + "integrity": "sha1-s55/HabrCnW6nBcySzR1PEfgZU0=", "dev": true }, - "concat-stream": { - "version": "1.6.2", - "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-1.6.2.tgz", - "integrity": "sha512-27HBghJxjiZtIk3Ycvn/4kbJk/1uZuJFfuPEns6LaEvpvG1f0hTea8lilrouyo9mVc2GWdcEZ8OLoGmSADlrCw==", + "dns-packet": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/dns-packet/-/dns-packet-1.3.1.tgz", + "integrity": "sha512-0UxfQkMhYAUaZI+xrNZOz/as5KgDU0M/fQ9b6SpkyLbk3GEswDi6PADJVaYJradtRVsRIlF1zLyOodbcTCDzUg==", "dev": true, "requires": { - "buffer-from": "^1.0.0", - "inherits": "^2.0.3", - "readable-stream": "^2.2.2", - "typedarray": "^0.0.6" + "ip": "^1.1.0", + "safe-buffer": "^5.0.1" } }, - "connect": { - "version": "3.7.0", - "resolved": "https://registry.npmjs.org/connect/-/connect-3.7.0.tgz", - "integrity": "sha512-ZqRXc+tZukToSNmh5C2iWMSoV3X1YUcPbqEM4DkEG5tNQXrQUZCNVGGv3IuicnkMtPfGf3Xtp8WCXs295iQ1pQ==", + "dns-txt": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/dns-txt/-/dns-txt-2.0.2.tgz", + "integrity": "sha1-uR2Ab10nGI5Ks+fRB9iBocxGQrY=", "dev": true, "requires": { - "debug": "2.6.9", - "finalhandler": "1.1.2", - "parseurl": "~1.3.3", - "utils-merge": "1.0.1" - }, - "dependencies": { - "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dev": true, - "requires": { - "ms": "2.0.0" - } - }, - "ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", - "dev": true - } + "buffer-indexof": "^1.0.0" } }, - "connect-history-api-fallback": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/connect-history-api-fallback/-/connect-history-api-fallback-1.6.0.tgz", - "integrity": "sha512-e54B99q/OUoH64zYYRf3HBP5z24G38h5D3qXu23JGRoigpX5Ss4r9ZnDk3g0Z8uQC2x2lPaJ+UlWBc1ZWBWdLg==", - "dev": true + "dom-converter": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/dom-converter/-/dom-converter-0.2.0.tgz", + "integrity": "sha512-gd3ypIPfOMr9h5jIKq8E3sHOTCjeirnl0WK5ZdS1AW0Odt0b1PaWaHdJ4Qk4klv+YB9aJBS7mESXjFoDQPu6DA==", + "requires": { + "utila": "~0.4" + } + }, + "dom-serialize": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/dom-serialize/-/dom-serialize-2.2.1.tgz", + "integrity": "sha1-ViromZ9Evl6jB29UGdzVnrQ6yVs=", + "dev": true, + "requires": { + "custom-event": "~1.0.0", + "ent": "~2.2.0", + "extend": "^3.0.0", + "void-elements": "^2.0.0" + } + }, + "dom-serializer": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-0.2.2.tgz", + "integrity": "sha512-2/xPb3ORsQ42nHYiSunXkDjPLBaEj/xTwUO4B7XCZQTRk7EBtTOPaygh10YAAh2OI1Qrp6NWfpAhzswj0ydt9g==", + "requires": { + "domelementtype": "^2.0.1", + "entities": "^2.0.0" + }, + "dependencies": { + "domelementtype": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-2.0.1.tgz", + "integrity": "sha512-5HOHUDsYZWV8FGWN0Njbr/Rn7f/eWSQi1v7+HsUVwXgn8nWWlL64zKDkS0n8ZmQ3mlWOMuXOnR+7Nx/5tMO5AQ==" + } + } }, - "console-browserify": { + "domain-browser": { "version": "1.2.0", - "resolved": "https://registry.npmjs.org/console-browserify/-/console-browserify-1.2.0.tgz", - "integrity": "sha512-ZMkYO/LkF17QvCPqM0gxw8yUzigAOZOSWSHg91FH6orS7vcEj5dVZTidN2fQ14yBSdg97RqhSNwLUXInd52OTA==", + "resolved": "https://registry.npmjs.org/domain-browser/-/domain-browser-1.2.0.tgz", + "integrity": "sha512-jnjyiM6eRyZl2H+W8Q/zLMA481hzi0eszAaBUzIVnmYVDBbnLxVNnfu1HgEBvCbL+71FrxMl3E6lpKH7Ge3OXA==", "dev": true }, - "constants-browserify": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/constants-browserify/-/constants-browserify-1.0.0.tgz", - "integrity": "sha1-wguW2MYXdIqvHBYCF2DNJ/y4y3U=", - "dev": true + "domelementtype": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-1.3.1.tgz", + "integrity": "sha512-BSKB+TSpMpFI/HOxCNr1O8aMOTZ8hT3pM3GQ0w/mWRmkhEDSFJkkyzz4XQsBV44BChwGkrDfMyjVD0eA2aFV3w==" }, - "content-disposition": { - "version": "0.5.3", - "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.3.tgz", - "integrity": "sha512-ExO0774ikEObIAEV9kDo50o+79VCUdEB6n6lzKgGwupcVeRlhrj3qGAfwq8G6uBJjkqLrhT0qEYFcWng8z1z0g==", + "domhandler": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-2.4.2.tgz", + "integrity": "sha512-JiK04h0Ht5u/80fdLMCEmV4zkNh2BcoMFBmZ/91WtYZ8qVXSKjiw7fXMgFPnHcSZgOo3XdinHvmnDUeMf5R4wA==", + "requires": { + "domelementtype": "1" + } + }, + "domutils": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/domutils/-/domutils-1.7.0.tgz", + "integrity": "sha512-Lgd2XcJ/NjEw+7tFvfKxOzCYKZsdct5lczQ2ZaQY8Djz7pfAD3Gbp8ySJWtreII/vDlMVmxwa6pHmdxIYgttDg==", + "requires": { + "dom-serializer": "0", + "domelementtype": "1" + } + }, + "dot-prop": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/dot-prop/-/dot-prop-5.2.0.tgz", + "integrity": "sha512-uEUyaDKoSQ1M4Oq8l45hSE26SnTxL6snNnqvK/VWx5wJhmff5z0FUVJDKDanor/6w3kzE3i7XZOk+7wC0EXr1A==", "dev": true, "requires": { - "safe-buffer": "5.1.2" + "is-obj": "^2.0.0" } }, - "content-type": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.4.tgz", - "integrity": "sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA==", + "duplexify": { + "version": "3.7.1", + "resolved": "https://registry.npmjs.org/duplexify/-/duplexify-3.7.1.tgz", + "integrity": "sha512-07z8uv2wMyS51kKhD1KsdXJg5WQ6t93RneqRxUHnskXVtlYYkLqM0gqStQZ3pj073g687jPCHrqNfCzawLYh5g==", + "dev": true, + "requires": { + "end-of-stream": "^1.0.0", + "inherits": "^2.0.1", + "readable-stream": "^2.0.0", + "stream-shift": "^1.0.0" + } + }, + "ecc-jsbn": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz", + "integrity": "sha1-OoOpBOVDUyh4dMVkt1SThoSamMk=", + "requires": { + "jsbn": "~0.1.0", + "safer-buffer": "^2.1.0" + } + }, + "ee-first": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", + "integrity": "sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0=", "dev": true }, - "convert-source-map": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.7.0.tgz", - "integrity": "sha512-4FJkXzKXEDB1snCFZlLP4gpC3JILicCpGbzG9f9G7tGqGCzETQ2hWPrcinA9oU4wtf2biUaEH5065UnMeR33oA==", + "electron-to-chromium": { + "version": "1.3.379", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.379.tgz", + "integrity": "sha512-NK9DBBYEBb5f9D7zXI0hiE941gq3wkBeQmXs1ingigA/jnTg5mhwY2Z5egwA+ZI8OLGKCx0h1Cl8/xeuIBuLlg==", + "dev": true + }, + "elliptic": { + "version": "6.5.2", + "resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.5.2.tgz", + "integrity": "sha512-f4x70okzZbIQl/NSRLkI/+tteV/9WqL98zx+SQ69KbXxmVrmjwsNUPn/gYJJ0sHvEak24cZgHIPegRePAtA/xw==", "dev": true, "requires": { - "safe-buffer": "~5.1.1" + "bn.js": "^4.4.0", + "brorand": "^1.0.1", + "hash.js": "^1.0.0", + "hmac-drbg": "^1.0.0", + "inherits": "^2.0.1", + "minimalistic-assert": "^1.0.0", + "minimalistic-crypto-utils": "^1.0.0" } }, - "cookie": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.4.0.tgz", - "integrity": "sha512-+Hp8fLp57wnUSt0tY0tHEXh4voZRDnoIrZPqlo3DPiI4y9lwg/jqx+1Om94/W6ZaPDOUbnjOt/99w66zk+l1Xg==", + "emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", "dev": true }, - "cookie-signature": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz", - "integrity": "sha1-4wOogrNCzD7oylE6eZmXNNqzriw=", + "emojis-list": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/emojis-list/-/emojis-list-2.1.0.tgz", + "integrity": "sha1-TapNnbAPmBmIDHn6RXrlsJof04k=" + }, + "encodeurl": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", + "integrity": "sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k=", "dev": true }, - "copy-concurrently": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/copy-concurrently/-/copy-concurrently-1.0.5.tgz", - "integrity": "sha512-f2domd9fsVDFtaFcbaRZuYXwtdmnzqbADSwhSWYxYB/Q8zsdUUFMXVRwXGDMWmbEzAn1kdRrtI1T/KTFOL4X2A==", + "encoding": { + "version": "0.1.12", + "resolved": "https://registry.npmjs.org/encoding/-/encoding-0.1.12.tgz", + "integrity": "sha1-U4tm8+5izRq1HsMjgp0flIDHS+s=", "dev": true, "requires": { - "aproba": "^1.1.1", - "fs-write-stream-atomic": "^1.0.8", - "iferr": "^0.1.5", - "mkdirp": "^0.5.1", - "rimraf": "^2.5.4", - "run-queue": "^1.0.0" + "iconv-lite": "~0.4.13" } }, - "copy-descriptor": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/copy-descriptor/-/copy-descriptor-0.1.1.tgz", - "integrity": "sha1-Z29us8OZl8LuGsOpJP1hJHSPV40=", - "dev": true + "end-of-stream": { + "version": "1.4.4", + "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz", + "integrity": "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==", + "dev": true, + "requires": { + "once": "^1.4.0" + } }, - "copy-webpack-plugin": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/copy-webpack-plugin/-/copy-webpack-plugin-5.1.1.tgz", - "integrity": "sha512-P15M5ZC8dyCjQHWwd4Ia/dm0SgVvZJMYeykVIVYXbGyqO4dWB5oyPHp9i7wjwo5LhtlhKbiBCdS2NvM07Wlybg==", + "engine.io": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/engine.io/-/engine.io-3.2.1.tgz", + "integrity": "sha512-+VlKzHzMhaU+GsCIg4AoXF1UdDFjHHwMmMKqMJNDNLlUlejz58FCy4LBqB2YVJskHGYl06BatYWKP2TVdVXE5w==", "dev": true, "requires": { - "cacache": "^12.0.3", - "find-cache-dir": "^2.1.0", - "glob-parent": "^3.1.0", - "globby": "^7.1.1", - "is-glob": "^4.0.1", - "loader-utils": "^1.2.3", - "minimatch": "^3.0.4", - "normalize-path": "^3.0.0", - "p-limit": "^2.2.1", - "schema-utils": "^1.0.0", - "serialize-javascript": "^2.1.2", - "webpack-log": "^2.0.0" + "accepts": "~1.3.4", + "base64id": "1.0.0", + "cookie": "0.3.1", + "debug": "~3.1.0", + "engine.io-parser": "~2.1.0", + "ws": "~3.3.1" }, "dependencies": { - "cacache": { - "version": "12.0.3", - "resolved": "https://registry.npmjs.org/cacache/-/cacache-12.0.3.tgz", - "integrity": "sha512-kqdmfXEGFepesTuROHMs3MpFLWrPkSSpRqOw80RCflZXy/khxaArvFrQ7uJxSUduzAufc6G0g1VUCOZXxWavPw==", + "cookie": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.3.1.tgz", + "integrity": "sha1-5+Ch+e9DtMi6klxcWpboBtFoc7s=", + "dev": true + }, + "debug": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", + "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", "dev": true, "requires": { - "bluebird": "^3.5.5", - "chownr": "^1.1.1", - "figgy-pudding": "^3.5.1", - "glob": "^7.1.4", - "graceful-fs": "^4.1.15", - "infer-owner": "^1.0.3", - "lru-cache": "^5.1.1", - "mississippi": "^3.0.0", - "mkdirp": "^0.5.1", - "move-concurrently": "^1.0.1", - "promise-inflight": "^1.0.1", - "rimraf": "^2.6.3", - "ssri": "^6.0.1", - "unique-filename": "^1.1.1", - "y18n": "^4.0.0" + "ms": "2.0.0" } }, - "find-cache-dir": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/find-cache-dir/-/find-cache-dir-2.1.0.tgz", - "integrity": "sha512-Tq6PixE0w/VMFfCgbONnkiQIVol/JJL7nRMi20fqzA4NRs9AfeqMGeRdPi3wIhYkxjeBaWh2rxwapn5Tu3IqOQ==", + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", + "dev": true + }, + "ws": { + "version": "3.3.3", + "resolved": "https://registry.npmjs.org/ws/-/ws-3.3.3.tgz", + "integrity": "sha512-nnWLa/NwZSt4KQJu51MYlCcSQ5g7INpOrOMt4XV8j4dqTXdmlUmSHQ8/oLC069ckre0fRsgfvsKwbTdtKLCDkA==", "dev": true, "requires": { - "commondir": "^1.0.1", - "make-dir": "^2.0.0", - "pkg-dir": "^3.0.0" + "async-limiter": "~1.0.0", + "safe-buffer": "~5.1.0", + "ultron": "~1.1.0" } } } }, - "core-js": { - "version": "3.6.4", - "resolved": "https://registry.npmjs.org/core-js/-/core-js-3.6.4.tgz", - "integrity": "sha512-4paDGScNgZP2IXXilaffL9X7968RuvwlkK3xWtZRVqgd8SYNiVKRJvkFd1aqqEuPfN7E68ZHEp9hDj6lHj4Hyw==" - }, - "core-js-compat": { - "version": "3.6.4", - "resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.6.4.tgz", - "integrity": "sha512-zAa3IZPvsJ0slViBQ2z+vgyyTuhd3MFn1rBQjZSKVEgB0UMYhUkCj9jJUVPgGTGqWvsBVmfnruXgTcNyTlEiSA==", - "dev": true, - "requires": { - "browserslist": "^4.8.3", - "semver": "7.0.0" - }, - "dependencies": { - "semver": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.0.0.tgz", - "integrity": "sha512-+GB6zVA9LWh6zovYQLALHwv5rb2PHGlJi3lfiqIHxR0uuwCgefcOJc59v9fv1w8GbStwxuuqqAjI9NMAOOgq1A==", - "dev": true - } - } - }, - "core-util-is": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", - "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=", - "dev": true - }, - "cosmiconfig": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-5.2.1.tgz", - "integrity": "sha512-H65gsXo1SKjf8zmrJ67eJk8aIRKV5ff2D4uKZIBZShbhGSpEmsQOPW/SKMKYhSTrqR7ufy6RP69rPogdaPh/kA==", - "dev": true, - "requires": { - "import-fresh": "^2.0.0", - "is-directory": "^0.3.1", - "js-yaml": "^3.13.1", - "parse-json": "^4.0.0" - } - }, - "coverage-istanbul-loader": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/coverage-istanbul-loader/-/coverage-istanbul-loader-2.0.3.tgz", - "integrity": "sha512-LiGRvyIuzVYs3M1ZYK1tF0HekjH0DJ8zFdUwAZq378EJzqOgToyb1690dp3TAUlP6Y+82uu42LRjuROVeJ54CA==", - "dev": true, - "requires": { - "convert-source-map": "^1.7.0", - "istanbul-lib-instrument": "^4.0.0", - "loader-utils": "^1.2.3", - "merge-source-map": "^1.1.0", - "schema-utils": "^2.6.1" + "engine.io-client": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/engine.io-client/-/engine.io-client-3.2.1.tgz", + "integrity": "sha512-y5AbkytWeM4jQr7m/koQLc5AxpRKC1hEVUb/s1FUAWEJq5AzJJ4NLvzuKPuxtDi5Mq755WuDvZ6Iv2rXj4PTzw==", + "dev": true, + "requires": { + "component-emitter": "1.2.1", + "component-inherit": "0.0.3", + "debug": "~3.1.0", + "engine.io-parser": "~2.1.1", + "has-cors": "1.1.0", + "indexof": "0.0.1", + "parseqs": "0.0.5", + "parseuri": "0.0.5", + "ws": "~3.3.1", + "xmlhttprequest-ssl": "~1.5.4", + "yeast": "0.1.2" }, "dependencies": { - "ajv": { - "version": "6.12.0", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.0.tgz", - "integrity": "sha512-D6gFiFA0RRLyUbvijN74DWAjXSFxWKaWP7mldxkVhyhAV3+SWA9HEJPHQ2c9soIeTFJqcSdFDGFgdqs1iUU2Hw==", + "component-emitter": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.2.1.tgz", + "integrity": "sha1-E3kY1teCg/ffemt8WmPhQOaUJeY=", + "dev": true + }, + "debug": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", + "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", "dev": true, "requires": { - "fast-deep-equal": "^3.1.1", - "fast-json-stable-stringify": "^2.0.0", - "json-schema-traverse": "^0.4.1", - "uri-js": "^4.2.2" + "ms": "2.0.0" } }, - "fast-deep-equal": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.1.tgz", - "integrity": "sha512-8UEa58QDLauDNfpbrX55Q9jrGHThw2ZMdOky5Gl1CDtVeJDPVrG4Jxx1N8jw2gkWaff5UUuX1KJd+9zGe2B+ZA==", + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", "dev": true }, - "schema-utils": { - "version": "2.6.5", - "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-2.6.5.tgz", - "integrity": "sha512-5KXuwKziQrTVHh8j/Uxz+QUbxkaLW9X/86NBlx/gnKgtsZA2GIVMUn17qWhRFwF8jdYb3Dig5hRO/W5mZqy6SQ==", + "ws": { + "version": "3.3.3", + "resolved": "https://registry.npmjs.org/ws/-/ws-3.3.3.tgz", + "integrity": "sha512-nnWLa/NwZSt4KQJu51MYlCcSQ5g7INpOrOMt4XV8j4dqTXdmlUmSHQ8/oLC069ckre0fRsgfvsKwbTdtKLCDkA==", "dev": true, "requires": { - "ajv": "^6.12.0", - "ajv-keywords": "^3.4.1" + "async-limiter": "~1.0.0", + "safe-buffer": "~5.1.0", + "ultron": "~1.1.0" } } } }, - "create-ecdh": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/create-ecdh/-/create-ecdh-4.0.3.tgz", - "integrity": "sha512-GbEHQPMOswGpKXM9kCWVrremUcBmjteUaQ01T9rkKCPDXfUHX0IoP9LpHYo2NPFampa4e+/pFDc3jQdxrxQLaw==", + "engine.io-parser": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/engine.io-parser/-/engine.io-parser-2.1.3.tgz", + "integrity": "sha512-6HXPre2O4Houl7c4g7Ic/XzPnHBvaEmN90vtRO9uLmwtRqQmTOw0QMevL1TOfL2Cpu1VzsaTmMotQgMdkzGkVA==", "dev": true, "requires": { - "bn.js": "^4.1.0", - "elliptic": "^6.0.0" + "after": "0.8.2", + "arraybuffer.slice": "~0.0.7", + "base64-arraybuffer": "0.1.5", + "blob": "0.0.5", + "has-binary2": "~1.0.2" } }, - "create-hash": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/create-hash/-/create-hash-1.2.0.tgz", - "integrity": "sha512-z00bCGNHDG8mHAkP7CtT1qVu+bFQUPjYq/4Iv3C3kWjTFV10zIjfSoeqXo9Asws8gwSHDGj/hl2u4OGIjapeCg==", + "enhanced-resolve": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-4.1.1.tgz", + "integrity": "sha512-98p2zE+rL7/g/DzMHMTF4zZlCgeVdJ7yr6xzEpJRYwFYrGi9ANdn5DnJURg6RpBkyk60XYDnWIv51VfIhfNGuA==", "dev": true, "requires": { - "cipher-base": "^1.0.1", - "inherits": "^2.0.1", - "md5.js": "^1.3.4", - "ripemd160": "^2.0.1", - "sha.js": "^2.4.0" + "graceful-fs": "^4.1.2", + "memory-fs": "^0.5.0", + "tapable": "^1.0.0" } }, - "create-hmac": { - "version": "1.1.7", - "resolved": "https://registry.npmjs.org/create-hmac/-/create-hmac-1.1.7.tgz", - "integrity": "sha512-MJG9liiZ+ogc4TzUwuvbER1JRdgvUFSB5+VR/g5h82fGaIRWMWddtKBHi7/sVhfjQZ6SehlyhvQYrcYkaUIpLg==", + "ent": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/ent/-/ent-2.2.0.tgz", + "integrity": "sha1-6WQhkyWiHQX0RGai9obtbOX13R0=", + "dev": true + }, + "entities": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/entities/-/entities-2.0.0.tgz", + "integrity": "sha512-D9f7V0JSRwIxlRI2mjMqufDrRDnx8p+eEOz7aUM9SuvF8gsBzra0/6tbjl1m8eQHrZlYj6PxqE00hZ1SAIKPLw==" + }, + "err-code": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/err-code/-/err-code-1.1.2.tgz", + "integrity": "sha1-BuARbTAo9q70gGhJ6w6mp0iuaWA=", + "dev": true + }, + "errno": { + "version": "0.1.7", + "resolved": "https://registry.npmjs.org/errno/-/errno-0.1.7.tgz", + "integrity": "sha512-MfrRBDWzIWifgq6tJj60gkAwtLNb6sQPlcFrSOflcP1aFmmruKQ2wRnze/8V6kgyz7H3FF8Npzv78mZ7XLLflg==", "dev": true, "requires": { - "cipher-base": "^1.0.3", - "create-hash": "^1.1.0", - "inherits": "^2.0.1", - "ripemd160": "^2.0.0", - "safe-buffer": "^5.0.1", - "sha.js": "^2.4.8" + "prr": "~1.0.1" } }, - "cross-spawn": { - "version": "6.0.5", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz", - "integrity": "sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==", - "dev": true, + "error-ex": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", + "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==", "requires": { - "nice-try": "^1.0.4", - "path-key": "^2.0.1", - "semver": "^5.5.0", - "shebang-command": "^1.2.0", - "which": "^1.2.9" - }, - "dependencies": { - "semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", - "dev": true - } + "is-arrayish": "^0.2.1" } }, - "crypto-browserify": { - "version": "3.12.0", - "resolved": "https://registry.npmjs.org/crypto-browserify/-/crypto-browserify-3.12.0.tgz", - "integrity": "sha512-fz4spIh+znjO2VjL+IdhEpRJ3YN6sMzITSBijk6FK2UvTqruSQW+/cCZTSNsMiZNvUeq0CqurF+dAbyiGOY6Wg==", + "es-abstract": { + "version": "1.17.4", + "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.17.4.tgz", + "integrity": "sha512-Ae3um/gb8F0mui/jPL+QiqmglkUsaQf7FwBEHYIFkztkneosu9imhqHpBzQ3h1vit8t5iQ74t6PEVvphBZiuiQ==", + "requires": { + "es-to-primitive": "^1.2.1", + "function-bind": "^1.1.1", + "has": "^1.0.3", + "has-symbols": "^1.0.1", + "is-callable": "^1.1.5", + "is-regex": "^1.0.5", + "object-inspect": "^1.7.0", + "object-keys": "^1.1.1", + "object.assign": "^4.1.0", + "string.prototype.trimleft": "^2.1.1", + "string.prototype.trimright": "^2.1.1" + } + }, + "es-to-primitive": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.1.tgz", + "integrity": "sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==", + "requires": { + "is-callable": "^1.1.4", + "is-date-object": "^1.0.1", + "is-symbol": "^1.0.2" + } + }, + "es6-promise": { + "version": "4.2.8", + "resolved": "https://registry.npmjs.org/es6-promise/-/es6-promise-4.2.8.tgz", + "integrity": "sha512-HJDGx5daxeIvxdBxvG2cb9g4tEvwIk3i8+nhX0yGrYmZUzbkdg8QbDevheDB8gd0//uPj4c1EQua8Q+MViT0/w==", + "dev": true + }, + "es6-promisify": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/es6-promisify/-/es6-promisify-5.0.0.tgz", + "integrity": "sha1-UQnWLz5W6pZ8S2NQWu8IKRyKUgM=", "dev": true, "requires": { - "browserify-cipher": "^1.0.0", - "browserify-sign": "^4.0.0", - "create-ecdh": "^4.0.0", - "create-hash": "^1.1.0", - "create-hmac": "^1.1.0", - "diffie-hellman": "^5.0.0", - "inherits": "^2.0.1", - "pbkdf2": "^3.0.3", - "public-encrypt": "^4.0.0", - "randombytes": "^2.0.0", - "randomfill": "^1.0.3" + "es6-promise": "^4.0.3" } }, - "css-parse": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/css-parse/-/css-parse-1.7.0.tgz", - "integrity": "sha1-Mh9s9zeCpv91ERE5D8BeLGV9jJs=", + "escape-html": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", + "integrity": "sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg=", "dev": true }, - "css-selector-tokenizer": { - "version": "0.7.2", - "resolved": "https://registry.npmjs.org/css-selector-tokenizer/-/css-selector-tokenizer-0.7.2.tgz", - "integrity": "sha512-yj856NGuAymN6r8bn8/Jl46pR+OC3eEvAhfGYDUe7YPtTPAYrSSw4oAniZ9Y8T5B92hjhwTBLUen0/vKPxf6pw==", + "escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=" + }, + "eslint-scope": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-4.0.3.tgz", + "integrity": "sha512-p7VutNr1O/QrxysMo3E45FjYDTeXBy0iTltPFNSqKAIfjDSXC+4dj+qfyuD8bfAXrW/y6lW3O76VaYNPKfpKrg==", "dev": true, "requires": { - "cssesc": "^3.0.0", - "fastparse": "^1.1.2", - "regexpu-core": "^4.6.0" + "esrecurse": "^4.1.0", + "estraverse": "^4.1.1" } }, - "cssauron": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/cssauron/-/cssauron-1.4.0.tgz", - "integrity": "sha1-pmAt/34EqDBtwNuaVR6S6LVmKtg=", + "esprima": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", + "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", + "dev": true + }, + "esrecurse": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.2.1.tgz", + "integrity": "sha512-64RBB++fIOAXPw3P9cy89qfMlvZEXZkqqJkjqqXIvzP5ezRZjW+lPWjw35UX/3EhUPFYbg5ER4JYgDw4007/DQ==", "dev": true, "requires": { - "through": "X.X.X" + "estraverse": "^4.1.0" } }, - "cssesc": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/cssesc/-/cssesc-3.0.0.tgz", - "integrity": "sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==", + "estraverse": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", + "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==", "dev": true }, - "custom-event": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/custom-event/-/custom-event-1.0.1.tgz", - "integrity": "sha1-XQKkaFCt8bSjF5RqOSj8y1v9BCU=", + "esutils": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", + "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", "dev": true }, - "cyclist": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/cyclist/-/cyclist-1.0.1.tgz", - "integrity": "sha1-WW6WmP0MgOEgOMK4LW6xs1tiJNk=", + "etag": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", + "integrity": "sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc=", + "dev": true + }, + "eventemitter3": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-4.0.0.tgz", + "integrity": "sha512-qerSRB0p+UDEssxTtm6EDKcE7W4OaoisfIMl4CngyEhjpYglocpNg6UEqCvemdGhosAsg4sO2dXJOdyBifPGCg==", "dev": true }, - "damerau-levenshtein": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/damerau-levenshtein/-/damerau-levenshtein-1.0.6.tgz", - "integrity": "sha512-JVrozIeElnj3QzfUIt8tB8YMluBJom4Vw9qTPpjGYQ9fYlB3D/rb6OordUxf3xeFB35LKWs0xqcO5U6ySvBtug==", + "events": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/events/-/events-3.1.0.tgz", + "integrity": "sha512-Rv+u8MLHNOdMjTAFeT3nCjHn2aGlx435FP/sDHNaRhDEMwyI/aB22Kj2qIN8R0cw3z28psEQLYwxVKLsKrMgWg==", "dev": true }, - "dashdash": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz", - "integrity": "sha1-hTz6D3y+L+1d4gMmuN1YEDX24vA=", + "eventsource": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/eventsource/-/eventsource-1.0.7.tgz", + "integrity": "sha512-4Ln17+vVT0k8aWq+t/bF5arcS3EpT9gYtW66EPacdj/mAFevznsnyoHLPy2BA8gbIQeIHoPsvwmfBftfcG//BQ==", "dev": true, "requires": { - "assert-plus": "^1.0.0" + "original": "^1.0.0" } }, - "date-format": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/date-format/-/date-format-2.1.0.tgz", - "integrity": "sha512-bYQuGLeFxhkxNOF3rcMtiZxvCBAquGzZm6oWA1oZ0g2THUzivaRhv8uOhdr19LmoobSOLoIAxeUK2RdbM8IFTA==", - "dev": true - }, - "debug": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", - "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", + "evp_bytestokey": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/evp_bytestokey/-/evp_bytestokey-1.0.3.tgz", + "integrity": "sha512-/f2Go4TognH/KvCISP7OUsHn85hT9nUkxxA9BEWxFn+Oj9o8ZNLm/40hdlgSLyuOimsrTKLUMEorQexp/aPQeA==", "dev": true, "requires": { - "ms": "^2.1.1" + "md5.js": "^1.3.4", + "safe-buffer": "^5.1.1" } }, - "debuglog": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/debuglog/-/debuglog-1.0.1.tgz", - "integrity": "sha1-qiT/uaw9+aI1GDfPstJ5NgzXhJI=", - "dev": true - }, - "decamelize": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", - "integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=", - "dev": true + "execa": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/execa/-/execa-1.0.0.tgz", + "integrity": "sha512-adbxcyWV46qiHyvSp50TKt05tB4tK3HcmF7/nxfAdhnox83seTDbwnaqKO4sXRy7roHAIFqJP/Rw/AuEbX61LA==", + "dev": true, + "requires": { + "cross-spawn": "^6.0.0", + "get-stream": "^4.0.0", + "is-stream": "^1.1.0", + "npm-run-path": "^2.0.0", + "p-finally": "^1.0.0", + "signal-exit": "^3.0.0", + "strip-eof": "^1.0.0" + } }, - "decode-uri-component": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/decode-uri-component/-/decode-uri-component-0.2.0.tgz", - "integrity": "sha1-6zkTMzRYd1y4TNGh+uBiEGu4dUU=", + "exit": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/exit/-/exit-0.1.2.tgz", + "integrity": "sha1-BjJjj42HfMghB9MKD/8aF8uhzQw=", "dev": true }, - "deep-equal": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/deep-equal/-/deep-equal-1.1.1.tgz", - "integrity": "sha512-yd9c5AdiqVcR+JjcwUQb9DkhJc8ngNr0MahEBGvDiJw8puWab2yZlh+nkasOnZP+EGTAP6rRp2JzJhJZzvNF8g==", + "expand-brackets": { + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-2.1.4.tgz", + "integrity": "sha1-t3c14xXOMPa27/D4OwQVGiJEliI=", "dev": true, "requires": { - "is-arguments": "^1.0.4", - "is-date-object": "^1.0.1", - "is-regex": "^1.0.4", - "object-is": "^1.0.1", - "object-keys": "^1.1.1", - "regexp.prototype.flags": "^1.2.0" + "debug": "^2.3.3", + "define-property": "^0.2.5", + "extend-shallow": "^2.0.1", + "posix-character-classes": "^0.1.0", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.1" + }, + "dependencies": { + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "requires": { + "ms": "2.0.0" + } + }, + "define-property": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", + "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", + "dev": true, + "requires": { + "is-descriptor": "^0.1.0" + } + }, + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "dev": true, + "requires": { + "is-extendable": "^0.1.0" + } + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", + "dev": true + } } }, - "default-gateway": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/default-gateway/-/default-gateway-4.2.0.tgz", - "integrity": "sha512-h6sMrVB1VMWVrW13mSc6ia/DwYYw5MN6+exNu1OaJeFac5aSAvwM7lZ0NVfTABuSkQelr4h5oebg3KB1XPdjgA==", + "express": { + "version": "4.17.1", + "resolved": "https://registry.npmjs.org/express/-/express-4.17.1.tgz", + "integrity": "sha512-mHJ9O79RqluphRrcw2X/GTh3k9tVv8YcoyY4Kkh4WDMUYKRZUq0h1o0w2rrrxBqM7VoeUVqgb27xlEMXTnYt4g==", "dev": true, "requires": { - "execa": "^1.0.0", - "ip-regex": "^2.1.0" + "accepts": "~1.3.7", + "array-flatten": "1.1.1", + "body-parser": "1.19.0", + "content-disposition": "0.5.3", + "content-type": "~1.0.4", + "cookie": "0.4.0", + "cookie-signature": "1.0.6", + "debug": "2.6.9", + "depd": "~1.1.2", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "etag": "~1.8.1", + "finalhandler": "~1.1.2", + "fresh": "0.5.2", + "merge-descriptors": "1.0.1", + "methods": "~1.1.2", + "on-finished": "~2.3.0", + "parseurl": "~1.3.3", + "path-to-regexp": "0.1.7", + "proxy-addr": "~2.0.5", + "qs": "6.7.0", + "range-parser": "~1.2.1", + "safe-buffer": "5.1.2", + "send": "0.17.1", + "serve-static": "1.14.1", + "setprototypeof": "1.1.1", + "statuses": "~1.5.0", + "type-is": "~1.6.18", + "utils-merge": "1.0.1", + "vary": "~1.1.2" + }, + "dependencies": { + "array-flatten": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", + "integrity": "sha1-ml9pkFGx5wczKPKgCJaLZOopVdI=", + "dev": true + }, + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "requires": { + "ms": "2.0.0" + } + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", + "dev": true + }, + "qs": { + "version": "6.7.0", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.7.0.tgz", + "integrity": "sha512-VCdBRNFTX1fyE7Nb6FYoURo/SPe62QCaAyzJvUjwRaIsc+NePBEniHlvxFmmX56+HZphIGtV0XeCirBtpDrTyQ==", + "dev": true + } } }, - "default-require-extensions": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/default-require-extensions/-/default-require-extensions-2.0.0.tgz", - "integrity": "sha1-9fj7sYp9bVCyH2QfZJ67Uiz+JPc=", + "extend": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", + "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==" + }, + "extend-shallow": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-3.0.2.tgz", + "integrity": "sha1-Jqcarwc7OfshJxcnRhMcJwQCjbg=", "dev": true, "requires": { - "strip-bom": "^3.0.0" + "assign-symbols": "^1.0.0", + "is-extendable": "^1.0.1" + }, + "dependencies": { + "is-extendable": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", + "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", + "dev": true, + "requires": { + "is-plain-object": "^2.0.4" + } + } } }, - "define-properties": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.3.tgz", - "integrity": "sha512-3MqfYKj2lLzdMSf8ZIZE/V+Zuy+BgD6f164e8K2w7dgnpKArBDerGYpM46IYYcjnkdPNMjPk9A6VFB8+3SKlXQ==", + "external-editor": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/external-editor/-/external-editor-3.1.0.tgz", + "integrity": "sha512-hMQ4CX1p1izmuLYyZqLMO/qGNw10wSv9QDCPfzXfyFrOaCSSoRfqE1Kf1s5an66J5JZC62NewG+mK49jOCtQew==", "dev": true, "requires": { - "object-keys": "^1.0.12" + "chardet": "^0.7.0", + "iconv-lite": "^0.4.24", + "tmp": "^0.0.33" } }, - "define-property": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-2.0.2.tgz", - "integrity": "sha512-jwK2UV4cnPpbcG7+VRARKTZPUWowwXA8bzH5NP6ud0oeAxyYPuGZUAC7hMugpCdz4BeSZl2Dl9k66CHJ/46ZYQ==", + "extglob": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/extglob/-/extglob-2.0.4.tgz", + "integrity": "sha512-Nmb6QXkELsuBr24CJSkilo6UHHgbekK5UiZgfE6UHD3Eb27YC6oD+bhcT+tJ6cl8dmsgdQxnWlcry8ksBIBLpw==", "dev": true, "requires": { - "is-descriptor": "^1.0.2", - "isobject": "^3.0.1" + "array-unique": "^0.3.2", + "define-property": "^1.0.0", + "expand-brackets": "^2.1.4", + "extend-shallow": "^2.0.1", + "fragment-cache": "^0.2.1", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.1" }, "dependencies": { + "define-property": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", + "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", + "dev": true, + "requires": { + "is-descriptor": "^1.0.0" + } + }, + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "dev": true, + "requires": { + "is-extendable": "^0.1.0" + } + }, "is-accessor-descriptor": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", @@ -4160,278 +4674,142 @@ } } }, - "del": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/del/-/del-4.1.1.tgz", - "integrity": "sha512-QwGuEUouP2kVwQenAsOof5Fv8K9t3D8Ca8NxcXKrIpEHjTXK5J2nXLdP+ALI1cgv8wj7KuwBhTwBkOZSJKM5XQ==", - "dev": true, - "requires": { - "@types/glob": "^7.1.1", - "globby": "^6.1.0", - "is-path-cwd": "^2.0.0", - "is-path-in-cwd": "^2.0.0", - "p-map": "^2.0.0", - "pify": "^4.0.1", - "rimraf": "^2.6.3" - }, - "dependencies": { - "globby": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/globby/-/globby-6.1.0.tgz", - "integrity": "sha1-9abXDoOV4hyFj7BInWTfAkJNUGw=", - "dev": true, - "requires": { - "array-union": "^1.0.1", - "glob": "^7.0.3", - "object-assign": "^4.0.1", - "pify": "^2.0.0", - "pinkie-promise": "^2.0.0" - }, - "dependencies": { - "pify": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", - "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=", - "dev": true - } - } - } - } - }, - "delayed-stream": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", - "integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk=", - "dev": true - }, - "depd": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz", - "integrity": "sha1-m81S4UwJd2PnSbJ0xDRu0uVgtak=", - "dev": true - }, - "dependency-graph": { - "version": "0.7.2", - "resolved": "https://registry.npmjs.org/dependency-graph/-/dependency-graph-0.7.2.tgz", - "integrity": "sha512-KqtH4/EZdtdfWX0p6MGP9jljvxSY6msy/pRUD4jgNwVpv3v1QmNLlsB3LDSSUg79BRVSn7jI1QPRtArGABovAQ==", - "dev": true + "extsprintf": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz", + "integrity": "sha1-lpGEQOMEGnpBT4xS48V06zw+HgU=" }, - "des.js": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/des.js/-/des.js-1.0.1.tgz", - "integrity": "sha512-Q0I4pfFrv2VPd34/vfLrFOoRmlYj3OV50i7fskps1jZWK1kApMWWT9G6RRUeYedLcBDIhnSDaUvJMb3AhUlaEA==", - "dev": true, - "requires": { - "inherits": "^2.0.1", - "minimalistic-assert": "^1.0.0" - } + "fast-deep-equal": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-2.0.1.tgz", + "integrity": "sha1-ewUhjd+WZ79/Nwv3/bLLFf3Qqkk=" }, - "destroy": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.0.4.tgz", - "integrity": "sha1-l4hXRCxEdJ5CBmE+N5RiBYJqvYA=", - "dev": true + "fast-json-stable-stringify": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.0.0.tgz", + "integrity": "sha1-1RQsDK7msRifh9OnYREGT4bIu/I=" }, - "detect-node": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/detect-node/-/detect-node-2.0.4.tgz", - "integrity": "sha512-ZIzRpLJrOj7jjP2miAtgqIfmzbxa4ZOr5jJc601zklsfEx9oTzmmj2nVpIPRpNlRTIh8lc1kyViIY7BWSGNmKw==", + "fastparse": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/fastparse/-/fastparse-1.1.2.tgz", + "integrity": "sha512-483XLLxTVIwWK3QTrMGRqUfUpoOs/0hbQrl2oz4J0pAcm3A3bu84wxTFqGqkJzewCLdME38xJLJAxBABfQT8sQ==", "dev": true }, - "dezalgo": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/dezalgo/-/dezalgo-1.0.3.tgz", - "integrity": "sha1-f3Qt4Gb8dIvI24IFad3c5Jvw1FY=", + "faye-websocket": { + "version": "0.10.0", + "resolved": "https://registry.npmjs.org/faye-websocket/-/faye-websocket-0.10.0.tgz", + "integrity": "sha1-TkkvjQTftviQA1B/btvy1QHnxvQ=", "dev": true, "requires": { - "asap": "^2.0.0", - "wrappy": "1" + "websocket-driver": ">=0.5.1" } }, - "di": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/di/-/di-0.0.1.tgz", - "integrity": "sha1-gGZJMmzqp8qjMG112YXqJ0i6kTw=", - "dev": true - }, - "diff": { + "fibers": { "version": "4.0.2", - "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz", - "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==", - "dev": true - }, - "diffie-hellman": { - "version": "5.0.3", - "resolved": "https://registry.npmjs.org/diffie-hellman/-/diffie-hellman-5.0.3.tgz", - "integrity": "sha512-kqag/Nl+f3GwyK25fhUMYj81BUOrZ9IuJsjIcDE5icNM9FJHAVm3VcUDxdLPoQtTuUylWm6ZIknYJwwaPxsUzg==", - "dev": true, - "requires": { - "bn.js": "^4.1.0", - "miller-rabin": "^4.0.0", - "randombytes": "^2.0.0" - } - }, - "dir-glob": { - "version": "2.2.2", - "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-2.2.2.tgz", - "integrity": "sha512-f9LBi5QWzIW3I6e//uxZoLBlUt9kcp66qo0sSCxL6YZKc75R1c4MFCoe/LaZiBGmgujvQdxc5Bn3QhfyvK5Hsw==", - "dev": true, - "requires": { - "path-type": "^3.0.0" - } - }, - "dns-equal": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/dns-equal/-/dns-equal-1.0.0.tgz", - "integrity": "sha1-s55/HabrCnW6nBcySzR1PEfgZU0=", - "dev": true - }, - "dns-packet": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/dns-packet/-/dns-packet-1.3.1.tgz", - "integrity": "sha512-0UxfQkMhYAUaZI+xrNZOz/as5KgDU0M/fQ9b6SpkyLbk3GEswDi6PADJVaYJradtRVsRIlF1zLyOodbcTCDzUg==", - "dev": true, - "requires": { - "ip": "^1.1.0", - "safe-buffer": "^5.0.1" - } - }, - "dns-txt": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/dns-txt/-/dns-txt-2.0.2.tgz", - "integrity": "sha1-uR2Ab10nGI5Ks+fRB9iBocxGQrY=", - "dev": true, - "requires": { - "buffer-indexof": "^1.0.0" - } - }, - "dom-serialize": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/dom-serialize/-/dom-serialize-2.2.1.tgz", - "integrity": "sha1-ViromZ9Evl6jB29UGdzVnrQ6yVs=", - "dev": true, + "resolved": "https://registry.npmjs.org/fibers/-/fibers-4.0.2.tgz", + "integrity": "sha512-FhICi1K4WZh9D6NC18fh2ODF3EWy1z0gzIdV9P7+s2pRjfRBnCkMDJ6x3bV1DkVymKH8HGrQa/FNOBjYvnJ/tQ==", "requires": { - "custom-event": "~1.0.0", - "ent": "~2.2.0", - "extend": "^3.0.0", - "void-elements": "^2.0.0" + "detect-libc": "^1.0.3" } }, - "domain-browser": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/domain-browser/-/domain-browser-1.2.0.tgz", - "integrity": "sha512-jnjyiM6eRyZl2H+W8Q/zLMA481hzi0eszAaBUzIVnmYVDBbnLxVNnfu1HgEBvCbL+71FrxMl3E6lpKH7Ge3OXA==", + "figgy-pudding": { + "version": "3.5.1", + "resolved": "https://registry.npmjs.org/figgy-pudding/-/figgy-pudding-3.5.1.tgz", + "integrity": "sha512-vNKxJHTEKNThjfrdJwHc7brvM6eVevuO5nTj6ez8ZQ1qbXTvGthucRF7S4vf2cr71QVnT70V34v0S1DyQsti0w==", "dev": true }, - "duplexify": { - "version": "3.7.1", - "resolved": "https://registry.npmjs.org/duplexify/-/duplexify-3.7.1.tgz", - "integrity": "sha512-07z8uv2wMyS51kKhD1KsdXJg5WQ6t93RneqRxUHnskXVtlYYkLqM0gqStQZ3pj073g687jPCHrqNfCzawLYh5g==", - "dev": true, - "requires": { - "end-of-stream": "^1.0.0", - "inherits": "^2.0.1", - "readable-stream": "^2.0.0", - "stream-shift": "^1.0.0" - } - }, - "ecc-jsbn": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz", - "integrity": "sha1-OoOpBOVDUyh4dMVkt1SThoSamMk=", + "figures": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/figures/-/figures-3.2.0.tgz", + "integrity": "sha512-yaduQFRKLXYOGgEn6AZau90j3ggSOyiqXU0F9JZfeXYhNa+Jk4X+s45A2zg5jns87GAFa34BBm2kXw4XpNcbdg==", "dev": true, "requires": { - "jsbn": "~0.1.0", - "safer-buffer": "^2.1.0" + "escape-string-regexp": "^1.0.5" } }, - "ee-first": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", - "integrity": "sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0=", - "dev": true - }, - "electron-to-chromium": { - "version": "1.3.377", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.377.tgz", - "integrity": "sha512-cm2WzMKf/3dW5+hNANKm8GAW6SwIWOqLTJ6GPCD0Bbw1qJ9Wzm9nmx9M+byzSsgw8CdCv5fb/wzLFqVS5h6QrA==", - "dev": true - }, - "elliptic": { - "version": "6.5.2", - "resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.5.2.tgz", - "integrity": "sha512-f4x70okzZbIQl/NSRLkI/+tteV/9WqL98zx+SQ69KbXxmVrmjwsNUPn/gYJJ0sHvEak24cZgHIPegRePAtA/xw==", + "file-loader": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/file-loader/-/file-loader-4.2.0.tgz", + "integrity": "sha512-+xZnaK5R8kBJrHK0/6HRlrKNamvVS5rjyuju+rnyxRGuwUJwpAMsVzUl5dz6rK8brkzjV6JpcFNjp6NqV0g1OQ==", "dev": true, "requires": { - "bn.js": "^4.4.0", - "brorand": "^1.0.1", - "hash.js": "^1.0.0", - "hmac-drbg": "^1.0.0", - "inherits": "^2.0.1", - "minimalistic-assert": "^1.0.0", - "minimalistic-crypto-utils": "^1.0.0" + "loader-utils": "^1.2.3", + "schema-utils": "^2.0.0" + }, + "dependencies": { + "ajv": { + "version": "6.12.0", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.0.tgz", + "integrity": "sha512-D6gFiFA0RRLyUbvijN74DWAjXSFxWKaWP7mldxkVhyhAV3+SWA9HEJPHQ2c9soIeTFJqcSdFDGFgdqs1iUU2Hw==", + "dev": true, + "requires": { + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + } + }, + "fast-deep-equal": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.1.tgz", + "integrity": "sha512-8UEa58QDLauDNfpbrX55Q9jrGHThw2ZMdOky5Gl1CDtVeJDPVrG4Jxx1N8jw2gkWaff5UUuX1KJd+9zGe2B+ZA==", + "dev": true + }, + "schema-utils": { + "version": "2.6.5", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-2.6.5.tgz", + "integrity": "sha512-5KXuwKziQrTVHh8j/Uxz+QUbxkaLW9X/86NBlx/gnKgtsZA2GIVMUn17qWhRFwF8jdYb3Dig5hRO/W5mZqy6SQ==", + "dev": true, + "requires": { + "ajv": "^6.12.0", + "ajv-keywords": "^3.4.1" + } + } } }, - "emoji-regex": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", - "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", - "dev": true - }, - "emojis-list": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/emojis-list/-/emojis-list-2.1.0.tgz", - "integrity": "sha1-TapNnbAPmBmIDHn6RXrlsJof04k=", - "dev": true - }, - "encodeurl": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", - "integrity": "sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k=", - "dev": true + "file-saver": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/file-saver/-/file-saver-2.0.2.tgz", + "integrity": "sha512-Wz3c3XQ5xroCxd1G8b7yL0Ehkf0TC9oYC6buPFkNnU9EnaPlifeAFCyCh+iewXTyFRcg0a6j3J7FmJsIhlhBdw==" }, - "encoding": { - "version": "0.1.12", - "resolved": "https://registry.npmjs.org/encoding/-/encoding-0.1.12.tgz", - "integrity": "sha1-U4tm8+5izRq1HsMjgp0flIDHS+s=", + "fileset": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/fileset/-/fileset-2.0.3.tgz", + "integrity": "sha1-jnVIqW08wjJ+5eZ0FocjozO7oqA=", "dev": true, "requires": { - "iconv-lite": "~0.4.13" + "glob": "^7.0.3", + "minimatch": "^3.0.3" } }, - "end-of-stream": { - "version": "1.4.4", - "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz", - "integrity": "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==", + "fill-range": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", + "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", "dev": true, "requires": { - "once": "^1.4.0" + "to-regex-range": "^5.0.1" } }, - "engine.io": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/engine.io/-/engine.io-3.2.1.tgz", - "integrity": "sha512-+VlKzHzMhaU+GsCIg4AoXF1UdDFjHHwMmMKqMJNDNLlUlejz58FCy4LBqB2YVJskHGYl06BatYWKP2TVdVXE5w==", + "finalhandler": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.1.2.tgz", + "integrity": "sha512-aAWcW57uxVNrQZqFXjITpW3sIUQmHGG3qSb9mUah9MgMC4NeWhNOlNjXEYq3HjRAvL6arUviZGGJsBg6z0zsWA==", "dev": true, "requires": { - "accepts": "~1.3.4", - "base64id": "1.0.0", - "cookie": "0.3.1", - "debug": "~3.1.0", - "engine.io-parser": "~2.1.0", - "ws": "~3.3.1" + "debug": "2.6.9", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "on-finished": "~2.3.0", + "parseurl": "~1.3.3", + "statuses": "~1.5.0", + "unpipe": "~1.0.0" }, "dependencies": { - "cookie": { - "version": "0.3.1", - "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.3.1.tgz", - "integrity": "sha1-5+Ch+e9DtMi6klxcWpboBtFoc7s=", - "dev": true - }, "debug": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", - "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", "dev": true, "requires": { "ms": "2.0.0" @@ -4442,637 +4820,771 @@ "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", "dev": true - }, - "ws": { - "version": "3.3.3", - "resolved": "https://registry.npmjs.org/ws/-/ws-3.3.3.tgz", - "integrity": "sha512-nnWLa/NwZSt4KQJu51MYlCcSQ5g7INpOrOMt4XV8j4dqTXdmlUmSHQ8/oLC069ckre0fRsgfvsKwbTdtKLCDkA==", - "dev": true, - "requires": { - "async-limiter": "~1.0.0", - "safe-buffer": "~5.1.0", - "ultron": "~1.1.0" - } } } }, - "engine.io-client": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/engine.io-client/-/engine.io-client-3.2.1.tgz", - "integrity": "sha512-y5AbkytWeM4jQr7m/koQLc5AxpRKC1hEVUb/s1FUAWEJq5AzJJ4NLvzuKPuxtDi5Mq755WuDvZ6Iv2rXj4PTzw==", + "find-cache-dir": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/find-cache-dir/-/find-cache-dir-3.0.0.tgz", + "integrity": "sha512-t7ulV1fmbxh5G9l/492O1p5+EBbr3uwpt6odhFTMc+nWyhmbloe+ja9BZ8pIBtqFWhOmCWVjx+pTW4zDkFoclw==", "dev": true, "requires": { - "component-emitter": "1.2.1", - "component-inherit": "0.0.3", - "debug": "~3.1.0", - "engine.io-parser": "~2.1.1", - "has-cors": "1.1.0", - "indexof": "0.0.1", - "parseqs": "0.0.5", - "parseuri": "0.0.5", - "ws": "~3.3.1", - "xmlhttprequest-ssl": "~1.5.4", - "yeast": "0.1.2" + "commondir": "^1.0.1", + "make-dir": "^3.0.0", + "pkg-dir": "^4.1.0" }, "dependencies": { - "component-emitter": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.2.1.tgz", - "integrity": "sha1-E3kY1teCg/ffemt8WmPhQOaUJeY=", - "dev": true + "find-up": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", + "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", + "dev": true, + "requires": { + "locate-path": "^5.0.0", + "path-exists": "^4.0.0" + } }, - "debug": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", - "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", + "locate-path": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", + "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", "dev": true, "requires": { - "ms": "2.0.0" + "p-locate": "^4.1.0" } }, - "ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", + "make-dir": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.0.2.tgz", + "integrity": "sha512-rYKABKutXa6vXTXhoV18cBE7PaewPXHe/Bdq4v+ZLMhxbWApkFFplT0LcbMW+6BbjnQXzZ/sAvSE/JdguApG5w==", + "dev": true, + "requires": { + "semver": "^6.0.0" + } + }, + "p-locate": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", + "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", + "dev": true, + "requires": { + "p-limit": "^2.2.0" + } + }, + "path-exists": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", "dev": true }, - "ws": { - "version": "3.3.3", - "resolved": "https://registry.npmjs.org/ws/-/ws-3.3.3.tgz", - "integrity": "sha512-nnWLa/NwZSt4KQJu51MYlCcSQ5g7INpOrOMt4XV8j4dqTXdmlUmSHQ8/oLC069ckre0fRsgfvsKwbTdtKLCDkA==", + "pkg-dir": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-4.2.0.tgz", + "integrity": "sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==", "dev": true, "requires": { - "async-limiter": "~1.0.0", - "safe-buffer": "~5.1.0", - "ultron": "~1.1.0" + "find-up": "^4.0.0" } } } }, - "engine.io-parser": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/engine.io-parser/-/engine.io-parser-2.1.3.tgz", - "integrity": "sha512-6HXPre2O4Houl7c4g7Ic/XzPnHBvaEmN90vtRO9uLmwtRqQmTOw0QMevL1TOfL2Cpu1VzsaTmMotQgMdkzGkVA==", - "dev": true, - "requires": { - "after": "0.8.2", - "arraybuffer.slice": "~0.0.7", - "base64-arraybuffer": "0.1.5", - "blob": "0.0.5", - "has-binary2": "~1.0.2" - } - }, - "enhanced-resolve": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-4.1.0.tgz", - "integrity": "sha512-F/7vkyTtyc/llOIn8oWclcB25KdRaiPBpZYDgJHgh/UHtpgT2p2eldQgtQnLtUvfMKPKxbRaQM/hHkvLHt1Vng==", + "find-up": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz", + "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==", "dev": true, "requires": { - "graceful-fs": "^4.1.2", - "memory-fs": "^0.4.0", - "tapable": "^1.0.0" + "locate-path": "^3.0.0" } }, - "ent": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/ent/-/ent-2.2.0.tgz", - "integrity": "sha1-6WQhkyWiHQX0RGai9obtbOX13R0=", - "dev": true - }, - "err-code": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/err-code/-/err-code-1.1.2.tgz", - "integrity": "sha1-BuARbTAo9q70gGhJ6w6mp0iuaWA=", + "flatted": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/flatted/-/flatted-2.0.1.tgz", + "integrity": "sha512-a1hQMktqW9Nmqr5aktAux3JMNqaucxGcjtjWnZLHX7yyPCmlSV3M54nGYbqT8K+0GhF3NBgmJCc3ma+WOgX8Jg==", "dev": true }, - "errno": { - "version": "0.1.7", - "resolved": "https://registry.npmjs.org/errno/-/errno-0.1.7.tgz", - "integrity": "sha512-MfrRBDWzIWifgq6tJj60gkAwtLNb6sQPlcFrSOflcP1aFmmruKQ2wRnze/8V6kgyz7H3FF8Npzv78mZ7XLLflg==", - "dev": true, - "requires": { - "prr": "~1.0.1" - } - }, - "error-ex": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", - "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==", - "dev": true, - "requires": { - "is-arrayish": "^0.2.1" - } - }, - "es-abstract": { - "version": "1.17.4", - "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.17.4.tgz", - "integrity": "sha512-Ae3um/gb8F0mui/jPL+QiqmglkUsaQf7FwBEHYIFkztkneosu9imhqHpBzQ3h1vit8t5iQ74t6PEVvphBZiuiQ==", - "dev": true, - "requires": { - "es-to-primitive": "^1.2.1", - "function-bind": "^1.1.1", - "has": "^1.0.3", - "has-symbols": "^1.0.1", - "is-callable": "^1.1.5", - "is-regex": "^1.0.5", - "object-inspect": "^1.7.0", - "object-keys": "^1.1.1", - "object.assign": "^4.1.0", - "string.prototype.trimleft": "^2.1.1", - "string.prototype.trimright": "^2.1.1" - } - }, - "es-to-primitive": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.1.tgz", - "integrity": "sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==", + "flush-write-stream": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/flush-write-stream/-/flush-write-stream-1.1.1.tgz", + "integrity": "sha512-3Z4XhFZ3992uIq0XOqb9AreonueSYphE6oYbpt5+3u06JWklbsPkNv3ZKkP9Bz/r+1MWCaMoSQ28P85+1Yc77w==", "dev": true, - "requires": { - "is-callable": "^1.1.4", - "is-date-object": "^1.0.1", - "is-symbol": "^1.0.2" + "requires": { + "inherits": "^2.0.3", + "readable-stream": "^2.3.6" } }, - "es6-promise": { - "version": "4.2.8", - "resolved": "https://registry.npmjs.org/es6-promise/-/es6-promise-4.2.8.tgz", - "integrity": "sha512-HJDGx5daxeIvxdBxvG2cb9g4tEvwIk3i8+nhX0yGrYmZUzbkdg8QbDevheDB8gd0//uPj4c1EQua8Q+MViT0/w==", - "dev": true - }, - "es6-promisify": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/es6-promisify/-/es6-promisify-5.0.0.tgz", - "integrity": "sha1-UQnWLz5W6pZ8S2NQWu8IKRyKUgM=", + "follow-redirects": { + "version": "1.10.0", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.10.0.tgz", + "integrity": "sha512-4eyLK6s6lH32nOvLLwlIOnr9zrL8Sm+OvW4pVTJNoXeGzYIkHVf+pADQi+OJ0E67hiuSLezPVPyBcIZO50TmmQ==", "dev": true, "requires": { - "es6-promise": "^4.0.3" + "debug": "^3.0.0" + }, + "dependencies": { + "debug": { + "version": "3.2.6", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.6.tgz", + "integrity": "sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ==", + "dev": true, + "requires": { + "ms": "^2.1.1" + } + } } }, - "escape-html": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", - "integrity": "sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg=", + "for-in": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/for-in/-/for-in-1.0.2.tgz", + "integrity": "sha1-gQaNKVqBQuwKxybG4iAMMPttXoA=", "dev": true }, - "escape-string-regexp": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=", - "dev": true + "forever-agent": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz", + "integrity": "sha1-+8cfDEGt6zf5bFd60e1C2P2sypE=" }, - "eslint-scope": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-4.0.3.tgz", - "integrity": "sha512-p7VutNr1O/QrxysMo3E45FjYDTeXBy0iTltPFNSqKAIfjDSXC+4dj+qfyuD8bfAXrW/y6lW3O76VaYNPKfpKrg==", - "dev": true, + "form-data": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.3.3.tgz", + "integrity": "sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ==", "requires": { - "esrecurse": "^4.1.0", - "estraverse": "^4.1.1" + "asynckit": "^0.4.0", + "combined-stream": "^1.0.6", + "mime-types": "^2.1.12" } }, - "esprima": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", - "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", + "forwarded": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.1.2.tgz", + "integrity": "sha1-mMI9qxF1ZXuMBXPozszZGw/xjIQ=", "dev": true }, - "esrecurse": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.2.1.tgz", - "integrity": "sha512-64RBB++fIOAXPw3P9cy89qfMlvZEXZkqqJkjqqXIvzP5ezRZjW+lPWjw35UX/3EhUPFYbg5ER4JYgDw4007/DQ==", + "fragment-cache": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/fragment-cache/-/fragment-cache-0.2.1.tgz", + "integrity": "sha1-QpD60n8T6Jvn8zeZxrxaCr//DRk=", "dev": true, "requires": { - "estraverse": "^4.1.0" + "map-cache": "^0.2.2" } }, - "estraverse": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", - "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==", - "dev": true - }, - "esutils": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", - "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", - "dev": true - }, - "etag": { - "version": "1.8.1", - "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", - "integrity": "sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc=", + "fresh": { + "version": "0.5.2", + "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", + "integrity": "sha1-PYyt2Q2XZWn6g1qx+OSyOhBWBac=", "dev": true }, - "eventemitter3": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-4.0.0.tgz", - "integrity": "sha512-qerSRB0p+UDEssxTtm6EDKcE7W4OaoisfIMl4CngyEhjpYglocpNg6UEqCvemdGhosAsg4sO2dXJOdyBifPGCg==", - "dev": true + "from2": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/from2/-/from2-2.3.0.tgz", + "integrity": "sha1-i/tVAr3kpNNs/e6gB/zKIdfjgq8=", + "dev": true, + "requires": { + "inherits": "^2.0.1", + "readable-stream": "^2.0.0" + } }, - "events": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/events/-/events-3.1.0.tgz", - "integrity": "sha512-Rv+u8MLHNOdMjTAFeT3nCjHn2aGlx435FP/sDHNaRhDEMwyI/aB22Kj2qIN8R0cw3z28psEQLYwxVKLsKrMgWg==", - "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==", + "dev": true, + "requires": { + "graceful-fs": "^4.1.2", + "jsonfile": "^4.0.0", + "universalify": "^0.1.0" + } }, - "eventsource": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/eventsource/-/eventsource-1.0.7.tgz", - "integrity": "sha512-4Ln17+vVT0k8aWq+t/bF5arcS3EpT9gYtW66EPacdj/mAFevznsnyoHLPy2BA8gbIQeIHoPsvwmfBftfcG//BQ==", + "fs-minipass": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-2.1.0.tgz", + "integrity": "sha512-V/JgOLFCS+R6Vcq0slCuaeWEdNC3ouDlJMNIsacH2VtALiu9mV4LPrHc5cDl8k5aw6J8jwgWWpiTo5RYhmIzvg==", "dev": true, "requires": { - "original": "^1.0.0" + "minipass": "^3.0.0" } }, - "evp_bytestokey": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/evp_bytestokey/-/evp_bytestokey-1.0.3.tgz", - "integrity": "sha512-/f2Go4TognH/KvCISP7OUsHn85hT9nUkxxA9BEWxFn+Oj9o8ZNLm/40hdlgSLyuOimsrTKLUMEorQexp/aPQeA==", + "fs-write-stream-atomic": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/fs-write-stream-atomic/-/fs-write-stream-atomic-1.0.10.tgz", + "integrity": "sha1-tH31NJPvkR33VzHnCp3tAYnbQMk=", "dev": true, "requires": { - "md5.js": "^1.3.4", - "safe-buffer": "^5.1.1" + "graceful-fs": "^4.1.2", + "iferr": "^0.1.5", + "imurmurhash": "^0.1.4", + "readable-stream": "1 || 2" } }, - "execa": { + "fs.realpath": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/execa/-/execa-1.0.0.tgz", - "integrity": "sha512-adbxcyWV46qiHyvSp50TKt05tB4tK3HcmF7/nxfAdhnox83seTDbwnaqKO4sXRy7roHAIFqJP/Rw/AuEbX61LA==", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=" + }, + "fsevents": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.1.2.tgz", + "integrity": "sha512-R4wDiBwZ0KzpgOWetKDug1FZcYhqYnUYKtfZYt4mD5SBz76q0KR4Q9o7GIPamsVPGmW3EYPPJ0dOOjvx32ldZA==", "dev": true, + "optional": true + }, + "fstream": { + "version": "1.0.12", + "resolved": "https://registry.npmjs.org/fstream/-/fstream-1.0.12.tgz", + "integrity": "sha512-WvJ193OHa0GHPEL+AycEJgxvBEwyfRkN1vhjca23OaPVMCaLCXTd5qAu82AjTcgP1UJmytkOKb63Ypde7raDIg==", "requires": { - "cross-spawn": "^6.0.0", - "get-stream": "^4.0.0", - "is-stream": "^1.1.0", - "npm-run-path": "^2.0.0", - "p-finally": "^1.0.0", - "signal-exit": "^3.0.0", - "strip-eof": "^1.0.0" + "graceful-fs": "^4.1.2", + "inherits": "~2.0.0", + "mkdirp": ">=0.5 0", + "rimraf": "2" } }, - "exit": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/exit/-/exit-0.1.2.tgz", - "integrity": "sha1-BjJjj42HfMghB9MKD/8aF8uhzQw=", - "dev": true + "function-bind": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", + "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==" }, - "expand-brackets": { - "version": "2.1.4", - "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-2.1.4.tgz", - "integrity": "sha1-t3c14xXOMPa27/D4OwQVGiJEliI=", - "dev": true, + "gauge": { + "version": "2.7.4", + "resolved": "https://registry.npmjs.org/gauge/-/gauge-2.7.4.tgz", + "integrity": "sha1-LANAXHU4w51+s3sxcCLjJfsBi/c=", "requires": { - "debug": "^2.3.3", - "define-property": "^0.2.5", - "extend-shallow": "^2.0.1", - "posix-character-classes": "^0.1.0", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.1" + "aproba": "^1.0.3", + "console-control-strings": "^1.0.0", + "has-unicode": "^2.0.0", + "object-assign": "^4.1.0", + "signal-exit": "^3.0.0", + "string-width": "^1.0.1", + "strip-ansi": "^3.0.1", + "wide-align": "^1.1.0" }, "dependencies": { - "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dev": true, - "requires": { - "ms": "2.0.0" - } - }, - "define-property": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", - "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", - "dev": true, + "is-fullwidth-code-point": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz", + "integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=", "requires": { - "is-descriptor": "^0.1.0" + "number-is-nan": "^1.0.0" } }, - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, + "string-width": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz", + "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=", "requires": { - "is-extendable": "^0.1.0" + "code-point-at": "^1.0.0", + "is-fullwidth-code-point": "^1.0.0", + "strip-ansi": "^3.0.0" } - }, - "ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", - "dev": true } } }, - "express": { - "version": "4.17.1", - "resolved": "https://registry.npmjs.org/express/-/express-4.17.1.tgz", - "integrity": "sha512-mHJ9O79RqluphRrcw2X/GTh3k9tVv8YcoyY4Kkh4WDMUYKRZUq0h1o0w2rrrxBqM7VoeUVqgb27xlEMXTnYt4g==", + "gaze": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/gaze/-/gaze-1.1.3.tgz", + "integrity": "sha512-BRdNm8hbWzFzWHERTrejLqwHDfS4GibPoq5wjTPIoJHoBtKGPg3xAFfxmM+9ztbXelxcf2hwQcaz1PtmFeue8g==", + "requires": { + "globule": "^1.0.0" + } + }, + "genfun": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/genfun/-/genfun-5.0.0.tgz", + "integrity": "sha512-KGDOARWVga7+rnB3z9Sd2Letx515owfk0hSxHGuqjANb1M+x2bGZGqHLiozPsYMdM2OubeMni/Hpwmjq6qIUhA==", + "dev": true + }, + "get-caller-file": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-1.0.3.tgz", + "integrity": "sha512-3t6rVToeoZfYSGd8YoLFR2DJkiQrIiUrGcjvFX2mDw3bn6k2OtwHN0TNCLbBO+w8qTvimhDkv+LSscbJY1vE6w==" + }, + "get-stdin": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/get-stdin/-/get-stdin-4.0.1.tgz", + "integrity": "sha1-uWjGsKBDhDJJAui/Gl3zJXmkUP4=" + }, + "get-stream": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-4.1.0.tgz", + "integrity": "sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w==", + "dev": true, + "requires": { + "pump": "^3.0.0" + } + }, + "get-value": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/get-value/-/get-value-2.0.6.tgz", + "integrity": "sha1-3BXKHGcjh8p2vTesCjlbogQqLCg=", + "dev": true + }, + "getpass": { + "version": "0.1.7", + "resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz", + "integrity": "sha1-Xv+OPmhNVprkyysSgmBOi6YhSfo=", + "requires": { + "assert-plus": "^1.0.0" + } + }, + "glob": { + "version": "7.1.4", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.4.tgz", + "integrity": "sha512-hkLPepehmnKk41pUGm3sYxoFs/umurYfYJCerbXEyFIWcAzvpipAgVkBqqT9RBKMGjnq6kMuyYwha6csxbiM1A==", + "requires": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.0.4", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + } + }, + "glob-parent": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-3.1.0.tgz", + "integrity": "sha1-nmr2KZ2NO9K9QEMIMr0RPfkGxa4=", "dev": true, "requires": { - "accepts": "~1.3.7", - "array-flatten": "1.1.1", - "body-parser": "1.19.0", - "content-disposition": "0.5.3", - "content-type": "~1.0.4", - "cookie": "0.4.0", - "cookie-signature": "1.0.6", - "debug": "2.6.9", - "depd": "~1.1.2", - "encodeurl": "~1.0.2", - "escape-html": "~1.0.3", - "etag": "~1.8.1", - "finalhandler": "~1.1.2", - "fresh": "0.5.2", - "merge-descriptors": "1.0.1", - "methods": "~1.1.2", - "on-finished": "~2.3.0", - "parseurl": "~1.3.3", - "path-to-regexp": "0.1.7", - "proxy-addr": "~2.0.5", - "qs": "6.7.0", - "range-parser": "~1.2.1", - "safe-buffer": "5.1.2", - "send": "0.17.1", - "serve-static": "1.14.1", - "setprototypeof": "1.1.1", - "statuses": "~1.5.0", - "type-is": "~1.6.18", - "utils-merge": "1.0.1", - "vary": "~1.1.2" + "is-glob": "^3.1.0", + "path-dirname": "^1.0.0" }, "dependencies": { - "array-flatten": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", - "integrity": "sha1-ml9pkFGx5wczKPKgCJaLZOopVdI=", - "dev": true - }, - "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "is-glob": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-3.1.0.tgz", + "integrity": "sha1-e6WuJCF4BKxwcHuWkiVnSGzD6Eo=", "dev": true, "requires": { - "ms": "2.0.0" + "is-extglob": "^2.1.0" } - }, - "ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", - "dev": true - }, - "qs": { - "version": "6.7.0", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.7.0.tgz", - "integrity": "sha512-VCdBRNFTX1fyE7Nb6FYoURo/SPe62QCaAyzJvUjwRaIsc+NePBEniHlvxFmmX56+HZphIGtV0XeCirBtpDrTyQ==", - "dev": true } } }, - "extend": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", - "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==", + "globals": { + "version": "11.12.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", + "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==", "dev": true }, - "extend-shallow": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-3.0.2.tgz", - "integrity": "sha1-Jqcarwc7OfshJxcnRhMcJwQCjbg=", + "globby": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/globby/-/globby-7.1.1.tgz", + "integrity": "sha1-+yzP+UAfhgCUXfral0QMypcrhoA=", "dev": true, "requires": { - "assign-symbols": "^1.0.0", - "is-extendable": "^1.0.1" + "array-union": "^1.0.1", + "dir-glob": "^2.0.0", + "glob": "^7.1.2", + "ignore": "^3.3.5", + "pify": "^3.0.0", + "slash": "^1.0.0" }, "dependencies": { - "is-extendable": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", - "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", - "dev": true, - "requires": { - "is-plain-object": "^2.0.4" - } + "pify": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz", + "integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=", + "dev": true } } }, - "external-editor": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/external-editor/-/external-editor-3.1.0.tgz", - "integrity": "sha512-hMQ4CX1p1izmuLYyZqLMO/qGNw10wSv9QDCPfzXfyFrOaCSSoRfqE1Kf1s5an66J5JZC62NewG+mK49jOCtQew==", - "dev": true, + "globule": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/globule/-/globule-1.3.1.tgz", + "integrity": "sha512-OVyWOHgw29yosRHCHo7NncwR1hW5ew0W/UrvtwvjefVJeQ26q4/8r8FmPsSF1hJ93IgWkyv16pCTz6WblMzm/g==", "requires": { - "chardet": "^0.7.0", - "iconv-lite": "^0.4.24", - "tmp": "^0.0.33" + "glob": "~7.1.1", + "lodash": "~4.17.12", + "minimatch": "~3.0.2" } }, - "extglob": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/extglob/-/extglob-2.0.4.tgz", - "integrity": "sha512-Nmb6QXkELsuBr24CJSkilo6UHHgbekK5UiZgfE6UHD3Eb27YC6oD+bhcT+tJ6cl8dmsgdQxnWlcry8ksBIBLpw==", + "graceful-fs": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.3.tgz", + "integrity": "sha512-a30VEBm4PEdx1dRB7MFK7BejejvCvBronbLjht+sHuGYj8PHs7M/5Z+rt5lw551vZ7yfTCj4Vuyy3mSJytDWRQ==" + }, + "handle-thing": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/handle-thing/-/handle-thing-2.0.0.tgz", + "integrity": "sha512-d4sze1JNC454Wdo2fkuyzCr6aHcbL6PGGuFAz0Li/NcOm1tCHGnWDRmJP85dh9IhQErTc2svWFEX5xHIOo//kQ==", + "dev": true + }, + "har-schema": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/har-schema/-/har-schema-2.0.0.tgz", + "integrity": "sha1-qUwiJOvKwEeCoNkDVSHyRzW37JI=" + }, + "har-validator": { + "version": "5.1.3", + "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-5.1.3.tgz", + "integrity": "sha512-sNvOCzEQNr/qrvJgc3UG/kD4QtlHycrzwS+6mfTrrSq97BvaYcPZZI1ZSqGSPR73Cxn4LKTD4PttRwfU7jWq5g==", + "requires": { + "ajv": "^6.5.5", + "har-schema": "^2.0.0" + } + }, + "has": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", + "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", + "requires": { + "function-bind": "^1.1.1" + } + }, + "has-ansi": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/has-ansi/-/has-ansi-2.0.0.tgz", + "integrity": "sha1-NPUEnOHs3ysGSa8+8k5F7TVBbZE=", + "requires": { + "ansi-regex": "^2.0.0" + } + }, + "has-binary2": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has-binary2/-/has-binary2-1.0.3.tgz", + "integrity": "sha512-G1LWKhDSvhGeAQ8mPVQlqNcOB2sJdwATtZKl2pDKKHfpf/rYj24lkinxf69blJbnsvtqqNU+L3SL50vzZhXOnw==", "dev": true, "requires": { - "array-unique": "^0.3.2", - "define-property": "^1.0.0", - "expand-brackets": "^2.1.4", - "extend-shallow": "^2.0.1", - "fragment-cache": "^0.2.1", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.1" + "isarray": "2.0.1" }, "dependencies": { - "define-property": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", - "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", - "dev": true, - "requires": { - "is-descriptor": "^1.0.0" - } - }, - "extend-shallow": { + "isarray": { "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - }, - "is-accessor-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", - "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-data-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", - "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.1.tgz", + "integrity": "sha1-o32U7ZzaLVmGXJ92/llu4fM4dB4=", + "dev": true + } + } + }, + "has-cors": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/has-cors/-/has-cors-1.1.0.tgz", + "integrity": "sha1-XkdHk/fqmEPRu5nCPu9J/xJv/zk=", + "dev": true + }, + "has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", + "dev": true + }, + "has-symbols": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.1.tgz", + "integrity": "sha512-PLcsoqu++dmEIZB+6totNFKq/7Do+Z0u4oT0zKOJNl3lYK6vGwwu2hjHs+68OEZbTjiUE9bgOABXbP/GvrS0Kg==" + }, + "has-unicode": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/has-unicode/-/has-unicode-2.0.1.tgz", + "integrity": "sha1-4Ob+aijPUROIVeCG0Wkedx3iqLk=" + }, + "has-value": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/has-value/-/has-value-1.0.0.tgz", + "integrity": "sha1-GLKB2lhbHFxR3vJMkw7SmgvmsXc=", + "dev": true, + "requires": { + "get-value": "^2.0.6", + "has-values": "^1.0.0", + "isobject": "^3.0.0" + } + }, + "has-values": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/has-values/-/has-values-1.0.0.tgz", + "integrity": "sha1-lbC2P+whRmGab+V/51Yo1aOe/k8=", + "dev": true, + "requires": { + "is-number": "^3.0.0", + "kind-of": "^4.0.0" + }, + "dependencies": { + "is-number": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", + "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", "dev": true, "requires": { - "kind-of": "^6.0.0" + "kind-of": "^3.0.2" + }, + "dependencies": { + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "requires": { + "is-buffer": "^1.1.5" + } + } } }, - "is-descriptor": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", - "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", + "kind-of": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-4.0.0.tgz", + "integrity": "sha1-IIE989cSkosgc3hpGkUGb65y3Vc=", "dev": true, "requires": { - "is-accessor-descriptor": "^1.0.0", - "is-data-descriptor": "^1.0.0", - "kind-of": "^6.0.2" + "is-buffer": "^1.1.5" } } } }, - "extsprintf": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz", - "integrity": "sha1-lpGEQOMEGnpBT4xS48V06zw+HgU=", - "dev": true + "hash-base": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/hash-base/-/hash-base-3.0.4.tgz", + "integrity": "sha1-X8hoaEfs1zSZQDMZprCj8/auSRg=", + "dev": true, + "requires": { + "inherits": "^2.0.1", + "safe-buffer": "^5.0.1" + } }, - "fast-deep-equal": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-2.0.1.tgz", - "integrity": "sha1-ewUhjd+WZ79/Nwv3/bLLFf3Qqkk=", - "dev": true + "hash.js": { + "version": "1.1.7", + "resolved": "https://registry.npmjs.org/hash.js/-/hash.js-1.1.7.tgz", + "integrity": "sha512-taOaskGt4z4SOANNseOviYDvjEJinIkRgmp7LbKP2YTTmVxWBl87s/uzK9r+44BclBSp2X7K1hqeNfz9JbBeXA==", + "dev": true, + "requires": { + "inherits": "^2.0.3", + "minimalistic-assert": "^1.0.1" + } }, - "fast-json-stable-stringify": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.0.0.tgz", - "integrity": "sha1-1RQsDK7msRifh9OnYREGT4bIu/I=", - "dev": true + "he": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz", + "integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==" }, - "fastparse": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/fastparse/-/fastparse-1.1.2.tgz", - "integrity": "sha512-483XLLxTVIwWK3QTrMGRqUfUpoOs/0hbQrl2oz4J0pAcm3A3bu84wxTFqGqkJzewCLdME38xJLJAxBABfQT8sQ==", + "hex-color-regex": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/hex-color-regex/-/hex-color-regex-1.1.0.tgz", + "integrity": "sha512-l9sfDFsuqtOqKDsQdqrMRk0U85RZc0RtOR9yPI7mRVOa4FsR/BVnZ0shmQRM96Ji99kYZP/7hn1cedc1+ApsTQ==", "dev": true }, - "faye-websocket": { - "version": "0.10.0", - "resolved": "https://registry.npmjs.org/faye-websocket/-/faye-websocket-0.10.0.tgz", - "integrity": "sha1-TkkvjQTftviQA1B/btvy1QHnxvQ=", + "hmac-drbg": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/hmac-drbg/-/hmac-drbg-1.0.1.tgz", + "integrity": "sha1-0nRXAQJabHdabFRXk+1QL8DGSaE=", "dev": true, "requires": { - "websocket-driver": ">=0.5.1" + "hash.js": "^1.0.3", + "minimalistic-assert": "^1.0.0", + "minimalistic-crypto-utils": "^1.0.1" } }, - "figgy-pudding": { - "version": "3.5.1", - "resolved": "https://registry.npmjs.org/figgy-pudding/-/figgy-pudding-3.5.1.tgz", - "integrity": "sha512-vNKxJHTEKNThjfrdJwHc7brvM6eVevuO5nTj6ez8ZQ1qbXTvGthucRF7S4vf2cr71QVnT70V34v0S1DyQsti0w==", - "dev": true - }, - "figures": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/figures/-/figures-3.2.0.tgz", - "integrity": "sha512-yaduQFRKLXYOGgEn6AZau90j3ggSOyiqXU0F9JZfeXYhNa+Jk4X+s45A2zg5jns87GAFa34BBm2kXw4XpNcbdg==", + "hosted-git-info": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-3.0.4.tgz", + "integrity": "sha512-4oT62d2jwSDBbLLFLZE+1vPuQ1h8p9wjrJ8Mqx5TjsyWmBMV5B13eJqn8pvluqubLf3cJPTfiYCIwNwDNmzScQ==", "dev": true, "requires": { - "escape-string-regexp": "^1.0.5" + "lru-cache": "^5.1.1" } }, - "file-loader": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/file-loader/-/file-loader-4.2.0.tgz", - "integrity": "sha512-+xZnaK5R8kBJrHK0/6HRlrKNamvVS5rjyuju+rnyxRGuwUJwpAMsVzUl5dz6rK8brkzjV6JpcFNjp6NqV0g1OQ==", + "hpack.js": { + "version": "2.1.6", + "resolved": "https://registry.npmjs.org/hpack.js/-/hpack.js-2.1.6.tgz", + "integrity": "sha1-h3dMCUnlE/QuhFdbPEVoH63ioLI=", "dev": true, "requires": { - "loader-utils": "^1.2.3", - "schema-utils": "^2.0.0" + "inherits": "^2.0.1", + "obuf": "^1.0.0", + "readable-stream": "^2.0.1", + "wbuf": "^1.1.0" + } + }, + "hsl-regex": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/hsl-regex/-/hsl-regex-1.0.0.tgz", + "integrity": "sha1-1JMwx4ntgZ4nakwNJy3/owsY/m4=", + "dev": true + }, + "hsla-regex": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/hsla-regex/-/hsla-regex-1.0.0.tgz", + "integrity": "sha1-wc56MWjIxmFAM6S194d/OyJfnDg=", + "dev": true + }, + "html-comment-regex": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/html-comment-regex/-/html-comment-regex-1.1.2.tgz", + "integrity": "sha512-P+M65QY2JQ5Y0G9KKdlDpo0zK+/OHptU5AaBwUfAIDJZk1MYf32Frm84EcOytfJE0t5JvkAnKlmjsXDnWzCJmQ==", + "dev": true + }, + "html-entities": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/html-entities/-/html-entities-1.2.1.tgz", + "integrity": "sha1-DfKTUfByEWNRXfueVUPl9u7VFi8=", + "dev": true + }, + "html-escaper": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/html-escaper/-/html-escaper-2.0.0.tgz", + "integrity": "sha512-a4u9BeERWGu/S8JiWEAQcdrg9v4QArtP9keViQjGMdff20fBdd8waotXaNmODqBe6uZ3Nafi7K/ho4gCQHV3Ig==", + "dev": true + }, + "html-minifier": { + "version": "3.5.21", + "resolved": "https://registry.npmjs.org/html-minifier/-/html-minifier-3.5.21.tgz", + "integrity": "sha512-LKUKwuJDhxNa3uf/LPR/KVjm/l3rBqtYeCOAekvG8F1vItxMUpueGd94i/asDDr8/1u7InxzFA5EeGjhhG5mMA==", + "requires": { + "camel-case": "3.0.x", + "clean-css": "4.2.x", + "commander": "2.17.x", + "he": "1.2.x", + "param-case": "2.1.x", + "relateurl": "0.2.x", + "uglify-js": "3.4.x" }, "dependencies": { - "ajv": { - "version": "6.12.0", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.0.tgz", - "integrity": "sha512-D6gFiFA0RRLyUbvijN74DWAjXSFxWKaWP7mldxkVhyhAV3+SWA9HEJPHQ2c9soIeTFJqcSdFDGFgdqs1iUU2Hw==", - "dev": true, + "commander": { + "version": "2.17.1", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.17.1.tgz", + "integrity": "sha512-wPMUt6FnH2yzG95SA6mzjQOEKUU3aLaDEmzs1ti+1E9h+CsrZghRlqEM/EJ4KscsQVG8uNN4uVreUeT8+drlgg==" + } + } + }, + "html-webpack-plugin": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/html-webpack-plugin/-/html-webpack-plugin-3.2.0.tgz", + "integrity": "sha1-sBq71yOsqqeze2r0SS69oD2d03s=", + "requires": { + "html-minifier": "^3.2.3", + "loader-utils": "^0.2.16", + "lodash": "^4.17.3", + "pretty-error": "^2.0.2", + "tapable": "^1.0.0", + "toposort": "^1.0.0", + "util.promisify": "1.0.0" + }, + "dependencies": { + "big.js": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/big.js/-/big.js-3.2.0.tgz", + "integrity": "sha512-+hN/Zh2D08Mx65pZ/4g5bsmNiZUuChDiQfTUQ7qJr4/kuopCr88xZsAXv6mBoZEsUI4OuGHlX59qE94K2mMW8Q==" + }, + "json5": { + "version": "0.5.1", + "resolved": "https://registry.npmjs.org/json5/-/json5-0.5.1.tgz", + "integrity": "sha1-Hq3nrMASA0rYTiOWdn6tn6VJWCE=" + }, + "loader-utils": { + "version": "0.2.17", + "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-0.2.17.tgz", + "integrity": "sha1-+G5jdNQyBabmxg6RlvF8Apm/s0g=", "requires": { - "fast-deep-equal": "^3.1.1", - "fast-json-stable-stringify": "^2.0.0", - "json-schema-traverse": "^0.4.1", - "uri-js": "^4.2.2" + "big.js": "^3.1.3", + "emojis-list": "^2.0.0", + "json5": "^0.5.0", + "object-assign": "^4.0.1" } }, - "fast-deep-equal": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.1.tgz", - "integrity": "sha512-8UEa58QDLauDNfpbrX55Q9jrGHThw2ZMdOky5Gl1CDtVeJDPVrG4Jxx1N8jw2gkWaff5UUuX1KJd+9zGe2B+ZA==", - "dev": true + "util.promisify": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/util.promisify/-/util.promisify-1.0.0.tgz", + "integrity": "sha512-i+6qA2MPhvoKLuxnJNpXAGhg7HphQOSUq2LKMZD0m15EiskXUkMvKdF4Uui0WYeCUGea+o2cw/ZuwehtfsrNkA==", + "requires": { + "define-properties": "^1.1.2", + "object.getownpropertydescriptors": "^2.0.3" + } + } + } + }, + "htmlparser2": { + "version": "3.10.1", + "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-3.10.1.tgz", + "integrity": "sha512-IgieNijUMbkDovyoKObU1DUhm1iwNYE/fuifEoEHfd1oZKZDaONBSkal7Y01shxsM49R4XaMdGez3WnF9UfiCQ==", + "requires": { + "domelementtype": "^1.3.1", + "domhandler": "^2.3.0", + "domutils": "^1.5.1", + "entities": "^1.1.1", + "inherits": "^2.0.1", + "readable-stream": "^3.1.1" + }, + "dependencies": { + "entities": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/entities/-/entities-1.1.2.tgz", + "integrity": "sha512-f2LZMYl1Fzu7YSBKg+RoROelpOaNrcGmE9AZubeDfrCEia483oW4MI4VyFd5VNHIgQ/7qm1I0wUHK1eJnn2y2w==" }, - "schema-utils": { - "version": "2.6.5", - "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-2.6.5.tgz", - "integrity": "sha512-5KXuwKziQrTVHh8j/Uxz+QUbxkaLW9X/86NBlx/gnKgtsZA2GIVMUn17qWhRFwF8jdYb3Dig5hRO/W5mZqy6SQ==", - "dev": true, + "readable-stream": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", + "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", "requires": { - "ajv": "^6.12.0", - "ajv-keywords": "^3.4.1" + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" } } } }, - "file-saver": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/file-saver/-/file-saver-2.0.2.tgz", - "integrity": "sha512-Wz3c3XQ5xroCxd1G8b7yL0Ehkf0TC9oYC6buPFkNnU9EnaPlifeAFCyCh+iewXTyFRcg0a6j3J7FmJsIhlhBdw==" + "http-cache-semantics": { + "version": "3.8.1", + "resolved": "https://registry.npmjs.org/http-cache-semantics/-/http-cache-semantics-3.8.1.tgz", + "integrity": "sha512-5ai2iksyV8ZXmnZhHH4rWPoxxistEexSi5936zIQ1bnNTW5VnA85B6P/VpXiRM017IgRvb2kKo1a//y+0wSp3w==", + "dev": true }, - "file-uri-to-path": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/file-uri-to-path/-/file-uri-to-path-1.0.0.tgz", - "integrity": "sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw==", - "dev": true, - "optional": true + "http-deceiver": { + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/http-deceiver/-/http-deceiver-1.2.7.tgz", + "integrity": "sha1-+nFolEq5pRnTN8sL7HKE3D5yPYc=", + "dev": true }, - "fileset": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/fileset/-/fileset-2.0.3.tgz", - "integrity": "sha1-jnVIqW08wjJ+5eZ0FocjozO7oqA=", + "http-errors": { + "version": "1.7.2", + "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.7.2.tgz", + "integrity": "sha512-uUQBt3H/cSIVfch6i1EuPNy/YsRSOUBXTVfZ+yR7Zjez3qjBz6i9+i4zjNaoqcoFVI4lQJ5plg63TvGfRSDCRg==", "dev": true, "requires": { - "glob": "^7.0.3", - "minimatch": "^3.0.3" + "depd": "~1.1.2", + "inherits": "2.0.3", + "setprototypeof": "1.1.1", + "statuses": ">= 1.5.0 < 2", + "toidentifier": "1.0.0" + }, + "dependencies": { + "inherits": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", + "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=", + "dev": true + } } }, - "fill-range": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", - "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", + "http-parser-js": { + "version": "0.4.10", + "resolved": "https://registry.npmjs.org/http-parser-js/-/http-parser-js-0.4.10.tgz", + "integrity": "sha1-ksnBN0w1CF912zWexWzCV8u5P6Q=", + "dev": true + }, + "http-proxy": { + "version": "1.18.0", + "resolved": "https://registry.npmjs.org/http-proxy/-/http-proxy-1.18.0.tgz", + "integrity": "sha512-84I2iJM/n1d4Hdgc6y2+qY5mDaz2PUVjlg9znE9byl+q0uC3DeByqBGReQu5tpLK0TAqTIXScRUV+dg7+bUPpQ==", "dev": true, "requires": { - "to-regex-range": "^5.0.1" + "eventemitter3": "^4.0.0", + "follow-redirects": "^1.0.0", + "requires-port": "^1.0.0" } }, - "finalhandler": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.1.2.tgz", - "integrity": "sha512-aAWcW57uxVNrQZqFXjITpW3sIUQmHGG3qSb9mUah9MgMC4NeWhNOlNjXEYq3HjRAvL6arUviZGGJsBg6z0zsWA==", + "http-proxy-agent": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-2.1.0.tgz", + "integrity": "sha512-qwHbBLV7WviBl0rQsOzH6o5lwyOIvwp/BdFnvVxXORldu5TmjFfjzBcWUWS5kWAZhmv+JtiDhSuQCp4sBfbIgg==", "dev": true, "requires": { - "debug": "2.6.9", - "encodeurl": "~1.0.2", - "escape-html": "~1.0.3", - "on-finished": "~2.3.0", - "parseurl": "~1.3.3", - "statuses": "~1.5.0", - "unpipe": "~1.0.0" + "agent-base": "4", + "debug": "3.1.0" }, "dependencies": { "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", + "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", "dev": true, "requires": { "ms": "2.0.0" @@ -5086,103 +5598,42 @@ } } }, - "find-cache-dir": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/find-cache-dir/-/find-cache-dir-3.0.0.tgz", - "integrity": "sha512-t7ulV1fmbxh5G9l/492O1p5+EBbr3uwpt6odhFTMc+nWyhmbloe+ja9BZ8pIBtqFWhOmCWVjx+pTW4zDkFoclw==", + "http-proxy-middleware": { + "version": "0.19.1", + "resolved": "https://registry.npmjs.org/http-proxy-middleware/-/http-proxy-middleware-0.19.1.tgz", + "integrity": "sha512-yHYTgWMQO8VvwNS22eLLloAkvungsKdKTLO8AJlftYIKNfJr3GK3zK0ZCfzDDGUBttdGc8xFy1mCitvNKQtC3Q==", "dev": true, "requires": { - "commondir": "^1.0.1", - "make-dir": "^3.0.0", - "pkg-dir": "^4.1.0" - }, - "dependencies": { - "find-up": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", - "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", - "dev": true, - "requires": { - "locate-path": "^5.0.0", - "path-exists": "^4.0.0" - } - }, - "locate-path": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", - "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", - "dev": true, - "requires": { - "p-locate": "^4.1.0" - } - }, - "make-dir": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.0.2.tgz", - "integrity": "sha512-rYKABKutXa6vXTXhoV18cBE7PaewPXHe/Bdq4v+ZLMhxbWApkFFplT0LcbMW+6BbjnQXzZ/sAvSE/JdguApG5w==", - "dev": true, - "requires": { - "semver": "^6.0.0" - } - }, - "p-locate": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", - "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", - "dev": true, - "requires": { - "p-limit": "^2.2.0" - } - }, - "path-exists": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", - "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", - "dev": true - }, - "pkg-dir": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-4.2.0.tgz", - "integrity": "sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==", - "dev": true, - "requires": { - "find-up": "^4.0.0" - } - } + "http-proxy": "^1.17.0", + "is-glob": "^4.0.0", + "lodash": "^4.17.11", + "micromatch": "^3.1.10" } }, - "find-up": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz", - "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==", - "dev": true, + "http-signature": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.2.0.tgz", + "integrity": "sha1-muzZJRFHcvPZW2WmCruPfBj7rOE=", "requires": { - "locate-path": "^3.0.0" + "assert-plus": "^1.0.0", + "jsprim": "^1.2.2", + "sshpk": "^1.7.0" } }, - "flatted": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/flatted/-/flatted-2.0.1.tgz", - "integrity": "sha512-a1hQMktqW9Nmqr5aktAux3JMNqaucxGcjtjWnZLHX7yyPCmlSV3M54nGYbqT8K+0GhF3NBgmJCc3ma+WOgX8Jg==", + "https-browserify": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/https-browserify/-/https-browserify-1.0.0.tgz", + "integrity": "sha1-7AbBDgo0wPL68Zn3/X/Hj//QPHM=", "dev": true }, - "flush-write-stream": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/flush-write-stream/-/flush-write-stream-1.1.1.tgz", - "integrity": "sha512-3Z4XhFZ3992uIq0XOqb9AreonueSYphE6oYbpt5+3u06JWklbsPkNv3ZKkP9Bz/r+1MWCaMoSQ28P85+1Yc77w==", - "dev": true, - "requires": { - "inherits": "^2.0.3", - "readable-stream": "^2.3.6" - } - }, - "follow-redirects": { - "version": "1.10.0", - "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.10.0.tgz", - "integrity": "sha512-4eyLK6s6lH32nOvLLwlIOnr9zrL8Sm+OvW4pVTJNoXeGzYIkHVf+pADQi+OJ0E67hiuSLezPVPyBcIZO50TmmQ==", + "https-proxy-agent": { + "version": "2.2.4", + "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-2.2.4.tgz", + "integrity": "sha512-OmvfoQ53WLjtA9HeYP9RNrWMJzzAz1JGaSFr1nijg0PVR1JaD/xbJq1mdEIIlxGpXp9eSe/O2LgU9DJmTPd0Eg==", "dev": true, "requires": { - "debug": "^3.0.0" + "agent-base": "^4.3.0", + "debug": "^3.1.0" }, "dependencies": { "debug": { @@ -5196,1187 +5647,1412 @@ } } }, - "for-in": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/for-in/-/for-in-1.0.2.tgz", - "integrity": "sha1-gQaNKVqBQuwKxybG4iAMMPttXoA=", + "humanize-ms": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/humanize-ms/-/humanize-ms-1.2.1.tgz", + "integrity": "sha1-xG4xWaKT9riW2ikxbYtv6Lt5u+0=", + "dev": true, + "requires": { + "ms": "^2.0.0" + } + }, + "iconv-lite": { + "version": "0.4.24", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", + "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", + "dev": true, + "requires": { + "safer-buffer": ">= 2.1.2 < 3" + } + }, + "ieee754": { + "version": "1.1.13", + "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.1.13.tgz", + "integrity": "sha512-4vf7I2LYV/HaWerSo3XmlMkp5eZ83i+/CDluXi/IGTs/O1sejBNhTtnxzmRZfvOUqj7lZjqHkeTvpgSFDlWZTg==", "dev": true }, - "forever-agent": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz", - "integrity": "sha1-+8cfDEGt6zf5bFd60e1C2P2sypE=", + "iferr": { + "version": "0.1.5", + "resolved": "https://registry.npmjs.org/iferr/-/iferr-0.1.5.tgz", + "integrity": "sha1-xg7taebY/bazEEofy8ocGS3FtQE=", "dev": true }, - "form-data": { - "version": "2.3.3", - "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.3.3.tgz", - "integrity": "sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ==", + "ignore": { + "version": "3.3.10", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-3.3.10.tgz", + "integrity": "sha512-Pgs951kaMm5GXP7MOvxERINe3gsaVjUWFm+UZPSq9xYriQAksyhg0csnS0KXSNRD5NmNdapXEpjxG49+AKh/ug==", + "dev": true + }, + "ignore-walk": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/ignore-walk/-/ignore-walk-3.0.3.tgz", + "integrity": "sha512-m7o6xuOaT1aqheYHKf8W6J5pYH85ZI9w077erOzLje3JsB1gkafkAhHHY19dqjulgIZHFm32Cp5uNZgcQqdJKw==", "dev": true, "requires": { - "asynckit": "^0.4.0", - "combined-stream": "^1.0.6", - "mime-types": "^2.1.12" + "minimatch": "^3.0.4" } }, - "forwarded": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.1.2.tgz", - "integrity": "sha1-mMI9qxF1ZXuMBXPozszZGw/xjIQ=", + "image-size": { + "version": "0.5.5", + "resolved": "https://registry.npmjs.org/image-size/-/image-size-0.5.5.tgz", + "integrity": "sha1-Cd/Uq50g4p6xw+gLiZA3jfnjy5w=", + "dev": true, + "optional": true + }, + "immediate": { + "version": "3.0.6", + "resolved": "https://registry.npmjs.org/immediate/-/immediate-3.0.6.tgz", + "integrity": "sha1-nbHb0Pr43m++D13V5Wu2BigN5ps=", "dev": true }, - "fragment-cache": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/fragment-cache/-/fragment-cache-0.2.1.tgz", - "integrity": "sha1-QpD60n8T6Jvn8zeZxrxaCr//DRk=", + "import-cwd": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/import-cwd/-/import-cwd-2.1.0.tgz", + "integrity": "sha1-qmzzbnInYShcs3HsZRn1PiQ1sKk=", "dev": true, "requires": { - "map-cache": "^0.2.2" + "import-from": "^2.1.0" } }, - "fresh": { - "version": "0.5.2", - "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", - "integrity": "sha1-PYyt2Q2XZWn6g1qx+OSyOhBWBac=", + "import-fresh": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-2.0.0.tgz", + "integrity": "sha1-2BNVwVYS04bGH53dOSLUMEgipUY=", + "dev": true, + "requires": { + "caller-path": "^2.0.0", + "resolve-from": "^3.0.0" + } + }, + "import-from": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/import-from/-/import-from-2.1.0.tgz", + "integrity": "sha1-M1238qev/VOqpHHUuAId7ja387E=", + "dev": true, + "requires": { + "resolve-from": "^3.0.0" + } + }, + "import-local": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/import-local/-/import-local-2.0.0.tgz", + "integrity": "sha512-b6s04m3O+s3CGSbqDIyP4R6aAwAeYlVq9+WUWep6iHa8ETRf9yei1U48C5MmfJmV9AiLYYBKPMq/W+/WRpQmCQ==", + "dev": true, + "requires": { + "pkg-dir": "^3.0.0", + "resolve-cwd": "^2.0.0" + } + }, + "imurmurhash": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", + "integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o=", + "dev": true + }, + "in-publish": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/in-publish/-/in-publish-2.0.1.tgz", + "integrity": "sha512-oDM0kUSNFC31ShNxHKUyfZKy8ZeXZBWMjMdZHKLOk13uvT27VTL/QzRGfRUcevJhpkZAvlhPYuXkF7eNWrtyxQ==" + }, + "indent-string": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-4.0.0.tgz", + "integrity": "sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==", + "dev": true + }, + "indexes-of": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/indexes-of/-/indexes-of-1.0.1.tgz", + "integrity": "sha1-8w9xbI4r00bHtn0985FVZqfAVgc=", + "dev": true + }, + "indexof": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/indexof/-/indexof-0.0.1.tgz", + "integrity": "sha1-gtwzbSMrkGIXnQWrMpOmYFn9Q10=", + "dev": true + }, + "infer-owner": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/infer-owner/-/infer-owner-1.0.4.tgz", + "integrity": "sha512-IClj+Xz94+d7irH5qRyfJonOdfTzuDaifE6ZPWfx0N0+/ATZCbuTPq2prFl526urkQd90WyUKIh1DfBQ2hMz9A==", "dev": true }, - "from2": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/from2/-/from2-2.3.0.tgz", - "integrity": "sha1-i/tVAr3kpNNs/e6gB/zKIdfjgq8=", - "dev": true, + "inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", "requires": { - "inherits": "^2.0.1", - "readable-stream": "^2.0.0" + "once": "^1.3.0", + "wrappy": "1" } }, - "fs-extra": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-7.0.1.tgz", - "integrity": "sha512-YJDaCJZEnBmcbw13fvdAM9AwNOJwOzrE4pqMqBq5nFiEqXUqHwlK4B+3pUw6JNvfSPtX05xFHtYy/1ni01eGCw==", + "inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" + }, + "ini": { + "version": "1.3.5", + "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.5.tgz", + "integrity": "sha512-RZY5huIKCMRWDUqZlEi72f/lmXKMvuszcMBduliQ3nnWbx9X/ZBQO7DijMEYS9EhHBb2qacRUMtC7svLwe0lcw==", + "dev": true + }, + "inquirer": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-7.0.0.tgz", + "integrity": "sha512-rSdC7zelHdRQFkWnhsMu2+2SO41mpv2oF2zy4tMhmiLWkcKbOAs87fWAJhVXttKVwhdZvymvnuM95EyEXg2/tQ==", "dev": true, "requires": { - "graceful-fs": "^4.1.2", - "jsonfile": "^4.0.0", - "universalify": "^0.1.0" + "ansi-escapes": "^4.2.1", + "chalk": "^2.4.2", + "cli-cursor": "^3.1.0", + "cli-width": "^2.0.0", + "external-editor": "^3.0.3", + "figures": "^3.0.0", + "lodash": "^4.17.15", + "mute-stream": "0.0.8", + "run-async": "^2.2.0", + "rxjs": "^6.4.0", + "string-width": "^4.1.0", + "strip-ansi": "^5.1.0", + "through": "^2.3.6" + }, + "dependencies": { + "ansi-regex": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.0.tgz", + "integrity": "sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==", + "dev": true + }, + "is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "dev": true + }, + "string-width": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.0.tgz", + "integrity": "sha512-zUz5JD+tgqtuDjMhwIg5uFVV3dtqZ9yQJlZVfq4I01/K5Paj5UHj7VyrQOJvzawSVlKpObApbfD0Ed6yJc+1eg==", + "dev": true, + "requires": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.0" + }, + "dependencies": { + "strip-ansi": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz", + "integrity": "sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==", + "dev": true, + "requires": { + "ansi-regex": "^5.0.0" + } + } + } + }, + "strip-ansi": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", + "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", + "dev": true, + "requires": { + "ansi-regex": "^4.1.0" + }, + "dependencies": { + "ansi-regex": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", + "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", + "dev": true + } + } + } } }, - "fs-minipass": { - "version": "1.2.7", - "resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-1.2.7.tgz", - "integrity": "sha512-GWSSJGFy4e9GUeCcbIkED+bgAoFyj7XF1mV8rma3QW4NIqX9Kyx79N/PF61H5udOV3aY1IaMLs6pGbH71nlCTA==", + "internal-ip": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/internal-ip/-/internal-ip-4.3.0.tgz", + "integrity": "sha512-S1zBo1D6zcsyuC6PMmY5+55YMILQ9av8lotMx447Bq6SAgo/sDK6y6uUKmuYhW7eacnIhFfsPmCNYdDzsnnDCg==", "dev": true, "requires": { - "minipass": "^2.6.0" + "default-gateway": "^4.2.0", + "ipaddr.js": "^1.9.0" } }, - "fs-write-stream-atomic": { - "version": "1.0.10", - "resolved": "https://registry.npmjs.org/fs-write-stream-atomic/-/fs-write-stream-atomic-1.0.10.tgz", - "integrity": "sha1-tH31NJPvkR33VzHnCp3tAYnbQMk=", + "invariant": { + "version": "2.2.4", + "resolved": "https://registry.npmjs.org/invariant/-/invariant-2.2.4.tgz", + "integrity": "sha512-phJfQVBuaJM5raOpJjSfkiD6BpbCE4Ns//LaXl6wGYtUBY83nWS6Rf9tXm2e8VaK60JEjYldbPif/A2B1C2gNA==", "dev": true, "requires": { - "graceful-fs": "^4.1.2", - "iferr": "^0.1.5", - "imurmurhash": "^0.1.4", - "readable-stream": "1 || 2" + "loose-envify": "^1.0.0" } }, - "fs.realpath": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", - "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=", + "invert-kv": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/invert-kv/-/invert-kv-2.0.0.tgz", + "integrity": "sha512-wPVv/y/QQ/Uiirj/vh3oP+1Ww+AWehmi1g5fFWGPF6IpCBCDVrhgHRMvrLfdYcwDh3QJbGXDW4JAuzxElLSqKA==", "dev": true }, - "fsevents": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.1.2.tgz", - "integrity": "sha512-R4wDiBwZ0KzpgOWetKDug1FZcYhqYnUYKtfZYt4mD5SBz76q0KR4Q9o7GIPamsVPGmW3EYPPJ0dOOjvx32ldZA==", - "dev": true, - "optional": true - }, - "function-bind": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", - "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==", + "ip": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/ip/-/ip-1.1.5.tgz", + "integrity": "sha1-vd7XARQpCCjAoDnnLvJfWq7ENUo=", "dev": true }, - "genfun": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/genfun/-/genfun-5.0.0.tgz", - "integrity": "sha512-KGDOARWVga7+rnB3z9Sd2Letx515owfk0hSxHGuqjANb1M+x2bGZGqHLiozPsYMdM2OubeMni/Hpwmjq6qIUhA==", + "ip-regex": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/ip-regex/-/ip-regex-2.1.0.tgz", + "integrity": "sha1-+ni/XS5pE8kRzp+BnuUUa7bYROk=", "dev": true }, - "gensync": { - "version": "1.0.0-beta.1", - "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.1.tgz", - "integrity": "sha512-r8EC6NO1sngH/zdD9fiRDLdcgnbayXah+mLgManTaIZJqEC1MZstmnox8KpnI2/fxQwrp5OpCOYWLp4rBl4Jcg==", + "ipaddr.js": { + "version": "1.9.1", + "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz", + "integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==", "dev": true }, - "get-caller-file": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-1.0.3.tgz", - "integrity": "sha512-3t6rVToeoZfYSGd8YoLFR2DJkiQrIiUrGcjvFX2mDw3bn6k2OtwHN0TNCLbBO+w8qTvimhDkv+LSscbJY1vE6w==", + "iqb-components": { + "version": "1.7.2", + "resolved": "https://registry.npmjs.org/iqb-components/-/iqb-components-1.7.2.tgz", + "integrity": "sha512-b5pQTS8FgXPToW+MaUt7EVxwd9jBoRH4OXde9C2uaIO9IQbguxFsyo1mFemoKjNLcjm2wvtXZJi63iQWdsYihg==" + }, + "is-absolute-url": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-absolute-url/-/is-absolute-url-2.1.0.tgz", + "integrity": "sha1-UFMN+4T8yap9vnhS6Do3uTufKqY=", "dev": true }, - "get-stream": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-4.1.0.tgz", - "integrity": "sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w==", + "is-accessor-descriptor": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", + "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=", "dev": true, "requires": { - "pump": "^3.0.0" + "kind-of": "^3.0.2" + }, + "dependencies": { + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "requires": { + "is-buffer": "^1.1.5" + } + } } }, - "get-value": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/get-value/-/get-value-2.0.6.tgz", - "integrity": "sha1-3BXKHGcjh8p2vTesCjlbogQqLCg=", + "is-arguments": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/is-arguments/-/is-arguments-1.0.4.tgz", + "integrity": "sha512-xPh0Rmt8NE65sNzvyUmWgI1tz3mKq74lGA0mL8LYZcoIzKOzDh6HmrYm3d18k60nHerC8A9Km8kYu87zfSFnLA==", "dev": true }, - "getpass": { - "version": "0.1.7", - "resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz", - "integrity": "sha1-Xv+OPmhNVprkyysSgmBOi6YhSfo=", + "is-arrayish": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", + "integrity": "sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0=" + }, + "is-binary-path": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", + "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", "dev": true, "requires": { - "assert-plus": "^1.0.0" + "binary-extensions": "^2.0.0" } }, - "glob": { - "version": "7.1.4", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.4.tgz", - "integrity": "sha512-hkLPepehmnKk41pUGm3sYxoFs/umurYfYJCerbXEyFIWcAzvpipAgVkBqqT9RBKMGjnq6kMuyYwha6csxbiM1A==", + "is-buffer": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz", + "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==", + "dev": true + }, + "is-callable": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.1.5.tgz", + "integrity": "sha512-ESKv5sMCJB2jnHTWZ3O5itG+O128Hsus4K4Qh1h2/cgn2vbgnLSVqfV46AeJA9D5EeeLa9w81KUXMtn34zhX+Q==" + }, + "is-color-stop": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-color-stop/-/is-color-stop-1.1.0.tgz", + "integrity": "sha1-z/9HGu5N1cnhWFmPvhKWe1za00U=", "dev": true, "requires": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.0.4", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" + "css-color-names": "^0.0.4", + "hex-color-regex": "^1.1.0", + "hsl-regex": "^1.0.0", + "hsla-regex": "^1.0.0", + "rgb-regex": "^1.0.1", + "rgba-regex": "^1.0.0" } }, - "glob-parent": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-3.1.0.tgz", - "integrity": "sha1-nmr2KZ2NO9K9QEMIMr0RPfkGxa4=", + "is-data-descriptor": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", + "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=", "dev": true, "requires": { - "is-glob": "^3.1.0", - "path-dirname": "^1.0.0" + "kind-of": "^3.0.2" }, "dependencies": { - "is-glob": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-3.1.0.tgz", - "integrity": "sha1-e6WuJCF4BKxwcHuWkiVnSGzD6Eo=", + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", "dev": true, "requires": { - "is-extglob": "^2.1.0" + "is-buffer": "^1.1.5" } } - } - }, - "globals": { - "version": "11.12.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", - "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==", - "dev": true + } }, - "globby": { - "version": "7.1.1", - "resolved": "https://registry.npmjs.org/globby/-/globby-7.1.1.tgz", - "integrity": "sha1-+yzP+UAfhgCUXfral0QMypcrhoA=", + "is-date-object": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.2.tgz", + "integrity": "sha512-USlDT524woQ08aoZFzh3/Z6ch9Y/EWXEHQ/AaRN0SkKq4t2Jw2R2339tSXmwuVoY7LLlBCbOIlx2myP/L5zk0g==" + }, + "is-descriptor": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", + "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", "dev": true, "requires": { - "array-union": "^1.0.1", - "dir-glob": "^2.0.0", - "glob": "^7.1.2", - "ignore": "^3.3.5", - "pify": "^3.0.0", - "slash": "^1.0.0" + "is-accessor-descriptor": "^0.1.6", + "is-data-descriptor": "^0.1.4", + "kind-of": "^5.0.0" }, "dependencies": { - "pify": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz", - "integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=", + "kind-of": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", + "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==", "dev": true } } }, - "graceful-fs": { - "version": "4.2.3", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.3.tgz", - "integrity": "sha512-a30VEBm4PEdx1dRB7MFK7BejejvCvBronbLjht+sHuGYj8PHs7M/5Z+rt5lw551vZ7yfTCj4Vuyy3mSJytDWRQ==", + "is-directory": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/is-directory/-/is-directory-0.3.1.tgz", + "integrity": "sha1-YTObbyR1/Hcv2cnYP1yFddwVSuE=", "dev": true }, - "hammerjs": { - "version": "2.0.8", - "resolved": "https://registry.npmjs.org/hammerjs/-/hammerjs-2.0.8.tgz", - "integrity": "sha1-BO93hiz/K7edMPdpIJWTAiK/YPE=" + "is-extendable": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz", + "integrity": "sha1-YrEQ4omkcUGOPsNqYX1HLjAd/Ik=", + "dev": true }, - "handle-thing": { + "is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=", + "dev": true + }, + "is-finite": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-finite/-/is-finite-1.1.0.tgz", + "integrity": "sha512-cdyMtqX/BOqqNBBiKlIVkytNHm49MtMlYyn1zxzvJKWmFMlGzm+ry5BBfYyeY9YmNKbRSo/o7OX9w9ale0wg3w==" + }, + "is-fullwidth-code-point": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/handle-thing/-/handle-thing-2.0.0.tgz", - "integrity": "sha512-d4sze1JNC454Wdo2fkuyzCr6aHcbL6PGGuFAz0Li/NcOm1tCHGnWDRmJP85dh9IhQErTc2svWFEX5xHIOo//kQ==", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", + "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=" + }, + "is-glob": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.1.tgz", + "integrity": "sha512-5G0tKtBTFImOqDnLB2hG6Bp2qcKEFduo4tZu9MT/H6NQv/ghhy30o55ufafxJ/LdH79LLs2Kfrn85TLKyA7BUg==", + "dev": true, + "requires": { + "is-extglob": "^2.1.1" + } + }, + "is-interactive": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-interactive/-/is-interactive-1.0.0.tgz", + "integrity": "sha512-2HvIEKRoqS62guEC+qBjpvRubdX910WCMuJTZ+I9yvqKU2/12eSL549HMwtabb4oupdj2sMP50k+XJfB/8JE6w==", "dev": true }, - "har-schema": { + "is-number": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", + "dev": true + }, + "is-obj": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/har-schema/-/har-schema-2.0.0.tgz", - "integrity": "sha1-qUwiJOvKwEeCoNkDVSHyRzW37JI=", + "resolved": "https://registry.npmjs.org/is-obj/-/is-obj-2.0.0.tgz", + "integrity": "sha512-drqDG3cbczxxEJRoOXcOjtdp1J/lyp1mNn0xaznRs8+muBhgQcrnbspox5X5fOw0HnMnbfDzvnEMEtqDEJEo8w==", "dev": true }, - "har-validator": { - "version": "5.1.3", - "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-5.1.3.tgz", - "integrity": "sha512-sNvOCzEQNr/qrvJgc3UG/kD4QtlHycrzwS+6mfTrrSq97BvaYcPZZI1ZSqGSPR73Cxn4LKTD4PttRwfU7jWq5g==", + "is-path-cwd": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/is-path-cwd/-/is-path-cwd-2.2.0.tgz", + "integrity": "sha512-w942bTcih8fdJPJmQHFzkS76NEP8Kzzvmw92cXsazb8intwLqPibPPdXf4ANdKV3rYMuuQYGIWtvz9JilB3NFQ==", + "dev": true + }, + "is-path-in-cwd": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-path-in-cwd/-/is-path-in-cwd-2.1.0.tgz", + "integrity": "sha512-rNocXHgipO+rvnP6dk3zI20RpOtrAM/kzbB258Uw5BWr3TpXi861yzjo16Dn4hUox07iw5AyeMLHWsujkjzvRQ==", "dev": true, "requires": { - "ajv": "^6.5.5", - "har-schema": "^2.0.0" + "is-path-inside": "^2.1.0" } }, - "has": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", - "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", + "is-path-inside": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-2.1.0.tgz", + "integrity": "sha512-wiyhTzfDWsvwAW53OBWF5zuvaOGlZ6PwYxAbPVDhpm+gM09xKQGjBq/8uYN12aDvMxnAnq3dxTyoSoRNmg5YFg==", "dev": true, "requires": { - "function-bind": "^1.1.1" + "path-is-inside": "^1.0.2" } }, - "has-ansi": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/has-ansi/-/has-ansi-2.0.0.tgz", - "integrity": "sha1-NPUEnOHs3ysGSa8+8k5F7TVBbZE=", - "dev": true, + "is-plain-obj": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-1.1.0.tgz", + "integrity": "sha1-caUMhCnfync8kqOQpKA7OfzVHT4=", + "dev": true + }, + "is-plain-object": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz", + "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==", "requires": { - "ansi-regex": "^2.0.0" + "isobject": "^3.0.1" } }, - "has-binary2": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/has-binary2/-/has-binary2-1.0.3.tgz", - "integrity": "sha512-G1LWKhDSvhGeAQ8mPVQlqNcOB2sJdwATtZKl2pDKKHfpf/rYj24lkinxf69blJbnsvtqqNU+L3SL50vzZhXOnw==", - "dev": true, + "is-promise": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-promise/-/is-promise-2.1.0.tgz", + "integrity": "sha1-eaKp7OfwlugPNtKy87wWwf9L8/o=", + "dev": true + }, + "is-regex": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.0.5.tgz", + "integrity": "sha512-vlKW17SNq44owv5AQR3Cq0bQPEb8+kF3UKZ2fiZNOWtztYE5i0CzCZxFDwO58qAOWtxdBRVO/V5Qin1wjCqFYQ==", "requires": { - "isarray": "2.0.1" - }, - "dependencies": { - "isarray": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.1.tgz", - "integrity": "sha1-o32U7ZzaLVmGXJ92/llu4fM4dB4=", - "dev": true - } + "has": "^1.0.3" } }, - "has-cors": { + "is-resolvable": { "version": "1.1.0", - "resolved": "https://registry.npmjs.org/has-cors/-/has-cors-1.1.0.tgz", - "integrity": "sha1-XkdHk/fqmEPRu5nCPu9J/xJv/zk=", + "resolved": "https://registry.npmjs.org/is-resolvable/-/is-resolvable-1.1.0.tgz", + "integrity": "sha512-qgDYXFSR5WvEfuS5dMj6oTMEbrrSaM0CrFk2Yiq/gXnBvD9pMa2jGXxyhGLfvhZpuMZe18CJpFxAt3CRs42NMg==", "dev": true }, - "has-flag": { + "is-stream": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz", + "integrity": "sha1-EtSj3U5o4Lec6428hBc66A2RykQ=", + "dev": true + }, + "is-svg": { "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", + "resolved": "https://registry.npmjs.org/is-svg/-/is-svg-3.0.0.tgz", + "integrity": "sha512-gi4iHK53LR2ujhLVVj+37Ykh9GLqYHX6JOVXbLAucaG/Cqw9xwdFOjDM2qeifLs1sF1npXXFvDu0r5HNgCMrzQ==", + "dev": true, + "requires": { + "html-comment-regex": "^1.1.0" + } + }, + "is-symbol": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.3.tgz", + "integrity": "sha512-OwijhaRSgqvhm/0ZdAcXNZt9lYdKFpcRDT5ULUuYXPoT794UNOdU+gpT6Rzo7b4V2HUl/op6GqY894AZwv9faQ==", + "requires": { + "has-symbols": "^1.0.1" + } + }, + "is-typedarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", + "integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=" + }, + "is-utf8": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/is-utf8/-/is-utf8-0.2.1.tgz", + "integrity": "sha1-Sw2hRCEE0bM2NA6AeX6GXPOffXI=" + }, + "is-windows": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-windows/-/is-windows-1.0.2.tgz", + "integrity": "sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA==", "dev": true }, - "has-symbols": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.1.tgz", - "integrity": "sha512-PLcsoqu++dmEIZB+6totNFKq/7Do+Z0u4oT0zKOJNl3lYK6vGwwu2hjHs+68OEZbTjiUE9bgOABXbP/GvrS0Kg==", + "is-wsl": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-2.1.1.tgz", + "integrity": "sha512-umZHcSrwlDHo2TGMXv0DZ8dIUGunZ2Iv68YZnrmCiBPkZ4aaOhtv7pXJKeki9k3qJ3RJr0cDyitcl5wEH3AYog==", "dev": true }, - "has-value": { + "isarray": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/has-value/-/has-value-1.0.0.tgz", - "integrity": "sha1-GLKB2lhbHFxR3vJMkw7SmgvmsXc=", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=" + }, + "isbinaryfile": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/isbinaryfile/-/isbinaryfile-3.0.3.tgz", + "integrity": "sha512-8cJBL5tTd2OS0dM4jz07wQd5g0dCCqIhUxPIGtZfa5L6hWlvV5MHTITy/DBAsF+Oe2LS1X3krBUhNwaGUWpWxw==", "dev": true, "requires": { - "get-value": "^2.0.6", - "has-values": "^1.0.0", - "isobject": "^3.0.0" + "buffer-alloc": "^1.2.0" } }, - "has-values": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/has-values/-/has-values-1.0.0.tgz", - "integrity": "sha1-lbC2P+whRmGab+V/51Yo1aOe/k8=", + "isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=" + }, + "isobject": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", + "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=" + }, + "isstream": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz", + "integrity": "sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo=" + }, + "istanbul-api": { + "version": "2.1.6", + "resolved": "https://registry.npmjs.org/istanbul-api/-/istanbul-api-2.1.6.tgz", + "integrity": "sha512-x0Eicp6KsShG1k1rMgBAi/1GgY7kFGEBwQpw3PXGEmu+rBcBNhqU8g2DgY9mlepAsLPzrzrbqSgCGANnki4POA==", "dev": true, "requires": { - "is-number": "^3.0.0", - "kind-of": "^4.0.0" + "async": "^2.6.2", + "compare-versions": "^3.4.0", + "fileset": "^2.0.3", + "istanbul-lib-coverage": "^2.0.5", + "istanbul-lib-hook": "^2.0.7", + "istanbul-lib-instrument": "^3.3.0", + "istanbul-lib-report": "^2.0.8", + "istanbul-lib-source-maps": "^3.0.6", + "istanbul-reports": "^2.2.4", + "js-yaml": "^3.13.1", + "make-dir": "^2.1.0", + "minimatch": "^3.0.4", + "once": "^1.4.0" }, "dependencies": { - "is-number": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", - "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } + "istanbul-lib-coverage": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.5.tgz", + "integrity": "sha512-8aXznuEPCJvGnMSRft4udDRDtb1V3pkQkMMI5LI+6HuQz5oQ4J2UFn1H82raA3qJtyOLkkwVqICBQkjnGtn5mA==", + "dev": true }, - "kind-of": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-4.0.0.tgz", - "integrity": "sha1-IIE989cSkosgc3hpGkUGb65y3Vc=", + "istanbul-lib-instrument": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-3.3.0.tgz", + "integrity": "sha512-5nnIN4vo5xQZHdXno/YDXJ0G+I3dAm4XgzfSVTPLQpj/zAV2dV6Juy0yaf10/zrJOJeHoN3fraFe+XRq2bFVZA==", "dev": true, "requires": { - "is-buffer": "^1.1.5" + "@babel/generator": "^7.4.0", + "@babel/parser": "^7.4.3", + "@babel/template": "^7.4.0", + "@babel/traverse": "^7.4.3", + "@babel/types": "^7.4.0", + "istanbul-lib-coverage": "^2.0.5", + "semver": "^6.0.0" } } } }, - "hash-base": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/hash-base/-/hash-base-3.0.4.tgz", - "integrity": "sha1-X8hoaEfs1zSZQDMZprCj8/auSRg=", - "dev": true, - "requires": { - "inherits": "^2.0.1", - "safe-buffer": "^5.0.1" - } + "istanbul-lib-coverage": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-3.0.0.tgz", + "integrity": "sha512-UiUIqxMgRDET6eR+o5HbfRYP1l0hqkWOs7vNxC/mggutCMUIhWMm8gAHb8tHlyfD3/l6rlgNA5cKdDzEAf6hEg==", + "dev": true }, - "hash.js": { - "version": "1.1.7", - "resolved": "https://registry.npmjs.org/hash.js/-/hash.js-1.1.7.tgz", - "integrity": "sha512-taOaskGt4z4SOANNseOviYDvjEJinIkRgmp7LbKP2YTTmVxWBl87s/uzK9r+44BclBSp2X7K1hqeNfz9JbBeXA==", + "istanbul-lib-hook": { + "version": "2.0.7", + "resolved": "https://registry.npmjs.org/istanbul-lib-hook/-/istanbul-lib-hook-2.0.7.tgz", + "integrity": "sha512-vrRztU9VRRFDyC+aklfLoeXyNdTfga2EI3udDGn4cZ6fpSXpHLV9X6CHvfoMCPtggg8zvDDmC4b9xfu0z6/llA==", "dev": true, "requires": { - "inherits": "^2.0.3", - "minimalistic-assert": "^1.0.1" + "append-transform": "^1.0.0" } }, - "hmac-drbg": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/hmac-drbg/-/hmac-drbg-1.0.1.tgz", - "integrity": "sha1-0nRXAQJabHdabFRXk+1QL8DGSaE=", + "istanbul-lib-instrument": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-4.0.1.tgz", + "integrity": "sha512-imIchxnodll7pvQBYOqUu88EufLCU56LMeFPZZM/fJZ1irYcYdqroaV+ACK1Ila8ls09iEYArp+nqyC6lW1Vfg==", "dev": true, "requires": { - "hash.js": "^1.0.3", - "minimalistic-assert": "^1.0.0", - "minimalistic-crypto-utils": "^1.0.1" + "@babel/core": "^7.7.5", + "@babel/parser": "^7.7.5", + "@babel/template": "^7.7.4", + "@babel/traverse": "^7.7.4", + "@istanbuljs/schema": "^0.1.2", + "istanbul-lib-coverage": "^3.0.0", + "semver": "^6.3.0" } }, - "hosted-git-info": { - "version": "2.8.8", - "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.8.tgz", - "integrity": "sha512-f/wzC2QaWBs7t9IYqB4T3sR1xviIViXJRJTWBlx2Gf3g0Xi5vI7Yy4koXQ1c9OYDGHN9sBy1DQ2AB8fqZBWhUg==", - "dev": true - }, - "hpack.js": { - "version": "2.1.6", - "resolved": "https://registry.npmjs.org/hpack.js/-/hpack.js-2.1.6.tgz", - "integrity": "sha1-h3dMCUnlE/QuhFdbPEVoH63ioLI=", + "istanbul-lib-report": { + "version": "2.0.8", + "resolved": "https://registry.npmjs.org/istanbul-lib-report/-/istanbul-lib-report-2.0.8.tgz", + "integrity": "sha512-fHBeG573EIihhAblwgxrSenp0Dby6tJMFR/HvlerBsrCTD5bkUuoNtn3gVh29ZCS824cGGBPn7Sg7cNk+2xUsQ==", "dev": true, "requires": { - "inherits": "^2.0.1", - "obuf": "^1.0.0", - "readable-stream": "^2.0.1", - "wbuf": "^1.1.0" + "istanbul-lib-coverage": "^2.0.5", + "make-dir": "^2.1.0", + "supports-color": "^6.1.0" + }, + "dependencies": { + "istanbul-lib-coverage": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.5.tgz", + "integrity": "sha512-8aXznuEPCJvGnMSRft4udDRDtb1V3pkQkMMI5LI+6HuQz5oQ4J2UFn1H82raA3qJtyOLkkwVqICBQkjnGtn5mA==", + "dev": true + }, + "supports-color": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-6.1.0.tgz", + "integrity": "sha512-qe1jfm1Mg7Nq/NSh6XE24gPXROEVsWHxC1LIx//XNlD9iw7YZQGjZNjYN7xGaEG6iKdA8EtNFW6R0gjnVXp+wQ==", + "dev": true, + "requires": { + "has-flag": "^3.0.0" + } + } } }, - "html-entities": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/html-entities/-/html-entities-1.2.1.tgz", - "integrity": "sha1-DfKTUfByEWNRXfueVUPl9u7VFi8=", - "dev": true - }, - "html-escaper": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/html-escaper/-/html-escaper-2.0.0.tgz", - "integrity": "sha512-a4u9BeERWGu/S8JiWEAQcdrg9v4QArtP9keViQjGMdff20fBdd8waotXaNmODqBe6uZ3Nafi7K/ho4gCQHV3Ig==", - "dev": true - }, - "http-cache-semantics": { - "version": "3.8.1", - "resolved": "https://registry.npmjs.org/http-cache-semantics/-/http-cache-semantics-3.8.1.tgz", - "integrity": "sha512-5ai2iksyV8ZXmnZhHH4rWPoxxistEexSi5936zIQ1bnNTW5VnA85B6P/VpXiRM017IgRvb2kKo1a//y+0wSp3w==", - "dev": true - }, - "http-deceiver": { - "version": "1.2.7", - "resolved": "https://registry.npmjs.org/http-deceiver/-/http-deceiver-1.2.7.tgz", - "integrity": "sha1-+nFolEq5pRnTN8sL7HKE3D5yPYc=", - "dev": true - }, - "http-errors": { - "version": "1.7.2", - "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.7.2.tgz", - "integrity": "sha512-uUQBt3H/cSIVfch6i1EuPNy/YsRSOUBXTVfZ+yR7Zjez3qjBz6i9+i4zjNaoqcoFVI4lQJ5plg63TvGfRSDCRg==", + "istanbul-lib-source-maps": { + "version": "3.0.6", + "resolved": "https://registry.npmjs.org/istanbul-lib-source-maps/-/istanbul-lib-source-maps-3.0.6.tgz", + "integrity": "sha512-R47KzMtDJH6X4/YW9XTx+jrLnZnscW4VpNN+1PViSYTejLVPWv7oov+Duf8YQSPyVRUvueQqz1TcsC6mooZTXw==", "dev": true, "requires": { - "depd": "~1.1.2", - "inherits": "2.0.3", - "setprototypeof": "1.1.1", - "statuses": ">= 1.5.0 < 2", - "toidentifier": "1.0.0" + "debug": "^4.1.1", + "istanbul-lib-coverage": "^2.0.5", + "make-dir": "^2.1.0", + "rimraf": "^2.6.3", + "source-map": "^0.6.1" }, "dependencies": { - "inherits": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", - "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=", + "istanbul-lib-coverage": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.5.tgz", + "integrity": "sha512-8aXznuEPCJvGnMSRft4udDRDtb1V3pkQkMMI5LI+6HuQz5oQ4J2UFn1H82raA3qJtyOLkkwVqICBQkjnGtn5mA==", + "dev": true + }, + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", "dev": true } } }, - "http-parser-js": { - "version": "0.4.10", - "resolved": "https://registry.npmjs.org/http-parser-js/-/http-parser-js-0.4.10.tgz", - "integrity": "sha1-ksnBN0w1CF912zWexWzCV8u5P6Q=", - "dev": true - }, - "http-proxy": { - "version": "1.18.0", - "resolved": "https://registry.npmjs.org/http-proxy/-/http-proxy-1.18.0.tgz", - "integrity": "sha512-84I2iJM/n1d4Hdgc6y2+qY5mDaz2PUVjlg9znE9byl+q0uC3DeByqBGReQu5tpLK0TAqTIXScRUV+dg7+bUPpQ==", + "istanbul-reports": { + "version": "2.2.7", + "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-2.2.7.tgz", + "integrity": "sha512-uu1F/L1o5Y6LzPVSVZXNOoD/KXpJue9aeLRd0sM9uMXfZvzomB0WxVamWb5ue8kA2vVWEmW7EG+A5n3f1kqHKg==", "dev": true, "requires": { - "eventemitter3": "^4.0.0", - "follow-redirects": "^1.0.0", - "requires-port": "^1.0.0" + "html-escaper": "^2.0.0" } }, - "http-proxy-agent": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-2.1.0.tgz", - "integrity": "sha512-qwHbBLV7WviBl0rQsOzH6o5lwyOIvwp/BdFnvVxXORldu5TmjFfjzBcWUWS5kWAZhmv+JtiDhSuQCp4sBfbIgg==", + "jasmine": { + "version": "2.8.0", + "resolved": "https://registry.npmjs.org/jasmine/-/jasmine-2.8.0.tgz", + "integrity": "sha1-awicChFXax8W3xG4AUbZHU6Lij4=", "dev": true, "requires": { - "agent-base": "4", - "debug": "3.1.0" + "exit": "^0.1.2", + "glob": "^7.0.6", + "jasmine-core": "~2.8.0" }, "dependencies": { - "debug": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", - "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", - "dev": true, - "requires": { - "ms": "2.0.0" - } - }, - "ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", + "jasmine-core": { + "version": "2.8.0", + "resolved": "https://registry.npmjs.org/jasmine-core/-/jasmine-core-2.8.0.tgz", + "integrity": "sha1-vMl5rh+f0FcB5F5S5l06XWPxok4=", "dev": true } } }, - "http-proxy-middleware": { - "version": "0.19.1", - "resolved": "https://registry.npmjs.org/http-proxy-middleware/-/http-proxy-middleware-0.19.1.tgz", - "integrity": "sha512-yHYTgWMQO8VvwNS22eLLloAkvungsKdKTLO8AJlftYIKNfJr3GK3zK0ZCfzDDGUBttdGc8xFy1mCitvNKQtC3Q==", - "dev": true, - "requires": { - "http-proxy": "^1.17.0", - "is-glob": "^4.0.0", - "lodash": "^4.17.11", - "micromatch": "^3.1.10" - } + "jasmine-core": { + "version": "3.5.0", + "resolved": "https://registry.npmjs.org/jasmine-core/-/jasmine-core-3.5.0.tgz", + "integrity": "sha512-nCeAiw37MIMA9w9IXso7bRaLl+c/ef3wnxsoSAlYrzS+Ot0zTG6nU8G/cIfGkqpkjX2wNaIW9RFG0TwIFnG6bA==", + "dev": true }, - "http-signature": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.2.0.tgz", - "integrity": "sha1-muzZJRFHcvPZW2WmCruPfBj7rOE=", + "jasmine-spec-reporter": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/jasmine-spec-reporter/-/jasmine-spec-reporter-4.2.1.tgz", + "integrity": "sha512-FZBoZu7VE5nR7Nilzy+Np8KuVIOxF4oXDPDknehCYBDE080EnlPu0afdZNmpGDBRCUBv3mj5qgqCRmk6W/K8vg==", "dev": true, "requires": { - "assert-plus": "^1.0.0", - "jsprim": "^1.2.2", - "sshpk": "^1.7.0" + "colors": "1.1.2" } }, - "https-browserify": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/https-browserify/-/https-browserify-1.0.0.tgz", - "integrity": "sha1-7AbBDgo0wPL68Zn3/X/Hj//QPHM=", + "jasminewd2": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/jasminewd2/-/jasminewd2-2.2.0.tgz", + "integrity": "sha1-43zwsX8ZnM4jvqcbIDk5Uka07E4=", "dev": true }, - "https-proxy-agent": { - "version": "2.2.4", - "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-2.2.4.tgz", - "integrity": "sha512-OmvfoQ53WLjtA9HeYP9RNrWMJzzAz1JGaSFr1nijg0PVR1JaD/xbJq1mdEIIlxGpXp9eSe/O2LgU9DJmTPd0Eg==", + "jest-worker": { + "version": "24.9.0", + "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-24.9.0.tgz", + "integrity": "sha512-51PE4haMSXcHohnSMdM42anbvZANYTqMrr52tVKPqqsPJMzoP6FYYDVqahX/HrAoKEKz3uUPzSvKs9A3qR4iVw==", "dev": true, "requires": { - "agent-base": "^4.3.0", - "debug": "^3.1.0" + "merge-stream": "^2.0.0", + "supports-color": "^6.1.0" }, "dependencies": { - "debug": { - "version": "3.2.6", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.6.tgz", - "integrity": "sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ==", + "supports-color": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-6.1.0.tgz", + "integrity": "sha512-qe1jfm1Mg7Nq/NSh6XE24gPXROEVsWHxC1LIx//XNlD9iw7YZQGjZNjYN7xGaEG6iKdA8EtNFW6R0gjnVXp+wQ==", "dev": true, "requires": { - "ms": "^2.1.1" + "has-flag": "^3.0.0" } } } }, - "humanize-ms": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/humanize-ms/-/humanize-ms-1.2.1.tgz", - "integrity": "sha1-xG4xWaKT9riW2ikxbYtv6Lt5u+0=", - "dev": true, - "requires": { - "ms": "^2.0.0" - } + "js-base64": { + "version": "2.5.2", + "resolved": "https://registry.npmjs.org/js-base64/-/js-base64-2.5.2.tgz", + "integrity": "sha512-Vg8czh0Q7sFBSUMWWArX/miJeBWYBPpdU/3M/DKSaekLMqrqVPaedp+5mZhie/r0lgrcaYBfwXatEew6gwgiQQ==" }, - "iconv-lite": { - "version": "0.4.24", - "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", - "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", + "js-levenshtein": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/js-levenshtein/-/js-levenshtein-1.1.6.tgz", + "integrity": "sha512-X2BB11YZtrRqY4EnQcLX5Rh373zbK4alC1FW7D7MBhL2gtcC17cTnr6DmfHZeS0s2rTHjUTMMHfG7gO8SSdw+g==", + "dev": true + }, + "js-tokens": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", + "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", + "dev": true + }, + "js-yaml": { + "version": "3.13.1", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.13.1.tgz", + "integrity": "sha512-YfbcO7jXDdyj0DGxYVSlSeQNHbD7XPWvrVWeVUujrQEoZzWJIRrCPoyk6kL6IAjAG2IolMK4T0hNUe0HOUs5Jw==", "dev": true, "requires": { - "safer-buffer": ">= 2.1.2 < 3" + "argparse": "^1.0.7", + "esprima": "^4.0.0" } }, - "ieee754": { - "version": "1.1.13", - "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.1.13.tgz", - "integrity": "sha512-4vf7I2LYV/HaWerSo3XmlMkp5eZ83i+/CDluXi/IGTs/O1sejBNhTtnxzmRZfvOUqj7lZjqHkeTvpgSFDlWZTg==", - "dev": true + "jsbn": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz", + "integrity": "sha1-peZUwuWi3rXyAdls77yoDA7y9RM=" }, - "iferr": { - "version": "0.1.5", - "resolved": "https://registry.npmjs.org/iferr/-/iferr-0.1.5.tgz", - "integrity": "sha1-xg7taebY/bazEEofy8ocGS3FtQE=", + "jsesc": { + "version": "2.5.2", + "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz", + "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==", "dev": true }, - "ignore": { - "version": "3.3.10", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-3.3.10.tgz", - "integrity": "sha512-Pgs951kaMm5GXP7MOvxERINe3gsaVjUWFm+UZPSq9xYriQAksyhg0csnS0KXSNRD5NmNdapXEpjxG49+AKh/ug==", + "json-parse-better-errors": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz", + "integrity": "sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw==", "dev": true }, - "ignore-walk": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/ignore-walk/-/ignore-walk-3.0.3.tgz", - "integrity": "sha512-m7o6xuOaT1aqheYHKf8W6J5pYH85ZI9w077erOzLje3JsB1gkafkAhHHY19dqjulgIZHFm32Cp5uNZgcQqdJKw==", - "dev": true, - "requires": { - "minimatch": "^3.0.4" - } + "json-schema": { + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.2.3.tgz", + "integrity": "sha1-tIDIkuWaLwWVTOcnvT8qTogvnhM=" }, - "image-size": { - "version": "0.5.5", - "resolved": "https://registry.npmjs.org/image-size/-/image-size-0.5.5.tgz", - "integrity": "sha1-Cd/Uq50g4p6xw+gLiZA3jfnjy5w=", - "dev": true, - "optional": true + "json-schema-traverse": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==" }, - "immediate": { - "version": "3.0.6", - "resolved": "https://registry.npmjs.org/immediate/-/immediate-3.0.6.tgz", - "integrity": "sha1-nbHb0Pr43m++D13V5Wu2BigN5ps=", + "json-stringify-safe": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", + "integrity": "sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus=" + }, + "json3": { + "version": "3.3.3", + "resolved": "https://registry.npmjs.org/json3/-/json3-3.3.3.tgz", + "integrity": "sha512-c7/8mbUsKigAbLkD5B010BK4D9LZm7A1pNItkEwiUZRpIN66exu/e7YQWysGun+TRKaJp8MhemM+VkfWv42aCA==", "dev": true }, - "import-cwd": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/import-cwd/-/import-cwd-2.1.0.tgz", - "integrity": "sha1-qmzzbnInYShcs3HsZRn1PiQ1sKk=", - "dev": true, + "json5": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.1.tgz", + "integrity": "sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow==", "requires": { - "import-from": "^2.1.0" + "minimist": "^1.2.0" } }, - "import-fresh": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-2.0.0.tgz", - "integrity": "sha1-2BNVwVYS04bGH53dOSLUMEgipUY=", + "jsonfile": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz", + "integrity": "sha1-h3Gq4HmbZAdrdmQPygWPnBDjPss=", "dev": true, "requires": { - "caller-path": "^2.0.0", - "resolve-from": "^3.0.0" + "graceful-fs": "^4.1.6" } }, - "import-from": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/import-from/-/import-from-2.1.0.tgz", - "integrity": "sha1-M1238qev/VOqpHHUuAId7ja387E=", - "dev": true, - "requires": { - "resolve-from": "^3.0.0" - } + "jsonparse": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/jsonparse/-/jsonparse-1.3.1.tgz", + "integrity": "sha1-P02uSpH6wxX3EGL4UhzCOfE2YoA=", + "dev": true }, - "import-local": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/import-local/-/import-local-2.0.0.tgz", - "integrity": "sha512-b6s04m3O+s3CGSbqDIyP4R6aAwAeYlVq9+WUWep6iHa8ETRf9yei1U48C5MmfJmV9AiLYYBKPMq/W+/WRpQmCQ==", - "dev": true, + "jsprim": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.1.tgz", + "integrity": "sha1-MT5mvB5cwG5Di8G3SZwuXFastqI=", "requires": { - "pkg-dir": "^3.0.0", - "resolve-cwd": "^2.0.0" + "assert-plus": "1.0.0", + "extsprintf": "1.3.0", + "json-schema": "0.2.3", + "verror": "1.10.0" } }, - "imurmurhash": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", - "integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o=", - "dev": true - }, - "indexof": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/indexof/-/indexof-0.0.1.tgz", - "integrity": "sha1-gtwzbSMrkGIXnQWrMpOmYFn9Q10=", - "dev": true - }, - "infer-owner": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/infer-owner/-/infer-owner-1.0.4.tgz", - "integrity": "sha512-IClj+Xz94+d7irH5qRyfJonOdfTzuDaifE6ZPWfx0N0+/ATZCbuTPq2prFl526urkQd90WyUKIh1DfBQ2hMz9A==", - "dev": true - }, - "inflight": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", - "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", + "jszip": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/jszip/-/jszip-3.2.2.tgz", + "integrity": "sha512-NmKajvAFQpbg3taXQXr/ccS2wcucR1AZ+NtyWp2Nq7HHVsXhcJFR8p0Baf32C2yVvBylFWVeKf+WI2AnvlPhpA==", "dev": true, "requires": { - "once": "^1.3.0", - "wrappy": "1" + "lie": "~3.3.0", + "pako": "~1.0.2", + "readable-stream": "~2.3.6", + "set-immediate-shim": "~1.0.1" } }, - "inherits": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", - "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", - "dev": true - }, - "ini": { - "version": "1.3.5", - "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.5.tgz", - "integrity": "sha512-RZY5huIKCMRWDUqZlEi72f/lmXKMvuszcMBduliQ3nnWbx9X/ZBQO7DijMEYS9EhHBb2qacRUMtC7svLwe0lcw==", - "dev": true - }, - "inquirer": { - "version": "6.5.1", - "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-6.5.1.tgz", - "integrity": "sha512-uxNHBeQhRXIoHWTSNYUFhQVrHYFThIt6IVo2fFmSe8aBwdR3/w6b58hJpiL/fMukFkvGzjg+hSxFtwvVmKZmXw==", + "karma": { + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/karma/-/karma-4.4.1.tgz", + "integrity": "sha512-L5SIaXEYqzrh6b1wqYC42tNsFMx2PWuxky84pK9coK09MvmL7mxii3G3bZBh/0rvD27lqDd0le9jyhzvwif73A==", "dev": true, "requires": { - "ansi-escapes": "^4.2.1", - "chalk": "^2.4.2", - "cli-cursor": "^3.1.0", - "cli-width": "^2.0.0", - "external-editor": "^3.0.3", - "figures": "^3.0.0", - "lodash": "^4.17.15", - "mute-stream": "0.0.8", - "run-async": "^2.2.0", - "rxjs": "^6.4.0", - "string-width": "^4.1.0", - "strip-ansi": "^5.1.0", - "through": "^2.3.6" + "bluebird": "^3.3.0", + "body-parser": "^1.16.1", + "braces": "^3.0.2", + "chokidar": "^3.0.0", + "colors": "^1.1.0", + "connect": "^3.6.0", + "di": "^0.0.1", + "dom-serialize": "^2.2.0", + "flatted": "^2.0.0", + "glob": "^7.1.1", + "graceful-fs": "^4.1.2", + "http-proxy": "^1.13.0", + "isbinaryfile": "^3.0.0", + "lodash": "^4.17.14", + "log4js": "^4.0.0", + "mime": "^2.3.1", + "minimatch": "^3.0.2", + "optimist": "^0.6.1", + "qjobs": "^1.1.4", + "range-parser": "^1.2.0", + "rimraf": "^2.6.0", + "safe-buffer": "^5.0.1", + "socket.io": "2.1.1", + "source-map": "^0.6.1", + "tmp": "0.0.33", + "useragent": "2.3.0" }, - "dependencies": { - "ansi-regex": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.0.tgz", - "integrity": "sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==", - "dev": true - }, - "is-fullwidth-code-point": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", - "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", - "dev": true - }, - "string-width": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.0.tgz", - "integrity": "sha512-zUz5JD+tgqtuDjMhwIg5uFVV3dtqZ9yQJlZVfq4I01/K5Paj5UHj7VyrQOJvzawSVlKpObApbfD0Ed6yJc+1eg==", - "dev": true, - "requires": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.0" - }, - "dependencies": { - "strip-ansi": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz", - "integrity": "sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==", - "dev": true, - "requires": { - "ansi-regex": "^5.0.0" - } - } - } + "dependencies": { + "mime": { + "version": "2.4.4", + "resolved": "https://registry.npmjs.org/mime/-/mime-2.4.4.tgz", + "integrity": "sha512-LRxmNwziLPT828z+4YkNzloCFC2YM4wrB99k+AV5ZbEyfGNWfG8SO1FUXLmLDBSo89NrJZ4DIWeLjy1CHGhMGA==", + "dev": true }, - "strip-ansi": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", - "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", - "dev": true, - "requires": { - "ansi-regex": "^4.1.0" - }, - "dependencies": { - "ansi-regex": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", - "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", - "dev": true - } - } + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true } } }, - "internal-ip": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/internal-ip/-/internal-ip-4.3.0.tgz", - "integrity": "sha512-S1zBo1D6zcsyuC6PMmY5+55YMILQ9av8lotMx447Bq6SAgo/sDK6y6uUKmuYhW7eacnIhFfsPmCNYdDzsnnDCg==", + "karma-chrome-launcher": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/karma-chrome-launcher/-/karma-chrome-launcher-3.1.0.tgz", + "integrity": "sha512-3dPs/n7vgz1rxxtynpzZTvb9y/GIaW8xjAwcIGttLbycqoFtI7yo1NGnQi6oFTherRE+GIhCAHZC4vEqWGhNvg==", "dev": true, "requires": { - "default-gateway": "^4.2.0", - "ipaddr.js": "^1.9.0" + "which": "^1.2.1" } }, - "invariant": { - "version": "2.2.4", - "resolved": "https://registry.npmjs.org/invariant/-/invariant-2.2.4.tgz", - "integrity": "sha512-phJfQVBuaJM5raOpJjSfkiD6BpbCE4Ns//LaXl6wGYtUBY83nWS6Rf9tXm2e8VaK60JEjYldbPif/A2B1C2gNA==", + "karma-coverage-istanbul-reporter": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/karma-coverage-istanbul-reporter/-/karma-coverage-istanbul-reporter-2.1.1.tgz", + "integrity": "sha512-CH8lTi8+kKXGvrhy94+EkEMldLCiUA0xMOiL31vvli9qK0T+qcXJAwWBRVJWnVWxYkTmyWar8lPz63dxX6/z1A==", "dev": true, "requires": { - "loose-envify": "^1.0.0" + "istanbul-api": "^2.1.6", + "minimatch": "^3.0.4" } }, - "invert-kv": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/invert-kv/-/invert-kv-2.0.0.tgz", - "integrity": "sha512-wPVv/y/QQ/Uiirj/vh3oP+1Ww+AWehmi1g5fFWGPF6IpCBCDVrhgHRMvrLfdYcwDh3QJbGXDW4JAuzxElLSqKA==", - "dev": true - }, - "ip": { - "version": "1.1.5", - "resolved": "https://registry.npmjs.org/ip/-/ip-1.1.5.tgz", - "integrity": "sha1-vd7XARQpCCjAoDnnLvJfWq7ENUo=", - "dev": true - }, - "ip-regex": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/ip-regex/-/ip-regex-2.1.0.tgz", - "integrity": "sha1-+ni/XS5pE8kRzp+BnuUUa7bYROk=", - "dev": true - }, - "ipaddr.js": { - "version": "1.9.1", - "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz", - "integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==", - "dev": true - }, - "iqb-components": { - "version": "1.6.4", - "resolved": "https://registry.npmjs.org/iqb-components/-/iqb-components-1.6.4.tgz", - "integrity": "sha512-iemYNOAyqaTwqigPnldO4cuKn6IdYpDVHBk8QTlgqXJD0j4RJWp5LXmfJDPnx6QOTMiB2jdEg+QI4z2F+8VotQ==", + "karma-jasmine": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/karma-jasmine/-/karma-jasmine-3.1.1.tgz", + "integrity": "sha512-pxBmv5K7IkBRLsFSTOpgiK/HzicQT3mfFF+oHAC7nxMfYKhaYFgxOa5qjnHW4sL5rUnmdkSajoudOnnOdPyW4Q==", + "dev": true, "requires": { - "tslib": "^1.9.0" + "jasmine-core": "^3.5.0" } }, - "is-absolute-url": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/is-absolute-url/-/is-absolute-url-3.0.3.tgz", - "integrity": "sha512-opmNIX7uFnS96NtPmhWQgQx6/NYFgsUXYMllcfzwWKUMwfo8kku1TvE6hkNcH+Q1ts5cMVrsY7j0bxXQDciu9Q==", + "karma-jasmine-html-reporter": { + "version": "1.5.2", + "resolved": "https://registry.npmjs.org/karma-jasmine-html-reporter/-/karma-jasmine-html-reporter-1.5.2.tgz", + "integrity": "sha512-ILBPsXqQ3eomq+oaQsM311/jxsypw5/d0LnZXj26XkfThwq7jZ55A2CFSKJVA5VekbbOGvMyv7d3juZj0SeTxA==", "dev": true }, - "is-accessor-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", - "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=", + "karma-source-map-support": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/karma-source-map-support/-/karma-source-map-support-1.4.0.tgz", + "integrity": "sha512-RsBECncGO17KAoJCYXjv+ckIz+Ii9NCi+9enk+rq6XC81ezYkb4/RHE6CTXdA7IOJqoF3wcaLfVG0CPmE5ca6A==", "dev": true, "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } + "source-map-support": "^0.5.5" } }, - "is-arguments": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/is-arguments/-/is-arguments-1.0.4.tgz", - "integrity": "sha512-xPh0Rmt8NE65sNzvyUmWgI1tz3mKq74lGA0mL8LYZcoIzKOzDh6HmrYm3d18k60nHerC8A9Km8kYu87zfSFnLA==", + "killable": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/killable/-/killable-1.0.1.tgz", + "integrity": "sha512-LzqtLKlUwirEUyl/nicirVmNiPvYs7l5n8wOPP7fyJVpUPkvCnW/vuiXGpylGUlnPDnB7311rARzAt3Mhswpjg==", "dev": true }, - "is-arrayish": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", - "integrity": "sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0=", - "dev": true + "kind-of": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", + "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==" }, - "is-binary-path": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", - "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", + "lcid": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/lcid/-/lcid-2.0.0.tgz", + "integrity": "sha512-avPEb8P8EGnwXKClwsNUgryVjllcRqtMYa49NTsbQagYuT1DcXnl1915oxWjoyGrXR6zH/Y0Zc96xWsPcoDKeA==", "dev": true, "requires": { - "binary-extensions": "^2.0.0" + "invert-kv": "^2.0.0" } }, - "is-buffer": { - "version": "1.1.6", - "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz", - "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==", - "dev": true - }, - "is-callable": { - "version": "1.1.5", - "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.1.5.tgz", - "integrity": "sha512-ESKv5sMCJB2jnHTWZ3O5itG+O128Hsus4K4Qh1h2/cgn2vbgnLSVqfV46AeJA9D5EeeLa9w81KUXMtn34zhX+Q==", - "dev": true - }, - "is-data-descriptor": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", - "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=", + "less": { + "version": "3.10.3", + "resolved": "https://registry.npmjs.org/less/-/less-3.10.3.tgz", + "integrity": "sha512-vz32vqfgmoxF1h3K4J+yKCtajH0PWmjkIFgbs5d78E/c/e+UQTnI+lWK+1eQRE95PXM2mC3rJlLSSP9VQHnaow==", "dev": true, "requires": { - "kind-of": "^3.0.2" + "clone": "^2.1.2", + "errno": "^0.1.1", + "graceful-fs": "^4.1.2", + "image-size": "~0.5.0", + "mime": "^1.4.1", + "mkdirp": "^0.5.0", + "promise": "^7.1.1", + "request": "^2.83.0", + "source-map": "~0.6.0" }, "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } + "optional": true } } }, - "is-date-object": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.2.tgz", - "integrity": "sha512-USlDT524woQ08aoZFzh3/Z6ch9Y/EWXEHQ/AaRN0SkKq4t2Jw2R2339tSXmwuVoY7LLlBCbOIlx2myP/L5zk0g==", - "dev": true + "less-loader": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/less-loader/-/less-loader-5.0.0.tgz", + "integrity": "sha512-bquCU89mO/yWLaUq0Clk7qCsKhsF/TZpJUzETRvJa9KSVEL9SO3ovCvdEHISBhrC81OwC8QSVX7E0bzElZj9cg==", + "dev": true, + "requires": { + "clone": "^2.1.1", + "loader-utils": "^1.1.0", + "pify": "^4.0.1" + } }, - "is-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", - "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", + "license-webpack-plugin": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/license-webpack-plugin/-/license-webpack-plugin-2.1.3.tgz", + "integrity": "sha512-vTSY5r9HOq4sxR2BIxdIXWKI+9n3b+DoQkhKHedB3TdSxTfXUDRxKXdAj5iejR+qNXprXsxvEu9W+zOhgGIkAw==", "dev": true, "requires": { - "is-accessor-descriptor": "^0.1.6", - "is-data-descriptor": "^0.1.4", - "kind-of": "^5.0.0" + "@types/webpack-sources": "^0.1.5", + "webpack-sources": "^1.2.0" + } + }, + "lie": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/lie/-/lie-3.3.0.tgz", + "integrity": "sha512-UaiMJzeWRlEujzAuw5LokY1L5ecNQYZKfmyZ9L7wDHb/p5etKaxXhohBcrw0EYby+G/NA52vRSN4N39dxHAIwQ==", + "dev": true, + "requires": { + "immediate": "~3.0.5" + } + }, + "load-json-file": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-1.1.0.tgz", + "integrity": "sha1-lWkFcI1YtLq0wiYbBPWfMcmTdMA=", + "requires": { + "graceful-fs": "^4.1.2", + "parse-json": "^2.2.0", + "pify": "^2.0.0", + "pinkie-promise": "^2.0.0", + "strip-bom": "^2.0.0" }, "dependencies": { - "kind-of": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", - "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==", - "dev": true + "parse-json": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-2.2.0.tgz", + "integrity": "sha1-9ID0BDTvgHQfhGkJn43qGPVaTck=", + "requires": { + "error-ex": "^1.2.0" + } + }, + "pify": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", + "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=" + }, + "strip-bom": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-2.0.0.tgz", + "integrity": "sha1-YhmoVhZSBJHzV4i9vxRHqZx+aw4=", + "requires": { + "is-utf8": "^0.2.0" + } } } }, - "is-directory": { - "version": "0.3.1", - "resolved": "https://registry.npmjs.org/is-directory/-/is-directory-0.3.1.tgz", - "integrity": "sha1-YTObbyR1/Hcv2cnYP1yFddwVSuE=", - "dev": true - }, - "is-extendable": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz", - "integrity": "sha1-YrEQ4omkcUGOPsNqYX1HLjAd/Ik=", - "dev": true - }, - "is-extglob": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", - "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=", + "loader-runner": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/loader-runner/-/loader-runner-2.4.0.tgz", + "integrity": "sha512-Jsmr89RcXGIwivFY21FcRrisYZfvLMTWx5kOLc+JTxtpBOG6xML0vzbc6SEQG2FO9/4Fc3wW4LVcB5DmGflaRw==", "dev": true }, - "is-fullwidth-code-point": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", - "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", - "dev": true + "loader-utils": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-1.2.3.tgz", + "integrity": "sha512-fkpz8ejdnEMG3s37wGL07iSBDg99O9D5yflE9RGNH3hRdx9SOwYfnGYdZOUIZitN8E+E2vkq3MUMYMvPYl5ZZA==", + "requires": { + "big.js": "^5.2.2", + "emojis-list": "^2.0.0", + "json5": "^1.0.1" + } }, - "is-glob": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.1.tgz", - "integrity": "sha512-5G0tKtBTFImOqDnLB2hG6Bp2qcKEFduo4tZu9MT/H6NQv/ghhy30o55ufafxJ/LdH79LLs2Kfrn85TLKyA7BUg==", + "locate-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz", + "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==", "dev": true, "requires": { - "is-extglob": "^2.1.1" + "p-locate": "^3.0.0", + "path-exists": "^3.0.0" } }, - "is-number": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", - "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", + "lodash": { + "version": "4.17.15", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.15.tgz", + "integrity": "sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A==" + }, + "lodash.clonedeep": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/lodash.clonedeep/-/lodash.clonedeep-4.5.0.tgz", + "integrity": "sha1-4j8/nE+Pvd6HJSnBBxhXoIblzO8=", "dev": true }, - "is-path-cwd": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/is-path-cwd/-/is-path-cwd-2.2.0.tgz", - "integrity": "sha512-w942bTcih8fdJPJmQHFzkS76NEP8Kzzvmw92cXsazb8intwLqPibPPdXf4ANdKV3rYMuuQYGIWtvz9JilB3NFQ==", + "lodash.memoize": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/lodash.memoize/-/lodash.memoize-4.1.2.tgz", + "integrity": "sha1-vMbEmkKihA7Zl/Mj6tpezRguC/4=", "dev": true }, - "is-path-in-cwd": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-path-in-cwd/-/is-path-in-cwd-2.1.0.tgz", - "integrity": "sha512-rNocXHgipO+rvnP6dk3zI20RpOtrAM/kzbB258Uw5BWr3TpXi861yzjo16Dn4hUox07iw5AyeMLHWsujkjzvRQ==", + "lodash.uniq": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/lodash.uniq/-/lodash.uniq-4.5.0.tgz", + "integrity": "sha1-0CJTc662Uq3BvILklFM5qEJ1R3M=", + "dev": true + }, + "log-symbols": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-3.0.0.tgz", + "integrity": "sha512-dSkNGuI7iG3mfvDzUuYZyvk5dD9ocYCYzNU6CYDE6+Xqd+gwme6Z00NS3dUh8mq/73HaEtT7m6W+yUPtU6BZnQ==", "dev": true, "requires": { - "is-path-inside": "^2.1.0" + "chalk": "^2.4.2" } }, - "is-path-inside": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-2.1.0.tgz", - "integrity": "sha512-wiyhTzfDWsvwAW53OBWF5zuvaOGlZ6PwYxAbPVDhpm+gM09xKQGjBq/8uYN12aDvMxnAnq3dxTyoSoRNmg5YFg==", + "log4js": { + "version": "4.5.1", + "resolved": "https://registry.npmjs.org/log4js/-/log4js-4.5.1.tgz", + "integrity": "sha512-EEEgFcE9bLgaYUKuozyFfytQM2wDHtXn4tAN41pkaxpNjAykv11GVdeI4tHtmPWW4Xrgh9R/2d7XYghDVjbKKw==", "dev": true, "requires": { - "path-is-inside": "^1.0.2" + "date-format": "^2.0.0", + "debug": "^4.1.1", + "flatted": "^2.0.0", + "rfdc": "^1.1.4", + "streamroller": "^1.0.6" } }, - "is-plain-obj": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-1.1.0.tgz", - "integrity": "sha1-caUMhCnfync8kqOQpKA7OfzVHT4=", + "loglevel": { + "version": "1.6.7", + "resolved": "https://registry.npmjs.org/loglevel/-/loglevel-1.6.7.tgz", + "integrity": "sha512-cY2eLFrQSAfVPhCgH1s7JI73tMbg9YC3v3+ZHVW67sBS7UxWzNEk/ZBbSfLykBWHp33dqqtOv82gjhKEi81T/A==", "dev": true }, - "is-plain-object": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz", - "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==", + "loose-envify": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz", + "integrity": "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==", "dev": true, "requires": { - "isobject": "^3.0.1" + "js-tokens": "^3.0.0 || ^4.0.0" } }, - "is-promise": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-promise/-/is-promise-2.1.0.tgz", - "integrity": "sha1-eaKp7OfwlugPNtKy87wWwf9L8/o=", - "dev": true - }, - "is-regex": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.0.5.tgz", - "integrity": "sha512-vlKW17SNq44owv5AQR3Cq0bQPEb8+kF3UKZ2fiZNOWtztYE5i0CzCZxFDwO58qAOWtxdBRVO/V5Qin1wjCqFYQ==", - "dev": true, + "loud-rejection": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/loud-rejection/-/loud-rejection-1.6.0.tgz", + "integrity": "sha1-W0b4AUft7leIcPCG0Eghz5mOVR8=", "requires": { - "has": "^1.0.3" + "currently-unhandled": "^0.4.1", + "signal-exit": "^3.0.0" } }, - "is-stream": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz", - "integrity": "sha1-EtSj3U5o4Lec6428hBc66A2RykQ=", - "dev": true + "lower-case": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/lower-case/-/lower-case-1.1.4.tgz", + "integrity": "sha1-miyr0bno4K6ZOkv31YdcOcQujqw=" }, - "is-symbol": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.3.tgz", - "integrity": "sha512-OwijhaRSgqvhm/0ZdAcXNZt9lYdKFpcRDT5ULUuYXPoT794UNOdU+gpT6Rzo7b4V2HUl/op6GqY894AZwv9faQ==", + "lru-cache": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz", + "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==", "dev": true, "requires": { - "has-symbols": "^1.0.1" + "yallist": "^3.0.2" + }, + "dependencies": { + "yallist": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", + "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==", + "dev": true + } } }, - "is-typedarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", - "integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=", - "dev": true - }, - "is-windows": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-windows/-/is-windows-1.0.2.tgz", - "integrity": "sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA==", - "dev": true - }, - "is-wsl": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-1.1.0.tgz", - "integrity": "sha1-HxbkqiKwTRM2tmGIpmrzxgDDpm0=", - "dev": true - }, - "isarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", - "dev": true - }, - "isbinaryfile": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/isbinaryfile/-/isbinaryfile-3.0.3.tgz", - "integrity": "sha512-8cJBL5tTd2OS0dM4jz07wQd5g0dCCqIhUxPIGtZfa5L6hWlvV5MHTITy/DBAsF+Oe2LS1X3krBUhNwaGUWpWxw==", + "magic-string": { + "version": "0.25.4", + "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.25.4.tgz", + "integrity": "sha512-oycWO9nEVAP2RVPbIoDoA4Y7LFIJ3xRYov93gAyJhZkET1tNuB0u7uWkZS2LpBWTJUWnmau/To8ECWRC+jKNfw==", "dev": true, "requires": { - "buffer-alloc": "^1.2.0" + "sourcemap-codec": "^1.4.4" } }, - "isexe": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", - "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=", - "dev": true - }, - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", - "dev": true + "make-dir": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-2.1.0.tgz", + "integrity": "sha512-LS9X+dc8KLxXCb8dni79fLIIUA5VyZoyjSMCwTluaXA0o27cCK0bhXkpgw+sTXVpPy/lSO57ilRixqk0vDmtRA==", + "dev": true, + "requires": { + "pify": "^4.0.1", + "semver": "^5.6.0" + }, + "dependencies": { + "semver": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", + "dev": true + } + } }, - "isstream": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz", - "integrity": "sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo=", + "make-error": { + "version": "1.3.6", + "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz", + "integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==", "dev": true }, - "istanbul-api": { - "version": "2.1.6", - "resolved": "https://registry.npmjs.org/istanbul-api/-/istanbul-api-2.1.6.tgz", - "integrity": "sha512-x0Eicp6KsShG1k1rMgBAi/1GgY7kFGEBwQpw3PXGEmu+rBcBNhqU8g2DgY9mlepAsLPzrzrbqSgCGANnki4POA==", + "make-fetch-happen": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/make-fetch-happen/-/make-fetch-happen-5.0.2.tgz", + "integrity": "sha512-07JHC0r1ykIoruKO8ifMXu+xEU8qOXDFETylktdug6vJDACnP+HKevOu3PXyNPzFyTSlz8vrBYlBO1JZRe8Cag==", "dev": true, "requires": { - "async": "^2.6.2", - "compare-versions": "^3.4.0", - "fileset": "^2.0.3", - "istanbul-lib-coverage": "^2.0.5", - "istanbul-lib-hook": "^2.0.7", - "istanbul-lib-instrument": "^3.3.0", - "istanbul-lib-report": "^2.0.8", - "istanbul-lib-source-maps": "^3.0.6", - "istanbul-reports": "^2.2.4", - "js-yaml": "^3.13.1", - "make-dir": "^2.1.0", - "minimatch": "^3.0.4", - "once": "^1.4.0" + "agentkeepalive": "^3.4.1", + "cacache": "^12.0.0", + "http-cache-semantics": "^3.8.1", + "http-proxy-agent": "^2.1.0", + "https-proxy-agent": "^2.2.3", + "lru-cache": "^5.1.1", + "mississippi": "^3.0.0", + "node-fetch-npm": "^2.0.2", + "promise-retry": "^1.1.1", + "socks-proxy-agent": "^4.0.0", + "ssri": "^6.0.0" }, "dependencies": { - "istanbul-lib-coverage": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.5.tgz", - "integrity": "sha512-8aXznuEPCJvGnMSRft4udDRDtb1V3pkQkMMI5LI+6HuQz5oQ4J2UFn1H82raA3qJtyOLkkwVqICBQkjnGtn5mA==", - "dev": true + "cacache": { + "version": "12.0.3", + "resolved": "https://registry.npmjs.org/cacache/-/cacache-12.0.3.tgz", + "integrity": "sha512-kqdmfXEGFepesTuROHMs3MpFLWrPkSSpRqOw80RCflZXy/khxaArvFrQ7uJxSUduzAufc6G0g1VUCOZXxWavPw==", + "dev": true, + "requires": { + "bluebird": "^3.5.5", + "chownr": "^1.1.1", + "figgy-pudding": "^3.5.1", + "glob": "^7.1.4", + "graceful-fs": "^4.1.15", + "infer-owner": "^1.0.3", + "lru-cache": "^5.1.1", + "mississippi": "^3.0.0", + "mkdirp": "^0.5.1", + "move-concurrently": "^1.0.1", + "promise-inflight": "^1.0.1", + "rimraf": "^2.6.3", + "ssri": "^6.0.1", + "unique-filename": "^1.1.1", + "y18n": "^4.0.0" + } }, - "istanbul-lib-instrument": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-3.3.0.tgz", - "integrity": "sha512-5nnIN4vo5xQZHdXno/YDXJ0G+I3dAm4XgzfSVTPLQpj/zAV2dV6Juy0yaf10/zrJOJeHoN3fraFe+XRq2bFVZA==", + "ssri": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/ssri/-/ssri-6.0.1.tgz", + "integrity": "sha512-3Wge10hNcT1Kur4PDFwEieXSCMCJs/7WvSACcrMYrNp+b8kDL1/0wJch5Ni2WrtwEa2IO8OsVfeKIciKCDx/QA==", "dev": true, "requires": { - "@babel/generator": "^7.4.0", - "@babel/parser": "^7.4.3", - "@babel/template": "^7.4.0", - "@babel/traverse": "^7.4.3", - "@babel/types": "^7.4.0", - "istanbul-lib-coverage": "^2.0.5", - "semver": "^6.0.0" + "figgy-pudding": "^3.5.1" } } } }, - "istanbul-lib-coverage": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-3.0.0.tgz", - "integrity": "sha512-UiUIqxMgRDET6eR+o5HbfRYP1l0hqkWOs7vNxC/mggutCMUIhWMm8gAHb8tHlyfD3/l6rlgNA5cKdDzEAf6hEg==", - "dev": true + "mamacro": { + "version": "0.0.3", + "resolved": "https://registry.npmjs.org/mamacro/-/mamacro-0.0.3.tgz", + "integrity": "sha512-qMEwh+UujcQ+kbz3T6V+wAmO2U8veoq2w+3wY8MquqwVA3jChfwY+Tk52GZKDfACEPjuZ7r2oJLejwpt8jtwTA==", + "dev": true + }, + "map-age-cleaner": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/map-age-cleaner/-/map-age-cleaner-0.1.3.tgz", + "integrity": "sha512-bJzx6nMoP6PDLPBFmg7+xRKeFZvFboMrGlxmNj9ClvX53KrmvM5bXFXEWjbz4cz1AFn+jWJ9z/DJSz7hrs0w3w==", + "dev": true, + "requires": { + "p-defer": "^1.0.0" + } + }, + "map-cache": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/map-cache/-/map-cache-0.2.2.tgz", + "integrity": "sha1-wyq9C9ZSXZsFFkW7TyasXcmKDb8=", + "dev": true + }, + "map-obj": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/map-obj/-/map-obj-1.0.1.tgz", + "integrity": "sha1-2TPOuSBdgr3PSIb2dCvcK03qFG0=" + }, + "map-visit": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/map-visit/-/map-visit-1.0.0.tgz", + "integrity": "sha1-7Nyo8TFE5mDxtb1B8S80edmN+48=", + "dev": true, + "requires": { + "object-visit": "^1.0.0" + } + }, + "material-design-icons": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/material-design-icons/-/material-design-icons-3.0.1.tgz", + "integrity": "sha1-mnHEh0chjrylHlGmbaaCA4zct78=" }, - "istanbul-lib-hook": { - "version": "2.0.7", - "resolved": "https://registry.npmjs.org/istanbul-lib-hook/-/istanbul-lib-hook-2.0.7.tgz", - "integrity": "sha512-vrRztU9VRRFDyC+aklfLoeXyNdTfga2EI3udDGn4cZ6fpSXpHLV9X6CHvfoMCPtggg8zvDDmC4b9xfu0z6/llA==", + "md5.js": { + "version": "1.3.5", + "resolved": "https://registry.npmjs.org/md5.js/-/md5.js-1.3.5.tgz", + "integrity": "sha512-xitP+WxNPcTTOgnTJcrhM0xvdPepipPSf3I8EIpGKeFLjt3PlJLIDG3u8EX53ZIubkb+5U2+3rELYpEhHhzdkg==", "dev": true, "requires": { - "append-transform": "^1.0.0" + "hash-base": "^3.0.0", + "inherits": "^2.0.1", + "safe-buffer": "^5.1.2" } }, - "istanbul-lib-instrument": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-4.0.1.tgz", - "integrity": "sha512-imIchxnodll7pvQBYOqUu88EufLCU56LMeFPZZM/fJZ1irYcYdqroaV+ACK1Ila8ls09iEYArp+nqyC6lW1Vfg==", + "mdn-data": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.0.4.tgz", + "integrity": "sha512-iV3XNKw06j5Q7mi6h+9vbx23Tv7JkjEVgKHW4pimwyDGWm0OIQntJJ+u1C6mg6mK1EaTv42XQ7w76yuzH7M2cA==", + "dev": true + }, + "media-typer": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", + "integrity": "sha1-hxDXrwqmJvj/+hzgAWhUUmMlV0g=", + "dev": true + }, + "mem": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/mem/-/mem-4.3.0.tgz", + "integrity": "sha512-qX2bG48pTqYRVmDB37rn/6PT7LcR8T7oAX3bf99u1Tt1nzxYfxkgqDwUwolPlXweM0XzBOBFzSx4kfp7KP1s/w==", "dev": true, "requires": { - "@babel/core": "^7.7.5", - "@babel/parser": "^7.7.5", - "@babel/template": "^7.7.4", - "@babel/traverse": "^7.7.4", - "@istanbuljs/schema": "^0.1.2", - "istanbul-lib-coverage": "^3.0.0", - "semver": "^6.3.0" + "map-age-cleaner": "^0.1.1", + "mimic-fn": "^2.0.0", + "p-is-promise": "^2.0.0" } }, - "istanbul-lib-report": { - "version": "2.0.8", - "resolved": "https://registry.npmjs.org/istanbul-lib-report/-/istanbul-lib-report-2.0.8.tgz", - "integrity": "sha512-fHBeG573EIihhAblwgxrSenp0Dby6tJMFR/HvlerBsrCTD5bkUuoNtn3gVh29ZCS824cGGBPn7Sg7cNk+2xUsQ==", + "memory-fs": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/memory-fs/-/memory-fs-0.5.0.tgz", + "integrity": "sha512-jA0rdU5KoQMC0e6ppoNRtpp6vjFq6+NY7r8hywnC7V+1Xj/MtHwGIbB1QaK/dunyjWteJzmkpd7ooeWg10T7GA==", "dev": true, "requires": { - "istanbul-lib-coverage": "^2.0.5", - "make-dir": "^2.1.0", - "supports-color": "^6.1.0" - }, - "dependencies": { - "istanbul-lib-coverage": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.5.tgz", - "integrity": "sha512-8aXznuEPCJvGnMSRft4udDRDtb1V3pkQkMMI5LI+6HuQz5oQ4J2UFn1H82raA3qJtyOLkkwVqICBQkjnGtn5mA==", - "dev": true - }, - "supports-color": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-6.1.0.tgz", - "integrity": "sha512-qe1jfm1Mg7Nq/NSh6XE24gPXROEVsWHxC1LIx//XNlD9iw7YZQGjZNjYN7xGaEG6iKdA8EtNFW6R0gjnVXp+wQ==", - "dev": true, - "requires": { - "has-flag": "^3.0.0" - } - } + "errno": "^0.1.3", + "readable-stream": "^2.0.1" } }, - "istanbul-lib-source-maps": { - "version": "3.0.6", - "resolved": "https://registry.npmjs.org/istanbul-lib-source-maps/-/istanbul-lib-source-maps-3.0.6.tgz", - "integrity": "sha512-R47KzMtDJH6X4/YW9XTx+jrLnZnscW4VpNN+1PViSYTejLVPWv7oov+Duf8YQSPyVRUvueQqz1TcsC6mooZTXw==", + "meow": { + "version": "3.7.0", + "resolved": "https://registry.npmjs.org/meow/-/meow-3.7.0.tgz", + "integrity": "sha1-cstmi0JSKCkKu/qFaJJYcwioAfs=", + "requires": { + "camelcase-keys": "^2.0.0", + "decamelize": "^1.1.2", + "loud-rejection": "^1.0.0", + "map-obj": "^1.0.1", + "minimist": "^1.1.3", + "normalize-package-data": "^2.3.4", + "object-assign": "^4.0.1", + "read-pkg-up": "^1.0.1", + "redent": "^1.0.0", + "trim-newlines": "^1.0.0" + } + }, + "merge-descriptors": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz", + "integrity": "sha1-sAqqVW3YtEVoFQ7J0blT8/kMu2E=", + "dev": true + }, + "merge-source-map": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/merge-source-map/-/merge-source-map-1.1.0.tgz", + "integrity": "sha512-Qkcp7P2ygktpMPh2mCQZaf3jhN6D3Z/qVZHSdWvQ+2Ef5HgRAPBO57A77+ENm0CPx2+1Ce/MYKi3ymqdfuqibw==", "dev": true, "requires": { - "debug": "^4.1.1", - "istanbul-lib-coverage": "^2.0.5", - "make-dir": "^2.1.0", - "rimraf": "^2.6.3", "source-map": "^0.6.1" }, "dependencies": { - "istanbul-lib-coverage": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.5.tgz", - "integrity": "sha512-8aXznuEPCJvGnMSRft4udDRDtb1V3pkQkMMI5LI+6HuQz5oQ4J2UFn1H82raA3qJtyOLkkwVqICBQkjnGtn5mA==", - "dev": true - }, "source-map": { "version": "0.6.1", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", @@ -6385,458 +7061,699 @@ } } }, - "istanbul-reports": { - "version": "2.2.7", - "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-2.2.7.tgz", - "integrity": "sha512-uu1F/L1o5Y6LzPVSVZXNOoD/KXpJue9aeLRd0sM9uMXfZvzomB0WxVamWb5ue8kA2vVWEmW7EG+A5n3f1kqHKg==", - "dev": true, - "requires": { - "html-escaper": "^2.0.0" - } + "merge-stream": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz", + "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==", + "dev": true }, - "jasmine": { - "version": "2.8.0", - "resolved": "https://registry.npmjs.org/jasmine/-/jasmine-2.8.0.tgz", - "integrity": "sha1-awicChFXax8W3xG4AUbZHU6Lij4=", + "methods": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz", + "integrity": "sha1-VSmk1nZUE07cxSZmVoNbD4Ua/O4=", + "dev": true + }, + "micromatch": { + "version": "3.1.10", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz", + "integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==", "dev": true, "requires": { - "exit": "^0.1.2", - "glob": "^7.0.6", - "jasmine-core": "~2.8.0" + "arr-diff": "^4.0.0", + "array-unique": "^0.3.2", + "braces": "^2.3.1", + "define-property": "^2.0.2", + "extend-shallow": "^3.0.2", + "extglob": "^2.0.4", + "fragment-cache": "^0.2.1", + "kind-of": "^6.0.2", + "nanomatch": "^1.2.9", + "object.pick": "^1.3.0", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.2" }, "dependencies": { - "jasmine-core": { - "version": "2.8.0", - "resolved": "https://registry.npmjs.org/jasmine-core/-/jasmine-core-2.8.0.tgz", - "integrity": "sha1-vMl5rh+f0FcB5F5S5l06XWPxok4=", - "dev": true + "braces": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz", + "integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==", + "dev": true, + "requires": { + "arr-flatten": "^1.1.0", + "array-unique": "^0.3.2", + "extend-shallow": "^2.0.1", + "fill-range": "^4.0.0", + "isobject": "^3.0.1", + "repeat-element": "^1.1.2", + "snapdragon": "^0.8.1", + "snapdragon-node": "^2.0.1", + "split-string": "^3.0.2", + "to-regex": "^3.0.1" + }, + "dependencies": { + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "dev": true, + "requires": { + "is-extendable": "^0.1.0" + } + } + } + }, + "fill-range": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz", + "integrity": "sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc=", + "dev": true, + "requires": { + "extend-shallow": "^2.0.1", + "is-number": "^3.0.0", + "repeat-string": "^1.6.1", + "to-regex-range": "^2.1.0" + }, + "dependencies": { + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "dev": true, + "requires": { + "is-extendable": "^0.1.0" + } + } + } + }, + "is-number": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", + "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", + "dev": true, + "requires": { + "kind-of": "^3.0.2" + }, + "dependencies": { + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "to-regex-range": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-2.1.1.tgz", + "integrity": "sha1-fIDBe53+vlmeJzZ+DU3VWQFB2zg=", + "dev": true, + "requires": { + "is-number": "^3.0.0", + "repeat-string": "^1.6.1" + } } } }, - "jasmine-core": { - "version": "3.5.0", - "resolved": "https://registry.npmjs.org/jasmine-core/-/jasmine-core-3.5.0.tgz", - "integrity": "sha512-nCeAiw37MIMA9w9IXso7bRaLl+c/ef3wnxsoSAlYrzS+Ot0zTG6nU8G/cIfGkqpkjX2wNaIW9RFG0TwIFnG6bA==", + "miller-rabin": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/miller-rabin/-/miller-rabin-4.0.1.tgz", + "integrity": "sha512-115fLhvZVqWwHPbClyntxEVfVDfl9DLLTuJvq3g2O/Oxi8AiNouAHvDSzHS0viUJc+V5vm3eq91Xwqn9dp4jRA==", + "dev": true, + "requires": { + "bn.js": "^4.0.0", + "brorand": "^1.0.1" + } + }, + "mime": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", + "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==", "dev": true }, - "jasmine-spec-reporter": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/jasmine-spec-reporter/-/jasmine-spec-reporter-4.2.1.tgz", - "integrity": "sha512-FZBoZu7VE5nR7Nilzy+Np8KuVIOxF4oXDPDknehCYBDE080EnlPu0afdZNmpGDBRCUBv3mj5qgqCRmk6W/K8vg==", - "dev": true, + "mime-db": { + "version": "1.43.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.43.0.tgz", + "integrity": "sha512-+5dsGEEovYbT8UY9yD7eE4XTc4UwJ1jBYlgaQQF38ENsKR3wj/8q8RFZrF9WIZpB2V1ArTVFUva8sAul1NzRzQ==" + }, + "mime-types": { + "version": "2.1.26", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.26.tgz", + "integrity": "sha512-01paPWYgLrkqAyrlDorC1uDwl2p3qZT7yl806vW7DvDoxwXi46jsjFbg+WdwotBIk6/MbEhO/dh5aZ5sNj/dWQ==", "requires": { - "colors": "1.1.2" + "mime-db": "1.43.0" } }, - "jasminewd2": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/jasminewd2/-/jasminewd2-2.2.0.tgz", - "integrity": "sha1-43zwsX8ZnM4jvqcbIDk5Uka07E4=", + "mimic-fn": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", + "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==", "dev": true }, - "jest-worker": { - "version": "24.9.0", - "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-24.9.0.tgz", - "integrity": "sha512-51PE4haMSXcHohnSMdM42anbvZANYTqMrr52tVKPqqsPJMzoP6FYYDVqahX/HrAoKEKz3uUPzSvKs9A3qR4iVw==", + "mini-css-extract-plugin": { + "version": "0.8.0", + "resolved": "https://registry.npmjs.org/mini-css-extract-plugin/-/mini-css-extract-plugin-0.8.0.tgz", + "integrity": "sha512-MNpRGbNA52q6U92i0qbVpQNsgk7LExy41MdAlG84FeytfDOtRIf/mCHdEgG8rpTKOaNKiqUnZdlptF469hxqOw==", "dev": true, "requires": { - "merge-stream": "^2.0.0", - "supports-color": "^6.1.0" + "loader-utils": "^1.1.0", + "normalize-url": "1.9.1", + "schema-utils": "^1.0.0", + "webpack-sources": "^1.1.0" }, "dependencies": { - "supports-color": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-6.1.0.tgz", - "integrity": "sha512-qe1jfm1Mg7Nq/NSh6XE24gPXROEVsWHxC1LIx//XNlD9iw7YZQGjZNjYN7xGaEG6iKdA8EtNFW6R0gjnVXp+wQ==", + "normalize-url": { + "version": "1.9.1", + "resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-1.9.1.tgz", + "integrity": "sha1-LMDWazHqIwNkWENuNiDYWVTGbDw=", "dev": true, "requires": { - "has-flag": "^3.0.0" + "object-assign": "^4.0.1", + "prepend-http": "^1.0.0", + "query-string": "^4.1.0", + "sort-keys": "^1.0.0" } } } }, - "js-tokens": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", - "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", + "minimalistic-assert": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz", + "integrity": "sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A==", "dev": true }, - "js-yaml": { - "version": "3.13.1", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.13.1.tgz", - "integrity": "sha512-YfbcO7jXDdyj0DGxYVSlSeQNHbD7XPWvrVWeVUujrQEoZzWJIRrCPoyk6kL6IAjAG2IolMK4T0hNUe0HOUs5Jw==", - "dev": true, + "minimalistic-crypto-utils": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/minimalistic-crypto-utils/-/minimalistic-crypto-utils-1.0.1.tgz", + "integrity": "sha1-9sAMHAsIIkblxNmd+4x8CDsrWCo=", + "dev": true + }, + "minimatch": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", + "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", "requires": { - "argparse": "^1.0.7", - "esprima": "^4.0.0" + "brace-expansion": "^1.1.7" } }, - "jsbn": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz", - "integrity": "sha1-peZUwuWi3rXyAdls77yoDA7y9RM=", - "dev": true + "minimist": { + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz", + "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==" }, - "jsesc": { - "version": "2.5.2", - "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz", - "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==", - "dev": true + "minipass": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.1.1.tgz", + "integrity": "sha512-UFqVihv6PQgwj8/yTGvl9kPz7xIAY+R5z6XYjRInD3Gk3qx6QGSD6zEcpeG4Dy/lQnv1J6zv8ejV90hyYIKf3w==", + "dev": true, + "requires": { + "yallist": "^4.0.0" + } }, - "json-parse-better-errors": { + "minipass-collect": { "version": "1.0.2", - "resolved": "https://registry.npmjs.org/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz", - "integrity": "sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw==", - "dev": true - }, - "json-schema": { - "version": "0.2.3", - "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.2.3.tgz", - "integrity": "sha1-tIDIkuWaLwWVTOcnvT8qTogvnhM=", - "dev": true - }, - "json-schema-traverse": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", - "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", - "dev": true - }, - "json-stringify-safe": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", - "integrity": "sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus=", - "dev": true - }, - "json3": { - "version": "3.3.3", - "resolved": "https://registry.npmjs.org/json3/-/json3-3.3.3.tgz", - "integrity": "sha512-c7/8mbUsKigAbLkD5B010BK4D9LZm7A1pNItkEwiUZRpIN66exu/e7YQWysGun+TRKaJp8MhemM+VkfWv42aCA==", - "dev": true - }, - "json5": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.1.tgz", - "integrity": "sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow==", + "resolved": "https://registry.npmjs.org/minipass-collect/-/minipass-collect-1.0.2.tgz", + "integrity": "sha512-6T6lH0H8OG9kITm/Jm6tdooIbogG9e0tLgpY6mphXSm/A9u8Nq1ryBG+Qspiub9LjWlBPsPS3tWQ/Botq4FdxA==", "dev": true, "requires": { - "minimist": "^1.2.0" + "minipass": "^3.0.0" } }, - "jsonfile": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz", - "integrity": "sha1-h3Gq4HmbZAdrdmQPygWPnBDjPss=", + "minipass-flush": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/minipass-flush/-/minipass-flush-1.0.5.tgz", + "integrity": "sha512-JmQSYYpPUqX5Jyn1mXaRwOda1uQ8HP5KAT/oDSLCzt1BYRhQU0/hDtsB1ufZfEEzMZ9aAVmsBw8+FWsIXlClWw==", "dev": true, "requires": { - "graceful-fs": "^4.1.6" + "minipass": "^3.0.0" } }, - "jsonparse": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/jsonparse/-/jsonparse-1.3.1.tgz", - "integrity": "sha1-P02uSpH6wxX3EGL4UhzCOfE2YoA=", - "dev": true + "minipass-pipeline": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/minipass-pipeline/-/minipass-pipeline-1.2.2.tgz", + "integrity": "sha512-3JS5A2DKhD2g0Gg8x3yamO0pj7YeKGwVlDS90pF++kxptwx/F+B//roxf9SqYil5tQo65bijy+dAuAFZmYOouA==", + "dev": true, + "requires": { + "minipass": "^3.0.0" + } }, - "jsprim": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.1.tgz", - "integrity": "sha1-MT5mvB5cwG5Di8G3SZwuXFastqI=", + "minizlib": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/minizlib/-/minizlib-1.3.3.tgz", + "integrity": "sha512-6ZYMOEnmVsdCeTJVE0W9ZD+pVnE8h9Hma/iOwwRDsdQoePpoX56/8B6z3P9VNwppJuBKNRuFDRNRqRWexT9G9Q==", "dev": true, "requires": { - "assert-plus": "1.0.0", - "extsprintf": "1.3.0", - "json-schema": "0.2.3", - "verror": "1.10.0" + "minipass": "^2.9.0" + }, + "dependencies": { + "minipass": { + "version": "2.9.0", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-2.9.0.tgz", + "integrity": "sha512-wxfUjg9WebH+CUDX/CdbRlh5SmfZiy/hpkxaRI16Y9W56Pa75sWgd/rvFilSgrauD9NyFymP/+JFV3KwzIsJeg==", + "dev": true, + "requires": { + "safe-buffer": "^5.1.2", + "yallist": "^3.0.0" + } + }, + "yallist": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", + "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==", + "dev": true + } } }, - "jszip": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/jszip/-/jszip-3.2.2.tgz", - "integrity": "sha512-NmKajvAFQpbg3taXQXr/ccS2wcucR1AZ+NtyWp2Nq7HHVsXhcJFR8p0Baf32C2yVvBylFWVeKf+WI2AnvlPhpA==", + "mississippi": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/mississippi/-/mississippi-3.0.0.tgz", + "integrity": "sha512-x471SsVjUtBRtcvd4BzKE9kFC+/2TeWgKCgw0bZcw1b9l2X3QX5vCWgF+KaZaYm87Ss//rHnWryupDrgLvmSkA==", "dev": true, "requires": { - "lie": "~3.3.0", - "pako": "~1.0.2", - "readable-stream": "~2.3.6", - "set-immediate-shim": "~1.0.1" + "concat-stream": "^1.5.0", + "duplexify": "^3.4.2", + "end-of-stream": "^1.1.0", + "flush-write-stream": "^1.0.0", + "from2": "^2.1.0", + "parallel-transform": "^1.1.0", + "pump": "^3.0.0", + "pumpify": "^1.3.3", + "stream-each": "^1.1.0", + "through2": "^2.0.0" } }, - "karma": { - "version": "4.4.1", - "resolved": "https://registry.npmjs.org/karma/-/karma-4.4.1.tgz", - "integrity": "sha512-L5SIaXEYqzrh6b1wqYC42tNsFMx2PWuxky84pK9coK09MvmL7mxii3G3bZBh/0rvD27lqDd0le9jyhzvwif73A==", + "mixin-deep": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/mixin-deep/-/mixin-deep-1.3.2.tgz", + "integrity": "sha512-WRoDn//mXBiJ1H40rqa3vH0toePwSsGb45iInWlTySa+Uu4k3tYUSxa2v1KqAiLtvlrSzaExqS1gtk96A9zvEA==", "dev": true, "requires": { - "bluebird": "^3.3.0", - "body-parser": "^1.16.1", - "braces": "^3.0.2", - "chokidar": "^3.0.0", - "colors": "^1.1.0", - "connect": "^3.6.0", - "di": "^0.0.1", - "dom-serialize": "^2.2.0", - "flatted": "^2.0.0", - "glob": "^7.1.1", - "graceful-fs": "^4.1.2", - "http-proxy": "^1.13.0", - "isbinaryfile": "^3.0.0", - "lodash": "^4.17.14", - "log4js": "^4.0.0", - "mime": "^2.3.1", - "minimatch": "^3.0.2", - "optimist": "^0.6.1", - "qjobs": "^1.1.4", - "range-parser": "^1.2.0", - "rimraf": "^2.6.0", - "safe-buffer": "^5.0.1", - "socket.io": "2.1.1", - "source-map": "^0.6.1", - "tmp": "0.0.33", - "useragent": "2.3.0" + "for-in": "^1.0.2", + "is-extendable": "^1.0.1" }, "dependencies": { - "mime": { - "version": "2.4.4", - "resolved": "https://registry.npmjs.org/mime/-/mime-2.4.4.tgz", - "integrity": "sha512-LRxmNwziLPT828z+4YkNzloCFC2YM4wrB99k+AV5ZbEyfGNWfG8SO1FUXLmLDBSo89NrJZ4DIWeLjy1CHGhMGA==", - "dev": true - }, - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "dev": true + "is-extendable": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", + "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", + "dev": true, + "requires": { + "is-plain-object": "^2.0.4" + } } } }, - "karma-chrome-launcher": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/karma-chrome-launcher/-/karma-chrome-launcher-3.1.0.tgz", - "integrity": "sha512-3dPs/n7vgz1rxxtynpzZTvb9y/GIaW8xjAwcIGttLbycqoFtI7yo1NGnQi6oFTherRE+GIhCAHZC4vEqWGhNvg==", + "mkdirp": { + "version": "0.5.1", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz", + "integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=", + "requires": { + "minimist": "0.0.8" + }, + "dependencies": { + "minimist": { + "version": "0.0.8", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz", + "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=" + } + } + }, + "move-concurrently": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/move-concurrently/-/move-concurrently-1.0.1.tgz", + "integrity": "sha1-viwAX9oy4LKa8fBdfEszIUxwH5I=", "dev": true, "requires": { - "which": "^1.2.1" + "aproba": "^1.1.1", + "copy-concurrently": "^1.0.0", + "fs-write-stream-atomic": "^1.0.8", + "mkdirp": "^0.5.1", + "rimraf": "^2.5.4", + "run-queue": "^1.0.3" } }, - "karma-coverage-istanbul-reporter": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/karma-coverage-istanbul-reporter/-/karma-coverage-istanbul-reporter-2.1.1.tgz", - "integrity": "sha512-CH8lTi8+kKXGvrhy94+EkEMldLCiUA0xMOiL31vvli9qK0T+qcXJAwWBRVJWnVWxYkTmyWar8lPz63dxX6/z1A==", - "dev": true, - "requires": { - "istanbul-api": "^2.1.6", - "minimatch": "^3.0.4" - } + "ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "dev": true }, - "karma-jasmine": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/karma-jasmine/-/karma-jasmine-3.1.1.tgz", - "integrity": "sha512-pxBmv5K7IkBRLsFSTOpgiK/HzicQT3mfFF+oHAC7nxMfYKhaYFgxOa5qjnHW4sL5rUnmdkSajoudOnnOdPyW4Q==", + "multicast-dns": { + "version": "6.2.3", + "resolved": "https://registry.npmjs.org/multicast-dns/-/multicast-dns-6.2.3.tgz", + "integrity": "sha512-ji6J5enbMyGRHIAkAOu3WdV8nggqviKCEKtXcOqfphZZtQrmHKycfynJ2V7eVPUA4NhJ6V7Wf4TmGbTwKE9B6g==", "dev": true, "requires": { - "jasmine-core": "^3.5.0" + "dns-packet": "^1.3.1", + "thunky": "^1.0.2" } }, - "karma-jasmine-html-reporter": { - "version": "1.5.2", - "resolved": "https://registry.npmjs.org/karma-jasmine-html-reporter/-/karma-jasmine-html-reporter-1.5.2.tgz", - "integrity": "sha512-ILBPsXqQ3eomq+oaQsM311/jxsypw5/d0LnZXj26XkfThwq7jZ55A2CFSKJVA5VekbbOGvMyv7d3juZj0SeTxA==", + "multicast-dns-service-types": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/multicast-dns-service-types/-/multicast-dns-service-types-1.1.0.tgz", + "integrity": "sha1-iZ8R2WhuXgXLkbNdXw5jt3PPyQE=", "dev": true }, - "karma-source-map-support": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/karma-source-map-support/-/karma-source-map-support-1.4.0.tgz", - "integrity": "sha512-RsBECncGO17KAoJCYXjv+ckIz+Ii9NCi+9enk+rq6XC81ezYkb4/RHE6CTXdA7IOJqoF3wcaLfVG0CPmE5ca6A==", + "mute-stream": { + "version": "0.0.8", + "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.8.tgz", + "integrity": "sha512-nnbWWOkoWyUsTjKrhgD0dcz22mdkSnpYqbEjIm2nhwhuxlSkpywJmBo8h0ZqJdkp73mb90SssHkN4rsRaBAfAA==", + "dev": true + }, + "nan": { + "version": "2.14.0", + "resolved": "https://registry.npmjs.org/nan/-/nan-2.14.0.tgz", + "integrity": "sha512-INOFj37C7k3AfaNTtX8RhsTw7qRy7eLET14cROi9+5HAVbbHuIWUHEauBv5qT4Av2tWasiTY1Jw6puUNqRJXQg==" + }, + "nanomatch": { + "version": "1.2.13", + "resolved": "https://registry.npmjs.org/nanomatch/-/nanomatch-1.2.13.tgz", + "integrity": "sha512-fpoe2T0RbHwBTBUOftAfBPaDEi06ufaUai0mE6Yn1kacc3SnTErfb/h+X94VXzI64rKFHYImXSvdwGGCmwOqCA==", "dev": true, "requires": { - "source-map-support": "^0.5.5" + "arr-diff": "^4.0.0", + "array-unique": "^0.3.2", + "define-property": "^2.0.2", + "extend-shallow": "^3.0.2", + "fragment-cache": "^0.2.1", + "is-windows": "^1.0.2", + "kind-of": "^6.0.2", + "object.pick": "^1.3.0", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.1" } }, - "killable": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/killable/-/killable-1.0.1.tgz", - "integrity": "sha512-LzqtLKlUwirEUyl/nicirVmNiPvYs7l5n8wOPP7fyJVpUPkvCnW/vuiXGpylGUlnPDnB7311rARzAt3Mhswpjg==", + "negotiator": { + "version": "0.6.2", + "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.2.tgz", + "integrity": "sha512-hZXc7K2e+PgeI1eDBe/10Ard4ekbfrrqG8Ep+8Jmf4JID2bNg7NvCPOZN+kfF574pFQI7mum2AUqDidoKqcTOw==", "dev": true }, - "kind-of": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", - "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", + "neo-async": { + "version": "2.6.1", + "resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.6.1.tgz", + "integrity": "sha512-iyam8fBuCUpWeKPGpaNMetEocMt364qkCsfL9JuhjXX6dRnguRVOfk2GZaDpPjcOKiiXCPINZC1GczQ7iTq3Zw==" + }, + "nice-try": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/nice-try/-/nice-try-1.0.5.tgz", + "integrity": "sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ==", "dev": true }, - "lcid": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/lcid/-/lcid-2.0.0.tgz", - "integrity": "sha512-avPEb8P8EGnwXKClwsNUgryVjllcRqtMYa49NTsbQagYuT1DcXnl1915oxWjoyGrXR6zH/Y0Zc96xWsPcoDKeA==", - "dev": true, + "no-case": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/no-case/-/no-case-2.3.2.tgz", + "integrity": "sha512-rmTZ9kz+f3rCvK2TD1Ue/oZlns7OGoIWP4fc3llxxRXlOkHKoWPPWJOfFYpITabSow43QJbRIoHQXtt10VldyQ==", "requires": { - "invert-kv": "^2.0.0" + "lower-case": "^1.1.1" } }, - "less": { - "version": "3.9.0", - "resolved": "https://registry.npmjs.org/less/-/less-3.9.0.tgz", - "integrity": "sha512-31CmtPEZraNUtuUREYjSqRkeETFdyEHSEPAGq4erDlUXtda7pzNmctdljdIagSb589d/qXGWiiP31R5JVf+v0w==", + "node-fetch-npm": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/node-fetch-npm/-/node-fetch-npm-2.0.3.tgz", + "integrity": "sha512-DgwoKEsqLnFZtk3ap7GWBHcHwnUhsNmQqEDcdjfQ8GofLEFJ081NAd4Uin3R7RFZBWVJCwHISw1oaEqPgSLloA==", "dev": true, "requires": { - "clone": "^2.1.2", - "errno": "^0.1.1", + "encoding": "^0.1.11", + "json-parse-better-errors": "^1.0.0", + "safe-buffer": "^5.1.1" + } + }, + "node-forge": { + "version": "0.9.0", + "resolved": "https://registry.npmjs.org/node-forge/-/node-forge-0.9.0.tgz", + "integrity": "sha512-7ASaDa3pD+lJ3WvXFsxekJQelBKRpne+GOVbLbtHYdd7pFspyeuJHnWfLplGf3SwKGbfs/aYl5V/JCIaHVUKKQ==", + "dev": true + }, + "node-gyp": { + "version": "3.8.0", + "resolved": "https://registry.npmjs.org/node-gyp/-/node-gyp-3.8.0.tgz", + "integrity": "sha512-3g8lYefrRRzvGeSowdJKAKyks8oUpLEd/DyPV4eMhVlhJ0aNaZqIrNUIPuEWWTAoPqyFkfGrM67MC69baqn6vA==", + "requires": { + "fstream": "^1.0.0", + "glob": "^7.0.3", "graceful-fs": "^4.1.2", - "image-size": "~0.5.0", - "mime": "^1.4.1", "mkdirp": "^0.5.0", - "promise": "^7.1.1", - "request": "^2.83.0", - "source-map": "~0.6.0" + "nopt": "2 || 3", + "npmlog": "0 || 1 || 2 || 3 || 4", + "osenv": "0", + "request": "^2.87.0", + "rimraf": "2", + "semver": "~5.3.0", + "tar": "^2.0.0", + "which": "1" }, "dependencies": { - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "dev": true, - "optional": true + "semver": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.3.0.tgz", + "integrity": "sha1-myzl094C0XxgEq0yaqa00M9U+U8=" + }, + "tar": { + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/tar/-/tar-2.2.2.tgz", + "integrity": "sha512-FCEhQ/4rE1zYv9rYXJw/msRqsnmlje5jHP6huWeBZ704jUTy02c5AZyWujpMR1ax6mVw9NyJMfuK2CMDWVIfgA==", + "requires": { + "block-stream": "*", + "fstream": "^1.0.12", + "inherits": "2" + } } } }, - "less-loader": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/less-loader/-/less-loader-5.0.0.tgz", - "integrity": "sha512-bquCU89mO/yWLaUq0Clk7qCsKhsF/TZpJUzETRvJa9KSVEL9SO3ovCvdEHISBhrC81OwC8QSVX7E0bzElZj9cg==", - "dev": true, - "requires": { - "clone": "^2.1.1", - "loader-utils": "^1.1.0", - "pify": "^4.0.1" - } - }, - "leven": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/leven/-/leven-3.1.0.tgz", - "integrity": "sha512-qsda+H8jTaUaN/x5vzW2rzc+8Rw4TAQ/4KjB46IwK5VH+IlVeeeje/EoZRpiXvIqjFgK84QffqPztGI3VBLG1A==", - "dev": true - }, - "levenary": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/levenary/-/levenary-1.1.1.tgz", - "integrity": "sha512-mkAdOIt79FD6irqjYSs4rdbnlT5vRonMEvBVPVb3XmevfS8kgRXwfes0dhPdEtzTWD/1eNE/Bm/G1iRt6DcnQQ==", + "node-libs-browser": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/node-libs-browser/-/node-libs-browser-2.2.1.tgz", + "integrity": "sha512-h/zcD8H9kaDZ9ALUWwlBUDo6TKF8a7qBSCSEGfjTVIYeqsioSKaAX+BN7NgiMGp6iSIXZ3PxgCu8KS3b71YK5Q==", "dev": true, "requires": { - "leven": "^3.1.0" + "assert": "^1.1.1", + "browserify-zlib": "^0.2.0", + "buffer": "^4.3.0", + "console-browserify": "^1.1.0", + "constants-browserify": "^1.0.0", + "crypto-browserify": "^3.11.0", + "domain-browser": "^1.1.1", + "events": "^3.0.0", + "https-browserify": "^1.0.0", + "os-browserify": "^0.3.0", + "path-browserify": "0.0.1", + "process": "^0.11.10", + "punycode": "^1.2.4", + "querystring-es3": "^0.2.0", + "readable-stream": "^2.3.3", + "stream-browserify": "^2.0.1", + "stream-http": "^2.7.2", + "string_decoder": "^1.0.0", + "timers-browserify": "^2.0.4", + "tty-browserify": "0.0.0", + "url": "^0.11.0", + "util": "^0.11.0", + "vm-browserify": "^1.0.1" + }, + "dependencies": { + "punycode": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz", + "integrity": "sha1-wNWmOycYgArY4esPpSachN1BhF4=", + "dev": true + } } }, - "license-webpack-plugin": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/license-webpack-plugin/-/license-webpack-plugin-2.1.2.tgz", - "integrity": "sha512-7poZHRla+ae0eEButlwMrPpkXyhNVBf2EHePYWT0jyLnI6311/OXJkTI2sOIRungRpQgU2oDMpro5bSFPT5F0A==", + "node-releases": { + "version": "1.1.52", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-1.1.52.tgz", + "integrity": "sha512-snSiT1UypkgGt2wxPqS6ImEUICbNCMb31yaxWrOLXjhlt2z2/IBpaOxzONExqSm4y5oLnAqjjRWu+wsDzK5yNQ==", "dev": true, "requires": { - "@types/webpack-sources": "^0.1.5", - "webpack-sources": "^1.2.0" + "semver": "^6.3.0" } }, - "lie": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/lie/-/lie-3.3.0.tgz", - "integrity": "sha512-UaiMJzeWRlEujzAuw5LokY1L5ecNQYZKfmyZ9L7wDHb/p5etKaxXhohBcrw0EYby+G/NA52vRSN4N39dxHAIwQ==", - "dev": true, + "node-sass": { + "version": "4.13.1", + "resolved": "https://registry.npmjs.org/node-sass/-/node-sass-4.13.1.tgz", + "integrity": "sha512-TTWFx+ZhyDx1Biiez2nB0L3YrCZ/8oHagaDalbuBSlqXgUPsdkUSzJsVxeDO9LtPB49+Fh3WQl3slABo6AotNw==", "requires": { - "immediate": "~3.0.5" + "async-foreach": "^0.1.3", + "chalk": "^1.1.1", + "cross-spawn": "^3.0.0", + "gaze": "^1.0.0", + "get-stdin": "^4.0.1", + "glob": "^7.0.3", + "in-publish": "^2.0.0", + "lodash": "^4.17.15", + "meow": "^3.7.0", + "mkdirp": "^0.5.1", + "nan": "^2.13.2", + "node-gyp": "^3.8.0", + "npmlog": "^4.0.0", + "request": "^2.88.0", + "sass-graph": "^2.2.4", + "stdout-stream": "^1.4.0", + "true-case-path": "^1.0.2" + }, + "dependencies": { + "ansi-styles": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", + "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=" + }, + "chalk": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", + "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", + "requires": { + "ansi-styles": "^2.2.1", + "escape-string-regexp": "^1.0.2", + "has-ansi": "^2.0.0", + "strip-ansi": "^3.0.0", + "supports-color": "^2.0.0" + } + }, + "cross-spawn": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-3.0.1.tgz", + "integrity": "sha1-ElYDfsufDF9549bvE14wdwGEuYI=", + "requires": { + "lru-cache": "^4.0.1", + "which": "^1.2.9" + } + }, + "lru-cache": { + "version": "4.1.5", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-4.1.5.tgz", + "integrity": "sha512-sWZlbEP2OsHNkXrMl5GYk/jKk70MBng6UU4YI/qGDYbgf6YbP4EvmqISbXCoJiRKs+1bSpFHVgQxvJ17F2li5g==", + "requires": { + "pseudomap": "^1.0.2", + "yallist": "^2.1.2" + } + }, + "supports-color": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", + "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=" + }, + "yallist": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-2.1.2.tgz", + "integrity": "sha1-HBH5IY8HYImkfdUS+TxmmaaoHVI=" + } } }, - "loader-runner": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/loader-runner/-/loader-runner-2.4.0.tgz", - "integrity": "sha512-Jsmr89RcXGIwivFY21FcRrisYZfvLMTWx5kOLc+JTxtpBOG6xML0vzbc6SEQG2FO9/4Fc3wW4LVcB5DmGflaRw==", - "dev": true - }, - "loader-utils": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-1.2.3.tgz", - "integrity": "sha512-fkpz8ejdnEMG3s37wGL07iSBDg99O9D5yflE9RGNH3hRdx9SOwYfnGYdZOUIZitN8E+E2vkq3MUMYMvPYl5ZZA==", - "dev": true, - "requires": { - "big.js": "^5.2.2", - "emojis-list": "^2.0.0", - "json5": "^1.0.1" + "nopt": { + "version": "3.0.6", + "resolved": "https://registry.npmjs.org/nopt/-/nopt-3.0.6.tgz", + "integrity": "sha1-xkZdvwirzU2zWTF/eaxopkayj/k=", + "requires": { + "abbrev": "1" } }, - "locate-path": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz", - "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==", - "dev": true, + "normalize-package-data": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.5.0.tgz", + "integrity": "sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA==", "requires": { - "p-locate": "^3.0.0", - "path-exists": "^3.0.0" + "hosted-git-info": "^2.1.4", + "resolve": "^1.10.0", + "semver": "2 || 3 || 4 || 5", + "validate-npm-package-license": "^3.0.1" + }, + "dependencies": { + "hosted-git-info": { + "version": "2.8.8", + "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.8.tgz", + "integrity": "sha512-f/wzC2QaWBs7t9IYqB4T3sR1xviIViXJRJTWBlx2Gf3g0Xi5vI7Yy4koXQ1c9OYDGHN9sBy1DQ2AB8fqZBWhUg==" + }, + "semver": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==" + } } }, - "lodash": { - "version": "4.17.15", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.15.tgz", - "integrity": "sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A==", + "normalize-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", + "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", "dev": true }, - "lodash.clonedeep": { - "version": "4.5.0", - "resolved": "https://registry.npmjs.org/lodash.clonedeep/-/lodash.clonedeep-4.5.0.tgz", - "integrity": "sha1-4j8/nE+Pvd6HJSnBBxhXoIblzO8=", + "normalize-range": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/normalize-range/-/normalize-range-0.1.2.tgz", + "integrity": "sha1-LRDAa9/TEuqXd2laTShDlFa3WUI=", "dev": true }, - "log4js": { - "version": "4.5.1", - "resolved": "https://registry.npmjs.org/log4js/-/log4js-4.5.1.tgz", - "integrity": "sha512-EEEgFcE9bLgaYUKuozyFfytQM2wDHtXn4tAN41pkaxpNjAykv11GVdeI4tHtmPWW4Xrgh9R/2d7XYghDVjbKKw==", - "dev": true, - "requires": { - "date-format": "^2.0.0", - "debug": "^4.1.1", - "flatted": "^2.0.0", - "rfdc": "^1.1.4", - "streamroller": "^1.0.6" - } - }, - "loglevel": { - "version": "1.6.7", - "resolved": "https://registry.npmjs.org/loglevel/-/loglevel-1.6.7.tgz", - "integrity": "sha512-cY2eLFrQSAfVPhCgH1s7JI73tMbg9YC3v3+ZHVW67sBS7UxWzNEk/ZBbSfLykBWHp33dqqtOv82gjhKEi81T/A==", + "normalize-url": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-3.3.0.tgz", + "integrity": "sha512-U+JJi7duF1o+u2pynbp2zXDW2/PADgC30f0GsHZtRh+HOcXHnw137TrNlyxxRvWW5fjKd3bcLHPxofWuCjaeZg==", "dev": true }, - "loose-envify": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz", - "integrity": "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==", + "npm-bundled": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/npm-bundled/-/npm-bundled-1.1.1.tgz", + "integrity": "sha512-gqkfgGePhTpAEgUsGEgcq1rqPXA+tv/aVBlgEzfXwA1yiUJF7xtEt3CtVwOjNYQOVknDk0F20w58Fnm3EtG0fA==", "dev": true, "requires": { - "js-tokens": "^3.0.0 || ^4.0.0" + "npm-normalize-package-bin": "^1.0.1" } }, - "lru-cache": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz", - "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==", + "npm-normalize-package-bin": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/npm-normalize-package-bin/-/npm-normalize-package-bin-1.0.1.tgz", + "integrity": "sha512-EPfafl6JL5/rU+ot6P3gRSCpPDW5VmIzX959Ob1+ySFUuuYHWHekXpwdUZcKP5C+DS4GEtdJluwBjnsNDl+fSA==", + "dev": true + }, + "npm-package-arg": { + "version": "6.1.1", + "resolved": "https://registry.npmjs.org/npm-package-arg/-/npm-package-arg-6.1.1.tgz", + "integrity": "sha512-qBpssaL3IOZWi5vEKUKW0cO7kzLeT+EQO9W8RsLOZf76KF9E/K9+wH0C7t06HXPpaH8WH5xF1MExLuCwbTqRUg==", "dev": true, "requires": { - "yallist": "^3.0.2" + "hosted-git-info": "^2.7.1", + "osenv": "^0.1.5", + "semver": "^5.6.0", + "validate-npm-package-name": "^3.0.0" + }, + "dependencies": { + "hosted-git-info": { + "version": "2.8.8", + "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.8.tgz", + "integrity": "sha512-f/wzC2QaWBs7t9IYqB4T3sR1xviIViXJRJTWBlx2Gf3g0Xi5vI7Yy4koXQ1c9OYDGHN9sBy1DQ2AB8fqZBWhUg==", + "dev": true + }, + "semver": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", + "dev": true + } } }, - "magic-string": { - "version": "0.25.3", - "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.25.3.tgz", - "integrity": "sha512-6QK0OpF/phMz0Q2AxILkX2mFhi7m+WMwTRg0LQKq/WBB0cDP4rYH3Wp4/d3OTXlrPLVJT/RFqj8tFeAR4nk8AA==", + "npm-packlist": { + "version": "1.4.8", + "resolved": "https://registry.npmjs.org/npm-packlist/-/npm-packlist-1.4.8.tgz", + "integrity": "sha512-5+AZgwru5IevF5ZdnFglB5wNlHG1AOOuw28WhUq8/8emhBmLv6jX5by4WJCh7lW0uSYZYS6DXqIsyZVIXRZU9A==", "dev": true, "requires": { - "sourcemap-codec": "^1.4.4" + "ignore-walk": "^3.0.1", + "npm-bundled": "^1.0.1", + "npm-normalize-package-bin": "^1.0.1" } }, - "make-dir": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-2.1.0.tgz", - "integrity": "sha512-LS9X+dc8KLxXCb8dni79fLIIUA5VyZoyjSMCwTluaXA0o27cCK0bhXkpgw+sTXVpPy/lSO57ilRixqk0vDmtRA==", + "npm-pick-manifest": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/npm-pick-manifest/-/npm-pick-manifest-3.0.2.tgz", + "integrity": "sha512-wNprTNg+X5nf+tDi+hbjdHhM4bX+mKqv6XmPh7B5eG+QY9VARfQPfCEH013H5GqfNj6ee8Ij2fg8yk0mzps1Vw==", "dev": true, "requires": { - "pify": "^4.0.1", - "semver": "^5.6.0" + "figgy-pudding": "^3.5.1", + "npm-package-arg": "^6.0.0", + "semver": "^5.4.1" }, "dependencies": { "semver": { @@ -6847,1299 +7764,1250 @@ } } }, - "make-error": { - "version": "1.3.6", - "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz", - "integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==", - "dev": true - }, - "make-fetch-happen": { - "version": "5.0.2", - "resolved": "https://registry.npmjs.org/make-fetch-happen/-/make-fetch-happen-5.0.2.tgz", - "integrity": "sha512-07JHC0r1ykIoruKO8ifMXu+xEU8qOXDFETylktdug6vJDACnP+HKevOu3PXyNPzFyTSlz8vrBYlBO1JZRe8Cag==", + "npm-registry-fetch": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/npm-registry-fetch/-/npm-registry-fetch-4.0.3.tgz", + "integrity": "sha512-WGvUx0lkKFhu9MbiGFuT9nG2NpfQ+4dCJwRwwtK2HK5izJEvwDxMeUyqbuMS7N/OkpVCqDorV6rO5E4V9F8lJw==", "dev": true, "requires": { - "agentkeepalive": "^3.4.1", - "cacache": "^12.0.0", - "http-cache-semantics": "^3.8.1", - "http-proxy-agent": "^2.1.0", - "https-proxy-agent": "^2.2.3", + "JSONStream": "^1.3.4", + "bluebird": "^3.5.1", + "figgy-pudding": "^3.4.1", "lru-cache": "^5.1.1", - "mississippi": "^3.0.0", - "node-fetch-npm": "^2.0.2", - "promise-retry": "^1.1.1", - "socks-proxy-agent": "^4.0.0", - "ssri": "^6.0.0" + "make-fetch-happen": "^5.0.0", + "npm-package-arg": "^6.1.0", + "safe-buffer": "^5.2.0" + }, + "dependencies": { + "safe-buffer": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.0.tgz", + "integrity": "sha512-fZEwUGbVl7kouZs1jCdMLdt95hdIv0ZeHg6L7qPeciMZhZ+/gdesW4wgTARkrFWEpspjEATAzUGPG8N2jJiwbg==", + "dev": true + } } }, - "mamacro": { - "version": "0.0.3", - "resolved": "https://registry.npmjs.org/mamacro/-/mamacro-0.0.3.tgz", - "integrity": "sha512-qMEwh+UujcQ+kbz3T6V+wAmO2U8veoq2w+3wY8MquqwVA3jChfwY+Tk52GZKDfACEPjuZ7r2oJLejwpt8jtwTA==", - "dev": true - }, - "map-age-cleaner": { - "version": "0.1.3", - "resolved": "https://registry.npmjs.org/map-age-cleaner/-/map-age-cleaner-0.1.3.tgz", - "integrity": "sha512-bJzx6nMoP6PDLPBFmg7+xRKeFZvFboMrGlxmNj9ClvX53KrmvM5bXFXEWjbz4cz1AFn+jWJ9z/DJSz7hrs0w3w==", + "npm-run-path": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-2.0.2.tgz", + "integrity": "sha1-NakjLfo11wZ7TLLd8jV7GHFTbF8=", "dev": true, "requires": { - "p-defer": "^1.0.0" + "path-key": "^2.0.0" } }, - "map-cache": { - "version": "0.2.2", - "resolved": "https://registry.npmjs.org/map-cache/-/map-cache-0.2.2.tgz", - "integrity": "sha1-wyq9C9ZSXZsFFkW7TyasXcmKDb8=", - "dev": true - }, - "map-visit": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/map-visit/-/map-visit-1.0.0.tgz", - "integrity": "sha1-7Nyo8TFE5mDxtb1B8S80edmN+48=", - "dev": true, + "npmlog": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/npmlog/-/npmlog-4.1.2.tgz", + "integrity": "sha512-2uUqazuKlTaSI/dC8AzicUck7+IrEaOnN/e0jd3Xtt1KcGpwx30v50mL7oPyr/h9bL3E4aZccVwpwP+5W9Vjkg==", "requires": { - "object-visit": "^1.0.0" + "are-we-there-yet": "~1.1.2", + "console-control-strings": "~1.1.0", + "gauge": "~2.7.3", + "set-blocking": "~2.0.0" } }, - "md5.js": { - "version": "1.3.5", - "resolved": "https://registry.npmjs.org/md5.js/-/md5.js-1.3.5.tgz", - "integrity": "sha512-xitP+WxNPcTTOgnTJcrhM0xvdPepipPSf3I8EIpGKeFLjt3PlJLIDG3u8EX53ZIubkb+5U2+3rELYpEhHhzdkg==", - "dev": true, + "nth-check": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/nth-check/-/nth-check-1.0.2.tgz", + "integrity": "sha512-WeBOdju8SnzPN5vTUJYxYUxLeXpCaVP5i5e0LF8fg7WORF2Wd7wFX/pk0tYZk7s8T+J7VLy0Da6J1+wCT0AtHg==", "requires": { - "hash-base": "^3.0.0", - "inherits": "^2.0.1", - "safe-buffer": "^5.1.2" + "boolbase": "~1.0.0" } }, - "media-typer": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", - "integrity": "sha1-hxDXrwqmJvj/+hzgAWhUUmMlV0g=", + "num2fraction": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/num2fraction/-/num2fraction-1.2.2.tgz", + "integrity": "sha1-b2gragJ6Tp3fpFZM0lidHU5mnt4=", "dev": true }, - "mem": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/mem/-/mem-4.3.0.tgz", - "integrity": "sha512-qX2bG48pTqYRVmDB37rn/6PT7LcR8T7oAX3bf99u1Tt1nzxYfxkgqDwUwolPlXweM0XzBOBFzSx4kfp7KP1s/w==", - "dev": true, - "requires": { - "map-age-cleaner": "^0.1.1", - "mimic-fn": "^2.0.0", - "p-is-promise": "^2.0.0" - } - }, - "memory-fs": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/memory-fs/-/memory-fs-0.4.1.tgz", - "integrity": "sha1-OpoguEYlI+RHz7x+i7gO1me/xVI=", - "dev": true, - "requires": { - "errno": "^0.1.3", - "readable-stream": "^2.0.1" - } - }, - "merge-descriptors": { + "number-is-nan": { "version": "1.0.1", - "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz", - "integrity": "sha1-sAqqVW3YtEVoFQ7J0blT8/kMu2E=", - "dev": true + "resolved": "https://registry.npmjs.org/number-is-nan/-/number-is-nan-1.0.1.tgz", + "integrity": "sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0=" }, - "merge-source-map": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/merge-source-map/-/merge-source-map-1.1.0.tgz", - "integrity": "sha512-Qkcp7P2ygktpMPh2mCQZaf3jhN6D3Z/qVZHSdWvQ+2Ef5HgRAPBO57A77+ENm0CPx2+1Ce/MYKi3ymqdfuqibw==", - "dev": true, - "requires": { - "source-map": "^0.6.1" - }, - "dependencies": { - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "dev": true - } - } + "oauth-sign": { + "version": "0.9.0", + "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.9.0.tgz", + "integrity": "sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ==" }, - "merge-stream": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz", - "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==", - "dev": true + "object-assign": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", + "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=" }, - "methods": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz", - "integrity": "sha1-VSmk1nZUE07cxSZmVoNbD4Ua/O4=", + "object-component": { + "version": "0.0.3", + "resolved": "https://registry.npmjs.org/object-component/-/object-component-0.0.3.tgz", + "integrity": "sha1-8MaapQ78lbhmwYb0AKM3acsvEpE=", "dev": true }, - "micromatch": { - "version": "3.1.10", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz", - "integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==", + "object-copy": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/object-copy/-/object-copy-0.1.0.tgz", + "integrity": "sha1-fn2Fi3gb18mRpBupde04EnVOmYw=", "dev": true, "requires": { - "arr-diff": "^4.0.0", - "array-unique": "^0.3.2", - "braces": "^2.3.1", - "define-property": "^2.0.2", - "extend-shallow": "^3.0.2", - "extglob": "^2.0.4", - "fragment-cache": "^0.2.1", - "kind-of": "^6.0.2", - "nanomatch": "^1.2.9", - "object.pick": "^1.3.0", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.2" + "copy-descriptor": "^0.1.0", + "define-property": "^0.2.5", + "kind-of": "^3.0.3" }, "dependencies": { - "braces": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz", - "integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==", - "dev": true, - "requires": { - "arr-flatten": "^1.1.0", - "array-unique": "^0.3.2", - "extend-shallow": "^2.0.1", - "fill-range": "^4.0.0", - "isobject": "^3.0.1", - "repeat-element": "^1.1.2", - "snapdragon": "^0.8.1", - "snapdragon-node": "^2.0.1", - "split-string": "^3.0.2", - "to-regex": "^3.0.1" - }, - "dependencies": { - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - } - } - }, - "fill-range": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz", - "integrity": "sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc=", - "dev": true, - "requires": { - "extend-shallow": "^2.0.1", - "is-number": "^3.0.0", - "repeat-string": "^1.6.1", - "to-regex-range": "^2.1.0" - }, - "dependencies": { - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - } - } - }, - "is-number": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", - "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", + "define-property": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", + "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", "dev": true, "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } + "is-descriptor": "^0.1.0" } }, - "to-regex-range": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-2.1.1.tgz", - "integrity": "sha1-fIDBe53+vlmeJzZ+DU3VWQFB2zg=", + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", "dev": true, "requires": { - "is-number": "^3.0.0", - "repeat-string": "^1.6.1" + "is-buffer": "^1.1.5" } } } }, - "miller-rabin": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/miller-rabin/-/miller-rabin-4.0.1.tgz", - "integrity": "sha512-115fLhvZVqWwHPbClyntxEVfVDfl9DLLTuJvq3g2O/Oxi8AiNouAHvDSzHS0viUJc+V5vm3eq91Xwqn9dp4jRA==", - "dev": true, - "requires": { - "bn.js": "^4.0.0", - "brorand": "^1.0.1" - } + "object-inspect": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.7.0.tgz", + "integrity": "sha512-a7pEHdh1xKIAgTySUGgLMx/xwDZskN1Ud6egYYN3EdRW4ZMPNEDUTF+hwy2LUC+Bl+SyLXANnwz/jyh/qutKUw==" }, - "mime": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", - "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==", + "object-is": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/object-is/-/object-is-1.0.2.tgz", + "integrity": "sha512-Epah+btZd5wrrfjkJZq1AOB9O6OxUQto45hzFd7lXGrpHPGE0W1k+426yrZV+k6NJOzLNNW/nVsmZdIWsAqoOQ==", "dev": true }, - "mime-db": { - "version": "1.43.0", - "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.43.0.tgz", - "integrity": "sha512-+5dsGEEovYbT8UY9yD7eE4XTc4UwJ1jBYlgaQQF38ENsKR3wj/8q8RFZrF9WIZpB2V1ArTVFUva8sAul1NzRzQ==", - "dev": true + "object-keys": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", + "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==" }, - "mime-types": { - "version": "2.1.26", - "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.26.tgz", - "integrity": "sha512-01paPWYgLrkqAyrlDorC1uDwl2p3qZT7yl806vW7DvDoxwXi46jsjFbg+WdwotBIk6/MbEhO/dh5aZ5sNj/dWQ==", + "object-visit": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/object-visit/-/object-visit-1.0.1.tgz", + "integrity": "sha1-95xEk68MU3e1n+OdOV5BBC3QRbs=", "dev": true, "requires": { - "mime-db": "1.43.0" + "isobject": "^3.0.0" } }, - "mimic-fn": { + "object.assign": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.0.tgz", + "integrity": "sha512-exHJeq6kBKj58mqGyTQ9DFvrZC/eR6OwxzoM9YRoGBqrXYonaFyGiFMuc9VZrXf7DarreEwMpurG3dd+CNyW5w==", + "requires": { + "define-properties": "^1.1.2", + "function-bind": "^1.1.1", + "has-symbols": "^1.0.0", + "object-keys": "^1.0.11" + } + }, + "object.getownpropertydescriptors": { "version": "2.1.0", - "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", - "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==", - "dev": true + "resolved": "https://registry.npmjs.org/object.getownpropertydescriptors/-/object.getownpropertydescriptors-2.1.0.tgz", + "integrity": "sha512-Z53Oah9A3TdLoblT7VKJaTDdXdT+lQO+cNpKVnya5JDe9uLvzu1YyY1yFDFrcxrlRgWrEFH0jJtD/IbuwjcEVg==", + "requires": { + "define-properties": "^1.1.3", + "es-abstract": "^1.17.0-next.1" + } }, - "mini-css-extract-plugin": { - "version": "0.8.0", - "resolved": "https://registry.npmjs.org/mini-css-extract-plugin/-/mini-css-extract-plugin-0.8.0.tgz", - "integrity": "sha512-MNpRGbNA52q6U92i0qbVpQNsgk7LExy41MdAlG84FeytfDOtRIf/mCHdEgG8rpTKOaNKiqUnZdlptF469hxqOw==", + "object.pick": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/object.pick/-/object.pick-1.3.0.tgz", + "integrity": "sha1-h6EKxMFpS9Lhy/U1kaZhQftd10c=", "dev": true, "requires": { - "loader-utils": "^1.1.0", - "normalize-url": "1.9.1", - "schema-utils": "^1.0.0", - "webpack-sources": "^1.1.0" + "isobject": "^3.0.1" } }, - "minimalistic-assert": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz", - "integrity": "sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A==", - "dev": true + "object.values": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/object.values/-/object.values-1.1.1.tgz", + "integrity": "sha512-WTa54g2K8iu0kmS/us18jEmdv1a4Wi//BZ/DTVYEcH0XhLM5NYdpDHja3gt57VrZLcNAO2WGA+KpWsDBaHt6eA==", + "dev": true, + "requires": { + "define-properties": "^1.1.3", + "es-abstract": "^1.17.0-next.1", + "function-bind": "^1.1.1", + "has": "^1.0.3" + } }, - "minimalistic-crypto-utils": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/minimalistic-crypto-utils/-/minimalistic-crypto-utils-1.0.1.tgz", - "integrity": "sha1-9sAMHAsIIkblxNmd+4x8CDsrWCo=", + "obuf": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/obuf/-/obuf-1.1.2.tgz", + "integrity": "sha512-PX1wu0AmAdPqOL1mWhqmlOd8kOIZQwGZw6rh7uby9fTc5lhaOWFLX3I6R1hrF9k3zUY40e6igsLGkDXK92LJNg==", "dev": true }, - "minimatch": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", - "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", + "on-finished": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.3.0.tgz", + "integrity": "sha1-IPEzZIGwg811M3mSoWlxqi2QaUc=", "dev": true, "requires": { - "brace-expansion": "^1.1.7" + "ee-first": "1.1.1" } }, - "minimist": { - "version": "1.2.5", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz", - "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==", + "on-headers": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/on-headers/-/on-headers-1.0.2.tgz", + "integrity": "sha512-pZAE+FJLoyITytdqK0U5s+FIpjN0JP3OzFi/u8Rx+EV5/W+JTWGXG8xFzevE7AjBfDqHv/8vL8qQsIhHnqRkrA==", "dev": true }, - "minipass": { - "version": "2.9.0", - "resolved": "https://registry.npmjs.org/minipass/-/minipass-2.9.0.tgz", - "integrity": "sha512-wxfUjg9WebH+CUDX/CdbRlh5SmfZiy/hpkxaRI16Y9W56Pa75sWgd/rvFilSgrauD9NyFymP/+JFV3KwzIsJeg==", - "dev": true, + "once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", "requires": { - "safe-buffer": "^5.1.2", - "yallist": "^3.0.0" + "wrappy": "1" } }, - "minizlib": { - "version": "1.3.3", - "resolved": "https://registry.npmjs.org/minizlib/-/minizlib-1.3.3.tgz", - "integrity": "sha512-6ZYMOEnmVsdCeTJVE0W9ZD+pVnE8h9Hma/iOwwRDsdQoePpoX56/8B6z3P9VNwppJuBKNRuFDRNRqRWexT9G9Q==", + "onetime": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.0.tgz", + "integrity": "sha512-5NcSkPHhwTVFIQN+TUqXoS5+dlElHXdpAWu9I0HP20YOtIi+aZ0Ct82jdlILDxjLEAWwvm+qj1m6aEtsDVmm6Q==", "dev": true, "requires": { - "minipass": "^2.9.0" + "mimic-fn": "^2.1.0" } }, - "mississippi": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/mississippi/-/mississippi-3.0.0.tgz", - "integrity": "sha512-x471SsVjUtBRtcvd4BzKE9kFC+/2TeWgKCgw0bZcw1b9l2X3QX5vCWgF+KaZaYm87Ss//rHnWryupDrgLvmSkA==", + "open": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/open/-/open-7.0.0.tgz", + "integrity": "sha512-K6EKzYqnwQzk+/dzJAQSBORub3xlBTxMz+ntpZpH/LyCa1o6KjXhuN+2npAaI9jaSmU3R1Q8NWf4KUWcyytGsQ==", "dev": true, "requires": { - "concat-stream": "^1.5.0", - "duplexify": "^3.4.2", - "end-of-stream": "^1.1.0", - "flush-write-stream": "^1.0.0", - "from2": "^2.1.0", - "parallel-transform": "^1.1.0", - "pump": "^3.0.0", - "pumpify": "^1.3.3", - "stream-each": "^1.1.0", - "through2": "^2.0.0" + "is-wsl": "^2.1.0" } }, - "mixin-deep": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/mixin-deep/-/mixin-deep-1.3.2.tgz", - "integrity": "sha512-WRoDn//mXBiJ1H40rqa3vH0toePwSsGb45iInWlTySa+Uu4k3tYUSxa2v1KqAiLtvlrSzaExqS1gtk96A9zvEA==", + "opn": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/opn/-/opn-5.5.0.tgz", + "integrity": "sha512-PqHpggC9bLV0VeWcdKhkpxY+3JTzetLSqTCWL/z/tFIbI6G8JCjondXklT1JinczLz2Xib62sSp0T/gKT4KksA==", "dev": true, "requires": { - "for-in": "^1.0.2", - "is-extendable": "^1.0.1" + "is-wsl": "^1.1.0" }, "dependencies": { - "is-extendable": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", - "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", - "dev": true, - "requires": { - "is-plain-object": "^2.0.4" - } + "is-wsl": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-1.1.0.tgz", + "integrity": "sha1-HxbkqiKwTRM2tmGIpmrzxgDDpm0=", + "dev": true } } }, - "mkdirp": { - "version": "0.5.1", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz", - "integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=", + "optimist": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/optimist/-/optimist-0.6.1.tgz", + "integrity": "sha1-2j6nRob6IaGaERwybpDrFaAZZoY=", "dev": true, "requires": { - "minimist": "0.0.8" + "minimist": "~0.0.1", + "wordwrap": "~0.0.2" }, "dependencies": { "minimist": { - "version": "0.0.8", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz", - "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=", + "version": "0.0.10", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.10.tgz", + "integrity": "sha1-3j+YVD2/lggr5IrRoMfNqDYwHc8=", "dev": true } } }, - "move-concurrently": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/move-concurrently/-/move-concurrently-1.0.1.tgz", - "integrity": "sha1-viwAX9oy4LKa8fBdfEszIUxwH5I=", + "ora": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/ora/-/ora-4.0.2.tgz", + "integrity": "sha512-YUOZbamht5mfLxPmk4M35CD/5DuOkAacxlEUbStVXpBAt4fyhBf+vZHI/HRkI++QUp3sNoeA2Gw4C+hi4eGSig==", "dev": true, "requires": { - "aproba": "^1.1.1", - "copy-concurrently": "^1.0.0", - "fs-write-stream-atomic": "^1.0.8", - "mkdirp": "^0.5.1", - "rimraf": "^2.5.4", - "run-queue": "^1.0.3" + "chalk": "^2.4.2", + "cli-cursor": "^3.1.0", + "cli-spinners": "^2.2.0", + "is-interactive": "^1.0.0", + "log-symbols": "^3.0.0", + "strip-ansi": "^5.2.0", + "wcwidth": "^1.0.1" + }, + "dependencies": { + "ansi-regex": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", + "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", + "dev": true + }, + "strip-ansi": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", + "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", + "dev": true, + "requires": { + "ansi-regex": "^4.1.0" + } + } } }, - "ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", - "dev": true - }, - "multicast-dns": { - "version": "6.2.3", - "resolved": "https://registry.npmjs.org/multicast-dns/-/multicast-dns-6.2.3.tgz", - "integrity": "sha512-ji6J5enbMyGRHIAkAOu3WdV8nggqviKCEKtXcOqfphZZtQrmHKycfynJ2V7eVPUA4NhJ6V7Wf4TmGbTwKE9B6g==", + "original": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/original/-/original-1.0.2.tgz", + "integrity": "sha512-hyBVl6iqqUOJ8FqRe+l/gS8H+kKYjrEndd5Pm1MfBtsEKA038HkkdbAl/72EAXGyonD/PFsvmVG+EvcIpliMBg==", "dev": true, "requires": { - "dns-packet": "^1.3.1", - "thunky": "^1.0.2" + "url-parse": "^1.4.3" } }, - "multicast-dns-service-types": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/multicast-dns-service-types/-/multicast-dns-service-types-1.1.0.tgz", - "integrity": "sha1-iZ8R2WhuXgXLkbNdXw5jt3PPyQE=", + "os-browserify": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/os-browserify/-/os-browserify-0.3.0.tgz", + "integrity": "sha1-hUNzx/XCMVkU/Jv8a9gjj92h7Cc=", "dev": true }, - "mute-stream": { - "version": "0.0.8", - "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.8.tgz", - "integrity": "sha512-nnbWWOkoWyUsTjKrhgD0dcz22mdkSnpYqbEjIm2nhwhuxlSkpywJmBo8h0ZqJdkp73mb90SssHkN4rsRaBAfAA==", - "dev": true + "os-homedir": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/os-homedir/-/os-homedir-1.0.2.tgz", + "integrity": "sha1-/7xJiDNuDoM94MFox+8VISGqf7M=" }, - "nan": { - "version": "2.14.0", - "resolved": "https://registry.npmjs.org/nan/-/nan-2.14.0.tgz", - "integrity": "sha512-INOFj37C7k3AfaNTtX8RhsTw7qRy7eLET14cROi9+5HAVbbHuIWUHEauBv5qT4Av2tWasiTY1Jw6puUNqRJXQg==", + "os-locale": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/os-locale/-/os-locale-3.1.0.tgz", + "integrity": "sha512-Z8l3R4wYWM40/52Z+S265okfFj8Kt2cC2MKY+xNi3kFs+XGI7WXu/I309QQQYbRW4ijiZ+yxs9pqEhJh0DqW3Q==", "dev": true, - "optional": true + "requires": { + "execa": "^1.0.0", + "lcid": "^2.0.0", + "mem": "^4.0.0" + } }, - "nanomatch": { - "version": "1.2.13", - "resolved": "https://registry.npmjs.org/nanomatch/-/nanomatch-1.2.13.tgz", - "integrity": "sha512-fpoe2T0RbHwBTBUOftAfBPaDEi06ufaUai0mE6Yn1kacc3SnTErfb/h+X94VXzI64rKFHYImXSvdwGGCmwOqCA==", - "dev": true, + "os-tmpdir": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz", + "integrity": "sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ=" + }, + "osenv": { + "version": "0.1.5", + "resolved": "https://registry.npmjs.org/osenv/-/osenv-0.1.5.tgz", + "integrity": "sha512-0CWcCECdMVc2Rw3U5w9ZjqX6ga6ubk1xDVKxtBQPK7wis/0F2r9T6k4ydGYhecl7YUBxBVxhL5oisPsNxAPe2g==", "requires": { - "arr-diff": "^4.0.0", - "array-unique": "^0.3.2", - "define-property": "^2.0.2", - "extend-shallow": "^3.0.2", - "fragment-cache": "^0.2.1", - "is-windows": "^1.0.2", - "kind-of": "^6.0.2", - "object.pick": "^1.3.0", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.1" + "os-homedir": "^1.0.0", + "os-tmpdir": "^1.0.0" } }, - "negotiator": { - "version": "0.6.2", - "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.2.tgz", - "integrity": "sha512-hZXc7K2e+PgeI1eDBe/10Ard4ekbfrrqG8Ep+8Jmf4JID2bNg7NvCPOZN+kfF574pFQI7mum2AUqDidoKqcTOw==", + "p-defer": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/p-defer/-/p-defer-1.0.0.tgz", + "integrity": "sha1-n26xgvbJqozXQwBKfU+WsZaw+ww=", "dev": true }, - "neo-async": { - "version": "2.6.1", - "resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.6.1.tgz", - "integrity": "sha512-iyam8fBuCUpWeKPGpaNMetEocMt364qkCsfL9JuhjXX6dRnguRVOfk2GZaDpPjcOKiiXCPINZC1GczQ7iTq3Zw==", + "p-finally": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/p-finally/-/p-finally-1.0.0.tgz", + "integrity": "sha1-P7z7FbiZpEEjs0ttzBi3JDNqLK4=", "dev": true }, - "nice-try": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/nice-try/-/nice-try-1.0.5.tgz", - "integrity": "sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ==", + "p-is-promise": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/p-is-promise/-/p-is-promise-2.1.0.tgz", + "integrity": "sha512-Y3W0wlRPK8ZMRbNq97l4M5otioeA5lm1z7bkNkxCka8HSPjR0xRWmpCmc9utiaLP9Jb1eD8BgeIxTW4AIF45Pg==", "dev": true }, - "node-fetch-npm": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/node-fetch-npm/-/node-fetch-npm-2.0.3.tgz", - "integrity": "sha512-DgwoKEsqLnFZtk3ap7GWBHcHwnUhsNmQqEDcdjfQ8GofLEFJ081NAd4Uin3R7RFZBWVJCwHISw1oaEqPgSLloA==", + "p-limit": { + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.2.2.tgz", + "integrity": "sha512-WGR+xHecKTr7EbUEhyLSh5Dube9JtdiG78ufaeLxTgpudf/20KqyMioIUZJAezlTIi6evxuoUs9YXc11cU+yzQ==", "dev": true, "requires": { - "encoding": "^0.1.11", - "json-parse-better-errors": "^1.0.0", - "safe-buffer": "^5.1.1" + "p-try": "^2.0.0" } }, - "node-forge": { - "version": "0.9.0", - "resolved": "https://registry.npmjs.org/node-forge/-/node-forge-0.9.0.tgz", - "integrity": "sha512-7ASaDa3pD+lJ3WvXFsxekJQelBKRpne+GOVbLbtHYdd7pFspyeuJHnWfLplGf3SwKGbfs/aYl5V/JCIaHVUKKQ==", - "dev": true + "p-locate": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz", + "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==", + "dev": true, + "requires": { + "p-limit": "^2.0.0" + } }, - "node-libs-browser": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/node-libs-browser/-/node-libs-browser-2.2.1.tgz", - "integrity": "sha512-h/zcD8H9kaDZ9ALUWwlBUDo6TKF8a7qBSCSEGfjTVIYeqsioSKaAX+BN7NgiMGp6iSIXZ3PxgCu8KS3b71YK5Q==", + "p-map": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/p-map/-/p-map-3.0.0.tgz", + "integrity": "sha512-d3qXVTF/s+W+CdJ5A29wywV2n8CQQYahlgz2bFiA+4eVNJbHJodPZ+/gXwPGh0bOqA+j8S+6+ckmvLGPk1QpxQ==", "dev": true, "requires": { - "assert": "^1.1.1", - "browserify-zlib": "^0.2.0", - "buffer": "^4.3.0", - "console-browserify": "^1.1.0", - "constants-browserify": "^1.0.0", - "crypto-browserify": "^3.11.0", - "domain-browser": "^1.1.1", - "events": "^3.0.0", - "https-browserify": "^1.0.0", - "os-browserify": "^0.3.0", - "path-browserify": "0.0.1", - "process": "^0.11.10", - "punycode": "^1.2.4", - "querystring-es3": "^0.2.0", - "readable-stream": "^2.3.3", - "stream-browserify": "^2.0.1", - "stream-http": "^2.7.2", - "string_decoder": "^1.0.0", - "timers-browserify": "^2.0.4", - "tty-browserify": "0.0.0", - "url": "^0.11.0", - "util": "^0.11.0", - "vm-browserify": "^1.0.1" - }, - "dependencies": { - "punycode": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz", - "integrity": "sha1-wNWmOycYgArY4esPpSachN1BhF4=", - "dev": true - } + "aggregate-error": "^3.0.0" } }, - "node-releases": { - "version": "1.1.52", - "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-1.1.52.tgz", - "integrity": "sha512-snSiT1UypkgGt2wxPqS6ImEUICbNCMb31yaxWrOLXjhlt2z2/IBpaOxzONExqSm4y5oLnAqjjRWu+wsDzK5yNQ==", + "p-retry": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/p-retry/-/p-retry-3.0.1.tgz", + "integrity": "sha512-XE6G4+YTTkT2a0UWb2kjZe8xNwf8bIbnqpc/IS/idOBVhyves0mK5OJgeocjx7q5pvX/6m23xuzVPYT1uGM73w==", "dev": true, "requires": { - "semver": "^6.3.0" + "retry": "^0.12.0" } }, - "normalize-package-data": { - "version": "2.5.0", - "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.5.0.tgz", - "integrity": "sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA==", + "p-try": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", + "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", + "dev": true + }, + "pacote": { + "version": "9.5.8", + "resolved": "https://registry.npmjs.org/pacote/-/pacote-9.5.8.tgz", + "integrity": "sha512-0Tl8Oi/K0Lo4MZmH0/6IsT3gpGf9eEAznLXEQPKgPq7FscnbUOyopnVpwXlnQdIbCUaojWy1Wd7VMyqfVsRrIw==", "dev": true, "requires": { - "hosted-git-info": "^2.1.4", - "resolve": "^1.10.0", - "semver": "2 || 3 || 4 || 5", - "validate-npm-package-license": "^3.0.1" + "bluebird": "^3.5.3", + "cacache": "^12.0.2", + "chownr": "^1.1.2", + "figgy-pudding": "^3.5.1", + "get-stream": "^4.1.0", + "glob": "^7.1.3", + "infer-owner": "^1.0.4", + "lru-cache": "^5.1.1", + "make-fetch-happen": "^5.0.0", + "minimatch": "^3.0.4", + "minipass": "^2.3.5", + "mississippi": "^3.0.0", + "mkdirp": "^0.5.1", + "normalize-package-data": "^2.4.0", + "npm-package-arg": "^6.1.0", + "npm-packlist": "^1.1.12", + "npm-pick-manifest": "^3.0.0", + "npm-registry-fetch": "^4.0.0", + "osenv": "^0.1.5", + "promise-inflight": "^1.0.1", + "promise-retry": "^1.1.1", + "protoduck": "^5.0.1", + "rimraf": "^2.6.2", + "safe-buffer": "^5.1.2", + "semver": "^5.6.0", + "ssri": "^6.0.1", + "tar": "^4.4.10", + "unique-filename": "^1.1.1", + "which": "^1.3.1" }, "dependencies": { + "cacache": { + "version": "12.0.3", + "resolved": "https://registry.npmjs.org/cacache/-/cacache-12.0.3.tgz", + "integrity": "sha512-kqdmfXEGFepesTuROHMs3MpFLWrPkSSpRqOw80RCflZXy/khxaArvFrQ7uJxSUduzAufc6G0g1VUCOZXxWavPw==", + "dev": true, + "requires": { + "bluebird": "^3.5.5", + "chownr": "^1.1.1", + "figgy-pudding": "^3.5.1", + "glob": "^7.1.4", + "graceful-fs": "^4.1.15", + "infer-owner": "^1.0.3", + "lru-cache": "^5.1.1", + "mississippi": "^3.0.0", + "mkdirp": "^0.5.1", + "move-concurrently": "^1.0.1", + "promise-inflight": "^1.0.1", + "rimraf": "^2.6.3", + "ssri": "^6.0.1", + "unique-filename": "^1.1.1", + "y18n": "^4.0.0" + } + }, + "minipass": { + "version": "2.9.0", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-2.9.0.tgz", + "integrity": "sha512-wxfUjg9WebH+CUDX/CdbRlh5SmfZiy/hpkxaRI16Y9W56Pa75sWgd/rvFilSgrauD9NyFymP/+JFV3KwzIsJeg==", + "dev": true, + "requires": { + "safe-buffer": "^5.1.2", + "yallist": "^3.0.0" + } + }, "semver": { "version": "5.7.1", "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", "dev": true + }, + "ssri": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/ssri/-/ssri-6.0.1.tgz", + "integrity": "sha512-3Wge10hNcT1Kur4PDFwEieXSCMCJs/7WvSACcrMYrNp+b8kDL1/0wJch5Ni2WrtwEa2IO8OsVfeKIciKCDx/QA==", + "dev": true, + "requires": { + "figgy-pudding": "^3.5.1" + } + }, + "yallist": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", + "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==", + "dev": true } } }, - "normalize-path": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", - "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", - "dev": true - }, - "normalize-range": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/normalize-range/-/normalize-range-0.1.2.tgz", - "integrity": "sha1-LRDAa9/TEuqXd2laTShDlFa3WUI=", + "pako": { + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/pako/-/pako-1.0.11.tgz", + "integrity": "sha512-4hLB8Py4zZce5s4yd9XzopqwVv/yGNhV1Bl8NTmCq1763HeK2+EwVTv+leGeL13Dnh2wfbqowVPXCIO0z4taYw==", "dev": true }, - "normalize-url": { - "version": "1.9.1", - "resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-1.9.1.tgz", - "integrity": "sha1-LMDWazHqIwNkWENuNiDYWVTGbDw=", + "parallel-transform": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/parallel-transform/-/parallel-transform-1.2.0.tgz", + "integrity": "sha512-P2vSmIu38uIlvdcU7fDkyrxj33gTUy/ABO5ZUbGowxNCopBq/OoD42bP4UmMrJoPyk4Uqf0mu3mtWBhHCZD8yg==", "dev": true, "requires": { - "object-assign": "^4.0.1", - "prepend-http": "^1.0.0", - "query-string": "^4.1.0", - "sort-keys": "^1.0.0" + "cyclist": "^1.0.1", + "inherits": "^2.0.3", + "readable-stream": "^2.1.5" } }, - "npm-bundled": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/npm-bundled/-/npm-bundled-1.1.1.tgz", - "integrity": "sha512-gqkfgGePhTpAEgUsGEgcq1rqPXA+tv/aVBlgEzfXwA1yiUJF7xtEt3CtVwOjNYQOVknDk0F20w58Fnm3EtG0fA==", - "dev": true, + "param-case": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/param-case/-/param-case-2.1.1.tgz", + "integrity": "sha1-35T9jPZTHs915r75oIWPvHK+Ikc=", "requires": { - "npm-normalize-package-bin": "^1.0.1" + "no-case": "^2.2.0" } }, - "npm-normalize-package-bin": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/npm-normalize-package-bin/-/npm-normalize-package-bin-1.0.1.tgz", - "integrity": "sha512-EPfafl6JL5/rU+ot6P3gRSCpPDW5VmIzX959Ob1+ySFUuuYHWHekXpwdUZcKP5C+DS4GEtdJluwBjnsNDl+fSA==", - "dev": true - }, - "npm-package-arg": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/npm-package-arg/-/npm-package-arg-6.1.0.tgz", - "integrity": "sha512-zYbhP2k9DbJhA0Z3HKUePUgdB1x7MfIfKssC+WLPFMKTBZKpZh5m13PgexJjCq6KW7j17r0jHWcCpxEqnnncSA==", + "parse-asn1": { + "version": "5.1.5", + "resolved": "https://registry.npmjs.org/parse-asn1/-/parse-asn1-5.1.5.tgz", + "integrity": "sha512-jkMYn1dcJqF6d5CpU689bq7w/b5ALS9ROVSpQDPrZsqqesUJii9qutvoT5ltGedNXMO2e16YUWIghG9KxaViTQ==", "dev": true, "requires": { - "hosted-git-info": "^2.6.0", - "osenv": "^0.1.5", - "semver": "^5.5.0", - "validate-npm-package-name": "^3.0.0" - }, - "dependencies": { - "semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", - "dev": true - } + "asn1.js": "^4.0.0", + "browserify-aes": "^1.0.0", + "create-hash": "^1.1.0", + "evp_bytestokey": "^1.0.0", + "pbkdf2": "^3.0.3", + "safe-buffer": "^5.1.1" } }, - "npm-packlist": { - "version": "1.4.8", - "resolved": "https://registry.npmjs.org/npm-packlist/-/npm-packlist-1.4.8.tgz", - "integrity": "sha512-5+AZgwru5IevF5ZdnFglB5wNlHG1AOOuw28WhUq8/8emhBmLv6jX5by4WJCh7lW0uSYZYS6DXqIsyZVIXRZU9A==", + "parse-json": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-4.0.0.tgz", + "integrity": "sha1-vjX1Qlvh9/bHRxhPmKeIy5lHfuA=", "dev": true, "requires": { - "ignore-walk": "^3.0.1", - "npm-bundled": "^1.0.1", - "npm-normalize-package-bin": "^1.0.1" + "error-ex": "^1.3.1", + "json-parse-better-errors": "^1.0.1" } }, - "npm-pick-manifest": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/npm-pick-manifest/-/npm-pick-manifest-3.0.2.tgz", - "integrity": "sha512-wNprTNg+X5nf+tDi+hbjdHhM4bX+mKqv6XmPh7B5eG+QY9VARfQPfCEH013H5GqfNj6ee8Ij2fg8yk0mzps1Vw==", - "dev": true, - "requires": { - "figgy-pudding": "^3.5.1", - "npm-package-arg": "^6.0.0", - "semver": "^5.4.1" - }, - "dependencies": { - "semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", - "dev": true - } - } + "parse5": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/parse5/-/parse5-5.1.1.tgz", + "integrity": "sha512-ugq4DFI0Ptb+WWjAdOK16+u/nHfiIrcE+sh8kZMaM0WllQKLI9rOUq6c2b7cwPkXdzfQESqvoqK6ug7U/Yyzug==", + "optional": true }, - "npm-registry-fetch": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/npm-registry-fetch/-/npm-registry-fetch-4.0.3.tgz", - "integrity": "sha512-WGvUx0lkKFhu9MbiGFuT9nG2NpfQ+4dCJwRwwtK2HK5izJEvwDxMeUyqbuMS7N/OkpVCqDorV6rO5E4V9F8lJw==", + "parseqs": { + "version": "0.0.5", + "resolved": "https://registry.npmjs.org/parseqs/-/parseqs-0.0.5.tgz", + "integrity": "sha1-1SCKNzjkZ2bikbouoXNoSSGouJ0=", "dev": true, "requires": { - "JSONStream": "^1.3.4", - "bluebird": "^3.5.1", - "figgy-pudding": "^3.4.1", - "lru-cache": "^5.1.1", - "make-fetch-happen": "^5.0.0", - "npm-package-arg": "^6.1.0", - "safe-buffer": "^5.2.0" - }, - "dependencies": { - "safe-buffer": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.0.tgz", - "integrity": "sha512-fZEwUGbVl7kouZs1jCdMLdt95hdIv0ZeHg6L7qPeciMZhZ+/gdesW4wgTARkrFWEpspjEATAzUGPG8N2jJiwbg==", - "dev": true - } + "better-assert": "~1.0.0" } }, - "npm-run-path": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-2.0.2.tgz", - "integrity": "sha1-NakjLfo11wZ7TLLd8jV7GHFTbF8=", + "parseuri": { + "version": "0.0.5", + "resolved": "https://registry.npmjs.org/parseuri/-/parseuri-0.0.5.tgz", + "integrity": "sha1-gCBKUNTbt3m/3G6+J3jZDkvOMgo=", "dev": true, "requires": { - "path-key": "^2.0.0" + "better-assert": "~1.0.0" } }, - "num2fraction": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/num2fraction/-/num2fraction-1.2.2.tgz", - "integrity": "sha1-b2gragJ6Tp3fpFZM0lidHU5mnt4=", + "parseurl": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", + "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==", "dev": true }, - "number-is-nan": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/number-is-nan/-/number-is-nan-1.0.1.tgz", - "integrity": "sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0=", + "pascalcase": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/pascalcase/-/pascalcase-0.1.1.tgz", + "integrity": "sha1-s2PlXoAGym/iF4TS2yK9FdeRfxQ=", "dev": true }, - "oauth-sign": { - "version": "0.9.0", - "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.9.0.tgz", - "integrity": "sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ==", + "path-browserify": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/path-browserify/-/path-browserify-0.0.1.tgz", + "integrity": "sha512-BapA40NHICOS+USX9SN4tyhq+A2RrN/Ws5F0Z5aMHDp98Fl86lX8Oti8B7uN93L4Ifv4fHOEA+pQw87gmMO/lQ==", "dev": true }, - "object-assign": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", - "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=", + "path-dirname": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/path-dirname/-/path-dirname-1.0.2.tgz", + "integrity": "sha1-zDPSTVJeCZpTiMAzbG4yuRYGCeA=", "dev": true }, - "object-component": { - "version": "0.0.3", - "resolved": "https://registry.npmjs.org/object-component/-/object-component-0.0.3.tgz", - "integrity": "sha1-8MaapQ78lbhmwYb0AKM3acsvEpE=", + "path-exists": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", + "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=", "dev": true }, - "object-copy": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/object-copy/-/object-copy-0.1.0.tgz", - "integrity": "sha1-fn2Fi3gb18mRpBupde04EnVOmYw=", - "dev": true, - "requires": { - "copy-descriptor": "^0.1.0", - "define-property": "^0.2.5", - "kind-of": "^3.0.3" - }, - "dependencies": { - "define-property": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", - "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", - "dev": true, - "requires": { - "is-descriptor": "^0.1.0" - } - }, - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } + "path-is-absolute": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=" }, - "object-inspect": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.7.0.tgz", - "integrity": "sha512-a7pEHdh1xKIAgTySUGgLMx/xwDZskN1Ud6egYYN3EdRW4ZMPNEDUTF+hwy2LUC+Bl+SyLXANnwz/jyh/qutKUw==", + "path-is-inside": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/path-is-inside/-/path-is-inside-1.0.2.tgz", + "integrity": "sha1-NlQX3t5EQw0cEa9hAn+s8HS9/FM=", "dev": true }, - "object-is": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/object-is/-/object-is-1.0.2.tgz", - "integrity": "sha512-Epah+btZd5wrrfjkJZq1AOB9O6OxUQto45hzFd7lXGrpHPGE0W1k+426yrZV+k6NJOzLNNW/nVsmZdIWsAqoOQ==", + "path-key": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz", + "integrity": "sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A=", "dev": true }, - "object-keys": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", - "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==", + "path-parse": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.6.tgz", + "integrity": "sha512-GSmOT2EbHrINBf9SR7CDELwlJ8AENk3Qn7OikK4nFYAu3Ote2+JYNVvkpAEQm3/TLNEJFD/xZJjzyxg3KBWOzw==" + }, + "path-to-regexp": { + "version": "0.1.7", + "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz", + "integrity": "sha1-32BBeABfUi8V60SQ5yR6G/qmf4w=", "dev": true }, - "object-visit": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/object-visit/-/object-visit-1.0.1.tgz", - "integrity": "sha1-95xEk68MU3e1n+OdOV5BBC3QRbs=", + "path-type": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-3.0.0.tgz", + "integrity": "sha512-T2ZUsdZFHgA3u4e5PfPbjd7HDDpxPnQb5jN0SrDsjNSuVXHJqtwTnWqG0B1jZrgmJ/7lj1EmVIByWt1gxGkWvg==", "dev": true, "requires": { - "isobject": "^3.0.0" + "pify": "^3.0.0" + }, + "dependencies": { + "pify": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz", + "integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=", + "dev": true + } } }, - "object.assign": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.0.tgz", - "integrity": "sha512-exHJeq6kBKj58mqGyTQ9DFvrZC/eR6OwxzoM9YRoGBqrXYonaFyGiFMuc9VZrXf7DarreEwMpurG3dd+CNyW5w==", + "pbkdf2": { + "version": "3.0.17", + "resolved": "https://registry.npmjs.org/pbkdf2/-/pbkdf2-3.0.17.tgz", + "integrity": "sha512-U/il5MsrZp7mGg3mSQfn742na2T+1/vHDCG5/iTI3X9MKUuYUZVLQhyRsg06mCgDBTd57TxzgZt7P+fYfjRLtA==", "dev": true, "requires": { - "define-properties": "^1.1.2", - "function-bind": "^1.1.1", - "has-symbols": "^1.0.0", - "object-keys": "^1.0.11" + "create-hash": "^1.1.2", + "create-hmac": "^1.1.4", + "ripemd160": "^2.0.1", + "safe-buffer": "^5.0.1", + "sha.js": "^2.4.8" } }, - "object.getownpropertydescriptors": { + "performance-now": { "version": "2.1.0", - "resolved": "https://registry.npmjs.org/object.getownpropertydescriptors/-/object.getownpropertydescriptors-2.1.0.tgz", - "integrity": "sha512-Z53Oah9A3TdLoblT7VKJaTDdXdT+lQO+cNpKVnya5JDe9uLvzu1YyY1yFDFrcxrlRgWrEFH0jJtD/IbuwjcEVg==", - "dev": true, + "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz", + "integrity": "sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns=" + }, + "picomatch": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.2.1.tgz", + "integrity": "sha512-ISBaA8xQNmwELC7eOjqFKMESB2VIqt4PPDD0nsS95b/9dZXvVKOlz9keMSnoGGKcOHXfTvDD6WMaRoSc9UuhRA==", + "dev": true + }, + "pify": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/pify/-/pify-4.0.1.tgz", + "integrity": "sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==", + "dev": true + }, + "pinkie": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/pinkie/-/pinkie-2.0.4.tgz", + "integrity": "sha1-clVrgM+g1IqXToDnckjoDtT3+HA=" + }, + "pinkie-promise": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/pinkie-promise/-/pinkie-promise-2.0.1.tgz", + "integrity": "sha1-ITXW36ejWMBprJsXh3YogihFD/o=", "requires": { - "define-properties": "^1.1.3", - "es-abstract": "^1.17.0-next.1" + "pinkie": "^2.0.0" } }, - "object.pick": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/object.pick/-/object.pick-1.3.0.tgz", - "integrity": "sha1-h6EKxMFpS9Lhy/U1kaZhQftd10c=", + "pkg-dir": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-3.0.0.tgz", + "integrity": "sha512-/E57AYkoeQ25qkxMj5PBOVgF8Kiu/h7cYS30Z5+R7WaiCCBfLq58ZI/dSeaEKb9WVJV5n/03QwrN3IeWIFllvw==", "dev": true, "requires": { - "isobject": "^3.0.1" + "find-up": "^3.0.0" } }, - "obuf": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/obuf/-/obuf-1.1.2.tgz", - "integrity": "sha512-PX1wu0AmAdPqOL1mWhqmlOd8kOIZQwGZw6rh7uby9fTc5lhaOWFLX3I6R1hrF9k3zUY40e6igsLGkDXK92LJNg==", - "dev": true - }, - "on-finished": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.3.0.tgz", - "integrity": "sha1-IPEzZIGwg811M3mSoWlxqi2QaUc=", + "pkg-up": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/pkg-up/-/pkg-up-3.1.0.tgz", + "integrity": "sha512-nDywThFk1i4BQK4twPQ6TA4RT8bDY96yeuCVBWL3ePARCiEKDRSrNGbFIgUJpLp+XeIR65v8ra7WuJOFUBtkMA==", "dev": true, "requires": { - "ee-first": "1.1.1" + "find-up": "^3.0.0" } }, - "on-headers": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/on-headers/-/on-headers-1.0.2.tgz", - "integrity": "sha512-pZAE+FJLoyITytdqK0U5s+FIpjN0JP3OzFi/u8Rx+EV5/W+JTWGXG8xFzevE7AjBfDqHv/8vL8qQsIhHnqRkrA==", - "dev": true - }, - "once": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", - "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", + "portfinder": { + "version": "1.0.25", + "resolved": "https://registry.npmjs.org/portfinder/-/portfinder-1.0.25.tgz", + "integrity": "sha512-6ElJnHBbxVA1XSLgBp7G1FiCkQdlqGzuF7DswL5tcea+E8UpuvPU7beVAjjRwCioTS9ZluNbu+ZyRvgTsmqEBg==", "dev": true, "requires": { - "wrappy": "1" + "async": "^2.6.2", + "debug": "^3.1.1", + "mkdirp": "^0.5.1" + }, + "dependencies": { + "debug": { + "version": "3.2.6", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.6.tgz", + "integrity": "sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ==", + "dev": true, + "requires": { + "ms": "^2.1.1" + } + } } }, - "onetime": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.0.tgz", - "integrity": "sha512-5NcSkPHhwTVFIQN+TUqXoS5+dlElHXdpAWu9I0HP20YOtIi+aZ0Ct82jdlILDxjLEAWwvm+qj1m6aEtsDVmm6Q==", + "posix-character-classes": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/posix-character-classes/-/posix-character-classes-0.1.1.tgz", + "integrity": "sha1-AerA/jta9xoqbAL+q7jB/vfgDqs=", + "dev": true + }, + "postcss": { + "version": "7.0.21", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.21.tgz", + "integrity": "sha512-uIFtJElxJo29QC753JzhidoAhvp/e/Exezkdhfmt8AymWT6/5B7W1WmponYWkHk2eg6sONyTch0A3nkMPun3SQ==", "dev": true, "requires": { - "mimic-fn": "^2.1.0" + "chalk": "^2.4.2", + "source-map": "^0.6.1", + "supports-color": "^6.1.0" + }, + "dependencies": { + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true + }, + "supports-color": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-6.1.0.tgz", + "integrity": "sha512-qe1jfm1Mg7Nq/NSh6XE24gPXROEVsWHxC1LIx//XNlD9iw7YZQGjZNjYN7xGaEG6iKdA8EtNFW6R0gjnVXp+wQ==", + "dev": true, + "requires": { + "has-flag": "^3.0.0" + } + } } }, - "open": { - "version": "6.4.0", - "resolved": "https://registry.npmjs.org/open/-/open-6.4.0.tgz", - "integrity": "sha512-IFenVPgF70fSm1keSd2iDBIDIBZkroLeuffXq+wKTzTJlBpesFWojV9lb8mzOfaAzM1sr7HQHuO0vtV0zYekGg==", + "postcss-calc": { + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/postcss-calc/-/postcss-calc-7.0.2.tgz", + "integrity": "sha512-rofZFHUg6ZIrvRwPeFktv06GdbDYLcGqh9EwiMutZg+a0oePCCw1zHOEiji6LCpyRcjTREtPASuUqeAvYlEVvQ==", "dev": true, "requires": { - "is-wsl": "^1.1.0" + "postcss": "^7.0.27", + "postcss-selector-parser": "^6.0.2", + "postcss-value-parser": "^4.0.2" + }, + "dependencies": { + "postcss": { + "version": "7.0.27", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.27.tgz", + "integrity": "sha512-WuQETPMcW9Uf1/22HWUWP9lgsIC+KEHg2kozMflKjbeUtw9ujvFX6QmIfozaErDkmLWS9WEnEdEe6Uo9/BNTdQ==", + "dev": true, + "requires": { + "chalk": "^2.4.2", + "source-map": "^0.6.1", + "supports-color": "^6.1.0" + } + }, + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true + }, + "supports-color": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-6.1.0.tgz", + "integrity": "sha512-qe1jfm1Mg7Nq/NSh6XE24gPXROEVsWHxC1LIx//XNlD9iw7YZQGjZNjYN7xGaEG6iKdA8EtNFW6R0gjnVXp+wQ==", + "dev": true, + "requires": { + "has-flag": "^3.0.0" + } + } } }, - "opn": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/opn/-/opn-5.5.0.tgz", - "integrity": "sha512-PqHpggC9bLV0VeWcdKhkpxY+3JTzetLSqTCWL/z/tFIbI6G8JCjondXklT1JinczLz2Xib62sSp0T/gKT4KksA==", + "postcss-colormin": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/postcss-colormin/-/postcss-colormin-4.0.3.tgz", + "integrity": "sha512-WyQFAdDZpExQh32j0U0feWisZ0dmOtPl44qYmJKkq9xFWY3p+4qnRzCHeNrkeRhwPHz9bQ3mo0/yVkaply0MNw==", "dev": true, "requires": { - "is-wsl": "^1.1.0" + "browserslist": "^4.0.0", + "color": "^3.0.0", + "has": "^1.0.0", + "postcss": "^7.0.0", + "postcss-value-parser": "^3.0.0" + }, + "dependencies": { + "postcss-value-parser": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz", + "integrity": "sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ==", + "dev": true + } } }, - "optimist": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/optimist/-/optimist-0.6.1.tgz", - "integrity": "sha1-2j6nRob6IaGaERwybpDrFaAZZoY=", + "postcss-convert-values": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/postcss-convert-values/-/postcss-convert-values-4.0.1.tgz", + "integrity": "sha512-Kisdo1y77KUC0Jmn0OXU/COOJbzM8cImvw1ZFsBgBgMgb1iL23Zs/LXRe3r+EZqM3vGYKdQ2YJVQ5VkJI+zEJQ==", "dev": true, "requires": { - "minimist": "~0.0.1", - "wordwrap": "~0.0.2" + "postcss": "^7.0.0", + "postcss-value-parser": "^3.0.0" }, "dependencies": { - "minimist": { - "version": "0.0.10", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.10.tgz", - "integrity": "sha1-3j+YVD2/lggr5IrRoMfNqDYwHc8=", + "postcss-value-parser": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz", + "integrity": "sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ==", "dev": true } } }, - "original": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/original/-/original-1.0.2.tgz", - "integrity": "sha512-hyBVl6iqqUOJ8FqRe+l/gS8H+kKYjrEndd5Pm1MfBtsEKA038HkkdbAl/72EAXGyonD/PFsvmVG+EvcIpliMBg==", + "postcss-discard-comments": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/postcss-discard-comments/-/postcss-discard-comments-4.0.2.tgz", + "integrity": "sha512-RJutN259iuRf3IW7GZyLM5Sw4GLTOH8FmsXBnv8Ab/Tc2k4SR4qbV4DNbyyY4+Sjo362SyDmW2DQ7lBSChrpkg==", "dev": true, "requires": { - "url-parse": "^1.4.3" + "postcss": "^7.0.0" } }, - "os-browserify": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/os-browserify/-/os-browserify-0.3.0.tgz", - "integrity": "sha1-hUNzx/XCMVkU/Jv8a9gjj92h7Cc=", - "dev": true - }, - "os-homedir": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/os-homedir/-/os-homedir-1.0.2.tgz", - "integrity": "sha1-/7xJiDNuDoM94MFox+8VISGqf7M=", - "dev": true - }, - "os-locale": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/os-locale/-/os-locale-3.1.0.tgz", - "integrity": "sha512-Z8l3R4wYWM40/52Z+S265okfFj8Kt2cC2MKY+xNi3kFs+XGI7WXu/I309QQQYbRW4ijiZ+yxs9pqEhJh0DqW3Q==", + "postcss-discard-duplicates": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/postcss-discard-duplicates/-/postcss-discard-duplicates-4.0.2.tgz", + "integrity": "sha512-ZNQfR1gPNAiXZhgENFfEglF93pciw0WxMkJeVmw8eF+JZBbMD7jp6C67GqJAXVZP2BWbOztKfbsdmMp/k8c6oQ==", "dev": true, "requires": { - "execa": "^1.0.0", - "lcid": "^2.0.0", - "mem": "^4.0.0" + "postcss": "^7.0.0" } }, - "os-tmpdir": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz", - "integrity": "sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ=", - "dev": true - }, - "osenv": { - "version": "0.1.5", - "resolved": "https://registry.npmjs.org/osenv/-/osenv-0.1.5.tgz", - "integrity": "sha512-0CWcCECdMVc2Rw3U5w9ZjqX6ga6ubk1xDVKxtBQPK7wis/0F2r9T6k4ydGYhecl7YUBxBVxhL5oisPsNxAPe2g==", + "postcss-discard-empty": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/postcss-discard-empty/-/postcss-discard-empty-4.0.1.tgz", + "integrity": "sha512-B9miTzbznhDjTfjvipfHoqbWKwd0Mj+/fL5s1QOz06wufguil+Xheo4XpOnc4NqKYBCNqqEzgPv2aPBIJLox0w==", "dev": true, "requires": { - "os-homedir": "^1.0.0", - "os-tmpdir": "^1.0.0" + "postcss": "^7.0.0" } }, - "p-defer": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/p-defer/-/p-defer-1.0.0.tgz", - "integrity": "sha1-n26xgvbJqozXQwBKfU+WsZaw+ww=", - "dev": true - }, - "p-finally": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/p-finally/-/p-finally-1.0.0.tgz", - "integrity": "sha1-P7z7FbiZpEEjs0ttzBi3JDNqLK4=", - "dev": true - }, - "p-is-promise": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/p-is-promise/-/p-is-promise-2.1.0.tgz", - "integrity": "sha512-Y3W0wlRPK8ZMRbNq97l4M5otioeA5lm1z7bkNkxCka8HSPjR0xRWmpCmc9utiaLP9Jb1eD8BgeIxTW4AIF45Pg==", - "dev": true - }, - "p-limit": { - "version": "2.2.2", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.2.2.tgz", - "integrity": "sha512-WGR+xHecKTr7EbUEhyLSh5Dube9JtdiG78ufaeLxTgpudf/20KqyMioIUZJAezlTIi6evxuoUs9YXc11cU+yzQ==", + "postcss-discard-overridden": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/postcss-discard-overridden/-/postcss-discard-overridden-4.0.1.tgz", + "integrity": "sha512-IYY2bEDD7g1XM1IDEsUT4//iEYCxAmP5oDSFMVU/JVvT7gh+l4fmjciLqGgwjdWpQIdb0Che2VX00QObS5+cTg==", "dev": true, "requires": { - "p-try": "^2.0.0" + "postcss": "^7.0.0" } }, - "p-locate": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz", - "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==", + "postcss-import": { + "version": "12.0.1", + "resolved": "https://registry.npmjs.org/postcss-import/-/postcss-import-12.0.1.tgz", + "integrity": "sha512-3Gti33dmCjyKBgimqGxL3vcV8w9+bsHwO5UrBawp796+jdardbcFl4RP5w/76BwNL7aGzpKstIfF9I+kdE8pTw==", "dev": true, "requires": { - "p-limit": "^2.0.0" + "postcss": "^7.0.1", + "postcss-value-parser": "^3.2.3", + "read-cache": "^1.0.0", + "resolve": "^1.1.7" + }, + "dependencies": { + "postcss-value-parser": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz", + "integrity": "sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ==", + "dev": true + } } }, - "p-map": { + "postcss-load-config": { "version": "2.1.0", - "resolved": "https://registry.npmjs.org/p-map/-/p-map-2.1.0.tgz", - "integrity": "sha512-y3b8Kpd8OAN444hxfBbFfj1FY/RjtTd8tzYwhUqNYXx0fXx2iX4maP4Qr6qhIKbQXI02wTLAda4fYUbDagTUFw==", - "dev": true - }, - "p-retry": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/p-retry/-/p-retry-3.0.1.tgz", - "integrity": "sha512-XE6G4+YTTkT2a0UWb2kjZe8xNwf8bIbnqpc/IS/idOBVhyves0mK5OJgeocjx7q5pvX/6m23xuzVPYT1uGM73w==", + "resolved": "https://registry.npmjs.org/postcss-load-config/-/postcss-load-config-2.1.0.tgz", + "integrity": "sha512-4pV3JJVPLd5+RueiVVB+gFOAa7GWc25XQcMp86Zexzke69mKf6Nx9LRcQywdz7yZI9n1udOxmLuAwTBypypF8Q==", "dev": true, "requires": { - "retry": "^0.12.0" + "cosmiconfig": "^5.0.0", + "import-cwd": "^2.0.0" } }, - "p-try": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", - "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", - "dev": true + "postcss-loader": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/postcss-loader/-/postcss-loader-3.0.0.tgz", + "integrity": "sha512-cLWoDEY5OwHcAjDnkyRQzAXfs2jrKjXpO/HQFcc5b5u/r7aa471wdmChmwfnv7x2u840iat/wi0lQ5nbRgSkUA==", + "dev": true, + "requires": { + "loader-utils": "^1.1.0", + "postcss": "^7.0.0", + "postcss-load-config": "^2.0.0", + "schema-utils": "^1.0.0" + } }, - "pacote": { - "version": "9.5.5", - "resolved": "https://registry.npmjs.org/pacote/-/pacote-9.5.5.tgz", - "integrity": "sha512-jAEP+Nqj4kyMWyNpfTU/Whx1jA7jEc5cCOlurm0/0oL+v8TAp1QSsK83N7bYe+2bEdFzMAtPG5TBebjzzGV0cA==", + "postcss-merge-longhand": { + "version": "4.0.11", + "resolved": "https://registry.npmjs.org/postcss-merge-longhand/-/postcss-merge-longhand-4.0.11.tgz", + "integrity": "sha512-alx/zmoeXvJjp7L4mxEMjh8lxVlDFX1gqWHzaaQewwMZiVhLo42TEClKaeHbRf6J7j82ZOdTJ808RtN0ZOZwvw==", "dev": true, "requires": { - "bluebird": "^3.5.3", - "cacache": "^12.0.2", - "figgy-pudding": "^3.5.1", - "get-stream": "^4.1.0", - "glob": "^7.1.3", - "infer-owner": "^1.0.4", - "lru-cache": "^5.1.1", - "make-fetch-happen": "^5.0.0", - "minimatch": "^3.0.4", - "minipass": "^2.3.5", - "mississippi": "^3.0.0", - "mkdirp": "^0.5.1", - "normalize-package-data": "^2.4.0", - "npm-package-arg": "^6.1.0", - "npm-packlist": "^1.1.12", - "npm-pick-manifest": "^2.2.3", - "npm-registry-fetch": "^4.0.0", - "osenv": "^0.1.5", - "promise-inflight": "^1.0.1", - "promise-retry": "^1.1.1", - "protoduck": "^5.0.1", - "rimraf": "^2.6.2", - "safe-buffer": "^5.1.2", - "semver": "^5.6.0", - "ssri": "^6.0.1", - "tar": "^4.4.8", - "unique-filename": "^1.1.1", - "which": "^1.3.1" + "css-color-names": "0.0.4", + "postcss": "^7.0.0", + "postcss-value-parser": "^3.0.0", + "stylehacks": "^4.0.0" }, "dependencies": { - "npm-pick-manifest": { - "version": "2.2.3", - "resolved": "https://registry.npmjs.org/npm-pick-manifest/-/npm-pick-manifest-2.2.3.tgz", - "integrity": "sha512-+IluBC5K201+gRU85vFlUwX3PFShZAbAgDNp2ewJdWMVSppdo/Zih0ul2Ecky/X7b51J7LrrUAP+XOmOCvYZqA==", - "dev": true, - "requires": { - "figgy-pudding": "^3.5.1", - "npm-package-arg": "^6.0.0", - "semver": "^5.4.1" - } - }, - "semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", + "postcss-value-parser": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz", + "integrity": "sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ==", "dev": true } } }, - "pako": { - "version": "1.0.11", - "resolved": "https://registry.npmjs.org/pako/-/pako-1.0.11.tgz", - "integrity": "sha512-4hLB8Py4zZce5s4yd9XzopqwVv/yGNhV1Bl8NTmCq1763HeK2+EwVTv+leGeL13Dnh2wfbqowVPXCIO0z4taYw==", - "dev": true - }, - "parallel-transform": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/parallel-transform/-/parallel-transform-1.2.0.tgz", - "integrity": "sha512-P2vSmIu38uIlvdcU7fDkyrxj33gTUy/ABO5ZUbGowxNCopBq/OoD42bP4UmMrJoPyk4Uqf0mu3mtWBhHCZD8yg==", + "postcss-merge-rules": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/postcss-merge-rules/-/postcss-merge-rules-4.0.3.tgz", + "integrity": "sha512-U7e3r1SbvYzO0Jr3UT/zKBVgYYyhAz0aitvGIYOYK5CPmkNih+WDSsS5tvPrJ8YMQYlEMvsZIiqmn7HdFUaeEQ==", "dev": true, "requires": { - "cyclist": "^1.0.1", - "inherits": "^2.0.3", - "readable-stream": "^2.1.5" + "browserslist": "^4.0.0", + "caniuse-api": "^3.0.0", + "cssnano-util-same-parent": "^4.0.0", + "postcss": "^7.0.0", + "postcss-selector-parser": "^3.0.0", + "vendors": "^1.0.0" + }, + "dependencies": { + "postcss-selector-parser": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-3.1.2.tgz", + "integrity": "sha512-h7fJ/5uWuRVyOtkO45pnt1Ih40CEleeyCHzipqAZO2e5H20g25Y48uYnFUiShvY4rZWNJ/Bib/KVPmanaCtOhA==", + "dev": true, + "requires": { + "dot-prop": "^5.2.0", + "indexes-of": "^1.0.1", + "uniq": "^1.0.1" + } + } } }, - "parse-asn1": { - "version": "5.1.5", - "resolved": "https://registry.npmjs.org/parse-asn1/-/parse-asn1-5.1.5.tgz", - "integrity": "sha512-jkMYn1dcJqF6d5CpU689bq7w/b5ALS9ROVSpQDPrZsqqesUJii9qutvoT5ltGedNXMO2e16YUWIghG9KxaViTQ==", + "postcss-minify-font-values": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/postcss-minify-font-values/-/postcss-minify-font-values-4.0.2.tgz", + "integrity": "sha512-j85oO6OnRU9zPf04+PZv1LYIYOprWm6IA6zkXkrJXyRveDEuQggG6tvoy8ir8ZwjLxLuGfNkCZEQG7zan+Hbtg==", "dev": true, "requires": { - "asn1.js": "^4.0.0", - "browserify-aes": "^1.0.0", - "create-hash": "^1.1.0", - "evp_bytestokey": "^1.0.0", - "pbkdf2": "^3.0.3", - "safe-buffer": "^5.1.1" + "postcss": "^7.0.0", + "postcss-value-parser": "^3.0.0" + }, + "dependencies": { + "postcss-value-parser": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz", + "integrity": "sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ==", + "dev": true + } } }, - "parse-json": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-4.0.0.tgz", - "integrity": "sha1-vjX1Qlvh9/bHRxhPmKeIy5lHfuA=", + "postcss-minify-gradients": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/postcss-minify-gradients/-/postcss-minify-gradients-4.0.2.tgz", + "integrity": "sha512-qKPfwlONdcf/AndP1U8SJ/uzIJtowHlMaSioKzebAXSG4iJthlWC9iSWznQcX4f66gIWX44RSA841HTHj3wK+Q==", "dev": true, "requires": { - "error-ex": "^1.3.1", - "json-parse-better-errors": "^1.0.1" + "cssnano-util-get-arguments": "^4.0.0", + "is-color-stop": "^1.0.0", + "postcss": "^7.0.0", + "postcss-value-parser": "^3.0.0" + }, + "dependencies": { + "postcss-value-parser": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz", + "integrity": "sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ==", + "dev": true + } } }, - "parse5": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/parse5/-/parse5-5.1.1.tgz", - "integrity": "sha512-ugq4DFI0Ptb+WWjAdOK16+u/nHfiIrcE+sh8kZMaM0WllQKLI9rOUq6c2b7cwPkXdzfQESqvoqK6ug7U/Yyzug==", - "optional": true - }, - "parseqs": { - "version": "0.0.5", - "resolved": "https://registry.npmjs.org/parseqs/-/parseqs-0.0.5.tgz", - "integrity": "sha1-1SCKNzjkZ2bikbouoXNoSSGouJ0=", + "postcss-minify-params": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/postcss-minify-params/-/postcss-minify-params-4.0.2.tgz", + "integrity": "sha512-G7eWyzEx0xL4/wiBBJxJOz48zAKV2WG3iZOqVhPet/9geefm/Px5uo1fzlHu+DOjT+m0Mmiz3jkQzVHe6wxAWg==", "dev": true, "requires": { - "better-assert": "~1.0.0" + "alphanum-sort": "^1.0.0", + "browserslist": "^4.0.0", + "cssnano-util-get-arguments": "^4.0.0", + "postcss": "^7.0.0", + "postcss-value-parser": "^3.0.0", + "uniqs": "^2.0.0" + }, + "dependencies": { + "postcss-value-parser": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz", + "integrity": "sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ==", + "dev": true + } } }, - "parseuri": { - "version": "0.0.5", - "resolved": "https://registry.npmjs.org/parseuri/-/parseuri-0.0.5.tgz", - "integrity": "sha1-gCBKUNTbt3m/3G6+J3jZDkvOMgo=", + "postcss-minify-selectors": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/postcss-minify-selectors/-/postcss-minify-selectors-4.0.2.tgz", + "integrity": "sha512-D5S1iViljXBj9kflQo4YutWnJmwm8VvIsU1GeXJGiG9j8CIg9zs4voPMdQDUmIxetUOh60VilsNzCiAFTOqu3g==", "dev": true, "requires": { - "better-assert": "~1.0.0" + "alphanum-sort": "^1.0.0", + "has": "^1.0.0", + "postcss": "^7.0.0", + "postcss-selector-parser": "^3.0.0" + }, + "dependencies": { + "postcss-selector-parser": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-3.1.2.tgz", + "integrity": "sha512-h7fJ/5uWuRVyOtkO45pnt1Ih40CEleeyCHzipqAZO2e5H20g25Y48uYnFUiShvY4rZWNJ/Bib/KVPmanaCtOhA==", + "dev": true, + "requires": { + "dot-prop": "^5.2.0", + "indexes-of": "^1.0.1", + "uniq": "^1.0.1" + } + } } }, - "parseurl": { - "version": "1.3.3", - "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", - "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==", - "dev": true - }, - "pascalcase": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/pascalcase/-/pascalcase-0.1.1.tgz", - "integrity": "sha1-s2PlXoAGym/iF4TS2yK9FdeRfxQ=", - "dev": true - }, - "path-browserify": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/path-browserify/-/path-browserify-0.0.1.tgz", - "integrity": "sha512-BapA40NHICOS+USX9SN4tyhq+A2RrN/Ws5F0Z5aMHDp98Fl86lX8Oti8B7uN93L4Ifv4fHOEA+pQw87gmMO/lQ==", - "dev": true - }, - "path-dirname": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/path-dirname/-/path-dirname-1.0.2.tgz", - "integrity": "sha1-zDPSTVJeCZpTiMAzbG4yuRYGCeA=", - "dev": true - }, - "path-exists": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", - "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=", - "dev": true - }, - "path-is-absolute": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", - "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=", - "dev": true - }, - "path-is-inside": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/path-is-inside/-/path-is-inside-1.0.2.tgz", - "integrity": "sha1-NlQX3t5EQw0cEa9hAn+s8HS9/FM=", - "dev": true - }, - "path-key": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz", - "integrity": "sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A=", - "dev": true - }, - "path-parse": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.6.tgz", - "integrity": "sha512-GSmOT2EbHrINBf9SR7CDELwlJ8AENk3Qn7OikK4nFYAu3Ote2+JYNVvkpAEQm3/TLNEJFD/xZJjzyxg3KBWOzw==", - "dev": true + "postcss-normalize-charset": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/postcss-normalize-charset/-/postcss-normalize-charset-4.0.1.tgz", + "integrity": "sha512-gMXCrrlWh6G27U0hF3vNvR3w8I1s2wOBILvA87iNXaPvSNo5uZAMYsZG7XjCUf1eVxuPfyL4TJ7++SGZLc9A3g==", + "dev": true, + "requires": { + "postcss": "^7.0.0" + } }, - "path-to-regexp": { - "version": "0.1.7", - "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz", - "integrity": "sha1-32BBeABfUi8V60SQ5yR6G/qmf4w=", - "dev": true + "postcss-normalize-display-values": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/postcss-normalize-display-values/-/postcss-normalize-display-values-4.0.2.tgz", + "integrity": "sha512-3F2jcsaMW7+VtRMAqf/3m4cPFhPD3EFRgNs18u+k3lTJJlVe7d0YPO+bnwqo2xg8YiRpDXJI2u8A0wqJxMsQuQ==", + "dev": true, + "requires": { + "cssnano-util-get-match": "^4.0.0", + "postcss": "^7.0.0", + "postcss-value-parser": "^3.0.0" + }, + "dependencies": { + "postcss-value-parser": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz", + "integrity": "sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ==", + "dev": true + } + } }, - "path-type": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/path-type/-/path-type-3.0.0.tgz", - "integrity": "sha512-T2ZUsdZFHgA3u4e5PfPbjd7HDDpxPnQb5jN0SrDsjNSuVXHJqtwTnWqG0B1jZrgmJ/7lj1EmVIByWt1gxGkWvg==", + "postcss-normalize-positions": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/postcss-normalize-positions/-/postcss-normalize-positions-4.0.2.tgz", + "integrity": "sha512-Dlf3/9AxpxE+NF1fJxYDeggi5WwV35MXGFnnoccP/9qDtFrTArZ0D0R+iKcg5WsUd8nUYMIl8yXDCtcrT8JrdA==", "dev": true, "requires": { - "pify": "^3.0.0" + "cssnano-util-get-arguments": "^4.0.0", + "has": "^1.0.0", + "postcss": "^7.0.0", + "postcss-value-parser": "^3.0.0" }, "dependencies": { - "pify": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz", - "integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=", + "postcss-value-parser": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz", + "integrity": "sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ==", "dev": true } } }, - "pbkdf2": { - "version": "3.0.17", - "resolved": "https://registry.npmjs.org/pbkdf2/-/pbkdf2-3.0.17.tgz", - "integrity": "sha512-U/il5MsrZp7mGg3mSQfn742na2T+1/vHDCG5/iTI3X9MKUuYUZVLQhyRsg06mCgDBTd57TxzgZt7P+fYfjRLtA==", + "postcss-normalize-repeat-style": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/postcss-normalize-repeat-style/-/postcss-normalize-repeat-style-4.0.2.tgz", + "integrity": "sha512-qvigdYYMpSuoFs3Is/f5nHdRLJN/ITA7huIoCyqqENJe9PvPmLhNLMu7QTjPdtnVf6OcYYO5SHonx4+fbJE1+Q==", "dev": true, "requires": { - "create-hash": "^1.1.2", - "create-hmac": "^1.1.4", - "ripemd160": "^2.0.1", - "safe-buffer": "^5.0.1", - "sha.js": "^2.4.8" + "cssnano-util-get-arguments": "^4.0.0", + "cssnano-util-get-match": "^4.0.0", + "postcss": "^7.0.0", + "postcss-value-parser": "^3.0.0" + }, + "dependencies": { + "postcss-value-parser": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz", + "integrity": "sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ==", + "dev": true + } } }, - "performance-now": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz", - "integrity": "sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns=", - "dev": true + "postcss-normalize-string": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/postcss-normalize-string/-/postcss-normalize-string-4.0.2.tgz", + "integrity": "sha512-RrERod97Dnwqq49WNz8qo66ps0swYZDSb6rM57kN2J+aoyEAJfZ6bMx0sx/F9TIEX0xthPGCmeyiam/jXif0eA==", + "dev": true, + "requires": { + "has": "^1.0.0", + "postcss": "^7.0.0", + "postcss-value-parser": "^3.0.0" + }, + "dependencies": { + "postcss-value-parser": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz", + "integrity": "sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ==", + "dev": true + } + } }, - "picomatch": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.2.1.tgz", - "integrity": "sha512-ISBaA8xQNmwELC7eOjqFKMESB2VIqt4PPDD0nsS95b/9dZXvVKOlz9keMSnoGGKcOHXfTvDD6WMaRoSc9UuhRA==", - "dev": true + "postcss-normalize-timing-functions": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/postcss-normalize-timing-functions/-/postcss-normalize-timing-functions-4.0.2.tgz", + "integrity": "sha512-acwJY95edP762e++00Ehq9L4sZCEcOPyaHwoaFOhIwWCDfik6YvqsYNxckee65JHLKzuNSSmAdxwD2Cud1Z54A==", + "dev": true, + "requires": { + "cssnano-util-get-match": "^4.0.0", + "postcss": "^7.0.0", + "postcss-value-parser": "^3.0.0" + }, + "dependencies": { + "postcss-value-parser": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz", + "integrity": "sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ==", + "dev": true + } + } }, - "pify": { + "postcss-normalize-unicode": { "version": "4.0.1", - "resolved": "https://registry.npmjs.org/pify/-/pify-4.0.1.tgz", - "integrity": "sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==", - "dev": true - }, - "pinkie": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/pinkie/-/pinkie-2.0.4.tgz", - "integrity": "sha1-clVrgM+g1IqXToDnckjoDtT3+HA=", - "dev": true - }, - "pinkie-promise": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/pinkie-promise/-/pinkie-promise-2.0.1.tgz", - "integrity": "sha1-ITXW36ejWMBprJsXh3YogihFD/o=", + "resolved": "https://registry.npmjs.org/postcss-normalize-unicode/-/postcss-normalize-unicode-4.0.1.tgz", + "integrity": "sha512-od18Uq2wCYn+vZ/qCOeutvHjB5jm57ToxRaMeNuf0nWVHaP9Hua56QyMF6fs/4FSUnVIw0CBPsU0K4LnBPwYwg==", "dev": true, "requires": { - "pinkie": "^2.0.0" + "browserslist": "^4.0.0", + "postcss": "^7.0.0", + "postcss-value-parser": "^3.0.0" + }, + "dependencies": { + "postcss-value-parser": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz", + "integrity": "sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ==", + "dev": true + } } }, - "pkg-dir": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-3.0.0.tgz", - "integrity": "sha512-/E57AYkoeQ25qkxMj5PBOVgF8Kiu/h7cYS30Z5+R7WaiCCBfLq58ZI/dSeaEKb9WVJV5n/03QwrN3IeWIFllvw==", + "postcss-normalize-url": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/postcss-normalize-url/-/postcss-normalize-url-4.0.1.tgz", + "integrity": "sha512-p5oVaF4+IHwu7VpMan/SSpmpYxcJMtkGppYf0VbdH5B6hN8YNmVyJLuY9FmLQTzY3fag5ESUUHDqM+heid0UVA==", "dev": true, "requires": { - "find-up": "^3.0.0" + "is-absolute-url": "^2.0.0", + "normalize-url": "^3.0.0", + "postcss": "^7.0.0", + "postcss-value-parser": "^3.0.0" + }, + "dependencies": { + "postcss-value-parser": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz", + "integrity": "sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ==", + "dev": true + } } }, - "portfinder": { - "version": "1.0.25", - "resolved": "https://registry.npmjs.org/portfinder/-/portfinder-1.0.25.tgz", - "integrity": "sha512-6ElJnHBbxVA1XSLgBp7G1FiCkQdlqGzuF7DswL5tcea+E8UpuvPU7beVAjjRwCioTS9ZluNbu+ZyRvgTsmqEBg==", + "postcss-normalize-whitespace": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/postcss-normalize-whitespace/-/postcss-normalize-whitespace-4.0.2.tgz", + "integrity": "sha512-tO8QIgrsI3p95r8fyqKV+ufKlSHh9hMJqACqbv2XknufqEDhDvbguXGBBqxw9nsQoXWf0qOqppziKJKHMD4GtA==", "dev": true, "requires": { - "async": "^2.6.2", - "debug": "^3.1.1", - "mkdirp": "^0.5.1" + "postcss": "^7.0.0", + "postcss-value-parser": "^3.0.0" }, "dependencies": { - "debug": { - "version": "3.2.6", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.6.tgz", - "integrity": "sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ==", - "dev": true, - "requires": { - "ms": "^2.1.1" - } + "postcss-value-parser": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz", + "integrity": "sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ==", + "dev": true } } }, - "posix-character-classes": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/posix-character-classes/-/posix-character-classes-0.1.1.tgz", - "integrity": "sha1-AerA/jta9xoqbAL+q7jB/vfgDqs=", - "dev": true - }, - "postcss": { - "version": "7.0.17", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.17.tgz", - "integrity": "sha512-546ZowA+KZ3OasvQZHsbuEpysvwTZNGJv9EfyCQdsIDltPSWHAeTQ5fQy/Npi2ZDtLI3zs7Ps/p6wThErhm9fQ==", + "postcss-ordered-values": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/postcss-ordered-values/-/postcss-ordered-values-4.1.2.tgz", + "integrity": "sha512-2fCObh5UanxvSxeXrtLtlwVThBvHn6MQcu4ksNT2tsaV2Fg76R2CV98W7wNSlX+5/pFwEyaDwKLLoEV7uRybAw==", "dev": true, "requires": { - "chalk": "^2.4.2", - "source-map": "^0.6.1", - "supports-color": "^6.1.0" + "cssnano-util-get-arguments": "^4.0.0", + "postcss": "^7.0.0", + "postcss-value-parser": "^3.0.0" }, "dependencies": { - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "postcss-value-parser": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz", + "integrity": "sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ==", "dev": true - }, - "supports-color": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-6.1.0.tgz", - "integrity": "sha512-qe1jfm1Mg7Nq/NSh6XE24gPXROEVsWHxC1LIx//XNlD9iw7YZQGjZNjYN7xGaEG6iKdA8EtNFW6R0gjnVXp+wQ==", - "dev": true, - "requires": { - "has-flag": "^3.0.0" - } } } }, - "postcss-import": { - "version": "12.0.1", - "resolved": "https://registry.npmjs.org/postcss-import/-/postcss-import-12.0.1.tgz", - "integrity": "sha512-3Gti33dmCjyKBgimqGxL3vcV8w9+bsHwO5UrBawp796+jdardbcFl4RP5w/76BwNL7aGzpKstIfF9I+kdE8pTw==", + "postcss-reduce-initial": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/postcss-reduce-initial/-/postcss-reduce-initial-4.0.3.tgz", + "integrity": "sha512-gKWmR5aUulSjbzOfD9AlJiHCGH6AEVLaM0AV+aSioxUDd16qXP1PCh8d1/BGVvpdWn8k/HiK7n6TjeoXN1F7DA==", "dev": true, "requires": { - "postcss": "^7.0.1", - "postcss-value-parser": "^3.2.3", - "read-cache": "^1.0.0", - "resolve": "^1.1.7" + "browserslist": "^4.0.0", + "caniuse-api": "^3.0.0", + "has": "^1.0.0", + "postcss": "^7.0.0" + } + }, + "postcss-reduce-transforms": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/postcss-reduce-transforms/-/postcss-reduce-transforms-4.0.2.tgz", + "integrity": "sha512-EEVig1Q2QJ4ELpJXMZR8Vt5DQx8/mo+dGWSR7vWXqcob2gQLyQGsionYcGKATXvQzMPn6DSN1vTN7yFximdIAg==", + "dev": true, + "requires": { + "cssnano-util-get-match": "^4.0.0", + "has": "^1.0.0", + "postcss": "^7.0.0", + "postcss-value-parser": "^3.0.0" }, "dependencies": { "postcss-value-parser": { @@ -8150,26 +9018,46 @@ } } }, - "postcss-load-config": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/postcss-load-config/-/postcss-load-config-2.1.0.tgz", - "integrity": "sha512-4pV3JJVPLd5+RueiVVB+gFOAa7GWc25XQcMp86Zexzke69mKf6Nx9LRcQywdz7yZI9n1udOxmLuAwTBypypF8Q==", + "postcss-selector-parser": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.0.2.tgz", + "integrity": "sha512-36P2QR59jDTOAiIkqEprfJDsoNrvwFei3eCqKd1Y0tUsBimsq39BLp7RD+JWny3WgB1zGhJX8XVePwm9k4wdBg==", "dev": true, "requires": { - "cosmiconfig": "^5.0.0", - "import-cwd": "^2.0.0" + "cssesc": "^3.0.0", + "indexes-of": "^1.0.1", + "uniq": "^1.0.1" } }, - "postcss-loader": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/postcss-loader/-/postcss-loader-3.0.0.tgz", - "integrity": "sha512-cLWoDEY5OwHcAjDnkyRQzAXfs2jrKjXpO/HQFcc5b5u/r7aa471wdmChmwfnv7x2u840iat/wi0lQ5nbRgSkUA==", + "postcss-svgo": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/postcss-svgo/-/postcss-svgo-4.0.2.tgz", + "integrity": "sha512-C6wyjo3VwFm0QgBy+Fu7gCYOkCmgmClghO+pjcxvrcBKtiKt0uCF+hvbMO1fyv5BMImRK90SMb+dwUnfbGd+jw==", "dev": true, "requires": { - "loader-utils": "^1.1.0", + "is-svg": "^3.0.0", "postcss": "^7.0.0", - "postcss-load-config": "^2.0.0", - "schema-utils": "^1.0.0" + "postcss-value-parser": "^3.0.0", + "svgo": "^1.0.0" + }, + "dependencies": { + "postcss-value-parser": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz", + "integrity": "sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ==", + "dev": true + } + } + }, + "postcss-unique-selectors": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/postcss-unique-selectors/-/postcss-unique-selectors-4.0.1.tgz", + "integrity": "sha512-+JanVaryLo9QwZjKrmJgkI4Fn8SBgRO6WXQBJi7KiAVPlmxikB5Jzc4EvXMT2H0/m0RjrVVm9rGNhZddm/8Spg==", + "dev": true, + "requires": { + "alphanum-sort": "^1.0.0", + "postcss": "^7.0.0", + "uniqs": "^2.0.0" } }, "postcss-value-parser": { @@ -8184,6 +9072,15 @@ "integrity": "sha1-1PRWKwzjaW5BrFLQ4ALlemNdxtw=", "dev": true }, + "pretty-error": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/pretty-error/-/pretty-error-2.1.1.tgz", + "integrity": "sha1-X0+HyPkeWuPzuoerTPXgOxoX8aM=", + "requires": { + "renderkid": "^2.0.1", + "utila": "~0.4" + } + }, "private": { "version": "0.1.8", "resolved": "https://registry.npmjs.org/private/-/private-0.1.8.tgz", @@ -8199,8 +9096,7 @@ "process-nextick-args": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", - "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==", - "dev": true + "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==" }, "promise": { "version": "7.3.1", @@ -8413,14 +9309,12 @@ "pseudomap": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/pseudomap/-/pseudomap-1.0.2.tgz", - "integrity": "sha1-8FKijacOYYkX7wqKw0wa5aaChrM=", - "dev": true + "integrity": "sha1-8FKijacOYYkX7wqKw0wa5aaChrM=" }, "psl": { "version": "1.7.0", "resolved": "https://registry.npmjs.org/psl/-/psl-1.7.0.tgz", - "integrity": "sha512-5NsSEDv8zY70ScRnOTn7bK7eanl2MvFrOrS/R6x+dBt5g1ghnj9Zv90kO8GwT8gxcu2ANyFprnFYB85IogIJOQ==", - "dev": true + "integrity": "sha512-5NsSEDv8zY70ScRnOTn7bK7eanl2MvFrOrS/R6x+dBt5g1ghnj9Zv90kO8GwT8gxcu2ANyFprnFYB85IogIJOQ==" }, "public-encrypt": { "version": "4.0.3", @@ -8472,8 +9366,7 @@ "punycode": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", - "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==", - "dev": true + "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==" }, "q": { "version": "1.4.1", @@ -8490,8 +9383,7 @@ "qs": { "version": "6.5.2", "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.2.tgz", - "integrity": "sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA==", - "dev": true + "integrity": "sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA==" }, "query-string": { "version": "4.3.4", @@ -8636,22 +9528,76 @@ "npm-normalize-package-bin": "^1.0.0" } }, - "read-package-tree": { - "version": "5.3.1", - "resolved": "https://registry.npmjs.org/read-package-tree/-/read-package-tree-5.3.1.tgz", - "integrity": "sha512-mLUDsD5JVtlZxjSlPPx1RETkNjjvQYuweKwNVt1Sn8kP5Jh44pvYuUHCp6xSVDZWbNxVxG5lyZJ921aJH61sTw==", - "dev": true, + "read-package-tree": { + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/read-package-tree/-/read-package-tree-5.3.1.tgz", + "integrity": "sha512-mLUDsD5JVtlZxjSlPPx1RETkNjjvQYuweKwNVt1Sn8kP5Jh44pvYuUHCp6xSVDZWbNxVxG5lyZJ921aJH61sTw==", + "dev": true, + "requires": { + "read-package-json": "^2.0.0", + "readdir-scoped-modules": "^1.0.0", + "util-promisify": "^2.1.0" + } + }, + "read-pkg": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-1.1.0.tgz", + "integrity": "sha1-9f+qXs0pyzHAR0vKfXVra7KePyg=", + "requires": { + "load-json-file": "^1.0.0", + "normalize-package-data": "^2.3.2", + "path-type": "^1.0.0" + }, + "dependencies": { + "path-type": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-1.1.0.tgz", + "integrity": "sha1-WcRPfuSR2nBNpBXaWkBwuk+P5EE=", + "requires": { + "graceful-fs": "^4.1.2", + "pify": "^2.0.0", + "pinkie-promise": "^2.0.0" + } + }, + "pify": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", + "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=" + } + } + }, + "read-pkg-up": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-1.0.1.tgz", + "integrity": "sha1-nWPBMnbAZZGNV/ACpX9AobZD+wI=", "requires": { - "read-package-json": "^2.0.0", - "readdir-scoped-modules": "^1.0.0", - "util-promisify": "^2.1.0" + "find-up": "^1.0.0", + "read-pkg": "^1.0.0" + }, + "dependencies": { + "find-up": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-1.1.2.tgz", + "integrity": "sha1-ay6YIrGizgpgq2TWEOzK1TyyTQ8=", + "requires": { + "path-exists": "^2.0.0", + "pinkie-promise": "^2.0.0" + } + }, + "path-exists": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-2.1.0.tgz", + "integrity": "sha1-D+tsZPD8UY2adU3V77YscCJ2H0s=", + "requires": { + "pinkie-promise": "^2.0.0" + } + } } }, "readable-stream": { "version": "2.3.7", "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "dev": true, "requires": { "core-util-is": "~1.0.0", "inherits": "~2.0.3", @@ -8683,6 +9629,25 @@ "picomatch": "^2.0.7" } }, + "redent": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/redent/-/redent-1.0.0.tgz", + "integrity": "sha1-z5Fqsf1fHxbfsggi3W7H9zDCr94=", + "requires": { + "indent-string": "^2.1.0", + "strip-indent": "^1.0.1" + }, + "dependencies": { + "indent-string": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-2.1.0.tgz", + "integrity": "sha1-ji1INIdCEhtKghi3oTfppSBJ3IA=", + "requires": { + "repeating": "^2.0.0" + } + } + } + }, "reflect-metadata": { "version": "0.1.13", "resolved": "https://registry.npmjs.org/reflect-metadata/-/reflect-metadata-0.1.13.tgz", @@ -8711,9 +9676,9 @@ "dev": true }, "regenerator-transform": { - "version": "0.14.3", - "resolved": "https://registry.npmjs.org/regenerator-transform/-/regenerator-transform-0.14.3.tgz", - "integrity": "sha512-zXHNKJspmONxBViAb3ZUmFoFPnTBs3zFhCEZJiwp/gkNzxVbTqNJVjYKx6Qk1tQ1P4XLf4TbH9+KBB7wGoAaUw==", + "version": "0.14.4", + "resolved": "https://registry.npmjs.org/regenerator-transform/-/regenerator-transform-0.14.4.tgz", + "integrity": "sha512-EaJaKPBI9GvKpvUz2mz4fhx7WPgvwRLY9v3hlNHWmAuJHI13T4nwKnNvm5RWJzEdnI5g5UwtOww+S8IdoUC2bw==", "dev": true, "requires": { "@babel/runtime": "^7.8.4", @@ -8777,12 +9742,56 @@ } } }, + "relateurl": { + "version": "0.2.7", + "resolved": "https://registry.npmjs.org/relateurl/-/relateurl-0.2.7.tgz", + "integrity": "sha1-VNvzd+UUQKypCkzSdGANP/LYiKk=" + }, "remove-trailing-separator": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/remove-trailing-separator/-/remove-trailing-separator-1.1.0.tgz", "integrity": "sha1-wkvOKig62tW8P1jg1IJJuSN52O8=", "dev": true }, + "renderkid": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/renderkid/-/renderkid-2.0.3.tgz", + "integrity": "sha512-z8CLQp7EZBPCwCnncgf9C4XAi3WR0dv+uWu/PjIyhhAb5d6IJ/QZqlHFprHeKT+59//V6BNUsLbvN8+2LarxGA==", + "requires": { + "css-select": "^1.1.0", + "dom-converter": "^0.2", + "htmlparser2": "^3.3.0", + "strip-ansi": "^3.0.0", + "utila": "^0.4.0" + }, + "dependencies": { + "css-select": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/css-select/-/css-select-1.2.0.tgz", + "integrity": "sha1-KzoRBTnFNV8c2NMUYj6HCxIeyFg=", + "requires": { + "boolbase": "~1.0.0", + "css-what": "2.1", + "domutils": "1.5.1", + "nth-check": "~1.0.1" + } + }, + "css-what": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/css-what/-/css-what-2.1.3.tgz", + "integrity": "sha512-a+EPoD+uZiNfh+5fxw2nO9QwFa6nJe2Or35fGY6Ipw1R3R4AGz1d1TEZrCegvw2YTmZ0jXirGYlzxxpYSHwpEg==" + }, + "domutils": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/domutils/-/domutils-1.5.1.tgz", + "integrity": "sha1-3NhIiib1Y9YQeeSMn3t+Mjc2gs8=", + "requires": { + "dom-serializer": "0", + "domelementtype": "1" + } + } + } + }, "repeat-element": { "version": "1.1.3", "resolved": "https://registry.npmjs.org/repeat-element/-/repeat-element-1.1.3.tgz", @@ -8795,11 +9804,18 @@ "integrity": "sha1-jcrkcOHIirwtYA//Sndihtp15jc=", "dev": true }, + "repeating": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/repeating/-/repeating-2.0.1.tgz", + "integrity": "sha1-UhTFOpJtNVJwdSf7q0FdvAjQbdo=", + "requires": { + "is-finite": "^1.0.0" + } + }, "request": { "version": "2.88.2", "resolved": "https://registry.npmjs.org/request/-/request-2.88.2.tgz", "integrity": "sha512-MsvtOrfG9ZcrOwAW+Qi+F6HbD0CWXEh9ou77uOb7FM2WPhwT7smM833PzanhJLsgXjN89Ir6V2PczXNnMpwKhw==", - "dev": true, "requires": { "aws-sign2": "~0.7.0", "aws4": "^1.8.0", @@ -8826,14 +9842,12 @@ "require-directory": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", - "integrity": "sha1-jGStX9MNqxyXbiNE/+f3kqam30I=", - "dev": true + "integrity": "sha1-jGStX9MNqxyXbiNE/+f3kqam30I=" }, "require-main-filename": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-1.0.1.tgz", - "integrity": "sha1-l/cXtp1IeE9fUmpsWqj/3aBVpNE=", - "dev": true + "integrity": "sha1-l/cXtp1IeE9fUmpsWqj/3aBVpNE=" }, "requires-port": { "version": "1.0.0", @@ -8845,7 +9859,6 @@ "version": "1.15.1", "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.15.1.tgz", "integrity": "sha512-84oo6ZTtoTUpjgNEr5SJyzQhzL72gaRodsSfyxC/AXRvwu0Yse9H8eF9IpGo7b8YetZhlI6v7ZQ6bKBFV/6S7w==", - "dev": true, "requires": { "path-parse": "^1.0.6" } @@ -8899,11 +9912,22 @@ "integrity": "sha512-5C9HXdzK8EAqN7JDif30jqsBzavB7wLpaubisuQIGHWf2gUXSpzy6ArX/+Da8RjFpagWsCn+pIgxTMAmKw9Zug==", "dev": true }, + "rgb-regex": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/rgb-regex/-/rgb-regex-1.0.1.tgz", + "integrity": "sha1-wODWiC3w4jviVKR16O3UGRX+rrE=", + "dev": true + }, + "rgba-regex": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/rgba-regex/-/rgba-regex-1.0.0.tgz", + "integrity": "sha1-QzdOLiyglosO8VI0YLfXMP8i7rM=", + "dev": true + }, "rimraf": { "version": "2.7.1", "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz", "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==", - "dev": true, "requires": { "glob": "^7.1.3" } @@ -8918,6 +9942,17 @@ "inherits": "^2.0.1" } }, + "rollup": { + "version": "1.25.2", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-1.25.2.tgz", + "integrity": "sha512-+7z6Wab/L45QCPcfpuTZKwKiB0tynj05s/+s2U3F2Bi7rOLPr9UcjUwO7/xpjlPNXA/hwnth6jBExFRGyf3tMg==", + "dev": true, + "requires": { + "@types/estree": "*", + "@types/node": "*", + "acorn": "^7.1.0" + } + }, "run-async": { "version": "2.4.0", "resolved": "https://registry.npmjs.org/run-async/-/run-async-2.4.0.tgz", @@ -8947,8 +9982,7 @@ "safe-buffer": { "version": "5.1.2", "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" }, "safe-regex": { "version": "1.1.0", @@ -8962,36 +9996,158 @@ "safer-buffer": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", - "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", - "dev": true + "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" }, "sass": { - "version": "1.22.9", - "resolved": "https://registry.npmjs.org/sass/-/sass-1.22.9.tgz", - "integrity": "sha512-FzU1X2V8DlnqabrL4u7OBwD2vcOzNMongEJEx3xMEhWY/v26FFR3aG0hyeu2T965sfR0E9ufJwmG+Qjz78vFPQ==", + "version": "1.23.3", + "resolved": "https://registry.npmjs.org/sass/-/sass-1.23.3.tgz", + "integrity": "sha512-1DKRZxJMOh4Bme16AbWTyYeJAjTlrvw2+fWshHHaepeJfGq2soFZTnt0YhWit+bohtDu4LdyPoEj6VFD4APHog==", "dev": true, "requires": { "chokidar": ">=2.0.0 <4.0.0" } }, + "sass-graph": { + "version": "2.2.4", + "resolved": "https://registry.npmjs.org/sass-graph/-/sass-graph-2.2.4.tgz", + "integrity": "sha1-E/vWPNHK8JCLn9k0dq1DpR0eC0k=", + "requires": { + "glob": "^7.0.0", + "lodash": "^4.0.0", + "scss-tokenizer": "^0.2.3", + "yargs": "^7.0.0" + }, + "dependencies": { + "camelcase": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-3.0.0.tgz", + "integrity": "sha1-MvxLn82vhF/N9+c7uXysImHwqwo=" + }, + "cliui": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-3.2.0.tgz", + "integrity": "sha1-EgYBU3qRbSmUD5NNo7SNWFo5IT0=", + "requires": { + "string-width": "^1.0.1", + "strip-ansi": "^3.0.1", + "wrap-ansi": "^2.0.0" + } + }, + "invert-kv": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/invert-kv/-/invert-kv-1.0.0.tgz", + "integrity": "sha1-EEqOSqym09jNFXqO+L+rLXo//bY=" + }, + "is-fullwidth-code-point": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz", + "integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=", + "requires": { + "number-is-nan": "^1.0.0" + } + }, + "lcid": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/lcid/-/lcid-1.0.0.tgz", + "integrity": "sha1-MIrMr6C8SDo4Z7S28rlQYlHRuDU=", + "requires": { + "invert-kv": "^1.0.0" + } + }, + "os-locale": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/os-locale/-/os-locale-1.4.0.tgz", + "integrity": "sha1-IPnxeuKe00XoveWDsT0gCYA8FNk=", + "requires": { + "lcid": "^1.0.0" + } + }, + "string-width": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz", + "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=", + "requires": { + "code-point-at": "^1.0.0", + "is-fullwidth-code-point": "^1.0.0", + "strip-ansi": "^3.0.0" + } + }, + "which-module": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/which-module/-/which-module-1.0.0.tgz", + "integrity": "sha1-u6Y8qGGUiZT/MHc2CJ47lgJsKk8=" + }, + "y18n": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-3.2.1.tgz", + "integrity": "sha1-bRX7qITAhnnA136I53WegR4H+kE=" + }, + "yargs": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-7.1.0.tgz", + "integrity": "sha1-a6MY6xaWFyf10oT46gA+jWFU0Mg=", + "requires": { + "camelcase": "^3.0.0", + "cliui": "^3.2.0", + "decamelize": "^1.1.1", + "get-caller-file": "^1.0.1", + "os-locale": "^1.4.0", + "read-pkg-up": "^1.0.1", + "require-directory": "^2.1.1", + "require-main-filename": "^1.0.1", + "set-blocking": "^2.0.0", + "string-width": "^1.0.2", + "which-module": "^1.0.0", + "y18n": "^3.2.1", + "yargs-parser": "^5.0.0" + } + }, + "yargs-parser": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-5.0.0.tgz", + "integrity": "sha1-J17PDX/+Bcd+ZOfIbkzZS/DhIoo=", + "requires": { + "camelcase": "^3.0.0" + } + } + } + }, "sass-loader": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/sass-loader/-/sass-loader-7.2.0.tgz", - "integrity": "sha512-h8yUWaWtsbuIiOCgR9fd9c2lRXZ2uG+h8Dzg/AGNj+Hg/3TO8+BBAW9mEP+mh8ei+qBKqSJ0F1FLlYjNBc61OA==", - "dev": true, + "version": "8.0.2", + "resolved": "https://registry.npmjs.org/sass-loader/-/sass-loader-8.0.2.tgz", + "integrity": "sha512-7o4dbSK8/Ol2KflEmSco4jTjQoV988bM82P9CZdmo9hR3RLnvNc0ufMNdMrB0caq38JQ/FgF4/7RcbcfKzxoFQ==", "requires": { "clone-deep": "^4.0.1", - "loader-utils": "^1.0.1", - "neo-async": "^2.5.0", - "pify": "^4.0.1", - "semver": "^5.5.0" + "loader-utils": "^1.2.3", + "neo-async": "^2.6.1", + "schema-utils": "^2.6.1", + "semver": "^6.3.0" }, "dependencies": { - "semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", - "dev": true + "ajv": { + "version": "6.12.0", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.0.tgz", + "integrity": "sha512-D6gFiFA0RRLyUbvijN74DWAjXSFxWKaWP7mldxkVhyhAV3+SWA9HEJPHQ2c9soIeTFJqcSdFDGFgdqs1iUU2Hw==", + "requires": { + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + } + }, + "fast-deep-equal": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.1.tgz", + "integrity": "sha512-8UEa58QDLauDNfpbrX55Q9jrGHThw2ZMdOky5Gl1CDtVeJDPVrG4Jxx1N8jw2gkWaff5UUuX1KJd+9zGe2B+ZA==" + }, + "schema-utils": { + "version": "2.6.5", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-2.6.5.tgz", + "integrity": "sha512-5KXuwKziQrTVHh8j/Uxz+QUbxkaLW9X/86NBlx/gnKgtsZA2GIVMUn17qWhRFwF8jdYb3Dig5hRO/W5mZqy6SQ==", + "requires": { + "ajv": "^6.12.0", + "ajv-keywords": "^3.4.1" + } } } }, @@ -9005,9 +10161,9 @@ } }, "sax": { - "version": "0.5.8", - "resolved": "https://registry.npmjs.org/sax/-/sax-0.5.8.tgz", - "integrity": "sha1-1HLbIo6zMcJQaw6MFVJK25OdEsE=", + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/sax/-/sax-1.2.4.tgz", + "integrity": "sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw==", "dev": true }, "schema-utils": { @@ -9021,6 +10177,25 @@ "ajv-keywords": "^3.1.0" } }, + "scss-tokenizer": { + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/scss-tokenizer/-/scss-tokenizer-0.2.3.tgz", + "integrity": "sha1-jrBtualyMzOCTT9VMGQRSYR85dE=", + "requires": { + "js-base64": "^2.1.8", + "source-map": "^0.4.2" + }, + "dependencies": { + "source-map": { + "version": "0.4.4", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.4.4.tgz", + "integrity": "sha1-66T12pwNyZneaAMti092FzZSA2s=", + "requires": { + "amdefine": ">=0.0.4" + } + } + } + }, "select-hose": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/select-hose/-/select-hose-2.0.0.tgz", @@ -9062,8 +10237,7 @@ "semver": { "version": "6.3.0", "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", - "dev": true + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==" }, "semver-dsl": { "version": "1.0.1", @@ -9222,8 +10396,7 @@ "set-blocking": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", - "integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc=", - "dev": true + "integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc=" }, "set-immediate-shim": { "version": "1.0.1", @@ -9280,7 +10453,6 @@ "version": "3.0.1", "resolved": "https://registry.npmjs.org/shallow-clone/-/shallow-clone-3.0.1.tgz", "integrity": "sha512-/6KqX+GVUdqPuPPd2LxDDxzX6CAbjJehAAOKlNpqqUpAqPM6HeL8f+o3a+JsyGjn2lv0WY8UsTgUJjU9Ok55NA==", - "dev": true, "requires": { "kind-of": "^6.0.2" } @@ -9303,8 +10475,24 @@ "signal-exit": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.2.tgz", - "integrity": "sha1-tf3AjxKH6hF4Yo5BXiUTK3NkbG0=", - "dev": true + "integrity": "sha1-tf3AjxKH6hF4Yo5BXiUTK3NkbG0=" + }, + "simple-swizzle": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/simple-swizzle/-/simple-swizzle-0.2.2.tgz", + "integrity": "sha1-pNprY1/8zMoz9w0Xy5JZLeleVXo=", + "dev": true, + "requires": { + "is-arrayish": "^0.3.1" + }, + "dependencies": { + "is-arrayish": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.3.2.tgz", + "integrity": "sha512-eVRqCvVlZbuw3GrM63ovNSNAeA1K16kaR/LRY/92w0zxQ5/1YzwblUX652i4Xs9RwAGjW9d9y6X88t8OaAJfWQ==", + "dev": true + } + } }, "slash": { "version": "1.0.0", @@ -9721,7 +10909,6 @@ "version": "3.1.0", "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.1.0.tgz", "integrity": "sha512-lr2EZCctC2BNR7j7WzJ2FpDznxky1sjfxvvYEyzxNyb6lZXHODmEoJeFu4JupYlkfha1KZpJyoqiJ7pgA1qq8Q==", - "dev": true, "requires": { "spdx-expression-parse": "^3.0.0", "spdx-license-ids": "^3.0.0" @@ -9730,14 +10917,12 @@ "spdx-exceptions": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/spdx-exceptions/-/spdx-exceptions-2.2.0.tgz", - "integrity": "sha512-2XQACfElKi9SlVb1CYadKDXvoajPgBVPn/gOQLrTvHdElaVhr7ZEbqJaRnJLVNeaI4cMEAgVCeBMKF6MWRDCRA==", - "dev": true + "integrity": "sha512-2XQACfElKi9SlVb1CYadKDXvoajPgBVPn/gOQLrTvHdElaVhr7ZEbqJaRnJLVNeaI4cMEAgVCeBMKF6MWRDCRA==" }, "spdx-expression-parse": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-3.0.0.tgz", "integrity": "sha512-Yg6D3XpRD4kkOmTpdgbUiEJFKghJH03fiC1OPll5h/0sO6neh2jqRDVHOQ4o/LMea0tgCkbMgea5ip/e+MkWyg==", - "dev": true, "requires": { "spdx-exceptions": "^2.1.0", "spdx-license-ids": "^3.0.0" @@ -9746,8 +10931,7 @@ "spdx-license-ids": { "version": "3.0.5", "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.5.tgz", - "integrity": "sha512-J+FWzZoynJEXGphVIS+XEh3kFSjZX/1i9gFBaWQcB+/tmpe2qUsSBABpcxqxnAxFdiUFEgAX1bjYGQvIZmoz9Q==", - "dev": true + "integrity": "sha512-J+FWzZoynJEXGphVIS+XEh3kFSjZX/1i9gFBaWQcB+/tmpe2qUsSBABpcxqxnAxFdiUFEgAX1bjYGQvIZmoz9Q==" }, "spdy": { "version": "4.0.1", @@ -9821,7 +11005,6 @@ "version": "1.16.1", "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.16.1.tgz", "integrity": "sha512-HXXqVUq7+pcKeLqqZj6mHFUMvXtOJt1uoUx09pFW6011inTMxqI8BA8PM95myrIyyKwdnzjdFjLiE6KBPVtJIg==", - "dev": true, "requires": { "asn1": "~0.2.3", "assert-plus": "^1.0.0", @@ -9835,14 +11018,21 @@ } }, "ssri": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/ssri/-/ssri-6.0.1.tgz", - "integrity": "sha512-3Wge10hNcT1Kur4PDFwEieXSCMCJs/7WvSACcrMYrNp+b8kDL1/0wJch5Ni2WrtwEa2IO8OsVfeKIciKCDx/QA==", + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/ssri/-/ssri-7.1.0.tgz", + "integrity": "sha512-77/WrDZUWocK0mvA5NTRQyveUf+wsrIc6vyrxpS8tVvYBcX215QbafrJR3KtkpskIzoFLqqNuuYQvxaMjXJ/0g==", "dev": true, "requires": { - "figgy-pudding": "^3.5.1" + "figgy-pudding": "^3.5.1", + "minipass": "^3.1.1" } }, + "stable": { + "version": "0.1.8", + "resolved": "https://registry.npmjs.org/stable/-/stable-0.1.8.tgz", + "integrity": "sha512-ji9qxRnOVfcuLDySj9qzhGSEFVobyt1kIOSkj1qZzYLzq7Tos/oUUWvotUPQLlrsidqsK6tBH89Bc9kL5zHA6w==", + "dev": true + }, "static-extend": { "version": "0.1.2", "resolved": "https://registry.npmjs.org/static-extend/-/static-extend-0.1.2.tgz", @@ -9870,6 +11060,14 @@ "integrity": "sha1-Fhx9rBd2Wf2YEfQ3cfqZOBR4Yow=", "dev": true }, + "stdout-stream": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/stdout-stream/-/stdout-stream-1.4.1.tgz", + "integrity": "sha512-j4emi03KXqJWcIeF8eIXkjMFN1Cmb8gUlDYGeBALLPo5qdyTfA9bOtl8m33lRoC+vFMkP3gl0WsDr6+gzxbbTA==", + "requires": { + "readable-stream": "^2.0.1" + } + }, "stream-browserify": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/stream-browserify/-/stream-browserify-2.0.2.tgz", @@ -9943,7 +11141,6 @@ "version": "2.1.1", "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==", - "dev": true, "requires": { "is-fullwidth-code-point": "^2.0.0", "strip-ansi": "^4.0.0" @@ -9952,14 +11149,12 @@ "ansi-regex": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", - "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=", - "dev": true + "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=" }, "strip-ansi": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", - "dev": true, "requires": { "ansi-regex": "^3.0.0" } @@ -9970,7 +11165,6 @@ "version": "2.1.1", "resolved": "https://registry.npmjs.org/string.prototype.trimleft/-/string.prototype.trimleft-2.1.1.tgz", "integrity": "sha512-iu2AGd3PuP5Rp7x2kEZCrB2Nf41ehzh+goo8TV7z8/XDBbsvc6HQIlUl9RjkZ4oyrW1XM5UwlGl1oVEaDjg6Ag==", - "dev": true, "requires": { "define-properties": "^1.1.3", "function-bind": "^1.1.1" @@ -9980,7 +11174,6 @@ "version": "2.1.1", "resolved": "https://registry.npmjs.org/string.prototype.trimright/-/string.prototype.trimright-2.1.1.tgz", "integrity": "sha512-qFvWL3/+QIgZXVmJBfpHmxLB7xsUXz6HsUmP8+5dRaC3Q7oKUv9Vo6aMCRZC1smrtyECFsIT30PqBJ1gTjAs+g==", - "dev": true, "requires": { "define-properties": "^1.1.3", "function-bind": "^1.1.1" @@ -9990,7 +11183,6 @@ "version": "1.1.1", "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, "requires": { "safe-buffer": "~5.1.0" } @@ -9999,7 +11191,6 @@ "version": "3.0.1", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", - "dev": true, "requires": { "ansi-regex": "^2.0.0" } @@ -10016,6 +11207,14 @@ "integrity": "sha1-u0P/VZim6wXYm1n80SnJgzE2Br8=", "dev": true }, + "strip-indent": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/strip-indent/-/strip-indent-1.0.1.tgz", + "integrity": "sha1-DHlipq3vp7vUrDZkYKY4VSrhoKI=", + "requires": { + "get-stdin": "^4.0.1" + } + }, "style-loader": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/style-loader/-/style-loader-1.0.0.tgz", @@ -10056,42 +11255,60 @@ } } }, - "stylus": { - "version": "0.54.5", - "resolved": "https://registry.npmjs.org/stylus/-/stylus-0.54.5.tgz", - "integrity": "sha1-QrlWCTHKcJDOhRWnmLqeaqPW3Hk=", + "stylehacks": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/stylehacks/-/stylehacks-4.0.3.tgz", + "integrity": "sha512-7GlLk9JwlElY4Y6a/rmbH2MhVlTyVmiJd1PfTCqFaIBEGMYNsrO/v3SeGTdhBThLg4Z+NbOk/qFMwCa+J+3p/g==", "dev": true, "requires": { - "css-parse": "1.7.x", - "debug": "*", - "glob": "7.0.x", - "mkdirp": "0.5.x", - "sax": "0.5.x", - "source-map": "0.1.x" + "browserslist": "^4.0.0", + "postcss": "^7.0.0", + "postcss-selector-parser": "^3.0.0" }, "dependencies": { - "glob": { - "version": "7.0.6", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.0.6.tgz", - "integrity": "sha1-IRuvr0nlJbjNkyYNFKsTYVKz9Xo=", + "postcss-selector-parser": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-3.1.2.tgz", + "integrity": "sha512-h7fJ/5uWuRVyOtkO45pnt1Ih40CEleeyCHzipqAZO2e5H20g25Y48uYnFUiShvY4rZWNJ/Bib/KVPmanaCtOhA==", "dev": true, "requires": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.0.2", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" + "dot-prop": "^5.2.0", + "indexes-of": "^1.0.1", + "uniq": "^1.0.1" } - }, - "source-map": { - "version": "0.1.43", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.1.43.tgz", - "integrity": "sha1-wkvBRspRfBRx9drL4lcbK3+eM0Y=", + } + } + }, + "stylus": { + "version": "0.54.7", + "resolved": "https://registry.npmjs.org/stylus/-/stylus-0.54.7.tgz", + "integrity": "sha512-Yw3WMTzVwevT6ZTrLCYNHAFmanMxdylelL3hkWNgPMeTCpMwpV3nXjpOHuBXtFv7aiO2xRuQS6OoAdgkNcSNug==", + "dev": true, + "requires": { + "css-parse": "~2.0.0", + "debug": "~3.1.0", + "glob": "^7.1.3", + "mkdirp": "~0.5.x", + "safer-buffer": "^2.1.2", + "sax": "~1.2.4", + "semver": "^6.0.0", + "source-map": "^0.7.3" + }, + "dependencies": { + "debug": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", + "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", "dev": true, "requires": { - "amdefine": ">=0.0.4" + "ms": "2.0.0" } + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", + "dev": true } } }, @@ -10115,6 +11332,27 @@ "has-flag": "^3.0.0" } }, + "svgo": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/svgo/-/svgo-1.3.2.tgz", + "integrity": "sha512-yhy/sQYxR5BkC98CY7o31VGsg014AKLEPxdfhora76l36hD9Rdy5NZA/Ocn6yayNPgSamYdtX2rFJdcv07AYVw==", + "dev": true, + "requires": { + "chalk": "^2.4.1", + "coa": "^2.0.2", + "css-select": "^2.0.0", + "css-select-base-adapter": "^0.1.1", + "css-tree": "1.0.0-alpha.37", + "csso": "^4.0.2", + "js-yaml": "^3.13.1", + "mkdirp": "~0.5.1", + "object.values": "^1.1.0", + "sax": "~1.2.4", + "stable": "^0.1.8", + "unquote": "~1.1.1", + "util.promisify": "~1.0.0" + } + }, "symbol-observable": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/symbol-observable/-/symbol-observable-1.2.0.tgz", @@ -10124,8 +11362,7 @@ "tapable": { "version": "1.1.3", "resolved": "https://registry.npmjs.org/tapable/-/tapable-1.1.3.tgz", - "integrity": "sha512-4WK/bYZmj8xLr+HUCODHGF1ZFzsYffasLUgEiMBY4fgtltdO6B4WJtlSbPaDTLpYTcGVwM2qLnFTICEcNxs3kA==", - "dev": true + "integrity": "sha512-4WK/bYZmj8xLr+HUCODHGF1ZFzsYffasLUgEiMBY4fgtltdO6B4WJtlSbPaDTLpYTcGVwM2qLnFTICEcNxs3kA==" }, "tar": { "version": "4.4.13", @@ -10140,12 +11377,39 @@ "mkdirp": "^0.5.0", "safe-buffer": "^5.1.2", "yallist": "^3.0.3" + }, + "dependencies": { + "fs-minipass": { + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-1.2.7.tgz", + "integrity": "sha512-GWSSJGFy4e9GUeCcbIkED+bgAoFyj7XF1mV8rma3QW4NIqX9Kyx79N/PF61H5udOV3aY1IaMLs6pGbH71nlCTA==", + "dev": true, + "requires": { + "minipass": "^2.6.0" + } + }, + "minipass": { + "version": "2.9.0", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-2.9.0.tgz", + "integrity": "sha512-wxfUjg9WebH+CUDX/CdbRlh5SmfZiy/hpkxaRI16Y9W56Pa75sWgd/rvFilSgrauD9NyFymP/+JFV3KwzIsJeg==", + "dev": true, + "requires": { + "safe-buffer": "^5.1.2", + "yallist": "^3.0.0" + } + }, + "yallist": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", + "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==", + "dev": true + } } }, "terser": { - "version": "4.6.3", - "resolved": "https://registry.npmjs.org/terser/-/terser-4.6.3.tgz", - "integrity": "sha512-Lw+ieAXmY69d09IIc/yqeBqXpEQIpDGZqT34ui1QWXIUpR2RjbqEkT8X7Lgex19hslSqcWM5iMN2kM11eMsESQ==", + "version": "4.5.1", + "resolved": "https://registry.npmjs.org/terser/-/terser-4.5.1.tgz", + "integrity": "sha512-lH9zLIbX8PRBEFCTvfHGCy0s9HEKnNso1Dx9swSopF3VUnFLB8DpQ61tHxoofovNC/sG0spajJM3EIIRSTByiQ==", "dev": true, "requires": { "commander": "^2.20.0", @@ -10162,31 +11426,127 @@ } }, "terser-webpack-plugin": { - "version": "1.4.3", - "resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-1.4.3.tgz", - "integrity": "sha512-QMxecFz/gHQwteWwSo5nTc6UaICqN1bMedC5sMtUc7y3Ha3Q8y6ZO0iCR8pq4RJC8Hjf0FEPEHZqcMB/+DFCrA==", + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-2.3.3.tgz", + "integrity": "sha512-gWHkaGzGYjmDoYxksFZynWTzvXOAjQ5dd7xuTMYlv4zpWlLSb6v0QLSZjELzP5dMs1ox30O1BIPs9dgqlMHuLQ==", "dev": true, "requires": { - "cacache": "^12.0.2", - "find-cache-dir": "^2.1.0", - "is-wsl": "^1.1.0", - "schema-utils": "^1.0.0", + "cacache": "^13.0.1", + "find-cache-dir": "^3.2.0", + "jest-worker": "^25.1.0", + "p-limit": "^2.2.2", + "schema-utils": "^2.6.4", "serialize-javascript": "^2.1.2", "source-map": "^0.6.1", - "terser": "^4.1.2", - "webpack-sources": "^1.4.0", - "worker-farm": "^1.7.0" + "terser": "^4.4.3", + "webpack-sources": "^1.4.3" }, "dependencies": { + "ajv": { + "version": "6.12.0", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.0.tgz", + "integrity": "sha512-D6gFiFA0RRLyUbvijN74DWAjXSFxWKaWP7mldxkVhyhAV3+SWA9HEJPHQ2c9soIeTFJqcSdFDGFgdqs1iUU2Hw==", + "dev": true, + "requires": { + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + } + }, + "fast-deep-equal": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.1.tgz", + "integrity": "sha512-8UEa58QDLauDNfpbrX55Q9jrGHThw2ZMdOky5Gl1CDtVeJDPVrG4Jxx1N8jw2gkWaff5UUuX1KJd+9zGe2B+ZA==", + "dev": true + }, "find-cache-dir": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/find-cache-dir/-/find-cache-dir-2.1.0.tgz", - "integrity": "sha512-Tq6PixE0w/VMFfCgbONnkiQIVol/JJL7nRMi20fqzA4NRs9AfeqMGeRdPi3wIhYkxjeBaWh2rxwapn5Tu3IqOQ==", + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/find-cache-dir/-/find-cache-dir-3.3.1.tgz", + "integrity": "sha512-t2GDMt3oGC/v+BMwzmllWDuJF/xcDtE5j/fCGbqDD7OLuJkj0cfh1YSA5VKPvwMeLFLNDBkwOKZ2X85jGLVftQ==", "dev": true, "requires": { "commondir": "^1.0.1", - "make-dir": "^2.0.0", - "pkg-dir": "^3.0.0" + "make-dir": "^3.0.2", + "pkg-dir": "^4.1.0" + } + }, + "find-up": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", + "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", + "dev": true, + "requires": { + "locate-path": "^5.0.0", + "path-exists": "^4.0.0" + } + }, + "has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true + }, + "jest-worker": { + "version": "25.1.0", + "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-25.1.0.tgz", + "integrity": "sha512-ZHhHtlxOWSxCoNOKHGbiLzXnl42ga9CxDr27H36Qn+15pQZd3R/F24jrmjDelw9j/iHUIWMWs08/u2QN50HHOg==", + "dev": true, + "requires": { + "merge-stream": "^2.0.0", + "supports-color": "^7.0.0" + } + }, + "locate-path": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", + "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", + "dev": true, + "requires": { + "p-locate": "^4.1.0" + } + }, + "make-dir": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.0.2.tgz", + "integrity": "sha512-rYKABKutXa6vXTXhoV18cBE7PaewPXHe/Bdq4v+ZLMhxbWApkFFplT0LcbMW+6BbjnQXzZ/sAvSE/JdguApG5w==", + "dev": true, + "requires": { + "semver": "^6.0.0" + } + }, + "p-locate": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", + "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", + "dev": true, + "requires": { + "p-limit": "^2.2.0" + } + }, + "path-exists": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", + "dev": true + }, + "pkg-dir": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-4.2.0.tgz", + "integrity": "sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==", + "dev": true, + "requires": { + "find-up": "^4.0.0" + } + }, + "schema-utils": { + "version": "2.6.5", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-2.6.5.tgz", + "integrity": "sha512-5KXuwKziQrTVHh8j/Uxz+QUbxkaLW9X/86NBlx/gnKgtsZA2GIVMUn17qWhRFwF8jdYb3Dig5hRO/W5mZqy6SQ==", + "dev": true, + "requires": { + "ajv": "^6.12.0", + "ajv-keywords": "^3.4.1" } }, "source-map": { @@ -10194,6 +11554,15 @@ "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", "dev": true + }, + "supports-color": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.1.0.tgz", + "integrity": "sha512-oRSIpR8pxT1Wr2FquTNnGet79b3BWljqOuoW/h4oBhxJ/HUbX5nX6JSruTkvXDCFMwDPvsaTTbvMLKZWSy0R5g==", + "dev": true, + "requires": { + "has-flag": "^4.0.0" + } } } }, @@ -10228,6 +11597,12 @@ "setimmediate": "^1.0.4" } }, + "timsort": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/timsort/-/timsort-0.3.0.tgz", + "integrity": "sha1-QFQRqOfmM5/mTbmiNN4R3DHgK9Q=", + "dev": true + }, "tmp": { "version": "0.0.33", "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.33.tgz", @@ -10302,11 +11677,15 @@ "integrity": "sha512-yaOH/Pk/VEhBWWTlhI+qXxDFXlejDGcQipMlyxda9nthulaxLZUNcUqFxokp0vcYnvteJln5FNQDRrxj3YcbVw==", "dev": true }, + "toposort": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/toposort/-/toposort-1.0.7.tgz", + "integrity": "sha1-LmhELZ9k7HILjMieZEOsbKqVACk=" + }, "tough-cookie": { "version": "2.5.0", "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.5.0.tgz", "integrity": "sha512-nlLsUzgm1kfLXSXfRZMc1KLAugd4hqJHDTvc2hDIwS3mZAfMEuMbc03SujMF+GEcpaX/qboeycw6iO8JwVv2+g==", - "dev": true, "requires": { "psl": "^1.1.28", "punycode": "^2.1.1" @@ -10318,6 +11697,19 @@ "integrity": "sha512-L0Orpi8qGpRG//Nd+H90vFB+3iHnue1zSSGmNOOCh1GLJ7rUKVwV2HvijphGQS2UmhUZewS9VgvxYIdgr+fG1A==", "dev": true }, + "trim-newlines": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/trim-newlines/-/trim-newlines-1.0.0.tgz", + "integrity": "sha1-WIeWa7WCpFA6QetST301ARgVphM=" + }, + "true-case-path": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/true-case-path/-/true-case-path-1.0.3.tgz", + "integrity": "sha512-m6s2OdQe5wgpFMC+pAJ+q9djG82O2jcHPOI6RNg1yy9rCYR+WD6Nbpl32fDpfC56nirdRy+opFa/Vk7HYhqaew==", + "requires": { + "glob": "^7.1.2" + } + }, "ts-node": { "version": "8.6.2", "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-8.6.2.tgz", @@ -10384,7 +11776,6 @@ "version": "0.6.0", "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz", "integrity": "sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0=", - "dev": true, "requires": { "safe-buffer": "^5.0.1" } @@ -10392,8 +11783,7 @@ "tweetnacl": { "version": "0.14.5", "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz", - "integrity": "sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q=", - "dev": true + "integrity": "sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q=" }, "type-fest": { "version": "0.11.0", @@ -10418,9 +11808,9 @@ "dev": true }, "typescript": { - "version": "3.5.3", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-3.5.3.tgz", - "integrity": "sha512-ACzBtm/PhXBDId6a6sDJfroT2pOWt/oOnk4/dElG5G33ZL776N3Y6/6bKZJBFpd+b05F3Ct9qDjMeJmRWtE2/g==", + "version": "3.7.5", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-3.7.5.tgz", + "integrity": "sha512-/P5lkRXkWHNAbcJIiHPfRoKqyd7bsyCma1hZNUGfn20qm64T6ZBlrzprymeu918H+mB/0rIg2gGK/BXkhhYgBw==", "dev": true }, "ua-parser": { @@ -10436,6 +11826,27 @@ "resolved": "https://registry.npmjs.org/ua-parser-js/-/ua-parser-js-0.7.21.tgz", "integrity": "sha512-+O8/qh/Qj8CgC6eYBVBykMrNtp5Gebn4dlGD/kKXVkJNDwyrAwSIqwz8CDf+tsAIWVycKcku6gIXJ0qwx/ZXaQ==" }, + "uglify-js": { + "version": "3.4.10", + "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.4.10.tgz", + "integrity": "sha512-Y2VsbPVs0FIshJztycsO2SfPk7/KAF/T72qzv9u5EpQ4kB2hQoHlhNQTsNyy6ul7lQtqJN/AoWeS23OzEiEFxw==", + "requires": { + "commander": "~2.19.0", + "source-map": "~0.6.1" + }, + "dependencies": { + "commander": { + "version": "2.19.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.19.0.tgz", + "integrity": "sha512-6tvAOO+D6OENvRAh524Dh9jcfKTYDQAqvqezbCW82xj5X0pSrcpxtvRKHLG0yBY6SD7PSDrJaj+0AiOcKVd1Xg==" + }, + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==" + } + } + }, "ultron": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/ultron/-/ultron-1.1.1.tgz", @@ -10482,6 +11893,18 @@ "set-value": "^2.0.1" } }, + "uniq": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/uniq/-/uniq-1.0.1.tgz", + "integrity": "sha1-sxxa6CVIRKOoKBVBzisEuGWnNP8=", + "dev": true + }, + "uniqs": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/uniqs/-/uniqs-2.0.0.tgz", + "integrity": "sha1-/+3ks2slKQaW5uFl1KWe25mOawI=", + "dev": true + }, "unique-filename": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/unique-filename/-/unique-filename-1.1.1.tgz", @@ -10534,6 +11957,12 @@ "integrity": "sha1-sr9O6FFKrmFltIF4KdIbLvSZBOw=", "dev": true }, + "unquote": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/unquote/-/unquote-1.1.1.tgz", + "integrity": "sha1-j97XMk7G6IoP+LkF58CYzcCG1UQ=", + "dev": true + }, "unset-value": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/unset-value/-/unset-value-1.0.0.tgz", @@ -10580,11 +12009,15 @@ "integrity": "sha512-aZwGpamFO61g3OlfT7OQCHqhGnW43ieH9WZeP7QxN/G/jS4jfqUkZxoryvJgVPEcrl5NL/ggHsSmLMHuH64Lhg==", "dev": true }, + "upper-case": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/upper-case/-/upper-case-1.1.3.tgz", + "integrity": "sha1-9rRQHC7EzdJrp4vnIilh3ndiFZg=" + }, "uri-js": { "version": "4.2.2", "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.2.2.tgz", "integrity": "sha512-KY9Frmirql91X2Qgjry0Wd4Y+YTdrdZheS8TFwvkbLWf/G5KNJDCh6pKL5OZctEW4+0Baa5idK2ZQuELRwPznQ==", - "dev": true, "requires": { "punycode": "^2.1.0" } @@ -10677,8 +12110,7 @@ "util-deprecate": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", - "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=", - "dev": true + "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=" }, "util-promisify": { "version": "2.1.0", @@ -10689,6 +12121,23 @@ "object.getownpropertydescriptors": "^2.0.3" } }, + "util.promisify": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/util.promisify/-/util.promisify-1.0.1.tgz", + "integrity": "sha512-g9JpC/3He3bm38zsLupWryXHoEcS22YHthuPQSJdMy6KNrzIRzWqcsHzD/WUnqe45whVou4VIsPew37DoXWNrA==", + "dev": true, + "requires": { + "define-properties": "^1.1.3", + "es-abstract": "^1.17.2", + "has-symbols": "^1.0.1", + "object.getownpropertydescriptors": "^2.1.0" + } + }, + "utila": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/utila/-/utila-0.4.0.tgz", + "integrity": "sha1-ihagXURWV6Oupe7MWxKk+lN5dyw=" + }, "utils-merge": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz", @@ -10698,14 +12147,12 @@ "uuid": { "version": "3.4.0", "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz", - "integrity": "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==", - "dev": true + "integrity": "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==" }, "validate-npm-package-license": { "version": "3.0.4", "resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz", "integrity": "sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew==", - "dev": true, "requires": { "spdx-correct": "^3.0.0", "spdx-expression-parse": "^3.0.0" @@ -10726,11 +12173,16 @@ "integrity": "sha1-IpnwLG3tMNSllhsLn3RSShj2NPw=", "dev": true }, + "vendors": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/vendors/-/vendors-1.0.4.tgz", + "integrity": "sha512-/juG65kTL4Cy2su4P8HjtkTxk6VmJDiOPBufWniqQ6wknac6jNiXS9vU+hO3wgusiyqWlzTbVHi0dyJqRONg3w==", + "dev": true + }, "verror": { "version": "1.10.0", "resolved": "https://registry.npmjs.org/verror/-/verror-1.10.0.tgz", "integrity": "sha1-OhBcoXBTr1XW4nDB+CiGguGNpAA=", - "dev": true, "requires": { "assert-plus": "^1.0.0", "core-util-is": "1.0.2", @@ -10847,13 +12299,12 @@ } }, "fsevents": { - "version": "1.2.11", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-1.2.11.tgz", - "integrity": "sha512-+ux3lx6peh0BpvY0JebGyZoiR4D+oYzdPZMKJwkZ+sFkNJzpL7tXc/wehS49gUAxg3tmMHPHZkA8JU2rhhgDHw==", + "version": "1.2.12", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-1.2.12.tgz", + "integrity": "sha512-Ggd/Ktt7E7I8pxZRbGIs7vwqAPscSESMrCSkx2FtWeqmheJgCo2R74fTsZFCifr0VTPwqRpPv17+6b8Zp7th0Q==", "dev": true, "optional": true, "requires": { - "bindings": "^1.5.0", "nan": "^2.12.1", "node-pre-gyp": "*" }, @@ -10903,7 +12354,7 @@ } }, "chownr": { - "version": "1.1.3", + "version": "1.1.4", "bundled": true, "dev": true, "optional": true @@ -11075,7 +12526,7 @@ } }, "minimist": { - "version": "0.0.8", + "version": "1.2.5", "bundled": true, "dev": true, "optional": true @@ -11100,12 +12551,12 @@ } }, "mkdirp": { - "version": "0.5.1", + "version": "0.5.3", "bundled": true, "dev": true, "optional": true, "requires": { - "minimist": "0.0.8" + "minimist": "^1.2.5" } }, "ms": { @@ -11115,7 +12566,7 @@ "optional": true }, "needle": { - "version": "2.4.0", + "version": "2.3.3", "bundled": true, "dev": true, "optional": true, @@ -11144,7 +12595,7 @@ } }, "nopt": { - "version": "4.0.1", + "version": "4.0.3", "bundled": true, "dev": true, "optional": true, @@ -11169,13 +12620,14 @@ "optional": true }, "npm-packlist": { - "version": "1.4.7", + "version": "1.4.8", "bundled": true, "dev": true, "optional": true, "requires": { "ignore-walk": "^3.0.1", - "npm-bundled": "^1.0.1" + "npm-bundled": "^1.0.1", + "npm-normalize-package-bin": "^1.0.1" } }, "npmlog": { @@ -11255,18 +12707,10 @@ "ini": "~1.3.0", "minimist": "^1.2.0", "strip-json-comments": "~2.0.1" - }, - "dependencies": { - "minimist": { - "version": "1.2.0", - "bundled": true, - "dev": true, - "optional": true - } } }, "readable-stream": { - "version": "2.3.6", + "version": "2.3.7", "bundled": true, "dev": true, "optional": true, @@ -11463,6 +12907,15 @@ "minimalistic-assert": "^1.0.0" } }, + "wcwidth": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/wcwidth/-/wcwidth-1.0.1.tgz", + "integrity": "sha1-8LDc+RW8X/FSivrbLA4XtTLaL+g=", + "dev": true, + "requires": { + "defaults": "^1.0.3" + } + }, "web-animations-js": { "version": "2.3.2", "resolved": "https://registry.npmjs.org/web-animations-js/-/web-animations-js-2.3.2.tgz", @@ -11479,9 +12932,9 @@ } }, "webpack": { - "version": "4.39.2", - "resolved": "https://registry.npmjs.org/webpack/-/webpack-4.39.2.tgz", - "integrity": "sha512-AKgTfz3xPSsEibH00JfZ9sHXGUwIQ6eZ9tLN8+VLzachk1Cw2LVmy+4R7ZiwTa9cZZ15tzySjeMui/UnSCAZhA==", + "version": "4.41.2", + "resolved": "https://registry.npmjs.org/webpack/-/webpack-4.41.2.tgz", + "integrity": "sha512-Zhw69edTGfbz9/8JJoyRQ/pq8FYUoY0diOXqW0T6yhgdhCv6wr0hra5DwwWexNRns2Z2+gsnrNcbe9hbGBgk/A==", "dev": true, "requires": { "@webassemblyjs/ast": "1.8.5", @@ -11507,31 +12960,94 @@ "terser-webpack-plugin": "^1.4.1", "watchpack": "^1.6.0", "webpack-sources": "^1.4.1" - } - }, - "webpack-core": { - "version": "0.6.9", - "resolved": "https://registry.npmjs.org/webpack-core/-/webpack-core-0.6.9.tgz", - "integrity": "sha1-/FcViMhVjad76e+23r3Fo7FyvcI=", - "dev": true, - "requires": { - "source-list-map": "~0.1.7", - "source-map": "~0.4.1" }, "dependencies": { - "source-list-map": { - "version": "0.1.8", - "resolved": "https://registry.npmjs.org/source-list-map/-/source-list-map-0.1.8.tgz", - "integrity": "sha1-xVCyq1Qn9rPyH1r+rYjE9Vh7IQY=", + "acorn": { + "version": "6.4.1", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-6.4.1.tgz", + "integrity": "sha512-ZVA9k326Nwrj3Cj9jlh3wGFutC2ZornPNARZwsNYqQYgN0EsV2d53w5RN/co65Ohn4sUAUtb1rSUAOD6XN9idA==", + "dev": true + }, + "cacache": { + "version": "12.0.3", + "resolved": "https://registry.npmjs.org/cacache/-/cacache-12.0.3.tgz", + "integrity": "sha512-kqdmfXEGFepesTuROHMs3MpFLWrPkSSpRqOw80RCflZXy/khxaArvFrQ7uJxSUduzAufc6G0g1VUCOZXxWavPw==", + "dev": true, + "requires": { + "bluebird": "^3.5.5", + "chownr": "^1.1.1", + "figgy-pudding": "^3.5.1", + "glob": "^7.1.4", + "graceful-fs": "^4.1.15", + "infer-owner": "^1.0.3", + "lru-cache": "^5.1.1", + "mississippi": "^3.0.0", + "mkdirp": "^0.5.1", + "move-concurrently": "^1.0.1", + "promise-inflight": "^1.0.1", + "rimraf": "^2.6.3", + "ssri": "^6.0.1", + "unique-filename": "^1.1.1", + "y18n": "^4.0.0" + } + }, + "find-cache-dir": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/find-cache-dir/-/find-cache-dir-2.1.0.tgz", + "integrity": "sha512-Tq6PixE0w/VMFfCgbONnkiQIVol/JJL7nRMi20fqzA4NRs9AfeqMGeRdPi3wIhYkxjeBaWh2rxwapn5Tu3IqOQ==", + "dev": true, + "requires": { + "commondir": "^1.0.1", + "make-dir": "^2.0.0", + "pkg-dir": "^3.0.0" + } + }, + "is-wsl": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-1.1.0.tgz", + "integrity": "sha1-HxbkqiKwTRM2tmGIpmrzxgDDpm0=", "dev": true }, + "memory-fs": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/memory-fs/-/memory-fs-0.4.1.tgz", + "integrity": "sha1-OpoguEYlI+RHz7x+i7gO1me/xVI=", + "dev": true, + "requires": { + "errno": "^0.1.3", + "readable-stream": "^2.0.1" + } + }, "source-map": { - "version": "0.4.4", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.4.4.tgz", - "integrity": "sha1-66T12pwNyZneaAMti092FzZSA2s=", + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true + }, + "ssri": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/ssri/-/ssri-6.0.1.tgz", + "integrity": "sha512-3Wge10hNcT1Kur4PDFwEieXSCMCJs/7WvSACcrMYrNp+b8kDL1/0wJch5Ni2WrtwEa2IO8OsVfeKIciKCDx/QA==", "dev": true, "requires": { - "amdefine": ">=0.0.4" + "figgy-pudding": "^3.5.1" + } + }, + "terser-webpack-plugin": { + "version": "1.4.3", + "resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-1.4.3.tgz", + "integrity": "sha512-QMxecFz/gHQwteWwSo5nTc6UaICqN1bMedC5sMtUc7y3Ha3Q8y6ZO0iCR8pq4RJC8Hjf0FEPEHZqcMB/+DFCrA==", + "dev": true, + "requires": { + "cacache": "^12.0.2", + "find-cache-dir": "^2.1.0", + "is-wsl": "^1.1.0", + "schema-utils": "^1.0.0", + "serialize-javascript": "^2.1.2", + "source-map": "^0.6.1", + "terser": "^4.1.2", + "webpack-sources": "^1.4.0", + "worker-farm": "^1.7.0" } } } @@ -11549,6 +13065,16 @@ "webpack-log": "^2.0.0" }, "dependencies": { + "memory-fs": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/memory-fs/-/memory-fs-0.4.1.tgz", + "integrity": "sha1-OpoguEYlI+RHz7x+i7gO1me/xVI=", + "dev": true, + "requires": { + "errno": "^0.1.3", + "readable-stream": "^2.0.1" + } + }, "mime": { "version": "2.4.4", "resolved": "https://registry.npmjs.org/mime/-/mime-2.4.4.tgz", @@ -11685,13 +13211,12 @@ } }, "fsevents": { - "version": "1.2.11", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-1.2.11.tgz", - "integrity": "sha512-+ux3lx6peh0BpvY0JebGyZoiR4D+oYzdPZMKJwkZ+sFkNJzpL7tXc/wehS49gUAxg3tmMHPHZkA8JU2rhhgDHw==", + "version": "1.2.12", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-1.2.12.tgz", + "integrity": "sha512-Ggd/Ktt7E7I8pxZRbGIs7vwqAPscSESMrCSkx2FtWeqmheJgCo2R74fTsZFCifr0VTPwqRpPv17+6b8Zp7th0Q==", "dev": true, "optional": true, "requires": { - "bindings": "^1.5.0", "nan": "^2.12.1", "node-pre-gyp": "*" }, @@ -11741,7 +13266,7 @@ } }, "chownr": { - "version": "1.1.3", + "version": "1.1.4", "bundled": true, "dev": true, "optional": true @@ -11913,7 +13438,7 @@ } }, "minimist": { - "version": "0.0.8", + "version": "1.2.5", "bundled": true, "dev": true, "optional": true @@ -11938,12 +13463,12 @@ } }, "mkdirp": { - "version": "0.5.1", + "version": "0.5.3", "bundled": true, "dev": true, "optional": true, "requires": { - "minimist": "0.0.8" + "minimist": "^1.2.5" } }, "ms": { @@ -11953,7 +13478,7 @@ "optional": true }, "needle": { - "version": "2.4.0", + "version": "2.3.3", "bundled": true, "dev": true, "optional": true, @@ -11982,7 +13507,7 @@ } }, "nopt": { - "version": "4.0.1", + "version": "4.0.3", "bundled": true, "dev": true, "optional": true, @@ -12007,13 +13532,14 @@ "optional": true }, "npm-packlist": { - "version": "1.4.7", + "version": "1.4.8", "bundled": true, "dev": true, "optional": true, "requires": { "ignore-walk": "^3.0.1", - "npm-bundled": "^1.0.1" + "npm-bundled": "^1.0.1", + "npm-normalize-package-bin": "^1.0.1" } }, "npmlog": { @@ -12093,18 +13619,10 @@ "ini": "~1.3.0", "minimist": "^1.2.0", "strip-json-comments": "~2.0.1" - }, - "dependencies": { - "minimist": { - "version": "1.2.0", - "bundled": true, - "dev": true, - "optional": true - } } }, "readable-stream": { - "version": "2.3.6", + "version": "2.3.7", "bundled": true, "dev": true, "optional": true, @@ -12242,6 +13760,12 @@ } } }, + "is-absolute-url": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/is-absolute-url/-/is-absolute-url-3.0.3.tgz", + "integrity": "sha512-opmNIX7uFnS96NtPmhWQgQx6/NYFgsUXYMllcfzwWKUMwfo8kku1TvE6hkNcH+Q1ts5cMVrsY7j0bxXQDciu9Q==", + "dev": true + }, "is-binary-path": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-1.0.1.tgz", @@ -12312,12 +13836,12 @@ } }, "webpack-merge": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/webpack-merge/-/webpack-merge-4.2.1.tgz", - "integrity": "sha512-4p8WQyS98bUJcCvFMbdGZyZmsKuWjWVnVHnAS3FFg0HDaRVrPbkivx2RYCre8UiemD67RsiFFLfn4JhLAin8Vw==", + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/webpack-merge/-/webpack-merge-4.2.2.tgz", + "integrity": "sha512-TUE1UGoTX2Cd42j3krGYqObZbOD+xF7u28WB7tfUordytSjbWTIjK/8V0amkBfTYN4/pB/GIDlJZZ657BGG19g==", "dev": true, "requires": { - "lodash": "^4.17.5" + "lodash": "^4.17.15" } }, "webpack-sources": { @@ -12339,12 +13863,12 @@ } }, "webpack-subresource-integrity": { - "version": "1.1.0-rc.6", - "resolved": "https://registry.npmjs.org/webpack-subresource-integrity/-/webpack-subresource-integrity-1.1.0-rc.6.tgz", - "integrity": "sha512-Az7y8xTniNhaA0620AV1KPwWOqawurVVDzQSpPAeR5RwNbL91GoBSJAAo9cfd+GiFHwsS5bbHepBw1e6Hzxy4w==", + "version": "1.3.4", + "resolved": "https://registry.npmjs.org/webpack-subresource-integrity/-/webpack-subresource-integrity-1.3.4.tgz", + "integrity": "sha512-6XbGYzjh30cGQT/NsC+9IAkJP8IL7/t47sbwR5DLSsamiD56Rwv4/+hsgEHsviPvrEFZ0JRAQtCRN3UsR2Pw9g==", "dev": true, "requires": { - "webpack-core": "^0.6.8" + "webpack-sources": "^1.3.0" } }, "websocket-driver": { @@ -12374,7 +13898,6 @@ "version": "1.3.1", "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", - "dev": true, "requires": { "isexe": "^2.0.0" } @@ -12385,6 +13908,14 @@ "integrity": "sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho=", "dev": true }, + "wide-align": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/wide-align/-/wide-align-1.1.3.tgz", + "integrity": "sha512-QGkOQc8XL6Bt5PwnsExKBPuMKBxnGxWWW3fU55Xt4feHozMUhdUMaBCk290qpm/wG5u/RSKzwdAC4i51YigihA==", + "requires": { + "string-width": "^1.0.2 || 2" + } + }, "wordwrap": { "version": "0.0.3", "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-0.0.3.tgz", @@ -12413,7 +13944,6 @@ "version": "2.1.0", "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-2.1.0.tgz", "integrity": "sha1-2Pw9KE3QV5T+hJc8rs3Rz4JP3YU=", - "dev": true, "requires": { "string-width": "^1.0.1", "strip-ansi": "^3.0.1" @@ -12423,7 +13953,6 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz", "integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=", - "dev": true, "requires": { "number-is-nan": "^1.0.0" } @@ -12432,7 +13961,6 @@ "version": "1.0.2", "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz", "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=", - "dev": true, "requires": { "code-point-at": "^1.0.0", "is-fullwidth-code-point": "^1.0.0", @@ -12444,8 +13972,7 @@ "wrappy": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", - "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", - "dev": true + "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=" }, "ws": { "version": "6.2.1", @@ -12499,9 +14026,9 @@ "dev": true }, "yallist": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", - "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==", + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", "dev": true }, "yamlparser": { @@ -12552,9 +14079,9 @@ "dev": true }, "zone.js": { - "version": "0.9.1", - "resolved": "https://registry.npmjs.org/zone.js/-/zone.js-0.9.1.tgz", - "integrity": "sha512-GkPiJL8jifSrKReKaTZ5jkhrMEgXbXYC+IPo1iquBjayRa0q86w3Dipjn8b415jpitMExe9lV8iTsv8tk3DGag==" + "version": "0.10.3", + "resolved": "https://registry.npmjs.org/zone.js/-/zone.js-0.10.3.tgz", + "integrity": "sha512-LXVLVEq0NNOqK/fLJo3d0kfzd4sxwn2/h67/02pjCjfKDxgx1i9QqpvtHD8CrBnSSwMw5+dy11O7FRX5mkO7Cg==" } } } diff --git a/package.json b/package.json index 5705f0cbfdea0dcc1c5cb3c1c6fd73a56b73034c..34de28b59be1f391dc075c7e09bf4e9382892732 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "itc-ng", - "version": "2.0.0-alpha", + "version": "3.1.0", "scripts": { "ng": "ng", "start": "ng serve", @@ -11,41 +11,42 @@ }, "private": true, "dependencies": { - "@angular/animations": "~8.2.14", - "@angular/cdk": "~8.2.3", - "@angular/common": "~8.2.14", - "@angular/compiler": "~8.2.14", - "@angular/core": "~8.2.14", - "@angular/flex-layout": "~8.0.0-beta.27", - "@angular/forms": "~8.2.14", - "@angular/material": "~8.2.3", - "@angular/platform-browser": "~8.2.14", - "@angular/platform-browser-dynamic": "~8.2.14", - "@angular/router": "~8.2.14", + "@angular/animations": "~9.0.6", + "@angular/cdk": "^9.1.2", + "@angular/common": "~9.0.6", + "@angular/compiler": "~9.0.6", + "@angular/core": "~9.0.6", + "@angular/flex-layout": "^9.0.0-beta.29", + "@angular/forms": "~9.0.6", + "@angular/material": "^9.1.2", + "@angular/platform-browser": "~9.0.6", + "@angular/platform-browser-dynamic": "~9.0.6", + "@angular/router": "~9.0.6", + "core-js": "~3.6.4", "@types/file-saver": "^2.0.1", "classlist.js": "^1.1.20150312", - "core-js": "^3.6.4", "file-saver": "^2.0.2", - "hammerjs": "^2.0.8", - "iqb-components": "1.6.x", - "rxjs": "^6.5.4", - "srcdoc-polyfill": "git+https://github.com/jugglinmike/srcdoc-polyfill.git", + "iqb-components": "^1.7.2", + "sass-loader": "^8.0.2", + "node-sass": "^4.13.1", + "fibers": "^4.0.2", + "html-webpack-plugin": "^3.2.0", + "material-design-icons": "~3.0.1", + "rxjs": "~6.5.4", "tslib": "^1.10.0", + "zone.js": "~0.10.2", + "srcdoc-polyfill": "git+https://github.com/jugglinmike/srcdoc-polyfill.git", "ua-parser": "^0.3.5", "ua-parser-js": "^0.7.21", - "web-animations-js": "^2.3.2", - "zone.js": "~0.9.1" + "web-animations-js": "^2.3.2" }, "devDependencies": { - "@angular-devkit/build-angular": "~0.803.23", - "@angular/cli": "~8.3.23", - "@angular/compiler-cli": "~8.2.14", - "@angular/language-service": "~8.2.14", - "@types/jasmine": "^3.5.1", + "@angular-devkit/build-angular": "~0.900.7", + "@angular/cli": "~9.0.6", + "@angular/compiler-cli": "~9.0.6", + "@angular/language-service": "~9.0.6", "@types/jasminewd2": "~2.0.8", - "@types/node": "^13.5.0", - "codelyzer": "^5.0.1", - "classlist.js": "1.1.20150312", + "codelyzer": "^5.1.2", "jasmine-core": "~3.5.0", "jasmine-spec-reporter": "~4.2.1", "karma": "~4.4.1", @@ -53,12 +54,10 @@ "karma-coverage-istanbul-reporter": "^2.1.1", "karma-jasmine": "~3.1.0", "karma-jasmine-html-reporter": "~1.5.1", - "protractor": "^5.4.2", - "ua-parser-js": "0.7.21", "ts-node": "~8.6.2", "tslint": "~5.20.1", - "typescript": "~3.5.0", - "web-animations-js": "2.3.2" + "typescript": "~3.7.5", + "protractor": "^5.4.3" }, "resolutions": { "tree-kill": "1.2.2" diff --git a/src/app/about/about.component.css b/src/app/about/about.component.css deleted file mode 100644 index 5b0d7dccc5371ab0350d50bf7bfddadcc41c2715..0000000000000000000000000000000000000000 --- a/src/app/about/about.component.css +++ /dev/null @@ -1,7 +0,0 @@ -.mat-card { - margin: 10px; -} - -.status { - background-color: lightgrey; -} diff --git a/src/app/about/about.component.html b/src/app/about/about.component.html deleted file mode 100644 index 7a2f2ed35271eacffbc9980c0dee508bdfeed206..0000000000000000000000000000000000000000 --- a/src/app/about/about.component.html +++ /dev/null @@ -1,55 +0,0 @@ -<div class="logo"> - <a [routerLink]="['/']"> - <img src="assets/IQB-LogoA.png" matTooltip="Startseite" alt="IQB-logo"/> - </a> -</div> -<div class="page-body"> - <div fxLayout="row" fxLayoutAlign="center start"> - <mat-card fxFlex="0 2 500px"> - <mat-card-title>IQB-Testcenter - Impressum/Datenschutz</mat-card-title> - - <!-- - - - - - - - - - - - - - - - - --> - <mat-card-content> - <p>Das <a href="http://www.iqb.hu-berlin.de" target="_blank">Institut zur Qualitätsentwicklung im Bildungswesen</a> - {{ 'app_intro1' | customtext:'app_intro1':cts.updateCount }}</p> - - <p>Die mit diesem System erhobenen Daten enthalten grundsätzlich keinen direkten - Personenbezug. Es werden z. B. nie Namen gespeichert. Um Auskünfte zu einer bestimmten Befragung bzw. Studie - zu erhalten, wenden Sie sich bitte an das <a href="mailto:mechtel@iqb.hu-berlin.de"> - IQB</a>. Wir benötigen dazu den ungefähren Zeitraum und das Bundesland, in dem die Befragung bzw. Studie - durchgeführt wurde.</p> - - <ul> - <li>Programmname: {{ appName }}</li> - <li>Programmversion: {{ appVersion }}</li> - <li>Copyright: {{ appPublisher }}</li> - </ul> - - <p> - <em>Postanschrift:</em><br/> - Humboldt-Universität zu Berlin<br/> - Institut zur Qualitätsentwicklung im Bildungswesen<br/> - Unter den Linden 6<br/> - 10099 Berlin</p> - <p> - <em>Sitz:</em><br/> - Luisenstr. 56<br/> - 10117 Berlin<br/> - Tel: +49 [30] 2093 - 46500 (Zentrale)<br/> - Fax: +49 [30] 2093 - 46599<br/> - E-Mail: <a href="mailto:iqboffice@iqb.hu-berlin.de">iqboffice@iqb.hu-berlin.de</a> - </p> - <p> - <em>Name und Anschrift der Datenschutzbeauftragten</em><br/> - Frau Gesine Hoffmann-Holland<br/> - Tel: +49 (30) 2093-2591<br/> - E-Mail: datenschutz@uv.hu-berlin.de<br/> - <a href="http://www.hu-berlin.de/de/datenschutz" target="_blank">www.hu-berlin.de/de/datenschutz</a> - </p> - </mat-card-content> - <mat-card-actions> - <button (click)="goBack()" mat-raised-button color="primary"><i class="material-icons">arrow_back</i> zurück zur Startseite</button> - </mat-card-actions> - </mat-card> - </div> -</div> diff --git a/src/app/about/about.component.spec.ts b/src/app/about/about.component.spec.ts deleted file mode 100644 index 6b773448f933eb773b9c1ecb26ce65ee19fc1e5d..0000000000000000000000000000000000000000 --- a/src/app/about/about.component.spec.ts +++ /dev/null @@ -1,25 +0,0 @@ -import { async, ComponentFixture, TestBed } from '@angular/core/testing'; - -import { AboutComponent } from './about.component'; - -describe('AboutComponent', () => { - let component: AboutComponent; - let fixture: ComponentFixture<AboutComponent>; - - beforeEach(async(() => { - TestBed.configureTestingModule({ - declarations: [ AboutComponent ] - }) - .compileComponents(); - })); - - beforeEach(() => { - fixture = TestBed.createComponent(AboutComponent); - component = fixture.componentInstance; - fixture.detectChanges(); - }); - - it('should create', () => { - expect(component).toBeTruthy(); - }); -}); diff --git a/src/app/about/about.component.ts b/src/app/about/about.component.ts deleted file mode 100644 index 990f371830d04c01c9ba594c646da8aa30ff1cd0..0000000000000000000000000000000000000000 --- a/src/app/about/about.component.ts +++ /dev/null @@ -1,21 +0,0 @@ -import { Component, Inject } from '@angular/core'; -import { Router } from '@angular/router'; -import { CustomtextService } from 'iqb-components'; - -@Component({ - templateUrl: './about.component.html' -}) -export class AboutComponent { - - constructor( - @Inject('APP_NAME') public appName: string, - @Inject('APP_PUBLISHER') public appPublisher: string, - @Inject('APP_VERSION') public appVersion: string, - private router: Router, - public cts: CustomtextService - ) { } - - goBack() { - this.router.navigate(['/']); - } -} diff --git a/src/app/app-root/admin-starter/admin-starter.component.html b/src/app/app-root/admin-starter/admin-starter.component.html new file mode 100644 index 0000000000000000000000000000000000000000..cfc808f8446e6b2ac38e235692f063fd0c91c88b --- /dev/null +++ b/src/app/app-root/admin-starter/admin-starter.component.html @@ -0,0 +1,30 @@ +<div fxLayout="row wrap" fxLayoutAlign="center stretch"> + <mat-card fxFlex="0 0 400px" fxLayout="column"> + <mat-card-title>Verwaltung: Bitte Studie wählen</mat-card-title> + <mat-card-content> + <div fxLayoutGap="10px" fxLayout="column"> + <p *ngIf="workspaces.length === 0"> + Sie sind mit Administrator-Funktionen angemeldet. Aktuell sind keine Studien für Sie freigegeben. + </p> + <button mat-raised-button color="primary" (click)="buttonGotoWorkspaceAdmin(ws)" + *ngFor="let ws of workspaces"> + {{ws.name}} + </button> + </div> + </mat-card-content> + <mat-card-actions> + <button mat-raised-button color="foreground" *ngIf="isSuperAdmin" [routerLink]="['/superadmin']">System-Admin</button> + <button mat-raised-button color="foreground" (click)="resetLogin()">Neu anmelden</button> + </mat-card-actions> + </mat-card> + + <mat-card fxFlex="0 0 400px" class="mat-card-gray"> + <mat-card-title>{{ 'app_title' | customtext:'app_title':cts.updateCount }}</mat-card-title> + + <mat-card-content> + + <status-card></status-card> + + </mat-card-content> + </mat-card> +</div> diff --git a/src/app/app-root/admin-starter/admin-starter.component.spec.ts b/src/app/app-root/admin-starter/admin-starter.component.spec.ts new file mode 100644 index 0000000000000000000000000000000000000000..88ba4e858719d9aeeccbcb1160016cb642a3b8ad --- /dev/null +++ b/src/app/app-root/admin-starter/admin-starter.component.spec.ts @@ -0,0 +1,37 @@ +import { async, ComponentFixture, TestBed } from '@angular/core/testing'; + +import { AdminStarterComponent } from './admin-starter.component'; +import {AppRoutingModule} from "../../app-routing.module"; +import {HttpClientModule} from "@angular/common/http"; +import {IqbComponentsModule} from "iqb-components"; +import {BackendService} from "../../backend.service"; + +describe('AdminStarterComponent', () => { + let component: AdminStarterComponent; + let fixture: ComponentFixture<AdminStarterComponent>; + + beforeEach(async(() => { + TestBed.configureTestingModule({ + declarations: [ AdminStarterComponent ], + imports: [ + HttpClientModule, + AppRoutingModule, + IqbComponentsModule + ], + providers: [ + BackendService + ] + }) + .compileComponents(); + })); + + beforeEach(() => { + fixture = TestBed.createComponent(AdminStarterComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/src/app/app-root/admin-starter/admin-starter.component.ts b/src/app/app-root/admin-starter/admin-starter.component.ts new file mode 100644 index 0000000000000000000000000000000000000000..233469548c53b92071b50d25e306fbe3919c433d --- /dev/null +++ b/src/app/app-root/admin-starter/admin-starter.component.ts @@ -0,0 +1,89 @@ +import {Component, OnDestroy, OnInit} from '@angular/core'; +import {MainDataService} from "../../maindata.service"; +import {Router} from "@angular/router"; +import {AuthAccessKeyType, AuthData, WorkspaceData} from "../../app.interfaces"; +import {from, Subscription} from "rxjs"; +import {concatMap} from "rxjs/operators"; +import {BackendService} from "../../backend.service"; +import {CustomtextService} from "iqb-components"; + + +@Component({ + templateUrl: './admin-starter.component.html', + styles: [ + 'mat-card {margin: 10px;}', + '.mat-card-gray {background-color: lightgray}' + ] +}) + +export class AdminStarterComponent implements OnInit, OnDestroy { + workspaces: WorkspaceData[] = []; + isSuperAdmin = false; + private getWorkspaceDataSubscription: Subscription = null; + + constructor( + private router: Router, + private bs: BackendService, + public cts: CustomtextService, + private mds: MainDataService + ) { } + + ngOnInit() { + setTimeout(() => { + this.mds.setSpinnerOn(); + this.bs.getSessionData().subscribe(authDataUntyped => { + if (this.getWorkspaceDataSubscription !== null) { + this.getWorkspaceDataSubscription.unsubscribe(); + } + + if (typeof authDataUntyped !== 'number') { + const authData = authDataUntyped as AuthData; + if (authData) { + if (authData.token) { + if (authData.access[AuthAccessKeyType.SUPER_ADMIN]) { + this.isSuperAdmin = true; + } + if (authData.access[AuthAccessKeyType.WORKSPACE_ADMIN]) { + this.workspaces = []; + this.getWorkspaceDataSubscription = from(authData.access[AuthAccessKeyType.WORKSPACE_ADMIN]).pipe( + concatMap(workspaceId => { + return this.bs.getWorkspaceData(workspaceId) + })).subscribe( + wsData => this.workspaces.push(wsData), + () => this.mds.setSpinnerOff(), + () => this.mds.setSpinnerOff() + ); + } else { + this.mds.setSpinnerOff(); + } + this.mds.setAuthData(authData); + } else { + this.mds.setAuthData(); + this.mds.setSpinnerOff(); + } + } else { + this.mds.setAuthData(); + this.mds.setSpinnerOff(); + } + } else { + this.mds.setSpinnerOff(); + } + }) + }); + } + + buttonGotoWorkspaceAdmin(ws: WorkspaceData) { + this.router.navigateByUrl('/admin/' + ws.id.toString() + '/files'); + } + + resetLogin() { + this.mds.setAuthData(); + this.router.navigate(['/']); + } + + ngOnDestroy() { + if (this.getWorkspaceDataSubscription !== null) { + this.getWorkspaceDataSubscription.unsubscribe(); + } + } +} diff --git a/src/app/sys-check/start.component.spec.ts b/src/app/app-root/app-root.component.spec.ts similarity index 56% rename from src/app/sys-check/start.component.spec.ts rename to src/app/app-root/app-root.component.spec.ts index 01270a2d580aa35fc43d8414799fa61e7e02e140..79d00922c309ed491417b3b2f8ed808f1bd47b69 100644 --- a/src/app/sys-check/start.component.spec.ts +++ b/src/app/app-root/app-root.component.spec.ts @@ -1,20 +1,20 @@ import { async, ComponentFixture, TestBed } from '@angular/core/testing'; -import { StartComponent } from './start.component'; +import { AppRootComponent } from './app-root.component'; -describe('StartComponent', () => { - let component: StartComponent; - let fixture: ComponentFixture<StartComponent>; +describe('AppRootComponent', () => { + let component: AppRootComponent; + let fixture: ComponentFixture<AppRootComponent>; beforeEach(async(() => { TestBed.configureTestingModule({ - declarations: [ StartComponent ] + declarations: [ AppRootComponent ], }) .compileComponents(); })); beforeEach(() => { - fixture = TestBed.createComponent(StartComponent); + fixture = TestBed.createComponent(AppRootComponent); component = fixture.componentInstance; fixture.detectChanges(); }); diff --git a/src/app/app-root/app-root.component.ts b/src/app/app-root/app-root.component.ts new file mode 100644 index 0000000000000000000000000000000000000000..424add3c787d5555f4a62c325f9797e462250039 --- /dev/null +++ b/src/app/app-root/app-root.component.ts @@ -0,0 +1,10 @@ +import {Component} from '@angular/core'; + +@Component({ + template: `<div class="root-body"> + <router-outlet></router-outlet> + </div> + ` +}) +export class AppRootComponent { +} diff --git a/src/app/app-root/code-input/code-input.component.html b/src/app/app-root/code-input/code-input.component.html new file mode 100644 index 0000000000000000000000000000000000000000..b0a54d8f8eca935568275e9682ae734491465f8e --- /dev/null +++ b/src/app/app-root/code-input/code-input.component.html @@ -0,0 +1,31 @@ +<div fxLayout="row wrap" fxLayoutAlign="center stretch"> + <mat-card fxFlex="0 0 400px"> + <form [formGroup]="codeinputform" (ngSubmit)="codeinput()"> + <mat-card-title>{{ 'login_codeInputTitle' | customtext:'login_codeInputTitle':cts.updateCount }}</mat-card-title> + <mat-card-subtitle>{{ 'login_codeInputPrompt' | customtext:'login_codeInputPrompt':cts.updateCount }}</mat-card-subtitle> + <mat-card-content> + <mat-form-field> + <input matInput formControlName="code"> <!-- no placeholder! --> + </mat-form-field> + <p style="color: chocolate"><b>{{ problemText }}</b></p> + </mat-card-content> + <mat-card-actions> + <button mat-raised-button type="submit" [disabled]="codeinputform.invalid" color="primary">Weiter</button> + <button mat-raised-button color="foreground" (click)="resetLogin()">Neu anmelden</button> + </mat-card-actions> + </form> + </mat-card> + + <mat-card fxFlex="0 0 400px" class="mat-card-gray"> + <mat-card-title>{{ 'app_title' | customtext:'app_title':cts.updateCount }}</mat-card-title> + + <mat-card-content> + + <status-card></status-card> + + </mat-card-content> + <mat-card-actions> + <button [routerLink]="['/priv']" mat-raised-button color="primary">Impressum/Datenschutz</button> + </mat-card-actions> + </mat-card> +</div> diff --git a/src/app/app-root/code-input/code-input.component.spec.ts b/src/app/app-root/code-input/code-input.component.spec.ts new file mode 100644 index 0000000000000000000000000000000000000000..786fcfedda1d7e6aacb4a498a205dac2f73cbd83 --- /dev/null +++ b/src/app/app-root/code-input/code-input.component.spec.ts @@ -0,0 +1,39 @@ +import { async, ComponentFixture, TestBed } from '@angular/core/testing'; + +import { CodeInputComponent } from './code-input.component'; +import {AppRoutingModule} from "../../app-routing.module"; +import {HttpClientModule} from "@angular/common/http"; +import {ReactiveFormsModule} from "@angular/forms"; +import {IqbComponentsModule} from "iqb-components"; +import {BackendService} from "../../backend.service"; + +describe('CodeInputComponent', () => { + let component: CodeInputComponent; + let fixture: ComponentFixture<CodeInputComponent>; + + beforeEach(async(() => { + TestBed.configureTestingModule({ + declarations: [ CodeInputComponent ], + imports: [ + HttpClientModule, + ReactiveFormsModule, + AppRoutingModule, + IqbComponentsModule + ], + providers: [ + BackendService + ] + }) + .compileComponents(); + })); + + beforeEach(() => { + fixture = TestBed.createComponent(CodeInputComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/src/app/app-root/code-input/code-input.component.ts b/src/app/app-root/code-input/code-input.component.ts new file mode 100644 index 0000000000000000000000000000000000000000..c3db5a06a08c81d6346d26eeb1f02acc1266befb --- /dev/null +++ b/src/app/app-root/code-input/code-input.component.ts @@ -0,0 +1,82 @@ +import {Component, OnInit, ViewChild} from '@angular/core'; +import {Router} from "@angular/router"; +import {MainDataService} from "../../maindata.service"; +import {FormControl, FormGroup, Validators} from "@angular/forms"; +import {CustomtextService, MessageDialogComponent, MessageDialogData, MessageType} from "iqb-components"; +import {MatDialog} from "@angular/material/dialog"; +import {AuthData} from "../../app.interfaces"; +import {BackendService} from "../../backend.service"; + +@Component({ + templateUrl: './code-input.component.html', + styles: [ + 'mat-card {margin: 10px;}', + '.mat-card-gray {background-color: lightgray}' + ] +}) +export class CodeInputComponent implements OnInit{ + @ViewChild('codeInputControl') codeInputControl: FormControl; + problemText = ''; + + codeinputform = new FormGroup({ + code: new FormControl('', [Validators.required, Validators.minLength(2)]), + }); + + constructor( + private router: Router, + public messageDialog: MatDialog, + public cts: CustomtextService, + public bs: BackendService, + public mds: MainDataService + ) { } + + ngOnInit(): void { + setTimeout(() => { + const element = <any>document.querySelector('.mat-input-element[formControlName="code"]'); + if (element) { + element.focus(); + } + }) + } + + codeinput() { + const codeData = this.codeinputform.value; + if (codeData['code'].length === 0) { + this.messageDialog.open(MessageDialogComponent, { + width: '400px', + data: <MessageDialogData>{ + // @ts-ignore + title: this.cts.getCustomText('login_codeInputTitle') + ': Leer', + // @ts-ignore + content: this.cts.getCustomText('login_codeInputPrompt'), + type: MessageType.error + } + }); + } else { + this.mds.setSpinnerOn(); + this.bs.codeLogin(codeData['code']).subscribe( + authData => { + this.mds.setSpinnerOff(); + this.problemText = ''; + if (typeof authData === 'number') { + const errCode = authData as number; + if (errCode === 400) { + this.problemText = 'Der Code ist leider nicht gültig. Bitte nocheinmal versuchen'; + } else { + this.problemText = 'Problem bei der Anmeldung.'; + // app.interceptor will show error message + } + } else { + const authDataTyped = authData as AuthData; + this.mds.setAuthData(authDataTyped); + this.router.navigate(['/r']); + } + }) + } + } + + resetLogin() { + this.mds.setAuthData(); + this.router.navigate(['/']); + } +} diff --git a/src/app/app-root/login/login.component.html b/src/app/app-root/login/login.component.html new file mode 100644 index 0000000000000000000000000000000000000000..1320054bf45d896e2c44dcfe5ace0fb410deaf43 --- /dev/null +++ b/src/app/app-root/login/login.component.html @@ -0,0 +1,35 @@ +<div fxLayout="row wrap" fxLayoutAlign="center stretch"> + <mat-card fxFlex="0 0 400px"> + <form [formGroup]="loginForm" (ngSubmit)="login()" *ngIf="mds.isApiValid"> + <mat-card-title>Anmelden</mat-card-title> + <mat-card-content fxLayout="column"> + <mat-form-field> + <input matInput formControlName="name" placeholder="Anmeldename" (keyup.enter)="pw.focus()"> + </mat-form-field> + <mat-form-field> + <input matInput #pw type="password" formControlName="pw" placeholder="Kennwort"> + </mat-form-field> + </mat-card-content> + <mat-card-actions> + <button mat-raised-button type="submit" [disabled]="loginForm.invalid" color="primary">Weiter</button> + </mat-card-actions> + </form> + <p style="color: chocolate"><b>{{ problemText }}</b></p> + <p style="color: chocolate" *ngIf="!mds.isApiValid"><b>Die Verbindung mit dem Server ist nicht möglich.</b></p> + </mat-card> + + <mat-card fxFlex="0 0 400px" class="mat-card-gray"> + <mat-card-title>{{ 'IQB-Testcenter' | customtext:'app_title':cts.updateCount }}</mat-card-title> + + <mat-card-content> + <p>Das <a href="http://www.iqb.hu-berlin.de" target="_blank">Institut zur Qualitätsentwicklung im Bildungswesen</a> + {{ '' | customtext:'app_intro1':cts.updateCount }}</p> + + <status-card></status-card> + </mat-card-content> + <mat-card-actions> + <button *ngIf="this.mds.sysCheckAvailable" [routerLink]="['/r/check-starter']" mat-raised-button color="primary">System-Check</button> + <button [routerLink]="['/priv']" mat-raised-button color="primary">Impressum/Datenschutz</button> + </mat-card-actions> + </mat-card> +</div> diff --git a/src/app/app-root/login/login.component.spec.ts b/src/app/app-root/login/login.component.spec.ts new file mode 100644 index 0000000000000000000000000000000000000000..64c03ad076d5bdce6b41c3cb06271ca6c115d7c9 --- /dev/null +++ b/src/app/app-root/login/login.component.spec.ts @@ -0,0 +1,39 @@ +import { async, ComponentFixture, TestBed } from '@angular/core/testing'; + +import { LoginComponent } from './login.component'; +import {HttpClientModule} from "@angular/common/http"; +import {ReactiveFormsModule} from "@angular/forms"; +import {AppRoutingModule} from "../../app-routing.module"; +import {IqbComponentsModule} from "iqb-components"; +import {BackendService} from "../../backend.service"; + +describe('LoginComponent', () => { + let component: LoginComponent; + let fixture: ComponentFixture<LoginComponent>; + + beforeEach(async(() => { + TestBed.configureTestingModule({ + declarations: [ LoginComponent ], + imports: [ + HttpClientModule, + ReactiveFormsModule, + AppRoutingModule, + IqbComponentsModule + ], + providers: [ + BackendService + ] + }) + .compileComponents(); + })); + + beforeEach(() => { + fixture = TestBed.createComponent(LoginComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/src/app/app-root/login/login.component.ts b/src/app/app-root/login/login.component.ts new file mode 100644 index 0000000000000000000000000000000000000000..df90df85ec456ddf74904d7f87e806eb6cc6f383 --- /dev/null +++ b/src/app/app-root/login/login.component.ts @@ -0,0 +1,79 @@ +import {Component, OnDestroy, OnInit} from '@angular/core'; +import {FormControl, FormGroup, Validators} from "@angular/forms"; +import {MainDataService} from "../../maindata.service"; +import {CustomtextService} from "iqb-components"; +import {ActivatedRoute, Router} from "@angular/router"; +import {Subscription} from "rxjs"; +import {AuthData} from "../../app.interfaces"; +import {BackendService} from "../../backend.service"; + +@Component({ + templateUrl: './login.component.html', + styles: [ + 'mat-card {margin: 10px;}', + '.mat-card-gray {background-color: lightgray}' + ] +}) + +export class LoginComponent implements OnInit, OnDestroy { + private routingSubscription: Subscription = null; + static oldLoginName = ''; + returnTo = ''; + problemText = ''; + + loginForm = new FormGroup({ + name: new FormControl(LoginComponent.oldLoginName, [Validators.required, Validators.minLength(3)]), + pw: new FormControl('') + }); + + constructor( + public mds: MainDataService, + public cts: CustomtextService, + private bs: BackendService, + private router: Router, + private route: ActivatedRoute + ) { } + + ngOnInit(): void { + this.mds.setSpinnerOff(); + this.routingSubscription = this.route.params.subscribe(params => { + this.returnTo = params['returnTo']; + }) + } + + login() { + const loginData = this.loginForm.value; + LoginComponent.oldLoginName = loginData['name']; + this.mds.setSpinnerOn(); + this.bs.login(loginData['name'], loginData['pw']).subscribe( + authData => { + this.mds.setSpinnerOff(); + this.problemText = ''; + if (typeof authData === 'number') { + const errCode = authData as number; + if (errCode === 400) { + this.problemText = 'Anmeldedaten sind nicht gültig. Bitte nocheinmal versuchen!'; + } else { + this.problemText = 'Problem bei der Anmeldung.'; + // app.interceptor will show error message + } + } else { + const authDataTyped = authData as AuthData; + this.mds.setAuthData(authDataTyped); + + if (this.returnTo) { + this.router.navigateByUrl(this.returnTo); + } else { + this.router.navigate(['/r']); + } + } + } + ); + } + + ngOnDestroy() { + if (this.routingSubscription !== null) { + this.routingSubscription.unsubscribe(); + } + } +} diff --git a/src/app/app-root/monitor-starter/monitor-starter.component.html b/src/app/app-root/monitor-starter/monitor-starter.component.html new file mode 100644 index 0000000000000000000000000000000000000000..da1cc929f542f34a58a8ac6188c2b3013d75be52 --- /dev/null +++ b/src/app/app-root/monitor-starter/monitor-starter.component.html @@ -0,0 +1,29 @@ +<div fxLayout="row wrap" fxLayoutAlign="center stretch"> + <mat-card fxFlex="0 0 400px" fxLayout="column"> + <mat-card-title>Testdurchführung überwachen</mat-card-title> + <mat-card-content> + <div fxLayoutGap="10px" fxLayout="column"> + <p *ngIf="workspaces.length === 0"> + Sie sind angemeldet. Aktuell sind keine Bereiche zur Überwachung für Sie freigegeben. + </p> + <button mat-raised-button color="primary" (click)="buttonGotoMonitor(ws)" + *ngFor="let ws of workspaces"> + {{ws.name}} + </button> + </div> + </mat-card-content> + <mat-card-actions> + <button mat-raised-button color="foreground" (click)="resetLogin()">Neu anmelden</button> + </mat-card-actions> + </mat-card> + + <mat-card fxFlex="0 0 400px" class="mat-card-gray"> + <mat-card-title>{{ 'app_title' | customtext:'app_title':cts.updateCount }}</mat-card-title> + + <mat-card-content> + + <status-card></status-card> + + </mat-card-content> + </mat-card> +</div> diff --git a/src/app/app-root/monitor-starter/monitor-starter.component.spec.ts b/src/app/app-root/monitor-starter/monitor-starter.component.spec.ts new file mode 100644 index 0000000000000000000000000000000000000000..50fc473dc82563a3f883e1d817194bb0e541dec1 --- /dev/null +++ b/src/app/app-root/monitor-starter/monitor-starter.component.spec.ts @@ -0,0 +1,38 @@ +import { async, ComponentFixture, TestBed } from '@angular/core/testing'; + +import { MonitorStarterComponent } from './monitor-starter.component'; +import {AppRoutingModule} from "../../app-routing.module"; +import {BackendService} from "../../test-controller/backend.service"; +import {MainDataService} from "../../maindata.service"; +import {HttpClientModule} from "@angular/common/http"; +import {IqbComponentsModule} from "iqb-components"; + +describe('MonitorStarterComponent', () => { + let component: MonitorStarterComponent; + let fixture: ComponentFixture<MonitorStarterComponent>; + + beforeEach(async(() => { + TestBed.configureTestingModule({ + declarations: [ MonitorStarterComponent ], + imports: [ + AppRoutingModule, + IqbComponentsModule, + HttpClientModule], + providers: [ + MainDataService, + BackendService + ], + }) + .compileComponents(); + })); + + beforeEach(() => { + fixture = TestBed.createComponent(MonitorStarterComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/src/app/app-root/monitor-starter/monitor-starter.component.ts b/src/app/app-root/monitor-starter/monitor-starter.component.ts new file mode 100644 index 0000000000000000000000000000000000000000..2f68a2aa825c87993e952188f76faf7da80bee91 --- /dev/null +++ b/src/app/app-root/monitor-starter/monitor-starter.component.ts @@ -0,0 +1,91 @@ +import {Component, OnDestroy, OnInit} from '@angular/core'; +import {AuthAccessKeyType, AuthData, WorkspaceData} from "../../app.interfaces"; +import {from, Subscription} from "rxjs"; +import {Router} from "@angular/router"; +import {BackendService} from "../../backend.service"; +import {MainDataService} from "../../maindata.service"; +import {concatMap} from "rxjs/operators"; +import {CustomtextService} from "iqb-components"; + +@Component({ + templateUrl: './monitor-starter.component.html', + styles: [ + 'mat-card {margin: 10px;}', + '.mat-card-gray {background-color: lightgray}' + ] +}) +export class MonitorStarterComponent implements OnInit, OnDestroy { + workspaces: WorkspaceData[] = []; + isWorkspaceMonitor = false; + private getWorkspaceDataSubscription: Subscription = null; + + constructor( + private router: Router, + private bs: BackendService, + public cts: CustomtextService, + private mds: MainDataService + ) { } + + ngOnInit() { + setTimeout(() => { + this.mds.setSpinnerOn(); + this.bs.getSessionData().subscribe(authDataUntyped => { + if (typeof authDataUntyped !== 'number') { + const authData = authDataUntyped as AuthData; + if (authData) { + if (authData.token) { + this.workspaces = []; + let scopeIdList = []; + if (authData.access[AuthAccessKeyType.TEST_GROUP_MONITOR]) { + scopeIdList = authData.access[AuthAccessKeyType.TEST_GROUP_MONITOR]; + this.isWorkspaceMonitor = false; + } else if (authData.access[AuthAccessKeyType.WORKSPACE_MONITOR]) { + scopeIdList = authData.access[AuthAccessKeyType.WORKSPACE_MONITOR]; + this.isWorkspaceMonitor = true; + } + if (this.getWorkspaceDataSubscription !== null) { + this.getWorkspaceDataSubscription.unsubscribe(); + } + this.getWorkspaceDataSubscription = from(scopeIdList).pipe( + concatMap(monitorScopeId => { + return this.bs.getWorkspaceData(monitorScopeId) + })).subscribe( + wsData => this.workspaces.push(wsData), + () => this.mds.setSpinnerOff(), + () => this.mds.setSpinnerOff() + ); + this.mds.setAuthData(authData); + } else { + this.mds.setAuthData(); + this.mds.setSpinnerOff(); + } + } else { + this.mds.setAuthData(); + this.mds.setSpinnerOff(); + } + } else { + this.mds.setSpinnerOff(); + } + }) + }); + } + + buttonGotoMonitor(ws: WorkspaceData) { + if (this.isWorkspaceMonitor) { + this.router.navigateByUrl('/wm/' + ws.id.toString()); + } else { + this.router.navigateByUrl('/gm/' + ws.id.toString()); + } + } + + resetLogin() { + this.mds.setAuthData(); + this.router.navigate(['/']); + } + + ngOnDestroy() { + if (this.getWorkspaceDataSubscription !== null) { + this.getWorkspaceDataSubscription.unsubscribe(); + } + } +} diff --git a/src/app/app-root/privacy/privacy.component.html b/src/app/app-root/privacy/privacy.component.html new file mode 100644 index 0000000000000000000000000000000000000000..f2d3b18d4b8c0d3215ca08cc749a01438a561220 --- /dev/null +++ b/src/app/app-root/privacy/privacy.component.html @@ -0,0 +1,46 @@ +<!-- this component is not sub route of app-root ! --> +<div class="root-body"> + <div fxLayout="row" fxLayoutAlign="center stretch"> + <mat-card fxFlex="0 0 500px"> + <mat-card-title>{{ 'app_title' | customtext:'app_title':cts.updateCount }} - Impressum/Datenschutz</mat-card-title> + + <!-- - - - - - - - - - - - - - - - - --> + <mat-card-content> + <p>Das <a href="http://www.iqb.hu-berlin.de" target="_blank">Institut zur Qualitätsentwicklung im Bildungswesen</a> + {{ 'app_intro1' | customtext:'app_intro1':cts.updateCount }}</p> + + <p>Die mit diesem System erhobenen Daten enthalten grundsätzlich keinen direkten + Personenbezug. Es werden z. B. nie Namen gespeichert. Um Auskünfte zu einer bestimmten Befragung bzw. Studie + zu erhalten, wenden Sie sich bitte an das <a href="mailto:mechtel@iqb.hu-berlin.de"> + IQB</a>. Wir benötigen dazu den ungefähren Zeitraum und das Bundesland, in dem die Befragung bzw. Studie + durchgeführt wurde.</p> + + <p> + <em>Postanschrift:</em><br/> + Humboldt-Universität zu Berlin<br/> + Institut zur Qualitätsentwicklung im Bildungswesen<br/> + Unter den Linden 6<br/> + 10099 Berlin</p> + <p> + <em>Sitz:</em><br/> + Luisenstr. 56<br/> + 10117 Berlin<br/> + Tel: +49 [30] 2093 - 46500 (Zentrale)<br/> + Fax: +49 [30] 2093 - 46599<br/> + E-Mail: <a href="mailto:iqboffice@iqb.hu-berlin.de">iqboffice@iqb.hu-berlin.de</a> + </p> + <p> + <em>Name und Anschrift der Datenschutzbeauftragten</em><br/> + Frau Gesine Hoffmann-Holland<br/> + Tel: +49 (30) 2093-2591<br/> + E-Mail: datenschutz@uv.hu-berlin.de<br/> + <a href="http://www.hu-berlin.de/de/datenschutz" target="_blank">www.hu-berlin.de/de/datenschutz</a> + </p> + <status-card></status-card> + </mat-card-content> + <mat-card-actions> + <button [routerLink]="['/']" mat-raised-button color="primary"><i class="material-icons">arrow_back</i> zurück zur Startseite</button> + </mat-card-actions> + </mat-card> + </div> +</div> diff --git a/src/app/app-root/privacy/privacy.component.spec.ts b/src/app/app-root/privacy/privacy.component.spec.ts new file mode 100644 index 0000000000000000000000000000000000000000..5643443839f50db8340693feeeb08aa69cb49797 --- /dev/null +++ b/src/app/app-root/privacy/privacy.component.spec.ts @@ -0,0 +1,32 @@ +import { async, ComponentFixture, TestBed } from '@angular/core/testing'; + +import { PrivacyComponent } from './privacy.component'; +import {AppRoutingModule} from "../../app-routing.module"; +import {IqbComponentsModule} from "iqb-components"; + +describe('PrivacyComponent', () => { + let component: PrivacyComponent; + let fixture: ComponentFixture<PrivacyComponent>; + + beforeEach(async(() => { + TestBed.configureTestingModule({ + declarations: [ PrivacyComponent ], + imports: [ + AppRoutingModule, + IqbComponentsModule + ], + + }) + .compileComponents(); + })); + + beforeEach(() => { + fixture = TestBed.createComponent(PrivacyComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/src/app/app-root/privacy/privacy.component.ts b/src/app/app-root/privacy/privacy.component.ts new file mode 100644 index 0000000000000000000000000000000000000000..402ce5f8c11a5df3acfc76293ec6955d3be2d075 --- /dev/null +++ b/src/app/app-root/privacy/privacy.component.ts @@ -0,0 +1,16 @@ +import { Component } from '@angular/core'; +import {CustomtextService} from "iqb-components"; + +@Component({ + templateUrl: './privacy.component.html', + styles: [ + 'mat-card {margin: 10px}' //'; background-color: lightgray}' + ] +}) +export class PrivacyComponent { + + constructor( + public cts: CustomtextService + ) { } + +} diff --git a/src/app/app-root/route-dispatcher/route-dispatcher.component.html b/src/app/app-root/route-dispatcher/route-dispatcher.component.html new file mode 100644 index 0000000000000000000000000000000000000000..faf58cf154d88950ea96da609f8783520c7e6b11 --- /dev/null +++ b/src/app/app-root/route-dispatcher/route-dispatcher.component.html @@ -0,0 +1,14 @@ +<div class="root-frame" fxLayout="row wrap" fxLayoutAlign="center stretch"> + <mat-card fxFlex="0 0 400px" fxLayout="column"> + <mat-card-title>Diese Seite wurde nicht gefunden.</mat-card-title> + <mat-card-content> + <div style="{margin: 50px;}"> + {{url}} + </div> + </mat-card-content> + + <mat-card-actions> + <button [routerLink]="['/']" mat-raised-button color="primary">Zur Startseite</button> + </mat-card-actions> + </mat-card> +</div> diff --git a/src/app/app-root/route-dispatcher/route-dispatcher.component.spec.ts b/src/app/app-root/route-dispatcher/route-dispatcher.component.spec.ts new file mode 100644 index 0000000000000000000000000000000000000000..0786b25548f0708150c51b01fc3fdbdfa561d648 --- /dev/null +++ b/src/app/app-root/route-dispatcher/route-dispatcher.component.spec.ts @@ -0,0 +1,27 @@ +import { async, ComponentFixture, TestBed } from '@angular/core/testing'; + +import { RouteDispatcherComponent } from './route-dispatcher.component'; +import {AppRoutingModule} from "../../app-routing.module"; + +describe('RouteDispatcherComponent', () => { + let component: RouteDispatcherComponent; + let fixture: ComponentFixture<RouteDispatcherComponent>; + + beforeEach(async(() => { + TestBed.configureTestingModule({ + declarations: [ RouteDispatcherComponent ], + imports: [AppRoutingModule] + }) + .compileComponents(); + })); + + beforeEach(() => { + fixture = TestBed.createComponent(RouteDispatcherComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/src/app/app-root/route-dispatcher/route-dispatcher.component.ts b/src/app/app-root/route-dispatcher/route-dispatcher.component.ts new file mode 100644 index 0000000000000000000000000000000000000000..f9f665ff41e99a08a6dc8d63492fdb4fbba4d3cb --- /dev/null +++ b/src/app/app-root/route-dispatcher/route-dispatcher.component.ts @@ -0,0 +1,28 @@ +import { Component, OnInit } from '@angular/core'; +import {CustomtextService} from "iqb-components"; +import {Router, RouterState, RouterStateSnapshot} from "@angular/router"; + +@Component({ + templateUrl: './route-dispatcher.component.html', + styles: [ + 'mat-card {margin: 10px;}', + '.root-frame {padding: 80px;}' + ] +}) + +export class RouteDispatcherComponent implements OnInit { + url = ''; + + constructor( + public cts: CustomtextService, + private router: Router) { + + const state: RouterState = router.routerState; + const snapshot: RouterStateSnapshot = state.snapshot; + this.url = snapshot.url; + } + + ngOnInit(): void { + } + +} diff --git a/src/app/app-root/status-card/status-card.component.html b/src/app/app-root/status-card/status-card.component.html new file mode 100644 index 0000000000000000000000000000000000000000..5bf5564948a48075548f9b7a4edfd0e84b414897 --- /dev/null +++ b/src/app/app-root/status-card/status-card.component.html @@ -0,0 +1,21 @@ +<div fxLayout="column"> + <div *ngIf="loginName"> + <p><b>Status: Angemeldet als "{{loginName}}"</b></p> + <p style="margin-bottom: 0px;"> + <b *ngIf="loginAuthority.length > 1">Berechtigungen:</b> + <b *ngIf="loginAuthority.length === 1">Berechtigung:</b> + </p> + <ul style="margin: 0px;"> + <li *ngFor="let loginAuth of loginAuthority">{{loginAuth}}</li> + </ul> + </div> + <p *ngIf="!loginName"><b>Status: Derzeit nicht angemeldet.</b></p> + <p style="margin-bottom: 0px;"><b>Angaben zu dieser Web-Anwendung:</b></p> + <ul style="margin: 0px;"> + <li>Interner Programmname: {{ appName }}</li> + <li>Programmversion: {{ appVersion }}</li> + <li *ngIf="!isProductionMode">Build-Modus: Dev</li> + <li>Erforderliche Version der Server-Programmierung: {{ apiVersionExpected }}</li> + <li>Copyright: {{ appPublisher }}</li> + </ul> +</div> diff --git a/src/app/app-root/status-card/status-card.component.spec.ts b/src/app/app-root/status-card/status-card.component.spec.ts new file mode 100644 index 0000000000000000000000000000000000000000..70cf3bcf7f969246d69a193ffcaf28b08b12e9d7 --- /dev/null +++ b/src/app/app-root/status-card/status-card.component.spec.ts @@ -0,0 +1,29 @@ +import { async, ComponentFixture, TestBed } from '@angular/core/testing'; + +import { StatusCardComponent } from './status-card.component'; +import {MainDataService} from "../../maindata.service"; + +describe('StatusCardComponent', () => { + let component: StatusCardComponent; + let fixture: ComponentFixture<StatusCardComponent>; + + beforeEach(async(() => { + TestBed.configureTestingModule({ + declarations: [ StatusCardComponent ], + providers: [ + MainDataService + ] + }) + .compileComponents(); + })); + + beforeEach(() => { + fixture = TestBed.createComponent(StatusCardComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/src/app/app-root/status-card/status-card.component.ts b/src/app/app-root/status-card/status-card.component.ts new file mode 100644 index 0000000000000000000000000000000000000000..f045564eb5eeccdb762e57109276e073cabda62d --- /dev/null +++ b/src/app/app-root/status-card/status-card.component.ts @@ -0,0 +1,56 @@ +import {Component, Inject, OnInit} from '@angular/core'; +import {MainDataService} from "../../maindata.service"; +import {AuthAccessKeyType, AuthFlagType} from "../../app.interfaces"; + +@Component({ + selector: 'status-card', + templateUrl: './status-card.component.html' +}) +export class StatusCardComponent implements OnInit { + loginName = ''; + loginAuthority: string[] = []; + + constructor( + @Inject('APP_NAME') public appName: string, + @Inject('APP_PUBLISHER') public appPublisher: string, + @Inject('APP_VERSION') public appVersion: string, + @Inject('API_VERSION_EXPECTED') public apiVersionExpected: string, + @Inject('IS_PRODUCTION_MODE') public isProductionMode + ) { } + + ngOnInit(): void { + setTimeout(() => { + const authData = MainDataService.getAuthData(); + if (authData) { + this.loginName = authData.displayName; + if (authData.access[AuthAccessKeyType.WORKSPACE_ADMIN]) { + this.loginAuthority.push('Verwaltung von Testinhalten'); + } + if (authData.access[AuthAccessKeyType.SUPER_ADMIN]) { + this.loginAuthority.push('Verwaltung von Nutzerrechten und von grundsätzlichen Systemeinstellungen'); + } + if (authData.access[AuthAccessKeyType.TEST]) { + if (authData.access[AuthAccessKeyType.TEST].length > 1) { + this.loginAuthority.push('Ausführung/Ansicht von Befragungen oder Testheften'); + } else { + this.loginAuthority.push('Ausführung/Ansicht einer Befragung oder eines Testheftes'); + } + } + if (authData.access[AuthAccessKeyType.WORKSPACE_MONITOR]) { + if (authData.access[AuthAccessKeyType.WORKSPACE_MONITOR].length > 1) { + this.loginAuthority.push('Beobachtung/Prüfung der Durchführung von Befragungen oder Kompetenztests'); + } else { + this.loginAuthority.push('Beobachtung/Prüfung der Durchführung einer Befragung oder eines Kompetenztests'); + } + } + if (authData.access[AuthAccessKeyType.TEST_GROUP_MONITOR]) { + this.loginAuthority.push('Beobachtung/Prüfung einer Testgruppe'); + } + if (authData.flags.indexOf(AuthFlagType.CODE_REQUIRED) >= 0) { + this.loginAuthority.push('Code-Eingabe erforderlich'); + } + } + }) + } + +} diff --git a/src/app/app-root/sys-check-starter/sys-check-starter.component.css b/src/app/app-root/sys-check-starter/sys-check-starter.component.css new file mode 100644 index 0000000000000000000000000000000000000000..db1722e0f7afa49f9d6e436650e5670f67150abf --- /dev/null +++ b/src/app/app-root/sys-check-starter/sys-check-starter.component.css @@ -0,0 +1,15 @@ +.check-title { + font-size: 16pt; + margin-bottom: 0; + height: 24px +} + +.check-description { + font-size: 9pt; + margin-top: 8px; + color: lightgray; + height: 24px; + margin-bottom: 18px; + white-space: normal; + line-height: 16px; +} diff --git a/src/app/app-root/sys-check-starter/sys-check-starter.component.html b/src/app/app-root/sys-check-starter/sys-check-starter.component.html new file mode 100644 index 0000000000000000000000000000000000000000..79b7ab2731aefd41a94c0184d4d777cd6f6fd15e --- /dev/null +++ b/src/app/app-root/sys-check-starter/sys-check-starter.component.html @@ -0,0 +1,35 @@ +<div fxLayout="row wrap" fxLayoutAlign="center stretch"> + <mat-card fxFlex="0 2 500px"> + <mat-card-title>{{ 'app_title' | customtext:'app_title':cts.updateCount }}: System-Check</mat-card-title> + <mat-card-content> + <p>Hier können Sie ermitteln, ob das Computersystem, das Sie gerade benutzen, für + die hier vorgesehenen Testungen geeignet ist.</p> + <p *ngIf="loading"> + Bitte warten... Konfiguration wird geladen + </p> + <span *ngIf="!loading"> + <p *ngIf="checkConfigList.length === 0"> + Auf diesem Server ist aktuell kein System-Check verfügbar. + </p> + <p *ngIf="checkConfigList.length > 1"> + Bitte wählen Sie einen Check aus! + </p> + <p *ngIf="checkConfigList.length === 1"> + Bitte klicken Sie auf den Schalter, um den Check zu starten! + </p> + </span> + <div fxLayout="column" fxLayoutGap="10px" *ngIf="checkConfigList?.length > 0"> + <button mat-raised-button color="primary" (click)="buttonStartCheck(c)" + *ngFor="let c of checkConfigList"> + <div fxLayout="column"> + <p class="check-title">{{c.label}}</p> + <p class="check-description">{{c.description}}</p> + </div> + </button> + </div> + </mat-card-content> + <mat-card-actions> + <button [routerLink]="['/']" mat-raised-button color="primary"><i class="material-icons">arrow_back</i> zurück zur Startseite</button> + </mat-card-actions> + </mat-card> +</div> diff --git a/src/app/app-root/sys-check-starter/sys-check-starter.component.spec.ts b/src/app/app-root/sys-check-starter/sys-check-starter.component.spec.ts new file mode 100644 index 0000000000000000000000000000000000000000..12286d34cb18f85e8767f062c9464b6a63a6804f --- /dev/null +++ b/src/app/app-root/sys-check-starter/sys-check-starter.component.spec.ts @@ -0,0 +1,37 @@ +import { async, ComponentFixture, TestBed } from '@angular/core/testing'; + +import { SysCheckStarterComponent } from './sys-check-starter.component'; +import {HttpClientModule} from "@angular/common/http"; +import {AppRoutingModule} from "../../app-routing.module"; +import {IqbComponentsModule} from "iqb-components"; +import {BackendService} from "../../backend.service"; + +describe('SysCheckStarterComponent', () => { + let component: SysCheckStarterComponent; + let fixture: ComponentFixture<SysCheckStarterComponent>; + + beforeEach(async(() => { + TestBed.configureTestingModule({ + declarations: [ SysCheckStarterComponent ], + imports: [ + HttpClientModule, + AppRoutingModule, + IqbComponentsModule + ], + providers: [ + BackendService + ] + }) + .compileComponents(); + })); + + beforeEach(() => { + fixture = TestBed.createComponent(SysCheckStarterComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/src/app/app-root/sys-check-starter/sys-check-starter.component.ts b/src/app/app-root/sys-check-starter/sys-check-starter.component.ts new file mode 100644 index 0000000000000000000000000000000000000000..733cec2af00f001958b64f22151cb0b68661421f --- /dev/null +++ b/src/app/app-root/sys-check-starter/sys-check-starter.component.ts @@ -0,0 +1,42 @@ +import {Component, OnInit} from '@angular/core'; +import {BackendService} from "../../backend.service"; +import {Router} from "@angular/router"; +import {MainDataService} from "../../maindata.service"; +import {SysCheckInfo} from "../../app.interfaces"; +import {CustomtextService} from "iqb-components"; + +@Component({ + templateUrl: './sys-check-starter.component.html', + styleUrls: ['./sys-check-starter.component.css'] +}) +export class SysCheckStarterComponent implements OnInit { + checkConfigList: SysCheckInfo[] = []; + loading = false; + + constructor( + public mds: MainDataService, + private bs: BackendService, + public cts: CustomtextService, + private router: Router + ) { } + + ngOnInit() { + setTimeout(() => { + this.loading = true; + this.mds.setSpinnerOn(); + this.bs.getSysCheckInfo().subscribe(myConfigs => { + if (myConfigs) { + this.checkConfigList = myConfigs; + } else { + this.checkConfigList = [] + } + this.loading = false; + this.mds.setSpinnerOff(); + }); + }) + } + + buttonStartCheck(checkInfo: SysCheckInfo) { + this.router.navigate([`/check/${checkInfo.workspaceId}/${checkInfo.name}`]); + } +} diff --git a/src/app/start/start.component.css b/src/app/app-root/test-starter/test-starter.component.css similarity index 78% rename from src/app/start/start.component.css rename to src/app/app-root/test-starter/test-starter.component.css index daaa3954799c28ca82a518ad0bee0ed00e093457..3b5ec57ae392c2fd46e02ace3a907721b9cc15e5 100644 --- a/src/app/start/start.component.css +++ b/src/app/app-root/test-starter/test-starter.component.css @@ -15,13 +15,10 @@ div.booklet_status { margin-bottom: 18px; } -.mat-card { +mat-card { margin: 10px; } -.status { - background-color: lightgrey; -} -.error-msg { - color: brown; +.mat-card-gray { + background-color: lightgray } diff --git a/src/app/app-root/test-starter/test-starter.component.html b/src/app/app-root/test-starter/test-starter.component.html new file mode 100644 index 0000000000000000000000000000000000000000..61e384e779e2d5a9652e6e1ddbcfdab8c95dcc62 --- /dev/null +++ b/src/app/app-root/test-starter/test-starter.component.html @@ -0,0 +1,31 @@ +<div fxLayout="row wrap" fxLayoutAlign="center stretch"> + <mat-card fxFlex="0 0 400px" fxLayout="column"> + <mat-card-title>{{ bookletSelectTitle }}</mat-card-title> + <mat-card-content> + <div fxLayoutGap="10px" fxLayout="column"> + <p style="color: chocolate"><b>{{ problemText }}</b></p> + <button mat-raised-button color="primary" (click)="startTest(b)" + [disabled]="b.locked" *ngFor="let b of booklets"> + <div class="booklet_title">{{b.label}}</div> + <div class="booklet_status">{{b.locked ? 'gesperrt' : (b.running ? 'Fortsetzen' : 'Starten')}}</div> + </button> + </div> + </mat-card-content> + <mat-card-actions> + <button mat-raised-button color="foreground" (click)="resetLogin()">Neu anmelden</button> + </mat-card-actions> + </mat-card> + + <mat-card fxFlex="0 0 400px" class="mat-card-gray"> + <mat-card-title>{{ 'app_title' | customtext:'app_title':cts.updateCount }}</mat-card-title> + + <mat-card-content> + <p *ngIf="booklets.length === 0">{{ 'login_bookletSelectPromptNull' | customtext: 'login_bookletSelectPromptNull':cts.updateCount}}</p> + <p *ngIf="booklets.length === 1">{{ 'login_bookletSelectPromptOne' | customtext: 'login_bookletSelectPromptOne':cts.updateCount}}</p> + <p *ngIf="booklets.length > 1">{{ 'login_bookletSelectPromptMany' | customtext: 'login_bookletSelectPromptMany':cts.updateCount}}</p> + + <status-card></status-card> + + </mat-card-content> + </mat-card> +</div> diff --git a/src/app/app-root/test-starter/test-starter.component.spec.ts b/src/app/app-root/test-starter/test-starter.component.spec.ts new file mode 100644 index 0000000000000000000000000000000000000000..94217d11a5a9c3c5c34879f8d8bc1c0a04287e25 --- /dev/null +++ b/src/app/app-root/test-starter/test-starter.component.spec.ts @@ -0,0 +1,35 @@ +import { async, ComponentFixture, TestBed } from '@angular/core/testing'; + +import { TestStarterComponent } from './test-starter.component'; +import {HttpClientModule} from "@angular/common/http"; +import {ReactiveFormsModule} from "@angular/forms"; +import {AppRoutingModule} from "../../app-routing.module"; +import {IqbComponentsModule} from "iqb-components"; + +describe('TestStarterComponent', () => { + let component: TestStarterComponent; + let fixture: ComponentFixture<TestStarterComponent>; + + beforeEach(async(() => { + TestBed.configureTestingModule({ + declarations: [ TestStarterComponent ], + imports: [ + HttpClientModule, + ReactiveFormsModule, + AppRoutingModule, + IqbComponentsModule + ], + }) + .compileComponents(); + })); + + beforeEach(() => { + fixture = TestBed.createComponent(TestStarterComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/src/app/app-root/test-starter/test-starter.component.ts b/src/app/app-root/test-starter/test-starter.component.ts new file mode 100644 index 0000000000000000000000000000000000000000..d12a2af1fada43e36659cfd211fa3626005d943c --- /dev/null +++ b/src/app/app-root/test-starter/test-starter.component.ts @@ -0,0 +1,98 @@ +import { Component, OnInit } from '@angular/core'; +import {AuthAccessKeyType, AuthData, BookletData} from "../../app.interfaces"; +import {from, Subscription} from "rxjs"; +import {concatMap} from "rxjs/operators"; +import {Router} from "@angular/router"; +import {BackendService} from "../../backend.service"; +import {MainDataService} from "../../maindata.service"; +import {CustomtextService} from "iqb-components"; + +@Component({ + templateUrl: './test-starter.component.html', + styleUrls: ['./test-starter.component.css'] +}) +export class TestStarterComponent implements OnInit { + booklets: BookletData[] = []; + private getBookletDataSubscription: Subscription = null; + public bookletSelectTitle = 'Bitte wählen'; + problemText = ''; + + constructor( + private router: Router, + private bs: BackendService, + public cts: CustomtextService, + private mds: MainDataService + ) { } + + ngOnInit(): void { + setTimeout(() => { + this.mds.setSpinnerOn(); + this.bs.getSessionData().subscribe(authDataUntyped => { + if (typeof authDataUntyped !== 'number') { + const authData = authDataUntyped as AuthData; + if (authData) { + if (authData.token) { + if (authData.access[AuthAccessKeyType.TEST]) { + this.booklets = []; + if (this.getBookletDataSubscription !== null) { + this.getBookletDataSubscription.unsubscribe(); + } + this.getBookletDataSubscription = from(authData.access[AuthAccessKeyType.TEST]).pipe( + concatMap(bookletId => { + return this.bs.getBookletData(bookletId) + })).subscribe( + bData => { + this.booklets.push(bData) + }, + e => { + this.problemText = `Fehler in der Netzwerkverbindung (${e}).`; + this.mds.setSpinnerOff(); + }, + () => { + this.problemText = this.booklets.length > 0 ? '' : 'Für diese Anmeldung wurde kein Test gefunden.'; + this.mds.setSpinnerOff(); + } + ); + } + this.mds.setAuthData(authData); + } else { + this.mds.setAuthData(); + this.mds.setSpinnerOff(); + } + } else { + this.mds.setAuthData(); + this.mds.setSpinnerOff(); + } + } else { + this.mds.setSpinnerOff(); + } + }) + }); + } + + startTest(b: BookletData) { + this.bs.startTest(b.id).subscribe(testId => { + if (typeof testId === 'number') { + const errCode = testId as number; + if (errCode === 423) { + this.problemText = 'Dieser Test ist gesperrt'; + } else { + this.problemText = `Problem beim Start (${errCode})`; + } + } else { + this.router.navigate(['/t', testId]); + } + }); + } + + resetLogin() { + this.mds.setAuthData(); + this.router.navigate(['/']); + } + + ngOnDestroy() { + if (this.getBookletDataSubscription !== null) { + this.getBookletDataSubscription.unsubscribe(); + } + } +} diff --git a/src/app/app-routing-guards.ts b/src/app/app-routing-guards.ts new file mode 100644 index 0000000000000000000000000000000000000000..5e3efd277a6793b250b774cd2e19bce24b7a69ec --- /dev/null +++ b/src/app/app-routing-guards.ts @@ -0,0 +1,88 @@ +import {Injectable} from "@angular/core"; +import {ActivatedRouteSnapshot, CanActivate, Router, RouterStateSnapshot} from "@angular/router"; +import {MainDataService} from "./maindata.service"; +import {Observable} from "rxjs"; +import {AuthAccessKeyType, AuthData, AuthFlagType} from "./app.interfaces"; +import {BackendService} from "./backend.service"; + +@Injectable() +export class RouteDispatcherActivateGuard implements CanActivate { + constructor( + private router: Router + ) { + } + + canActivate( + next: ActivatedRouteSnapshot, + state: RouterStateSnapshot): Observable<boolean> | Promise<boolean> | boolean { + + const authData = MainDataService.getAuthData(); + if (authData) { + if (authData.token) { + if (authData.access[AuthAccessKeyType.WORKSPACE_ADMIN] || authData.access[AuthAccessKeyType.SUPER_ADMIN]) { + this.router.navigate(['/r/admin-starter']); + } else if (authData.flags.indexOf(AuthFlagType.CODE_REQUIRED) >= 0) { + this.router.navigate(['/r/code-input']); + } else if (authData.access[AuthAccessKeyType.TEST]) { + this.router.navigate(['/r/test-starter']); + } else if (authData.access[AuthAccessKeyType.TEST_GROUP_MONITOR] || authData.access[AuthAccessKeyType.WORKSPACE_MONITOR]) { + this.router.navigate(['/r/monitor-starter']); + } else { + this.router.navigate(['/r/login', '']); + } + } else { + this.router.navigate(['/r/login', '']); + } + } else { + this.router.navigate(['/r/login', '']); + } + + return false; + } +} + +@Injectable() +export class DirectLoginActivateGuard implements CanActivate { + constructor( + private mds: MainDataService, + private bs: BackendService, + private router: Router + ) { + } + + canActivate( + next: ActivatedRouteSnapshot, + state: RouterStateSnapshot): Observable<boolean> | Promise<boolean> | boolean { + + const authData = MainDataService.getAuthData(); + if (!authData) { + const directLoginName = state.url.substr(1); + if (directLoginName.length > 0 && directLoginName.indexOf('/') < 0) { + this.bs.nameOnlyLogin(directLoginName).subscribe(authData => { + if (typeof authData !== 'number') { + this.mds.setAuthData(authData as AuthData); + this.router.navigate(['/r']); + } + }) + } + } + return true + } +} + +@Injectable({ + providedIn: 'root' +}) +export class CodeInputComponentActivateGuard implements CanActivate { + canActivate( + next: ActivatedRouteSnapshot, + state: RouterStateSnapshot): Observable<boolean> | Promise<boolean> | boolean { + + const authData = MainDataService.getAuthData(); + if (authData) { + return authData.flags.indexOf(AuthFlagType.CODE_REQUIRED) >= 0 + } else { + return false + } + } +} diff --git a/src/app/app-routing.module.ts b/src/app/app-routing.module.ts index 6dd129c5018bac41c6f2f3b8dd671fa3733ce8a5..f3076c5059fa47c7536327ac92839afc3c012e24 100644 --- a/src/app/app-routing.module.ts +++ b/src/app/app-routing.module.ts @@ -1,22 +1,51 @@ -import { AboutComponent } from './about/about.component'; -import { StartComponent } from './start/start.component'; import { NgModule } from '@angular/core'; import { Routes, RouterModule } from '@angular/router'; +import {AppRootComponent} from "./app-root/app-root.component"; +import {LoginComponent} from "./app-root/login/login.component"; +import {SysCheckStarterComponent} from "./app-root/sys-check-starter/sys-check-starter.component"; +import {AdminStarterComponent} from "./app-root/admin-starter/admin-starter.component"; +import {CodeInputComponent} from "./app-root/code-input/code-input.component"; +import { + CodeInputComponentActivateGuard, + DirectLoginActivateGuard, + RouteDispatcherActivateGuard +} from "./app-routing-guards"; +import {TestStarterComponent} from "./app-root/test-starter/test-starter.component"; +import {RouteDispatcherComponent} from "./app-root/route-dispatcher/route-dispatcher.component"; +import {PrivacyComponent} from "./app-root/privacy/privacy.component"; const routes: Routes = [ - {path: '', component: StartComponent, pathMatch: 'full'}, - {path: 'start', component: StartComponent}, - {path: 'about', component: AboutComponent}, - {path: 'check', loadChildren: './sys-check/sys-check.module#SysCheckModule'}, - {path: 'admin', loadChildren: './workspace-admin/workspace.module#WorkspaceModule'}, - {path: 'superadmin', loadChildren: './superadmin/superadmin.module#SuperadminModule'}, - {path: 'wsmonitor', loadChildren: './workspace-monitor/workspace-monitor.module#WorkspaceMonitorModule'}, - {path: 't', loadChildren: './test-controller/test-controller.module#TestControllerModule'} + { + path: '', + redirectTo: 'r/route-dispatcher', + pathMatch: 'full' + }, + {path: 'r', component: AppRootComponent, + children: [ + {path: '', redirectTo: 'route-dispatcher', pathMatch: 'full'}, + {path: 'login', redirectTo: 'route-dispatcher', pathMatch: 'full'}, + {path: 'login/:returnTo', component: LoginComponent}, + {path: 'check-starter', component: SysCheckStarterComponent}, + {path: 'test-starter', component: TestStarterComponent}, + {path: 'admin-starter', component: AdminStarterComponent}, + {path: 'route-dispatcher', component: RouteDispatcherComponent, canActivate: [RouteDispatcherActivateGuard]}, + {path: 'code-input', component: CodeInputComponent, canActivate: [CodeInputComponentActivateGuard]} + ] + }, + {path: 'priv', component: PrivacyComponent}, + {path: 'check', loadChildren: () => import('./sys-check/sys-check.module').then(m => m.SysCheckModule)}, + {path: 'admin', loadChildren: () => import('./workspace-admin/workspace.module').then(m => m.WorkspaceModule)}, + {path: 'superadmin', loadChildren: () => import('./superadmin/superadmin.module').then(m => m.SuperadminModule)}, + {path: 'wm', loadChildren: () => import('./workspace-monitor/workspace-monitor.module').then(m => m.WorkspaceMonitorModule)}, + {path: 'gm', loadChildren: () => import('./group-monitor/group-monitor.module').then(m => m.GroupMonitorModule)}, + {path: 't', loadChildren: () => import('./test-controller/test-controller.module').then(m => m.TestControllerModule)}, + {path: '**', component: RouteDispatcherComponent, canActivate: [DirectLoginActivateGuard]} ]; @NgModule({ imports: [RouterModule.forRoot(routes)], - exports: [RouterModule] + exports: [RouterModule], + providers: [RouteDispatcherActivateGuard, DirectLoginActivateGuard, CodeInputComponentActivateGuard] }) export class AppRoutingModule { } diff --git a/src/app/app.component.html b/src/app/app.component.html new file mode 100644 index 0000000000000000000000000000000000000000..d671eb9cbd85ce6986f553f251839e5f88ae332c --- /dev/null +++ b/src/app/app.component.html @@ -0,0 +1,16 @@ +<div class="logo"> + <a [routerLink]="['/']"> + <img src="assets/IQB-LogoA.png" matTooltip="Zur Startseite" alt="IQB-logo"/> + </a> +</div> +<div class="error-msg" *ngIf="showError" [matTooltip]="errorData?.description" fxLayout="row" fxLayoutAlign="space-between center"> + <mat-icon>error</mat-icon> + {{ errorData?.label }} + <button mat-button (click)="closeErrorBox()" matTooltip="Fehlernachricht ausblenden" fxFlex="none"> + <mat-icon>clear</mat-icon> + </button> +</div> +<div class="spinner" *ngIf="mds.isSpinnerOn$ | async"> + <mat-spinner></mat-spinner> +</div> +<router-outlet></router-outlet> diff --git a/src/app/app.component.scss b/src/app/app.component.scss deleted file mode 100644 index 3e1cc1e787202b161b19d492ec19b7655d765446..0000000000000000000000000000000000000000 --- a/src/app/app.component.scss +++ /dev/null @@ -1,37 +0,0 @@ -@import '~@angular/material/theming'; -@import '../iqb-theme1.scss'; - -.itp-fill-remaining-space { - flex: 1 1 auto; -} - -.mat-toolbar { - overflow: auto; - position: absolute; - width: 100%; - height: 70px; - font-family: inherit; - background-color: #003333; - /* background: linear-gradient(to left, #003333, #045659, #0d7b84, #1aa2b2, #2acae5); */ - color: white; -} - -mat-toolbar > span { - text-overflow: ellipsis; - white-space: nowrap; - overflow: hidden; -} - -.logo { - width: 80px; - margin-right: 20px; - margin-top: 12px; -} - -.material-icons { - font-size: 2.0rem; -} - -.mat-button { - text-align: right; -} diff --git a/src/app/app.component.spec.ts b/src/app/app.component.spec.ts index 96cdb8b9f5072dd494030e20943e55118bd2b283..d5ede5d8aa11be1d7a502f085a180b15ecb7468f 100644 --- a/src/app/app.component.spec.ts +++ b/src/app/app.component.spec.ts @@ -1,15 +1,23 @@ import { TestBed, async } from '@angular/core/testing'; import { RouterTestingModule } from '@angular/router/testing'; import { AppComponent } from './app.component'; +import {HttpClientModule} from "@angular/common/http"; +import {BackendService} from "./backend.service"; +import {AppRoutingModule} from "./app-routing.module"; describe('AppComponent', () => { beforeEach(async(() => { TestBed.configureTestingModule({ imports: [ - RouterTestingModule + RouterTestingModule, + HttpClientModule, + AppRoutingModule ], declarations: [ AppComponent ], + providers: [ + BackendService + ] }).compileComponents(); })); it('should create the app', async(() => { @@ -17,15 +25,4 @@ describe('AppComponent', () => { const app = fixture.debugElement.componentInstance; expect(app).toBeTruthy(); })); - it(`should have as title 'app'`, async(() => { - const fixture = TestBed.createComponent(AppComponent); - const app = fixture.debugElement.componentInstance; - expect(app.title).toEqual('app'); - })); - it('should render title in a h1 tag', async(() => { - const fixture = TestBed.createComponent(AppComponent); - fixture.detectChanges(); - const compiled = fixture.debugElement.nativeElement; - expect(compiled.querySelector('h1').textContent).toContain('Welcome to itc-ng!'); - })); }); diff --git a/src/app/app.component.ts b/src/app/app.component.ts index 7f8db55eb6a019005b83e5ceac26738c21bf6ccf..b1d9dc6479123a7491e97f7bd2df004c1ada0b2c 100644 --- a/src/app/app.component.ts +++ b/src/app/app.component.ts @@ -1,104 +1,116 @@ import { MainDataService } from './maindata.service'; -import { Component, OnInit } from '@angular/core'; +import {Component, Inject, OnDestroy, OnInit} from '@angular/core'; import { BackendService } from './backend.service'; -import { LoginData } from './app.interfaces'; -import {CustomtextService, ServerError} from 'iqb-components'; -import { appconfig } from './app.config'; +import {CustomtextService} from 'iqb-components'; +import {Subscription} from "rxjs"; +import {AppError} from "./app.interfaces"; @Component({ selector: 'tc-root', - template: `<router-outlet></router-outlet>`, - styleUrls: ['./app.component.scss'] + templateUrl: './app.component.html' }) -export class AppComponent implements OnInit { +export class AppComponent implements OnInit, OnDestroy { + private appErrorSubscription: Subscription = null; + showError = false; + errorData: AppError; constructor ( - private mds: MainDataService, + public mds: MainDataService, private bs: BackendService, - private cts: CustomtextService + private cts: CustomtextService, + @Inject('API_VERSION_EXPECTED') private readonly expectedApiVersion: string, ) { } - private static getStringFromLocalStorage(key: string) { - const storageEntry = localStorage.getItem(key); - if (storageEntry !== null) { - if (storageEntry.length > 0) { - return (storageEntry as string); + private static isValidVersion(expectedVersion: string, reportedVersion: string): boolean { + if (expectedVersion) { + const searchPattern = /\d+/g; + const expectedVersionNumbers = expectedVersion.match(searchPattern); + if (expectedVersionNumbers) { + if (reportedVersion) { + const reportedVersionNumbers = reportedVersion.match(searchPattern); + if (reportedVersionNumbers) { + if (reportedVersionNumbers[0] !== expectedVersionNumbers[0]) { + return false; + } else if (expectedVersionNumbers.length > 1) { + if ((reportedVersionNumbers.length < 2) || +reportedVersionNumbers[1] < +expectedVersionNumbers[1]) { + return false; + } else if ((expectedVersionNumbers.length > 2) && reportedVersionNumbers[1] === expectedVersionNumbers[1]) { + if ((reportedVersionNumbers.length < 3) || +reportedVersionNumbers[2] < +expectedVersionNumbers[2]) { + return false; + } + } + } + } else { + return false; + } + } else { + return false; + } } } - return ''; + return true; + } + + closeErrorBox() { + this.showError = false; } ngOnInit() { - this.mds.addCustomtextsFromDefList(appconfig.customtextsApp); - this.mds.addCustomtextsFromDefList(appconfig.customtextsLogin); - this.mds.addCustomtextsFromDefList(appconfig.customtextsBooklet); + setTimeout(() => { + this.mds.appConfig.setDefaultCustomTexts(); - // give a message to the central message broadcast + this.appErrorSubscription = this.mds.appError$.subscribe(err => { + if (err && !this.mds.errorReportingSilent) { + this.errorData = err; + this.showError = true; + } + }); - window.addEventListener('message', (event: MessageEvent) => { - const msgData = event.data; - const msgType = msgData['type']; - if ((msgType !== undefined) && (msgType !== null)) { - if (msgType.substr(0, 3) === 'vo.') { - this.mds.postMessage$.next(event); + window.addEventListener('message', (event: MessageEvent) => { + const msgData = event.data; + const msgType = msgData['type']; + if ((msgType !== undefined) && (msgType !== null)) { + if (msgType.substr(0, 3) === 'vo.') { + this.mds.postMessage$.next(event); + } } - } - }); + }); - this.bs.getSysConfig().subscribe(sc => { - this.mds.setDefaultCustomtexts(sc); - this.mds.addCustomtextsFromDefList(appconfig.customtextsApp); - // restore login status if stored in localStorage - const adminToken = AppComponent.getStringFromLocalStorage('at'); - if (adminToken) { - this.bs.getAdminSession(adminToken).subscribe( - (admindata: LoginData) => { - if (admindata instanceof ServerError) { - this.mds.setNewLoginData(); - } else { - this.mds.setNewLoginData(admindata); - } + this.bs.getSysConfig().subscribe(sc => { + if (sc) { + this.cts.addCustomTexts(sc.customTexts); + const authData = MainDataService.getAuthData(); + if (authData) { + this.cts.addCustomTexts(authData.customTexts); } - ); - } else { - const loginToken = AppComponent.getStringFromLocalStorage('lt'); - if (loginToken) { - const personToken = AppComponent.getStringFromLocalStorage('pt'); - let bookletDbId = 0; - if (personToken) { - const bookletDbIdStr = AppComponent.getStringFromLocalStorage('bi'); - if (bookletDbIdStr) { - bookletDbId = Number(bookletDbIdStr); - } + this.mds.isApiValid = AppComponent.isValidVersion(this.expectedApiVersion, sc.version); + if (!this.mds.isApiValid) { + this.mds.appError$.next({ + label: "Server-Problem: API-Version ungültig", + description: "erwartet: " + this.expectedApiVersion + ", gefunden: " + sc.version, + category: "FATAL" + }); } - const code = AppComponent.getStringFromLocalStorage('c'); - - // bookletDbId is not yet checked by getLoginData, only passed-through - this.bs.getSession(loginToken, personToken).subscribe(ld => { - if (ld instanceof ServerError) { - this.mds.setNewLoginData(); - } else { - const loginData = ld as LoginData; - loginData.loginToken = loginToken; - loginData.personToken = personToken; - if (personToken.length === 0) { - loginData.code = code; - loginData.testId = 0; - } - this.mds.setNewLoginData(loginData); - if (loginData.customTexts) { - this.cts.addCustomTexts(loginData.customTexts); - } - } - }); + if (sc.mainLogo) { + console.warn('SysConfig.mainLogo not implemented yet'); + } + this.mds.setTestConfig(sc.testConfig); } else { - this.mds.setNewLoginData(); - this.mds.addCustomtextsFromDefList(appconfig.customtextsLogin); - this.mds.addCustomtextsFromDefList(appconfig.customtextsBooklet); + this.mds.isApiValid = false; } - } + }); + + this.bs.getSysCheckInfo().subscribe(myConfigs => { + this.mds.sysCheckAvailable = !!myConfigs; + }); }); } + + ngOnDestroy() { + if (this.appErrorSubscription !== null) { + this.appErrorSubscription.unsubscribe(); + } + } } diff --git a/src/app/app.config.ts b/src/app/app.config.ts deleted file mode 100644 index ebf413c6c432a633ba5def3af901f34daca929d4..0000000000000000000000000000000000000000 --- a/src/app/app.config.ts +++ /dev/null @@ -1,143 +0,0 @@ -import { CustomTextDefs } from 'iqb-components'; - -export interface CustomTextsDefList { - keyPrefix: string; - description: string; - defList: CustomTextDefs; -} - -export const customtextKeySeparator = '_'; - -export const appconfig = { - customtextsApp: <CustomTextsDefList>{ - keyPrefix: 'app', - description: 'Textanpassungen, die vor der Anmeldung am System vorgenommen werden sollen', - defList: { - 'title': { - defaultvalue: 'IQB-Testcenter', - description: 'Titel der Hauptanwendung, z. B. Homepage' - }, - 'intro1': { - defaultvalue: 'betreibt auf diesen Seiten eine Pilotanwendung für das computerbasierte Leistungstesten von ' + - 'Schülerinnen und Schülern. Der Zugang zu einem Test ist nur möglich, wenn Sie von Testverantwortlichen ' + - 'Zugangsdaten erhalten haben, die Sie bitte links eingeben. Es sind keine weiteren Seiten öffentlich verfügbar.', - description: 'Begrüßungstext auf der Startseite' - } - } - }, - - customtextsLogin: <CustomTextsDefList>{ - keyPrefix: 'login', - description: 'Für Textanpassungen unmittelbar nach dem Login bzw. der Eingabe des Personencodes', - defList: { - 'testRunningText': { - defaultvalue: 'Ein Testheft ist gestartet', - description: 'Nachricht, dass ein Test (Booklet) gestartet ist' - }, - 'testRunningLongText': { - defaultvalue: 'Es wird gerade ein Test ausgeführt. Bitte durch Klicken auf eine der beiden Schaltflächen ' + - 'links wählen, ob der Test fortgesetzt oder beendet werden soll!', - description: 'Nachricht, dass ein Test (Booklet) gestartet ist, mit Aufforderung zum Klicken' - }, - 'testEndButtonText': { - defaultvalue: 'Test beenden', - description: 'Schalterbeschriftung für "Test beenden"' - }, - 'testReturnButtonText': { - defaultvalue: 'Zum Test zurückkehren', - description: 'Schalterbeschriftung für "Zurück zum Test"' - }, - 'bookletSelectPromptNull': { - defaultvalue: 'Beendet. Es können keine weiteren Testhefte gestartet werden.', - description: 'Nachricht für den Fall, dass Booklet(s) beendet wurden und keine weiteren zur Verfügung stehen' - }, - 'bookletSelectPromptOne': { - defaultvalue: 'Bitte klicke auf die Schaltfläche auf der linken Seite, um den Test zu starten!', - description: 'Aufforderung, aus einer Schalterliste einen Test auszusuchen' - }, - 'bookletSelectPromptMany': { - defaultvalue: 'Bitte klicke auf eine der Schaltflächen auf der linken Seite, um einen Test zu starten!', - description: '' - }, - 'codeInputPrompt': { - defaultvalue: 'Bitte Log-in eingeben, der auf dem Zettel steht!', - description: '' - }, - 'trialmodeText': { - defaultvalue: 'Ausführungsmodus "trial": Navigationsbeschränkungen sowie Zeit-Beschränkungen, ' + - 'die eventuell für das Testheft oder bestimmte Aufgaben festgelegt wurden, gelten nicht.', - description: '' - }, - 'reviewmodeText': { - defaultvalue: 'Ausführungsmodus "review": Beschränkungen für Zeit und Navigation sind nicht wirksam. Antworten werden ' + - 'nicht gespeichert. Sie können Kommentare über das Menü oben rechts speichern.', - description: '' - }, - 'codeInputTitle': { - defaultvalue: 'Log-in eingeben', - description: '' - } - } - }, - customtextsBooklet: <CustomTextsDefList>{ - keyPrefix: 'booklet', - description: 'Für Textanpassungen nach dem Laden des Testheftes, also während der Durchführung des Tests bzw. der Befragung', - defList: { - 'msgPresentationNotCompleteTitleNext': { - defaultvalue: 'Weiterblättern nicht möglich!', - description: '' - }, - 'msgPresentationNotCompleteTextNext': { - defaultvalue: 'Du kannst erst weiterblättern, wenn Audio-Dateien vollständig abgespielt wurden ' - + 'und wenn du in allen Fenstern bis ganz nach unten gescrollt hast.', - description: '' - }, - 'msgPresentationNotCompleteTitlePrev': { - defaultvalue: 'Zurückblättern - Warnung', - description: '' - }, - 'msgPresentationNotCompleteTextPrev': { - defaultvalue: 'Eine Audio-Datei ist noch nicht bis zu Ende abgespielt oder Seiten wurden noch nicht vollständig gezeigt. ' - + 'Wenn du jetzt zurückblätterst, kannst Du später Audio-Dateien nicht nocheinmal starten.', - description: '' - }, - 'codeToEnterTitle': { - defaultvalue: 'Freigabewort', - description: '' - }, - 'codeToEnterPrompt': { - defaultvalue: 'Bitte gib das Freigabewort ein, das angesagt wurde!', - description: '' - }, - 'msgSoonTimeOver5Minutes': { - defaultvalue: 'Du hast noch 5 Minuten Zeit für die Bearbeitung der Aufgaben in diesem Abschnitt.', - description: '' - }, - 'msgSoonTimeOver1Minute': { - defaultvalue: 'Du hast noch 1 Minute Zeit für die Bearbeitung der Aufgaben in diesem Abschnitt.', - description: '' - }, - 'msgTimerStarted': { - defaultvalue: 'Die Bearbeitungszeit für diesen Abschnitt hat begonnen: ', - description: '' - }, - 'msgTimerCancelled': { - defaultvalue: 'Die Bearbeitung des Abschnittes wurde abgebrochen.', - description: '' - }, - 'msgTimeOver': { - defaultvalue: 'Die Bearbeitung des Abschnittes ist beendet.', - description: '' - }, - 'warningLeaveTimerBlockTitle': { - defaultvalue: 'Aufgabenabschnitt verlassen?', - description: '' - }, - 'warningLeaveTimerBlockPrompt': { - defaultvalue: 'Wenn du jetzt weiterblätterst, beendest ' + - 'du vorzeitig die Bearbeitung dieses Aufgabenabschnitts und du kannst nicht mehr zurück.', - description: '' - } - } - } -}; diff --git a/src/app/app.interceptor.ts b/src/app/app.interceptor.ts index 639c5488fa00d59a741d863cc7b932f9b1d3c5b0..f672651dccb64b86a9f6403f01d81ecea4bbd0f3 100644 --- a/src/app/app.interceptor.ts +++ b/src/app/app.interceptor.ts @@ -1,40 +1,119 @@ import { MainDataService } from './maindata.service'; import { Injectable } from '@angular/core'; -import { HttpInterceptor, HttpRequest, - HttpHandler, HttpEvent } from '@angular/common/http'; -import { Observable } from 'rxjs'; +import { + HttpInterceptor, HttpRequest, + HttpHandler, HttpEvent, HttpErrorResponse +} from '@angular/common/http'; +import {Observable, throwError} from 'rxjs'; +import {catchError} from "rxjs/operators"; +import {Router, RouterState, RouterStateSnapshot} from "@angular/router"; +import {ApiError} from "./app.interfaces"; @Injectable() export class AuthInterceptor implements HttpInterceptor { - constructor(public mds: MainDataService) {} + constructor( + private mds: MainDataService, + private router: Router) {} intercept(request: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> { - - if (request.headers.get('AuthToken') !== null) { - return next.handle(request); + if (!this.mds.isApiValid) { + this.mds.appError$.next({ + label: "Server-Problem: API-Version ungültig", + description: "Keine weiteren Server-Aufrufe erlaubt", + category: "FATAL" + }); + return throwError(new ApiError(500, "API-Version ungültig")); } - const loginData = this.mds.loginData$.getValue(); - let authData; - if (loginData === null) { - authData = { - l: '', - p: '', - at: '' - }; - } else { - authData = { - l: loginData.loginToken, - p: loginData.personToken, - at: loginData.adminToken - }; + // if (request.headers.get('AuthToken') !== null) { + // return next.handle(request); + // } + let tokenStr = ''; + const authData = MainDataService.getAuthData(); + if (authData) { + if (authData.token) { + tokenStr = authData.token; + } } + const requestA = request.clone({ setHeaders: { - AuthToken: JSON.stringify(authData) + AuthToken: tokenStr } }); - return next.handle(requestA); + return next.handle(requestA).pipe( + catchError(e => { + let apiError = new ApiError(999); + if (e instanceof HttpErrorResponse) { + const httpError = e as HttpErrorResponse; + apiError.code = httpError.status; + apiError.info = httpError.message + " // " + httpError.error; + if (httpError.error instanceof ErrorEvent) { + this.mds.appError$.next({ + label: 'Fehler in der Netzwerkverbindung', + description: httpError.message, + category: "PROBLEM" + }) + } else { + let ignoreError = false; + let goToLoginPage = false; + let label = 'Unbekanntes Verbindungsproblem'; + switch (httpError.status) { + case 400: { + ignoreError = true; + // apiError.info = ?? TODO - from request body + break; + } + case 401: { + goToLoginPage = true; + label = 'Bitte für diese Aktion erst anmelden!'; + break; + } + case 403: { + label = 'Für diese Funktion haben Sie keine Berechtigung.'; + break; + } + case 404: { + label = 'Daten/Objekt nicht gefunden.'; + break; + } + case 410: { + goToLoginPage = true; + label = 'Anmeldung abgelaufen. Bitte erneut anmelden!'; + break; + } + case 422: { + ignoreError = true; + // apiError.info = ?? TODO - from request body + label = 'Die übermittelten Objekte sind fehlerhaft!'; + break; + } + case 500: { + label = 'Allgemeines Server-Problem.'; + break; + } + } + if (!ignoreError) { + if (goToLoginPage) { + console.warn('AuthError' + httpError.status + ' (' + label + ')'); + MainDataService.resetAuthData(); + const state: RouterState = this.router.routerState; + const snapshot: RouterStateSnapshot = state.snapshot; + this.router.navigate(['/r/login', snapshot.url]); + } else { + this.mds.appError$.next({ + label: label, + description: httpError.message, + category: "PROBLEM" + }); + } + } + } + } + + return throwError(apiError); + }) + ) } } diff --git a/src/app/app.interfaces.ts b/src/app/app.interfaces.ts index 0d959270f42c67fa627cda7cadd5dd3a44f5d65e..a65b3889306737d2038273821a01951d8483c73d 100644 --- a/src/app/app.interfaces.ts +++ b/src/app/app.interfaces.ts @@ -1,69 +1,64 @@ -export interface BookletData { - id: string; - filename: string; - label: string; +export enum AuthFlagType { + CODE_REQUIRED = "codeRequired", + PENDING = "pending", + EXPIRED = "expired" } -export interface BookletDataListByCode { - [code: string]: BookletData[]; +export enum AuthAccessKeyType { + WORKSPACE_ADMIN = "workspaceAdmin", + SUPER_ADMIN = "superAdmin", + TEST = "test", + WORKSPACE_MONITOR = "workspaceMonitor", + TEST_GROUP_MONITOR = "testGroupMonitor" } -export interface BookletListByCode { - [code: string]: string[]; +export interface AccessType { + [key: string]: string[]; } -export interface LoginData { - loginToken: string; - personToken: string; - code: string; // TODO after https://github.com/iqb-berlin/testcenter-iqb-ng/issues/52 remove - name: string; - - mode: string; - - groupName: string; - - workspaceName: string; - - booklets: BookletListByCode; - - testId: number; - bookletLabel: string; - - customTexts: KeyValuePair; - - adminToken: string; - workspaces: WorkspaceData[]; - isSuperadmin: boolean; +export interface AuthData { + token: string; + displayName: string; + customTexts: KeyValuePairs; + flags: AuthFlagType[]; + access: AccessType; } -export interface BookletStatus { - statusLabel: string; - lastUnit: number; - canStart: boolean; - id: number; - label: string; +export interface WorkspaceData { + id: string; + name: string; + role: "RW" | "RO" | "n.d."; } -export interface PersonTokenAndTestId { - personToken: string; - testId: number; +export interface BookletData { + id: string; + label: string; + running: boolean; + locked: boolean; } -export interface SysConfig { - customTexts: KeyValuePair; - version: string; +export interface KeyValuePairs { + [K: string]: string; } -export interface KeyValuePair { - [K: string]: string; +export interface AppError { + label: string; + description: string; + category: 'WARNING' | 'FATAL' | 'PROBLEM' } -export interface KeyValuePairNumber { - [K: string]: number; +export class ApiError { + code: number; + info: string; + constructor(code: number, info = '') { + this.code = code; + this.info = info + } } -export interface WorkspaceData { - id: number; +export interface SysCheckInfo { + workspaceId: string; name: string; - role: string; + label: string; + description: string; } diff --git a/src/app/app.module.spec.ts b/src/app/app.module.spec.ts new file mode 100644 index 0000000000000000000000000000000000000000..30c3268c88b40383755bc3f7b35b08714646dd35 --- /dev/null +++ b/src/app/app.module.spec.ts @@ -0,0 +1,13 @@ +import {AppModule} from "./app.module"; + +describe('AppModule', () => { + let appModule: AppModule; + + beforeEach(() => { + appModule = new AppModule(); + }); + + it('should create an instance', () => { + expect(appModule).toBeTruthy(); + }); +}); diff --git a/src/app/app.module.ts b/src/app/app.module.ts index 7fa451345e4aae791c8ae203e4793d853fe33e6d..1ffed1323c25e913af3e2caa53f2adbfdcf2d9bb 100644 --- a/src/app/app.module.ts +++ b/src/app/app.module.ts @@ -1,59 +1,86 @@ -import { AboutComponent } from './about/about.component'; import { BrowserModule } from '@angular/platform-browser'; import {HTTP_INTERCEPTORS, HttpClientModule} from '@angular/common/http'; import { BrowserAnimationsModule } from '@angular/platform-browser/animations'; -import { NgModule } from '@angular/core'; +import {ApplicationModule, NgModule} from '@angular/core'; import { ReactiveFormsModule } from '@angular/forms'; - -import { MatButtonModule, MatCheckboxModule, MatMenuModule, MatTooltipModule, MatCardModule, - MatToolbarModule, MatIconModule, MatDialogModule, MatFormFieldModule, MatInputModule, - MatTabsModule, MatProgressSpinnerModule, MatRadioModule, MatProgressBarModule } from '@angular/material'; import { AppRoutingModule } from './app-routing.module'; import { AppComponent } from './app.component'; import { BackendService } from './backend.service'; -import { StartComponent } from './start/start.component'; import { LocationStrategy, HashLocationStrategy } from '@angular/common'; import { FlexLayoutModule } from '@angular/flex-layout'; -import { ErrormsgComponent } from './errormsg/errormsg.component'; import {AuthInterceptor} from './app.interceptor'; import { IqbComponentsModule } from 'iqb-components'; +import {MatButtonModule} from "@angular/material/button"; +import {MatCardModule} from "@angular/material/card"; +import {MatCheckboxModule} from "@angular/material/checkbox"; +import {MatDialog, MatDialogModule} from '@angular/material/dialog'; +import {MatFormFieldModule} from "@angular/material/form-field"; +import {MatIconModule} from "@angular/material/icon"; +import {MatInputModule} from "@angular/material/input"; +import {MatMenuModule} from "@angular/material/menu"; +import {MatProgressBarModule} from "@angular/material/progress-bar"; +import {MatProgressSpinnerModule} from "@angular/material/progress-spinner"; +import {MatRadioModule} from "@angular/material/radio"; +import {MatTabsModule} from "@angular/material/tabs"; +import {MatToolbarModule} from "@angular/material/toolbar"; +import {MatTooltipModule} from "@angular/material/tooltip"; +import {RouterModule} from "@angular/router"; +import { AppRootComponent } from './app-root/app-root.component'; +import { SysCheckStarterComponent } from './app-root/sys-check-starter/sys-check-starter.component'; +import { LoginComponent } from './app-root/login/login.component'; +import { CodeInputComponent } from './app-root/code-input/code-input.component'; +import { AdminStarterComponent } from './app-root/admin-starter/admin-starter.component'; +import { RouteDispatcherComponent } from './app-root/route-dispatcher/route-dispatcher.component'; +import { StatusCardComponent } from './app-root/status-card/status-card.component'; +import { TestStarterComponent } from './app-root/test-starter/test-starter.component'; +import { MonitorStarterComponent } from './app-root/monitor-starter/monitor-starter.component'; +import { PrivacyComponent } from './app-root/privacy/privacy.component'; @NgModule({ declarations: [ AppComponent, - StartComponent, - AboutComponent, - ErrormsgComponent + AppRootComponent, + SysCheckStarterComponent, + LoginComponent, + CodeInputComponent, + AdminStarterComponent, + RouteDispatcherComponent, + StatusCardComponent, + TestStarterComponent, + MonitorStarterComponent, + PrivacyComponent ], imports: [ + ApplicationModule, BrowserModule, BrowserAnimationsModule, MatButtonModule, + MatCardModule, + MatCheckboxModule, + MatDialogModule, MatFormFieldModule, - MatMenuModule, - MatToolbarModule, - MatProgressBarModule, MatIconModule, MatInputModule, - MatTooltipModule, - MatCheckboxModule, + MatMenuModule, + MatProgressBarModule, + MatProgressSpinnerModule, MatRadioModule, - MatDialogModule, MatTabsModule, - MatProgressSpinnerModule, - MatCardModule, + MatToolbarModule, + MatTooltipModule, FlexLayoutModule, ReactiveFormsModule, HttpClientModule, - MatToolbarModule, + RouterModule, AppRoutingModule, IqbComponentsModule.forRoot() ], providers: [ BackendService, + MatDialog, { provide: HTTP_INTERCEPTORS, useClass: AuthInterceptor, diff --git a/src/app/backend.service.spec.ts b/src/app/backend.service.spec.ts index c31039d7e5bcc7bc70e7213ce06744a0dc6ed009..ffdc1397ca5ced3a08516d7183bbc820c1001627 100644 --- a/src/app/backend.service.spec.ts +++ b/src/app/backend.service.spec.ts @@ -1,14 +1,16 @@ import { TestBed, inject } from '@angular/core/testing'; import { BackendService } from './backend.service'; +import {HttpClientModule} from "@angular/common/http"; -describe('BackendService', () => { + +describe('HttpClient testing', () => { beforeEach(() => { TestBed.configureTestingModule({ + imports: [HttpClientModule], providers: [BackendService] }); }); - it('should be created', inject([BackendService], (service: BackendService) => { expect(service).toBeTruthy(); })); diff --git a/src/app/backend.service.ts b/src/app/backend.service.ts index abdaf1fc8d3a697f68746f698914b4668eedb5e3..1ebe43264566b9ca785737964a5217ed0751ac36 100644 --- a/src/app/backend.service.ts +++ b/src/app/backend.service.ts @@ -1,13 +1,20 @@ import { Injectable, Inject } from '@angular/core'; -import {HttpClient, HttpParams} from '@angular/common/http'; -import { Observable, of } from 'rxjs'; +import {HttpClient} from '@angular/common/http'; +import {Observable, of} from 'rxjs'; import {catchError, map, switchMap} from 'rxjs/operators'; -import {LoginData, BookletStatus, PersonTokenAndTestId, KeyValuePair, SysConfig} from './app.interfaces'; -import {ErrorHandler, ServerError} from 'iqb-components'; +import { + SysCheckInfo, + AuthData, + WorkspaceData, + BookletData, ApiError +} from './app.interfaces'; +import {SysConfig} from "./config/app.config"; // ============================================================================ -@Injectable() +@Injectable({ + providedIn: 'root' +}) export class BackendService { constructor( @@ -16,91 +23,119 @@ export class BackendService { ) {} - login(name: string, password: string): Observable<LoginData | ServerError> { - - return this.http - .put<LoginData>(this.serverUrl + 'session/login', {name, password}) + login(name: string, password: string): Observable<AuthData | number> { + if (password) { + return this.http + .put<AuthData>(this.serverUrl + 'session/admin', {name, password}) .pipe( - catchError(ErrorHandler.handle), - switchMap(myLoginData => { - if (myLoginData instanceof ServerError) { - if ((myLoginData as ServerError).code === 401) { + catchError((err: ApiError) => { + console.warn(`login Api-Error: ${err.code} ${err.info} `); + return of(err.code) + }), + switchMap(authData => { + if (typeof authData === 'number') { + const errCode = authData as number; + if (errCode === 400) { return this.http - .put<LoginData>(this.serverUrl + 'session/admin', {name, password}) - .pipe(catchError(ErrorHandler.handle)); + .put<AuthData>(this.serverUrl + 'session/login', {name, password}) + .pipe(catchError(errCode => of(errCode))); } else { - return of(myLoginData); + return of(errCode); } } else { - return of(myLoginData); + return of(authData); } }) ); + } else { + return this.nameOnlyLogin(name); + } } - - getSession(loginToken: string, personToken: string): Observable<LoginData | ServerError> { - - const authToken = JSON.stringify({l: loginToken, p: personToken}); + nameOnlyLogin(name: string): Observable<AuthData | number> { return this.http - .get<LoginData>(this.serverUrl + 'session', {headers: {'AuthToken': authToken}}) - .pipe(catchError(ErrorHandler.handle)); + .put<AuthData>(this.serverUrl + 'session/login', {name}) + .pipe( + catchError((err: ApiError) => { + console.warn(`nameOnlyLogin Api-Error: ${err.code} ${err.info} `); + return of(err.code) + }) + ); } - - getAdminSession(adminToken: string): Observable<LoginData | ServerError> { - - const authToken = JSON.stringify({at: adminToken}); + codeLogin(code: string): Observable<AuthData | number> { return this.http - .get<LoginData>(this.serverUrl + 'session', {headers: {'AuthToken': authToken}}) - .pipe(catchError(ErrorHandler.handle)); + .put<AuthData>(this.serverUrl + 'session/person', {code}) + .pipe( + catchError((err: ApiError) => { + console.warn(`codeLogin Api-Error: ${err.code} ${err.info} `); + return of(err.code) + }) + ); } - - getSysConfig(): Observable<KeyValuePair> { - + getWorkspaceData(workspaceId: string): Observable<WorkspaceData> { return this.http - .get<SysConfig>(this.serverUrl + `system/config`) - .pipe(catchError(() => of(null))) - .pipe(map((sysConfig: SysConfig): KeyValuePair => { - console.log(sysConfig.version); // TODO check for system version mismatch https://github.com/iqb-berlin/testcenter-iqb-ng/issues/53 - return sysConfig.customTexts; + .get<WorkspaceData>(this.serverUrl + 'workspace/' + workspaceId) + .pipe(catchError(() => { + console.warn('get workspace data failed for ' + workspaceId); + return of(<WorkspaceData>{ + id: workspaceId, + name: workspaceId, + role: "n.d." + }) })); } - - getBookletState(bookletName: string, code = ''): Observable<BookletStatus | ServerError> { - - // TODO after https://github.com/iqb-berlin/testcenter-iqb-ng/issues/52 is resolved, - // this must be removed, we would have a personToken here - const params = new HttpParams().set('code', code); - + getSessionData(): Observable<AuthData | number> { return this.http - .get<BookletStatus>(this.serverUrl + `booklet/${bookletName}/state`, {params}) - .pipe(catchError(ErrorHandler.handle)); + .get<AuthData>(this.serverUrl + 'session') + .pipe( + catchError((err: ApiError) => of(err.code)) + ) } - - startBooklet(code: string, bookletName: string, bookletLabel: string): Observable<PersonTokenAndTestId | ServerError> { - + getBookletData(bookletId: string): Observable<BookletData> { return this.http - .put<PersonTokenAndTestId>(this.serverUrl + `test`, {code, bookletName, bookletLabel}) - .pipe(catchError(ErrorHandler.handle)); + .get<BookletData>(this.serverUrl + 'booklet/' + bookletId) + .pipe( + map(bData => { + bData.id = bookletId; + return bData + }), + catchError(() => { + console.warn('get booklet data failed for ' + bookletId); + return of(<BookletData>{ + id: bookletId, + label: bookletId, + locked: true, + running: false + }) + })); } - - addBookletLogClose(testId: number): Observable<boolean | ServerError> { - + startTest(bookletName: string): Observable<string | number> { return this.http - .put<boolean>(this.serverUrl + `test/${testId}/log`, {timestamp: Date.now(), entry: 'BOOKLETLOCKEDbyTESTEE'}) - .pipe(catchError(ErrorHandler.handle)); + .put<number>(this.serverUrl + 'test', {bookletName}) + .pipe( + map((testId: number) => String(testId)), + catchError((err: ApiError) => of(err.code)) + ); } + getSysConfig(): Observable<SysConfig> { + return this.http + .get<SysConfig>(this.serverUrl + `system/config`) + .pipe(catchError(() => of(null))) + } - lockBooklet(testId: number): Observable<boolean | ServerError> { - + getSysCheckInfo(): Observable<SysCheckInfo[]> { return this.http - .patch<boolean>(this.serverUrl + `test/${testId}/lock`, {}) - .pipe(catchError(ErrorHandler.handle)); + .get<SysCheckInfo[]>(this.serverUrl + 'sys-checks') + .pipe( + catchError(() => { + return of([]); + }) + ); } } diff --git a/src/app/config/app.config.ts b/src/app/config/app.config.ts new file mode 100644 index 0000000000000000000000000000000000000000..6433ddde68c390d1f489c95415c9454f95c9ed58 --- /dev/null +++ b/src/app/config/app.config.ts @@ -0,0 +1,26 @@ +// @ts-ignore +import customTextsDefault from './custom-texts.json'; +import {CustomtextService} from "iqb-components"; +import {KeyValuePairs} from "../app.interfaces"; + +export interface SysConfig { + customTexts: KeyValuePairs; + version: string; + mainLogo: string; + testConfig: KeyValuePairs; +} + +export class AppConfig { + constructor( + private cts: CustomtextService + ) { + } + + setDefaultCustomTexts() { + let ctDefaults = {}; + for (const k of Object.keys(customTextsDefault)) { + ctDefaults[k] = customTextsDefault[k].defaultvalue + } + this.cts.addCustomTexts(ctDefaults); + } +} diff --git a/src/app/config/booklet-config.json b/src/app/config/booklet-config.json new file mode 100644 index 0000000000000000000000000000000000000000..937c581115f071b83eef0f554f29fb7b197969ab --- /dev/null +++ b/src/app/config/booklet-config.json @@ -0,0 +1,91 @@ +{ + "loading_mode": { + "label": "Ladeverhalten beim Start", + "options": { + "LAZY": "Start sobald wie möglich, Laden im Hintergrund fortsetzen", + "EAGER": "Testheft erst dann starten, wenn alle Inhalte geladen sind" + }, + "defaultvalue": "LAZY" + }, + "log_mode": { + "label": "Erfassen und Speichern von Log-Daten", + "options": { + "OFF": "Ausgeschaltet", + "LEAN": "Nur wichtige Meldungen", + "RICH": "Alles" + }, + "defaultvalue": "RICH" + }, + "page_navibuttons": { + "label": "Navigationsbuttons für die Seitennavigation (innerhalb einer Aufgabe)", + "options": { + "OFF": "Keine Seitennavigation unterstützen (übernimmt ggf. die Aufgabe selbst)", + "MERGED": "Die Seitennavigation wird durch die Aufgabennavigation mit übernommen", + "SEPARATE_TOP": "Seitennavigation über getrennte Button-Leiste - oben", + "SEPARATE_BOTTOM": "Seitennavigation über getrennte Button-Leiste - unten" + }, + "defaultvalue": "SEPARATE_BOTTOM" + }, + "unit_navibuttons": { + "label": "Navigationsbuttons für die Navigation zwischen den Aufgaben", + "options": { + "OFF": "Keine Buttons für Aufgabennavigation anzeigen (übernimmt ggf. die Aufgabe selbst)", + "ARROWS_ONLY": "Nur die Buttons für 'Weiter' und 'Zurück' anzeigen", + "FULL": "Buttons für 'Weiter' und 'Zurück' und dazwischen kleine Buttons für jede Aufgabe anzeigen" + }, + "defaultvalue": "FULL" + }, + "unit_menu": { + "label": "Extra-Seite mit großen Buttons für Aufgaben zum direkten Springen", + "options": { + "OFF": "Ausgeschaltet", + "ENABLED_ONLY": "Eingeschaltet - nur die Aufgaben anzeigen, die noch freigegeben sind", + "FULL": "Eingeschaltet - auch die Aufgaben anzeigen, die nicht mehr freigegeben sind (gegraut)" + }, + "defaultvalue": "ENABLED_ONLY" + }, + "force_presentation_complete": { + "label": "Verhalten, wenn noch nicht alle Elemente der Aufgabe angezeigt wurden", + "options": { + "OFF": "Ignorieren - Weiterblättern möglich", + "ON": "Weiterblättern verhindern, bis Anzeige vollständig" + }, + "defaultvalue": "OFF" + }, + "force_responses_complete": { + "label": "Verhalten, wenn noch nicht alle Antworten der Aufgabe vollständig gegeben wurden", + "options": { + "OFF": "Ignorieren - Weiterblättern möglich", + "SOME": "Weiterblättern erst möglich, wenn einige Antworten gegeben wurden", + "COMPLETE": "Weiterblättern erst möglich, wenn alle Antworten gegeben wurden", + "COMPLETE_AND_VALID": "Weiterblättern erst möglich, wenn alle Antworten gegeben wurden und als gültig eingeschätzt wurden" + }, + "defaultvalue": "OFF" + }, + "unit_screenheader": { + "label": "Legt fest, ob im obersten Seitenbereich Platz für Logo, Navigations-Buttons u. ä. gelassen wird.", + "options": { + "OFF": "Kein Seitenkopf. Achtung: Logo bleibt sichtbar (überlappt).", + "WITH_UNIT_TITLE": "Seitenkopf wird angezeigt mit Titel der Unit (s. Booklet-XML)", + "WITH_BOOKLET_TITLE": "Seitenkopf wird angezeigt mit Titel des Booklets (s. Booklet-XML)", + "EMPTY": "Seitenkopf wird angezeigt (leer)" + }, + "defaultvalue": "EMPTY" + }, + "unit_title": { + "label": "Festlegung, ob oberhalb des Unitbereiches eine Zeile mit dem Unit-Titel gezeigt werden soll", + "options": { + "OFF": "Keine Titelzeile", + "ON": "Eine Zeile wird eingeblendet mit dem Unit-Titel (s. Booklet-XML)." + }, + "defaultvalue": "ON" + }, + "unit_show_time_left": { + "label": "Festlegung, ob im obersten Seitenbereich bei einer festgelegten Maximalzeit für einen Testbereich die verbleibende Zeit angezeigt wird.", + "options": { + "OFF": "Die verbleibende Zeit wird nicht angezeigt.", + "ON": "Die verbleibende Zeit wird angezeigt." + }, + "defaultvalue": "OFF" + } +} diff --git a/src/app/config/booklet-config.md b/src/app/config/booklet-config.md new file mode 100644 index 0000000000000000000000000000000000000000..7b29e372fa1d6b043184c8f5a2d16e2c92806430 --- /dev/null +++ b/src/app/config/booklet-config.md @@ -0,0 +1,38 @@ +# Booklet config +There are some configuration parameters for adjusting the behaviour during the test.This +document describes the ways to bring the parameters to the application and lists +all possible keys. + +### Configuration file on the server +There is one file on the server where the application looks for booklet definitions: +``` +/config/bookletDefintions.json +``` +This configuration is loaded at (re)start of the application and is applied for +all booklets, if no other configuration is found. This is a simple JSON file with +key value pairs. Example: +``` +{ + "force_responses_complete": "OFF", + "unit_navibuttons": "ARROWS_ONLY", +... +} +``` +The adminstrator of the server can upload this file. We aim at providing an +administration feature of the super-admin section of the application to manage +this configuration. + +### Configuration via booklet XML +The configuration can be set for every single booklet. You need to add one XML-Element +into the booklet-file. Example: +``` +... +</Metadata> +<BookletConfig> + <Config key="force_responses_complete">OFF</CustomText> + <Config key="unit_navibuttons">ARROWS_ONLY</CustomText> +... +</BookletConfig> +``` + +### List of parameters diff --git a/src/app/config/booklet-config.ts b/src/app/config/booklet-config.ts new file mode 100644 index 0000000000000000000000000000000000000000..cd2018d8457bc07818dd02f9af1cb6aafd492be2 --- /dev/null +++ b/src/app/config/booklet-config.ts @@ -0,0 +1,67 @@ +export class BookletConfig { + // this file is generated by 'generateBookletConfigClass' script from 'app/config/booklet-config.json' + // do not change anything here directly! + + loading_mode: "LAZY" | "EAGER" = "LAZY"; + log_mode: "OFF" | "LEAN" | "RICH" = "RICH"; + page_navibuttons: "OFF" | "MERGED" | "SEPARATE_TOP" | "SEPARATE_BOTTOM" = "SEPARATE_BOTTOM"; + unit_navibuttons: "OFF" | "ARROWS_ONLY" | "FULL" = "FULL"; + unit_menu: "OFF" | "ENABLED_ONLY" | "FULL" = "ENABLED_ONLY"; + force_presentation_complete: "OFF" | "ON" = "OFF"; + force_responses_complete: "OFF" | "SOME" | "COMPLETE" | "COMPLETE_AND_VALID" = "OFF"; + unit_screenheader: "OFF" | "WITH_UNIT_TITLE" | "WITH_BOOKLET_TITLE" | "EMPTY" = "EMPTY"; + unit_title: "OFF" | "ON" = "ON"; + + public setFromKeyValuePairs(config) { + if (config) { + if (config['loading_mode']) { this.loading_mode = config['loading_mode']} + if (config['log_mode']) { this.log_mode = config['log_mode']} + if (config['page_navibuttons']) { this.page_navibuttons = config['page_navibuttons']} + if (config['unit_navibuttons']) { this.unit_navibuttons = config['unit_navibuttons']} + if (config['unit_menu']) { this.unit_menu = config['unit_menu']} + if (config['force_presentation_complete']) { this.force_presentation_complete = config['force_presentation_complete']} + if (config['force_responses_complete']) { this.force_responses_complete = config['force_responses_complete']} + if (config['unit_screenheader']) { this.unit_screenheader = config['unit_screenheader']} + if (config['unit_title']) { this.unit_title = config['unit_title']} + } + } + + public setFromXml(bookletConfigElement: Element) { + if (bookletConfigElement) { + const bookletConfigs = Array.prototype.slice.call(bookletConfigElement.childNodes).filter(function (e) { return e.nodeType === 1; }); + for (let childIndex = 0; childIndex < bookletConfigs.length; childIndex++) { + const configKey = bookletConfigs[childIndex].getAttribute('key'); + const configValue = bookletConfigs[childIndex].textContent; + switch (configKey) { + case 'loading_mode': + this.loading_mode = configValue; + break; + case 'log_mode': + this.log_mode = configValue; + break; + case 'page_navibuttons': + this.page_navibuttons = configValue; + break; + case 'unit_navibuttons': + this.unit_navibuttons = configValue; + break; + case 'unit_menu': + this.unit_menu = configValue; + break; + case 'force_presentation_complete': + this.force_presentation_complete = configValue; + break; + case 'force_responses_complete': + this.force_responses_complete = configValue; + break; + case 'unit_screenheader': + this.unit_screenheader = configValue; + break; + case 'unit_title': + this.unit_title = configValue; + break; + } + } + } + } +} diff --git a/src/app/config/custom-texts.json b/src/app/config/custom-texts.json new file mode 100644 index 0000000000000000000000000000000000000000..bb523bab2b802e92dc1302bf076e3622ae1a6734 --- /dev/null +++ b/src/app/config/custom-texts.json @@ -0,0 +1,126 @@ +{ + "app_title": { + "label": "Titel der Hauptanwendung", + "defaultvalue": "IQB-Testcenter" + }, + "app_intro1": { + "label": "Begrüßungstext auf der Startseite (Text nach IQB-Link)", + "defaultvalue": "betreibt auf diesen Seiten eine Anwendung für das computerbasierte Leistungstesten von Schülerinnen und Schülern. Der Zugang zu einem Test ist nur möglich, wenn Sie von Testverantwortlichen Zugangsdaten erhalten haben. Es sind keine weiteren Seiten öffentlich verfügbar." + }, + "login_testRunningText": { + "label": "Kurznachricht, dass ein Test (Booklet) gestartet ist", + "defaultvalue": "Ein Testheft ist gestartet" + }, + "login_testRunningTextAndClick": { + "label": "Nachricht, dass ein Test (Booklet) gestartet ist, mit Aufforderung zum Klicken", + "defaultvalue": "Es wird gerade ein Test ausgeführt. Bitte durch Klicken auf eine der beiden Schaltflächen links wählen, ob der Test fortgesetzt oder beendet werden soll!" + }, + "login_testEndButtonLabel": { + "label": "Schalterbeschriftung für 'Test beenden'", + "defaultvalue": "Test beenden" + }, + "booklet_warningLeaveTimerBlockTextPrompt": { + "label": "Schalterbeschriftung für 'Zurück zum Test'", + "defaultvalue": "Du verlässt einen zeitbeschränkten Bereich und kannst nicht zurückkehren. Trotzdem weiterblättern?" + }, + "login_testReturnButtonLabel": { + "label": "Schalterbeschriftung für 'Zurück zum Test'", + "defaultvalue": "Zum Test zurückkehren" + }, + "login_bookletSelectPromptNull": { + "label": "Nachricht für den Fall, dass Booklet(s) beendet wurden und keine weiteren zur Verfügung stehen", + "defaultvalue": "Beendet. Es können keine weiteren Testhefte gestartet werden." + }, + "login_bookletSelectPromptOne": { + "label": "Aufforderung, den einen gefundenen Test anzuklicken (auf Schalter klicken)", + "defaultvalue": "Bitte klicke auf die Schaltfläche auf der linken Seite, um den Test zu starten!" + }, + "login_bookletSelectPromptMany": { + "label": "Aufforderung, aus der Liste der gefundenen Tests einen auszusuchen (auf Schalter klicken)", + "defaultvalue": "Bitte klicke auf eine der Schaltflächen auf der linken Seite, um einen Test zu starten!" + }, + "login_codeInputPrompt": { + "label": "Aufforderung, Code einzugeben (bei einem zweistufigen Login-Prozess)", + "defaultvalue": "Bitte Log-in eingeben, der auf dem Zettel steht!" + }, + "login_codeInputTitle": { + "label": "Titel des Eingabeformulares für den Code", + "defaultvalue": "Log-in eingeben" + }, + "booklet_msgPresentationNotCompleteTitleNext": { + "label": "Titel der Nachricht (Dialogbox), dass nicht weitergeblättert werden kann, solange die Präsentation des Aufgabeninhaltes nicht abgeschlossen ist", + "defaultvalue": "Weiterblättern nicht möglich!" + }, + "booklet_msgPresentationNotCompleteTextNext": { + "label": "Nachrichttext, dass nicht weitergeblättert werden kann, solange die Präsentation des Aufgabeninhaltes nicht abgeschlossen ist", + "defaultvalue": "Du kannst erst weiterblättern, wenn Audio-Dateien vollständig abgespielt wurden und wenn du in allen Fenstern bis ganz nach unten gescrollt hast." + }, + "booklet_msgPresentationNotCompleteTitlePrev": { + "label": "Titel der Nachricht (Dialogbox), dass nicht zurückgeblättert werden kann, solange die Präsentation des Aufgabeninhaltes nicht abgeschlossen ist", + "defaultvalue": "Zurückblättern - Warnung" + }, + "booklet_msgPresentationNotCompleteTextPrev": { + "label": "Nachrichttext, dass nicht zurückgeblättert werden kann, solange die Präsentation des Aufgabeninhaltes nicht abgeschlossen ist", + "defaultvalue": "Eine Audio-Datei ist noch nicht bis zu Ende abgespielt oder Seiten wurden noch nicht vollständig gezeigt. Wenn du jetzt zurückblätterst, kannst Du später Audio-Dateien nicht nocheinmal starten." + }, + "booklet_codeToEnterTitle": { + "label": "Titel der Dialogbox für die Eingabe eines Freigabewortes", + "defaultvalue": "Freigabewort" + }, + "booklet_codeToEnterPrompt": { + "label": "Aufforderung für die Eingabe eines Freigabewortes (Dialog-Box)", + "defaultvalue": "Bitte gib das Freigabewort ein, das angesagt wurde!" + }, + "booklet_msgSoonTimeOver5Minutes": { + "label": "Nachricht, dass für die Bearbeitung eines Abschnittes noch 5 min Zeit sind", + "defaultvalue": "Du hast noch 5 Minuten Zeit für die Bearbeitung der Aufgaben in diesem Abschnitt." + }, + "booklet_msgSoonTimeOver1Minute": { + "label": "Nachricht, dass für die Bearbeitung eines Abschnittes noch 1 min Zeit ist", + "defaultvalue": "Du hast noch 1 Minute Zeit für die Bearbeitung der Aufgaben in diesem Abschnitt." + }, + "booklet_msgTimerStarted": { + "label": "Nachricht, dass der Timer für die Bearbeitung eines Abschnittes gestartet wurde", + "defaultvalue": "Die Bearbeitungszeit für diesen Abschnitt hat begonnen: " + }, + "booklet_msgTimerCancelled": { + "label": "Nachricht, dass die Bearbeitung eines Abschnittes mit Timer abgebrochen wurde", + "defaultvalue": "Die Bearbeitung des Abschnittes wurde abgebrochen." + }, + "booklet_msgTimeOver": { + "label": "Nachricht, dass die Bearbeitungszeit für einen Abschnitt abgelaufen ist.", + "defaultvalue": "Die Bearbeitung des Abschnittes ist beendet." + }, + "booklet_warningLeaveTimerBlockTitle": { + "label": "Titel für Warnung (Dialogbox) vor dem vorzeitigen Verlassen eines Abschnittes mit Timer", + "defaultvalue": "Aufgabenabschnitt verlassen?" + }, + "booklet_warningLeaveTimerBlockPrompt": { + "label": "Warnung vor dem vorzeitigen Verlassen eines Abschnittes mit Timer", + "defaultvalue": "Wenn du jetzt weiterblätterst, beendest du vorzeitig die Bearbeitung dieses Aufgabenabschnitts und du kannst nicht mehr zurück." + }, + "booklet_tasklisttitle": { + "label": "Titel für die Auflistung der Aufgaben (Schalter)", + "defaultvalue": "Aufgaben" + }, + "booklet_warningLeaveTestTitle": { + "label": "Titel für Warnung (Dialogbox) vor dem vorzeitigen Verlassen des Tests", + "defaultvalue": "Test verlassen?" + }, + "booklet_warningLeaveTestPrompt": { + "label": "Warnung vor dem vorzeitigen Verlassen des Tests", + "defaultvalue": "Der Test ist noch nicht beendet. Möchtest Du den Test trotzdem verlassen?" + }, + "syscheck_questionsintro": { + "label": "Aufforderung, die Fragen (Questionnaire) zu beantworten", + "defaultvalue": "Bitte bearbeiten Sie die nachfolgenden Fragen." + }, + "booklet_errormessage": { + "label": "Nachricht an die Testperson, wenn ein schwerer Fehler aufgetreten ist", + "defaultvalue": "Es ist ein schwerer Fehler aufgetreten. Bitte rufe die Aufsichtsperson und beschreibe das Problem!" + }, + "booklet_pausedmessage": { + "label": "Nachricht an die Testperson, wenn der Test vom System unterbrochen wurde", + "defaultvalue": "Der Test wurde kurz angehalten." + } +} diff --git a/src/app/config/custom-texts.md b/src/app/config/custom-texts.md new file mode 100644 index 0000000000000000000000000000000000000000..397c3db842de340a735e501c8cc08deb58151ed3 --- /dev/null +++ b/src/app/config/custom-texts.md @@ -0,0 +1,65 @@ +# CustomTexts +This application enables changes of texts during runtime. It's an implementation +of the CustomTextPipe/CustomTextService +of [iqb-components](https://github.com/iqb-berlin/iqb-components). The idea is, that +there might be some cases where the standard titles, prompts or explanations are not +suitable for the specific environment the iqb-testcenter application is run in. One +could change the source code and rebuild the application, but for minor changes we +use this text replacement feature 'custom texts'. + +This document +describes the ways to bring the custom texts to the application and lists +all possible keys. + +### Configuration file on the server +There is one file on the server where the application looks for custom texts: +``` +/config/customTexts.json +``` +These custom texts are loaded at (re)start of the application and the replacement starts +as soon as possible. This is a simple JSON file with key value pairs. Example: +``` +{ + "login_testEndButtonText": "Test beenden", + "login_bookletSelectPrompt": "Bitte wählen", +... +} +``` +The adminstrator of the server can upload this file. We aim at providing an +administration feature of the super-admin section of the application to manage +these texts. + +### Configuration via login configuration +For some tests, the test authority might like to change standard titles, prompts or explanations +furthermore depending on the testtaker. For example, the questionnaire for teachers +will use 'Please contact the administrator of the survey' and the booklet for students +will prompt 'Please ask the test proctor'. + +The login configuration goes with the XML file for the longin(s). There is one optional +section 'CustomTexts' in every login file. Text replacements in this section will apply +for every login of this file. Example: +``` +<CustomTexts> + <CustomText key="login_testEndButtonText">Test beenden</CustomText> + <CustomText key="login_bookletSelectPrompt">Bitte wählen</CustomText> +... +</CustomTexts> +``` +### Configuration of System check +In the definition file for system checks, there is also one place to define text +replacements: +``` +<Config> + <UploadSpeed ... + <DownloadSpeed ... + <CustomText key="syscheck_questionsintro">...</CustomText> + <CustomText key="app_intro1">...</CustomText> +... +</Config> +``` + + + +### List of possible replacements +| Key | Used for | Default | +| :------------- | :---------- | :----------- | diff --git a/src/app/config/mode-options.json b/src/app/config/mode-options.json new file mode 100644 index 0000000000000000000000000000000000000000..8c286e539f83370b24a63f06efd7f635dfb37475 --- /dev/null +++ b/src/app/config/mode-options.json @@ -0,0 +1,9 @@ +{ + "canReview": "Es können Reviews abgegeben werden (Kommentare/Einschätzungen zur Unit bzw. zum Test)", + "saveResponses": "Es werden Antworten und Logs gespeichert.", + "forceTimeRestrictions": "Alle Zeitbeschränkungen für Testabschnitte werden angewendet.", + "forceNaviRestrictions": "Alle Navigationsbeschränkungen des Booklets werden angewendet (z. B. erst weiter, wenn vollständig angezeigt).", + "presetCode": "Sollte ein Testabschnitt mit einem Freigabewort geschützt sein, wird dieses bei der Eingabebox schon eingetragen.", + "showTimeLeft": "Sollte eine Maximalzeit für einen Testabschnitt festgelegt sein, wird die verbleibende Zeit angezeigt, auch wenn die Booklet-Konfiguration dies unterbindet.", + "showUnitMenu": "Die Seite mit der Aufgaben-Übersicht wird erlaubt, auch wenn das Booklet dies unterbindet." +} diff --git a/src/app/config/test-mode.md b/src/app/config/test-mode.md new file mode 100644 index 0000000000000000000000000000000000000000..38b8e93e9df3b32a75f117e70434c8e6e45c3dfc --- /dev/null +++ b/src/app/config/test-mode.md @@ -0,0 +1,15 @@ +# Modes for test execution + +For the test or the survey, all execution parameters are given by +the XML definition files. But before the test starts in production (hot) mode, there is +the need to evaluate the test content and configuration. Then, some restrictions of the +test may make it really hard to evaluate. For example, it would take too much time if +you have to wait for the completion of all audio sequences. One could adapt the +test definition for the evaluation period, but this is dangerous: After evaluation, you +will change the test definition again and then risk new errors. + +Our system allows multiple modes to run the test. Every login carries a token that declares +this mode. You can first review only the design of the units and its arrangement, +then switch on some restrictions and store responses, and finally evaluate the +test like a testtaker. + diff --git a/src/app/config/test-mode.ts b/src/app/config/test-mode.ts new file mode 100644 index 0000000000000000000000000000000000000000..6c061771f7e089c7f8180bc3f152aecf366b7c18 --- /dev/null +++ b/src/app/config/test-mode.ts @@ -0,0 +1,38 @@ +// @ts-ignore +import testModes from './test-modes.json'; + +// this file is generated by 'generateTestModeClass' script from 'app/config/test-modes.json' and 'app/config/mode-options.json' +// do not change anything here directly! + +export class TestMode { + canReview: false; + saveResponses: false; + forceTimeRestrictions: false; + forceNaviRestrictions: false; + presetCode: true; + showTimeLeft: true; + showUnitMenu: false; + modeLabel: "Nur Ansicht (Demo)"; + + public constructor (loginMode: string = 'DEMO') { + if (loginMode) { + const regExPattern = /(DEMO|HOT|REVIEW|TRIAL)/; + if (regExPattern.test(loginMode.toUpperCase())) { + const mode = loginMode.toUpperCase().match(regExPattern)[0]; + const modeConfig = testModes[mode]; + this.canReview = modeConfig.config.canReview; + this.saveResponses = modeConfig.config.saveResponses; + this.forceTimeRestrictions = modeConfig.config.forceTimeRestrictions; + this.forceNaviRestrictions = modeConfig.config.forceNaviRestrictions; + this.presetCode = modeConfig.config.presetCode; + this.showTimeLeft = modeConfig.config.showTimeLeft; + this.showUnitMenu = modeConfig.config.showUnitMenu; + this.modeLabel = modeConfig.label; + } else { + console.error('TestConfig: invalid loginMode - take DEMO'); + } + } else { + console.error('TestConfig: empty loginMode - take DEMO'); + } + } +} diff --git a/src/app/config/test-modes.json b/src/app/config/test-modes.json new file mode 100644 index 0000000000000000000000000000000000000000..b5d80d9eef41b2b0eaf35c31831165789e43c368 --- /dev/null +++ b/src/app/config/test-modes.json @@ -0,0 +1,50 @@ +{ + "DEMO": { + "label": "Nur Ansicht (Demo)", + "config": { + "canReview": false, + "saveResponses": false, + "forceTimeRestrictions": false, + "forceNaviRestrictions": false, + "presetCode": true, + "showTimeLeft": true, + "showUnitMenu": false + } + }, + "HOT": { + "label": "Durchführung Test/Befragung", + "config": { + "canReview": false, + "saveResponses": true, + "forceTimeRestrictions": true, + "forceNaviRestrictions": true, + "presetCode": false, + "showTimeLeft": false, + "showUnitMenu": false + } + }, + "REVIEW": { + "label": "Prüfdurchgang ohne Speichern", + "config": { + "canReview": true, + "saveResponses": false, + "forceTimeRestrictions": false, + "forceNaviRestrictions": false, + "presetCode": true, + "showTimeLeft": true, + "showUnitMenu": true + } + }, + "TRIAL": { + "label": "Prüfdurchgang mit Speichern", + "config": { + "canReview": false, + "saveResponses": true, + "forceTimeRestrictions": true, + "forceNaviRestrictions": true, + "presetCode": true, + "showTimeLeft": false, + "showUnitMenu": false + } + } +} diff --git a/src/app/errormsg/errormsg.component.css b/src/app/errormsg/errormsg.component.css deleted file mode 100644 index 361c51c845e8d3bbf1d870adc71ef9d538a03701..0000000000000000000000000000000000000000 --- a/src/app/errormsg/errormsg.component.css +++ /dev/null @@ -1,3 +0,0 @@ -div { - color: brown; -} diff --git a/src/app/errormsg/errormsg.component.html b/src/app/errormsg/errormsg.component.html deleted file mode 100644 index 8181a966ad3ed84d8f6807da641f1b206544e7ac..0000000000000000000000000000000000000000 --- a/src/app/errormsg/errormsg.component.html +++ /dev/null @@ -1,3 +0,0 @@ -<div *ngIf="errorMsg !== null" [matTooltip]="errorMsg.labelSystem"> - {{ errorMsg.labelNice }} -</div> diff --git a/src/app/errormsg/errormsg.component.ts b/src/app/errormsg/errormsg.component.ts deleted file mode 100644 index df70027d3ae4caf7259f4f934bdd05a903db5022..0000000000000000000000000000000000000000 --- a/src/app/errormsg/errormsg.component.ts +++ /dev/null @@ -1,29 +0,0 @@ -import { ServerError } from 'iqb-components'; -import { MainDataService } from '../maindata.service'; -import { Component, OnInit, OnDestroy } from '@angular/core'; -import { Subscription } from 'rxjs'; - -@Component({ - selector: 'app-errormsg', - templateUrl: './errormsg.component.html', - styleUrls: ['./errormsg.component.css'] -}) -export class ErrormsgComponent implements OnInit, OnDestroy { - public errorMsg: ServerError = null; - private globalErrorMsgSubscription: Subscription = null; - - constructor( - private mds: MainDataService - ) { } - - ngOnInit() { - this.globalErrorMsgSubscription = this.mds.globalErrorMsg$.subscribe(m => this.errorMsg = m); - } - - // % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % - ngOnDestroy() { - if (this.globalErrorMsgSubscription !== null) { - this.globalErrorMsgSubscription.unsubscribe(); - } - } -} diff --git a/src/app/group-monitor/group-monitor-routing.module.ts b/src/app/group-monitor/group-monitor-routing.module.ts new file mode 100644 index 0000000000000000000000000000000000000000..f30f73f35c7a86e3e0588af4234b9b3897c3cae9 --- /dev/null +++ b/src/app/group-monitor/group-monitor-routing.module.ts @@ -0,0 +1,14 @@ +import { NgModule } from '@angular/core'; +import { Routes, RouterModule } from '@angular/router'; +import {GroupMonitorComponent} from "./group-monitor.component"; + + +const routes: Routes = [ + {path: '', component: GroupMonitorComponent} +]; + +@NgModule({ + imports: [RouterModule.forChild(routes)], + exports: [RouterModule] +}) +export class GroupMonitorRoutingModule { } diff --git a/src/app/group-monitor/group-monitor.component.css b/src/app/group-monitor/group-monitor.component.css new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/src/app/group-monitor/group-monitor.component.html b/src/app/group-monitor/group-monitor.component.html new file mode 100644 index 0000000000000000000000000000000000000000..b61dd6b79f43c0561f41a10e079e8bc73c346e7c --- /dev/null +++ b/src/app/group-monitor/group-monitor.component.html @@ -0,0 +1,3 @@ +<div class="page-header"> + <p>Monitor der Testdurchführung - Gruppe</p> +</div> diff --git a/src/app/errormsg/errormsg.component.spec.ts b/src/app/group-monitor/group-monitor.component.spec.ts similarity index 53% rename from src/app/errormsg/errormsg.component.spec.ts rename to src/app/group-monitor/group-monitor.component.spec.ts index 671f65752579547c16014a187633fa6901a0ef36..23d08de21cbd8fb3d951bec1eb02048197e4df46 100644 --- a/src/app/errormsg/errormsg.component.spec.ts +++ b/src/app/group-monitor/group-monitor.component.spec.ts @@ -1,20 +1,20 @@ import { async, ComponentFixture, TestBed } from '@angular/core/testing'; -import { ErrormsgComponent } from './errormsg.component'; +import { GroupMonitorComponent } from './group-monitor.component'; -describe('ErrormsgComponent', () => { - let component: ErrormsgComponent; - let fixture: ComponentFixture<ErrormsgComponent>; +describe('GroupMonitorComponent', () => { + let component: GroupMonitorComponent; + let fixture: ComponentFixture<GroupMonitorComponent>; beforeEach(async(() => { TestBed.configureTestingModule({ - declarations: [ ErrormsgComponent ] + declarations: [ GroupMonitorComponent ] }) .compileComponents(); })); beforeEach(() => { - fixture = TestBed.createComponent(ErrormsgComponent); + fixture = TestBed.createComponent(GroupMonitorComponent); component = fixture.componentInstance; fixture.detectChanges(); }); diff --git a/src/app/group-monitor/group-monitor.component.ts b/src/app/group-monitor/group-monitor.component.ts new file mode 100644 index 0000000000000000000000000000000000000000..ae00cf4fb86064d35d5ec893f0b4925f4b330653 --- /dev/null +++ b/src/app/group-monitor/group-monitor.component.ts @@ -0,0 +1,15 @@ +import { Component, OnInit } from '@angular/core'; + +@Component({ + selector: 'app-group-monitor', + templateUrl: './group-monitor.component.html', + styleUrls: ['./group-monitor.component.css'] +}) +export class GroupMonitorComponent implements OnInit { + + constructor() { } + + ngOnInit(): void { + } + +} diff --git a/src/app/group-monitor/group-monitor.module.ts b/src/app/group-monitor/group-monitor.module.ts new file mode 100644 index 0000000000000000000000000000000000000000..28b4366b34b80014696bac7c5006f85bb58007a8 --- /dev/null +++ b/src/app/group-monitor/group-monitor.module.ts @@ -0,0 +1,15 @@ +import { NgModule } from '@angular/core'; +import { CommonModule } from '@angular/common'; + +import { GroupMonitorRoutingModule } from './group-monitor-routing.module'; +import { GroupMonitorComponent } from './group-monitor.component'; + + +@NgModule({ + declarations: [GroupMonitorComponent], + imports: [ + CommonModule, + GroupMonitorRoutingModule + ] +}) +export class GroupMonitorModule { } diff --git a/src/app/maindata.service.spec.ts b/src/app/maindata.service.spec.ts index 06bf324c9e8388e1920fd756916fc47b0aba98d4..2a25eaee9691d49c16984a4fdafcfad059f3d36e 100644 --- a/src/app/maindata.service.spec.ts +++ b/src/app/maindata.service.spec.ts @@ -1,11 +1,13 @@ import { TestBed, inject } from '@angular/core/testing'; import { MainDataService } from './maindata.service'; +import {HttpClientModule} from "@angular/common/http"; describe('MainDataService', () => { beforeEach(() => { TestBed.configureTestingModule({ - providers: [MainDataService] + providers: [MainDataService], + imports: [HttpClientModule] }); }); diff --git a/src/app/maindata.service.ts b/src/app/maindata.service.ts index 186fdc8dfdfc15c3a2630ba606a83d7b9f5ea79a..4d6214bc5cab6006f30d78cf562dd0207f4ad05a 100644 --- a/src/app/maindata.service.ts +++ b/src/app/maindata.service.ts @@ -1,194 +1,104 @@ -import { BackendService } from './backend.service'; -import { BehaviorSubject, Subject, forkJoin } from 'rxjs'; -import { Injectable } from '@angular/core'; -import { LoginData } from './app.interfaces'; -import { CustomtextService, ServerError } from 'iqb-components'; -import { appconfig, customtextKeySeparator, CustomTextsDefList } from './app.config'; +import {BackendService} from './backend.service'; +import {BehaviorSubject, Subject} from 'rxjs'; +import {Injectable} from '@angular/core'; +import { + AppError, + AuthData, KeyValuePairs +} from './app.interfaces'; +import {CustomtextService} from 'iqb-components'; +import {AppConfig} from "./config/app.config"; + +const localStorageAuthDataKey = 'iqb-tc-a'; +const localStorageTestConfigKey = 'iqb-tc-c'; @Injectable({ providedIn: 'root' }) -export class MainDataService { - private static get defaultLoginData(): LoginData { - return { - loginToken: '', - personToken: '', - mode: '', - groupName: '', - name: '', - workspaceName: '', - booklets: null, - code: '', - testId: 0, - bookletLabel: '', - customTexts: {}, - adminToken: '', - workspaces: [], - isSuperadmin: false - }; - } - public loginData$ = new BehaviorSubject<LoginData>(MainDataService.defaultLoginData); - public globalErrorMsg$ = new BehaviorSubject<ServerError>(null); +export class MainDataService { + public appError$ = new Subject<AppError>(); + public errorReportingSilent = false; + public isSpinnerOn$ = new BehaviorSubject<boolean>(false); + public progressVisualEnabled = true; + public isApiValid = true; + public appConfig: AppConfig = null; + public sysCheckAvailable = false; // set by app.component.ts public postMessage$ = new Subject<MessageEvent>(); - public get adminToken(): string { - const myLoginData = this.loginData$.getValue(); - if (myLoginData) { - return myLoginData.adminToken; - } else { - return ''; + static getAuthData(): AuthData { + let myReturn: AuthData = null; + const storageEntry = localStorage.getItem(localStorageAuthDataKey); + if (storageEntry !== null) { + if (storageEntry.length > 0) { + try { + myReturn = JSON.parse(storageEntry as string); + } + catch (e) { + console.warn("corrupt localStorage authData entry"); + myReturn = null + } + } } + return myReturn; } - constructor( - private bs: BackendService, - private cts: CustomtextService - ) {} - - // ensures consistency - setNewLoginData(logindata?: LoginData) { - const myLoginData: LoginData = MainDataService.defaultLoginData; - if (!logindata) { - logindata = MainDataService.defaultLoginData; + static resetAuthData() { + const storageEntry = localStorage.getItem(localStorageAuthDataKey); + if (storageEntry) { + localStorage.removeItem(localStorageAuthDataKey); } + } - if ((logindata.adminToken)) { // .length > 0) && (logindata.name.length > 0)) { - myLoginData.adminToken = logindata.adminToken; - myLoginData.name = logindata.name; - myLoginData.workspaces = logindata.workspaces; - myLoginData.isSuperadmin = logindata.isSuperadmin; - } else if ( - (logindata.loginToken.length > 0) && - (logindata.name.length > 0) && - (logindata.mode.length > 0) && - (logindata.groupName.length > 0) && - (logindata.workspaceName.length > 0) && - (logindata.booklets)) { - - const validCodes = Object.keys(logindata.booklets); - if (validCodes.length > 0) { - myLoginData.loginToken = logindata.loginToken; - myLoginData.name = logindata.name; - myLoginData.mode = logindata.mode; - myLoginData.groupName = logindata.groupName; - myLoginData.workspaceName = logindata.workspaceName; - myLoginData.booklets = logindata.booklets; - if (logindata.code.length > 0) { - if (logindata.code in logindata.booklets) { - myLoginData.code = logindata.code; - } - } - if (logindata.personToken.length > 0) { - myLoginData.personToken = logindata.personToken; - myLoginData.testId = logindata.testId; - if (myLoginData.testId > 0) { - myLoginData.bookletLabel = logindata.bookletLabel; - } - } + static getTestConfig(): KeyValuePairs { + let myReturn: KeyValuePairs = null; + const storageEntry = localStorage.getItem(localStorageTestConfigKey); + if (storageEntry !== null) { + if (storageEntry.length > 0) { + try { + myReturn = JSON.parse(storageEntry as string); + } + catch (e) { + console.warn("corrupt localStorage testConfig entry"); + myReturn = null } + } } - - this.loginData$.next(myLoginData); - localStorage.setItem('lt', myLoginData.loginToken); - localStorage.setItem('at', myLoginData.adminToken); - localStorage.setItem('pt', myLoginData.personToken); - localStorage.setItem('bi', myLoginData.testId.toString()); + return myReturn; } - // +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - setCode ( newCode: string) { - const myLoginData = this.loginData$.getValue(); - myLoginData.code = newCode; - this.setNewLoginData(myLoginData); + constructor( + private bs: BackendService, + private cts: CustomtextService + ) { + this.appConfig = new AppConfig(cts); } - // +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - setBookletDbId ( personToken: string, bId: number, bLabel: string) { - const myLoginData = this.loginData$.getValue(); - myLoginData.personToken = personToken; - myLoginData.testId = bId; - myLoginData.bookletLabel = bLabel; - this.setNewLoginData(myLoginData); + setSpinnerOn() { + this.isSpinnerOn$.next(true) } - - getBookletDbId(): number { - - return this.loginData$.getValue().testId; + setSpinnerOff() { + this.isSpinnerOn$.next(false) } - // +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - endBooklet () { - const myLoginData = this.loginData$.getValue(); - if (myLoginData.testId > 0 && myLoginData.mode === 'hot') { - forkJoin( - this.bs.addBookletLogClose(myLoginData.testId), - this.bs.lockBooklet(myLoginData.testId) - ).subscribe(() => { - myLoginData.testId = 0; - myLoginData.bookletLabel = ''; - this.setNewLoginData(myLoginData); - }); + setAuthData(authData: AuthData = null) { + if (authData) { + if (authData.customTexts) { + this.cts.addCustomTexts(authData.customTexts); + } + localStorage.setItem(localStorageAuthDataKey, JSON.stringify(authData)); } else { - myLoginData.testId = 0; - myLoginData.bookletLabel = ''; - this.setNewLoginData(myLoginData); + localStorage.removeItem(localStorageAuthDataKey); } } - // +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - getCode(): string { - const myLoginData = this.loginData$.getValue(); - return myLoginData.code; - } - - // +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - getBookletLabel(): string { - const myLoginData = this.loginData$.getValue(); - return myLoginData.bookletLabel; - } - - // +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - getPersonToken(): string { - const myLoginData = this.loginData$.getValue(); - return myLoginData.personToken; - } - - public addCustomtextsFromDefList(customtextList: CustomTextsDefList) { - const myCustomTexts: {[key: string]: string} = {}; - for (const ct of Object.keys(customtextList.defList)) { - myCustomTexts[customtextList.keyPrefix + customtextKeySeparator + ct] = customtextList.defList[ct].defaultvalue; - } - this.cts.addCustomTexts(myCustomTexts); - } - - public setDefaultCustomtexts(newTexts: {[key: string]: string}) { - if (newTexts) { - for (const ctKey of Object.keys(newTexts)) { - const sepIndex = ctKey.indexOf(customtextKeySeparator); - if (sepIndex > 1) { - const keyPrefix = ctKey.slice(0 , sepIndex - 1); - const keyId = ctKey.slice(sepIndex + 1); - - switch (keyPrefix) { - case 'app': { - appconfig.customtextsApp.defList[keyId].defaultvalue = newTexts[ctKey]; - break; - } - case 'login': { - appconfig.customtextsLogin.defList[keyId].defaultvalue = newTexts[ctKey]; - break; - } - case 'booklet': { - appconfig.customtextsBooklet.defList[keyId].defaultvalue = newTexts[ctKey]; - break; - } - } - } - } + setTestConfig(testConfig: KeyValuePairs = null) { + if (testConfig) { + localStorage.setItem(localStorageTestConfigKey, JSON.stringify(testConfig)); + } else { + localStorage.removeItem(localStorageTestConfigKey); } } } diff --git a/src/app/start/start-button-data.class.ts b/src/app/start/start-button-data.class.ts deleted file mode 100644 index 67f92dabe32f01a92367280c6c33a83a55d6bad2..0000000000000000000000000000000000000000 --- a/src/app/start/start-button-data.class.ts +++ /dev/null @@ -1,46 +0,0 @@ -import { map } from 'rxjs/operators'; -import { BackendService } from '../backend.service'; -import { BookletStatus } from '../app.interfaces'; -import { ServerError } from 'iqb-components'; -// import { of } from 'rxjs'; -// import { pipe } from '@angular/core/src/render3'; - -export class StartButtonData { - id: string; - label: string; - filename: string; - isEnabled: boolean; - statustxt: string; - lastUnit: number; - - constructor( - id: string - ) { - this.id = id; - this.label = ''; - this.filename = ''; - this.isEnabled = false; - this.statustxt = 'Bitte warten'; - } - - public getBookletStatus(bs: BackendService, code = '') { - return bs.getBookletState(this.id, code) - .pipe( - map(respDataUntyped => { - let myreturn = false; - if (respDataUntyped instanceof ServerError) { - const e = respDataUntyped as ServerError; - this.statustxt = e.code.toString() + ': ' + e.labelNice; - } else { - const respData = respDataUntyped as BookletStatus; - this.statustxt = respData.statusLabel; - this.isEnabled = respData.canStart; - myreturn = respData.canStart; - this.lastUnit = respData.lastUnit; - this.label = respData.label; - } - return myreturn; - }) - ); - } - } diff --git a/src/app/start/start.component.html b/src/app/start/start.component.html deleted file mode 100644 index 1820bb590541ecd8c89b00091cce0312c4b97538..0000000000000000000000000000000000000000 --- a/src/app/start/start.component.html +++ /dev/null @@ -1,150 +0,0 @@ -<div class="logo"> - <a [routerLink]="['/']"> - <img src="assets/IQB-LogoA.png" matTooltip="Startseite" alt="IQB-Logo"/> - </a> -</div> -<div class="page-body"> - <div class="spinner-container" *ngIf="dataLoading"> - <mat-spinner></mat-spinner> - </div> - <div fxLayout="row wrap" fxLayoutAlign="center stretch" style="padding: 30px;"> - - - <!-- XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX --> - <mat-card fxFlex="0 0 400px" fxLayout="column" *ngIf="showLoginForm"> - <!-- - - - - - - - - - - - - - - - - --> - <form [formGroup]="testtakerloginform" (ngSubmit)="login()"> - <mat-card-title>Anmelden</mat-card-title> - <mat-card-content fxLayout="column"> - <mat-form-field> - <input matInput formControlName="testname" placeholder="Anmeldename" (keyup.enter)="pw.focus()"> - </mat-form-field> - <mat-form-field> - <input matInput #pw type="password" formControlName="testpw" placeholder="Kennwort" (keyup.enter)="login()"> - </mat-form-field> - </mat-card-content> - <mat-card-actions> - <button mat-raised-button type="submit" [disabled]="testtakerloginform.invalid" color="primary">Weiter</button> - </mat-card-actions> - </form> - <p class="error-msg">{{ (mds.globalErrorMsg$ | async)?.labelNice }}</p> - - </mat-card> - - <!-- - - - - - - - - - - - - - - - - --> - <mat-card fxFlex="0 0 400px" *ngIf="showCodeForm"> - <form [formGroup]="codeinputform" (ngSubmit)="codeinput()"> - <mat-card-title>{{ 'login_codeInputTitle' | customtext:'login_codeInputTitle':cts.updateCount }}</mat-card-title> - <mat-card-content> - <mat-form-field> - <input matInput formControlName="code" (keyup.enter)="codeinput()"> <!-- no placeholder! --> - </mat-form-field> - </mat-card-content> - <mat-card-actions> - <button mat-raised-button type="submit" [disabled]="codeinputform.invalid" color="primary">Weiter</button> - <button mat-raised-button color="foreground" (click)="resetLogin()">Neu anmelden</button> - </mat-card-actions> - </form> - </mat-card> - - <!-- - - - - - - - - - - - - - - - - --> - <mat-card fxFlex="0 0 400px" fxLayout="column" *ngIf="showBookletButtons"> - <mat-card-title>{{ bookletSelectTitle }}</mat-card-title> - <mat-card-content> - <div fxLayoutGap="10px" fxLayout="column"> - <p *ngIf="bookletlist.length === 0"> - Für diese Anmeldung wurde kein Test gefunden. - </p> - <button mat-raised-button color="primary" (click)="startBooklet(b)" - [disabled]="!b.isEnabled" *ngFor="let b of bookletlist"> - <div class="booklet_title">{{b.label}}</div> - <div class="booklet_status">{{b.statustxt}}</div> - </button> - </div> - </mat-card-content> - <mat-card-actions> - <button mat-raised-button color="foreground" (click)="resetLogin()">Neu anmelden</button> - </mat-card-actions> - </mat-card> - - <!-- - - - - - - - - - - - - - - - - --> - <mat-card fxFlex="0 0 400px" fxLayout="column" *ngIf="showTestRunningButtons && !dataLoading"> - <mat-card-title>{{ 'login_testRunningText' | customtext:'login_testRunningText':cts.updateCount }}</mat-card-title> - <mat-card-content> - <div fxLayout="column" fxLayoutGap="20px"> - <button mat-raised-button color="primary" [routerLink]="['/t']">{{ 'login_testReturnButtonText' | customtext:'login_testReturnButtonText':cts.updateCount }}</button> - <button mat-raised-button color="primary" (click)="stopBooklet()">{{ 'login_testEndButtonText' | customtext:'login_testEndButtonText':cts.updateCount }}</button> - <button mat-raised-button color="foreground" (click)="resetLogin()">Neu anmelden</button> - </div> - </mat-card-content> - </mat-card> - - <mat-card fxFlex="0 0 400px" fxLayout="column" *ngIf="showAdminSelection"> - <mat-card-title>Studie wählen</mat-card-title> - <mat-card-content> - <div fxLayoutGap="10px" fxLayout="column"> - <p *ngIf="(mds.loginData$ | async)?.workspaces.length === 0"> - Sie sind mit Administrator-Funktionen angemeldet. Aktuell sind keine Studien für Sie freigegeben. - </p> - <button mat-raised-button color="primary" (click)="buttonGotoWorkspaceAdmin(ws)" - *ngFor="let ws of (mds.loginData$ | async)?.workspaces"> - {{ws.name}} - </button> - </div> - </mat-card-content> - <mat-card-actions> - <button mat-raised-button color="foreground" *ngIf="(mds.loginData$ | async)?.isSuperadmin" [routerLink]="['/superadmin']">Nutzer/Arbeitsbereiche</button> - <button mat-raised-button color="foreground" (click)="resetLogin()">Neu anmelden</button> - </mat-card-actions> - </mat-card> - - <!-- XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX --> - <!-- XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX --> - <mat-card fxFlex="0 2 400px" fxLayout="column" class="status"> - <mat-card-title>{{ 'app_title' | customtext:'app_title':cts.updateCount }}</mat-card-title> - - <!-- - - - - - - - - - - - - - - - - --> - <mat-card-content> - <div *ngIf="showLoginForm"> - <p>Das <a href="http://www.iqb.hu-berlin.de" target="_blank">Institut zur Qualitätsentwicklung im Bildungswesen</a> - {{ 'app_intro1' | customtext:'app_intro1':cts.updateCount }}</p> - - <p>Die mit diesem System erhobenen Daten enthalten grundsätzlich keinen direkten - Personenbezug. Es werden z. B. nie Namen gespeichert. Um Auskünfte zu einer bestimmten Befragung bzw. Studie - zu erhalten, wenden Sie sich bitte an das <a href="mailto:mechtel@iqb.hu-berlin.de"> - IQB</a>. Wir benötigen dazu den ungefähren Zeitraum und das Bundesland, in dem die Befragung bzw. Studie - durchgeführt wurde.</p> - </div> - - <!-- - - - - - - - - - - - - - - - - --> - <div *ngIf="!showLoginForm"> - <p>Anmeldestatus:</p> - <ul> - <li *ngFor="let line of loginStatusText">{{ line }}</li> - </ul> - </div> - - <!-- - - - - - - - - - - - - - - - - --> - <div *ngIf="showCodeForm"> - <p>{{ 'login_codeInputPrompt' | customtext:'login_codeInputPrompt':cts.updateCount }}</p> - </div> - - <!-- - - - - - - - - - - - - - - - - --> - <div *ngIf="showBookletButtons"> - <p>{{ bookletSelectPrompt }}</p> - </div> - - <!-- - - - - - - - - - - - - - - - - --> - <div *ngIf="showTestRunningButtons"> - <p>{{ 'login_testRunningLongText' | customtext:'login_testRunningLongText':cts.updateCount }}</p> - </div> - <div class="error-msg">{{ (mds.globalErrorMsg$ | async)?.labelNice }}</div> - - </mat-card-content> - <mat-card-actions> - <button mat-raised-button color="foreground" [routerLink]="['/about']">Impressum/Datenschutz</button> - <button mat-raised-button color="foreground" [routerLink]="['/check']">System-Check</button> - </mat-card-actions> - </mat-card> - </div> -</div> diff --git a/src/app/start/start.component.spec.ts b/src/app/start/start.component.spec.ts deleted file mode 100644 index 01270a2d580aa35fc43d8414799fa61e7e02e140..0000000000000000000000000000000000000000 --- a/src/app/start/start.component.spec.ts +++ /dev/null @@ -1,25 +0,0 @@ -import { async, ComponentFixture, TestBed } from '@angular/core/testing'; - -import { StartComponent } from './start.component'; - -describe('StartComponent', () => { - let component: StartComponent; - let fixture: ComponentFixture<StartComponent>; - - beforeEach(async(() => { - TestBed.configureTestingModule({ - declarations: [ StartComponent ] - }) - .compileComponents(); - })); - - beforeEach(() => { - fixture = TestBed.createComponent(StartComponent); - component = fixture.componentInstance; - fixture.detectChanges(); - }); - - it('should create', () => { - expect(component).toBeTruthy(); - }); -}); diff --git a/src/app/start/start.component.ts b/src/app/start/start.component.ts deleted file mode 100644 index 89b83b1a87fa1e3722a143020c426f97a414dfe8..0000000000000000000000000000000000000000 --- a/src/app/start/start.component.ts +++ /dev/null @@ -1,305 +0,0 @@ -import { MainDataService } from '../maindata.service'; -import { Subscription, forkJoin } from 'rxjs'; -import {CustomtextService, MessageDialogComponent, MessageDialogData, MessageType, ServerError} from 'iqb-components'; -import { MatDialog } from '@angular/material'; -import { BackendService } from '../backend.service'; -import {PersonTokenAndTestId, LoginData, WorkspaceData} from '../app.interfaces'; -import { Router } from '@angular/router'; -import { Component, OnInit, OnDestroy } from '@angular/core'; -import { FormGroup, FormBuilder, Validators } from '@angular/forms'; -import { StartButtonData } from './start-button-data.class'; -import { appconfig } from '../app.config'; - -@Component({ - templateUrl: './start.component.html', - styleUrls: ['./start.component.css'] -}) -export class StartComponent implements OnInit, OnDestroy { - public dataLoading = false; - public showLoginForm = true; - public showCodeForm = false; - public showBookletButtons = false; - public bookletlist: StartButtonData[] = []; - public showTestRunningButtons = false; - public showAdminSelection = false; - - private loginDataSubscription: Subscription = null; - - // for template - private validCodes = []; - private loginStatusText = ['nicht angemeldet']; - public bookletSelectTitle = 'Bitte wählen'; - - private testtakerloginform: FormGroup; - private codeinputform: FormGroup; - private lastloginname = ''; - public bookletSelectPrompt = 'Bitte wählen'; - - // ?? - // private sessiondata: PersonBooklets; - // private code = ''; - // private isError = false; - // private errorMessage = ''; - - - constructor(private fb: FormBuilder, - public mds: MainDataService, - public messsageDialog: MatDialog, - private router: Router, - private bs: BackendService, - public cts: CustomtextService) { - } - - ngOnInit() { - this.loginDataSubscription = this.mds.loginData$.subscribe(logindata => { - this.bookletlist = []; - if (logindata.adminToken.length > 0) { - this.showLoginForm = false; - this.showAdminSelection = true; - this.showCodeForm = false; - this.showBookletButtons = false; - this.showTestRunningButtons = false; - this.loginStatusText = []; - this.loginStatusText.push('Admin-Bereich '); - console.log(logindata); - this.loginStatusText.push('angemeldet als ' + logindata.name); - if (logindata.isSuperadmin) { - this.loginStatusText.push('Rechte auch für Anlegen/Löschen von Nutzern und Workspaces'); - } - } else if (logindata.loginToken.length > 0) { - // Statustext box - this.showAdminSelection = false; - this.loginStatusText = []; - this.loginStatusText.push('Studie: ' + logindata.workspaceName); - this.loginStatusText.push('angemeldet als "' + - logindata.name + (logindata.code.length > 0 ? ('/' + logindata.code + '"') : '"')); - this.loginStatusText.push('Gruppe: ' + logindata.groupName); - - if (logindata.mode === 'run-trial') { - // @ts-ignore - const tmt = this.cts.getCustomText('login_trialmodeText'); - if (tmt.length > 0) { - this.loginStatusText.push(tmt); - } - } else if (logindata.mode === 'run-review') { - // @ts-ignore - const tmt = this.cts.getCustomText('login_reviewmodeText'); - if (tmt.length > 0) { - this.loginStatusText.push(tmt); - } - } - - this.showLoginForm = false; - let createBookletSelectButtons = false; - if (logindata.personToken.length > 0) { - // test started or just finished - this.showBookletButtons = false; - this.showCodeForm = false; - this.showLoginForm = false; - if (logindata.testId === 0) { - this.showBookletButtons = true; - this.showTestRunningButtons = false; - // booklet finished - // buttons to select booklet - - createBookletSelectButtons = true; - this.loginStatusText.push('Nicht gestartet.'); - } else { - // booklet started - this.showBookletButtons = false; - this.showTestRunningButtons = true; - - this.loginStatusText.push('Gestartet: "' + logindata.bookletLabel + '"'); - } - - } else { - this.showTestRunningButtons = false; - - this.validCodes = Object.keys(logindata.booklets); - if (this.validCodes.length > 1) { - if (logindata.code.length > 0) { - this.showCodeForm = false; - this.showBookletButtons = true; - // code given - // buttons to select booklet - - createBookletSelectButtons = true; - } else { - // code not yet given - // code prompt - this.showCodeForm = true; - this.showBookletButtons = false; - } - } else { - // no code but there is only one code - // buttons to select booklet - - this.showCodeForm = false; - this.showBookletButtons = true; - createBookletSelectButtons = true; - } - } - - if (createBookletSelectButtons) { - if (logindata.booklets[logindata.code].length > 0) { - const myBookletStatusLoadings = []; - for (const booklet of logindata.booklets[logindata.code]) { - const myTest = new StartButtonData(booklet); - myBookletStatusLoadings.push(myTest.getBookletStatus(this.bs, logindata.code)); - this.bookletlist.push(myTest); - } - this.dataLoading = true; - forkJoin(myBookletStatusLoadings).subscribe(allOk => { - this.dataLoading = false; - - let numberOfOpenBooklets = 0; - for (const ok of allOk) { - if (ok) { - numberOfOpenBooklets += 1; - } - } - - if (numberOfOpenBooklets === 0) { - this.bookletSelectTitle = 'Beendet'; - // @ts-ignore - this.bookletSelectPrompt = this.cts.getCustomText('login_bookletSelectPromptNull'); - } else if (numberOfOpenBooklets === 1) { - this.bookletSelectPrompt = 'Bitte links auf den Testheft-Schalter klicken!'; - this.bookletSelectTitle = 'Bitte starten'; - // @ts-ignore - this.bookletSelectPrompt = this.cts.getCustomText('login_bookletSelectPromptOne'); - } else { - this.bookletSelectPrompt = 'Bitte links ein Testheft wählen und klicken!'; - this.bookletSelectTitle = 'Bitte wählen'; - // @ts-ignore - this.bookletSelectPrompt = this.cts.getCustomText('login_bookletSelectPromptMany'); - } - }); - } else { - this.bookletSelectTitle = 'Kein Zugriff'; - this.bookletSelectPrompt = 'Keine Informationen zu dieser Anmeldung verfügbar'; - } - } - } else { - // blank start, only login form - this.validCodes = []; - this.loginStatusText = ['nicht angemeldet']; - this.showBookletButtons = false; - this.showCodeForm = false; - this.showAdminSelection = false; - this.showLoginForm = true; - this.showTestRunningButtons = false; - } - }); // loginDataSubscription - - - this.testtakerloginform = this.fb.group({ - testname: this.fb.control(this.lastloginname, [Validators.required, Validators.minLength(3)]), - testpw: this.fb.control('', []) - }); - - this.codeinputform = this.fb.group({ - code: this.fb.control('', [Validators.required, Validators.minLength(1)]) - }); - } - - // # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # - login() { - this.dataLoading = true; - this.bs.login(this.testtakerloginform.get('testname').value, this.testtakerloginform.get('testpw').value).subscribe( - loginData => { - if (loginData instanceof ServerError) { - const e = loginData as ServerError; - this.mds.globalErrorMsg$.next(e); - this.mds.addCustomtextsFromDefList(appconfig.customtextsLogin); - // no change in other data - } else { - this.mds.globalErrorMsg$.next(null); - if ((loginData as LoginData).customTexts) { - this.cts.addCustomTexts((loginData as LoginData).customTexts); - } - this.mds.setNewLoginData(loginData as LoginData); - } - this.dataLoading = false; - } - ); - } - - // # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # - codeinput() { - const myCode = this.codeinputform.get('code').value as string; - if (myCode.length === 0) { - this.messsageDialog.open(MessageDialogComponent, { - width: '400px', - data: <MessageDialogData>{ - // @ts-ignore - title: this.cts.getCustomText('login_codeInputTitle') + ': Leer', - // @ts-ignore - content: this.cts.getCustomText('login_codeInputPrompt'), - type: MessageType.error - } - }); - } else if (this.validCodes.indexOf(myCode) < 0) { - this.messsageDialog.open(MessageDialogComponent, { - width: '400px', - data: <MessageDialogData>{ - // @ts-ignore - title: this.cts.getCustomText('login_codeInputTitle') + ': Ungültig', - // @ts-ignore - content: this.cts.getCustomText('login_codeInputPrompt'), - type: MessageType.error - } - }); - } else { - this.mds.setCode(myCode); - } - } - - // # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # - startBooklet(b: StartButtonData) { - this.bs.startBooklet(this.mds.getCode(), b.id, b.label).subscribe( - startReturnUntyped => { - if (startReturnUntyped instanceof ServerError) { - const e = startReturnUntyped as ServerError; - this.mds.globalErrorMsg$.next(e); - } else { - const startReturn = startReturnUntyped as PersonTokenAndTestId; - this.mds.globalErrorMsg$.next(null); - // ************************************************ - - // by setting bookletDbId$ the test-controller will load the booklet - this.dataLoading = true; - this.mds.setBookletDbId(startReturn.personToken, startReturn.testId, b.label); - this.router.navigateByUrl('/t'); - - // ************************************************ - } - } - ); - } - - // # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # - resetLogin() { - this.mds.setNewLoginData(); - } - - // # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # - stopBooklet() { - this.mds.endBooklet(); - } - - buttonGotoWorkspaceAdmin(ws: WorkspaceData) { - this.router.navigateByUrl('/admin/' + ws.id.toString() + '/files'); - } - - buttonGotoWorkspaceMonitor(ws: WorkspaceData) { - this.router.navigateByUrl('/wsmonitor/' + ws.id.toString()); - } - - // % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % - ngOnDestroy() { - if (this.loginDataSubscription !== null) { - this.loginDataSubscription.unsubscribe(); - } - } -} diff --git a/src/app/superadmin/backend.service.spec.ts b/src/app/superadmin/backend.service.spec.ts index c31039d7e5bcc7bc70e7213ce06744a0dc6ed009..ffdc1397ca5ced3a08516d7183bbc820c1001627 100644 --- a/src/app/superadmin/backend.service.spec.ts +++ b/src/app/superadmin/backend.service.spec.ts @@ -1,14 +1,16 @@ import { TestBed, inject } from '@angular/core/testing'; import { BackendService } from './backend.service'; +import {HttpClientModule} from "@angular/common/http"; -describe('BackendService', () => { + +describe('HttpClient testing', () => { beforeEach(() => { TestBed.configureTestingModule({ + imports: [HttpClientModule], providers: [BackendService] }); }); - it('should be created', inject([BackendService], (service: BackendService) => { expect(service).toBeTruthy(); })); diff --git a/src/app/superadmin/backend.service.ts b/src/app/superadmin/backend.service.ts index 00da11b36d391cfa6f1b85f92bf27cdc16414e85..f00f7768a9e27f919754356c499eb21e926488a1 100644 --- a/src/app/superadmin/backend.service.ts +++ b/src/app/superadmin/backend.service.ts @@ -1,10 +1,14 @@ import { Injectable, Inject } from '@angular/core'; import { HttpClient } from '@angular/common/http'; import { Observable, of } from 'rxjs'; -import { catchError } from 'rxjs/operators'; +import {catchError, map} from 'rxjs/operators'; +import {IdAndName, IdLabelSelectedData, IdRoleData, UserData} from "./superadmin.interfaces"; +import {ApiError} from "../app.interfaces"; -@Injectable() +@Injectable({ + providedIn: 'root' +}) export class BackendService { @@ -13,109 +17,123 @@ export class BackendService { private http: HttpClient) { } - getUsers(): Observable<IdAndName[]> { - + getUsers(): Observable<UserData[]> { return this.http - .get<NameOnly[]>(this.serverUrl + 'users') - .pipe(catchError(() => [])); + .get<UserData[]>(this.serverUrl + 'users') + .pipe(catchError((err: ApiError) => { + console.warn(`getUsers Api-Error: ${err.code} ${err.info} `); + return [] + })); } addUser(name: string, password: string): Observable<Boolean> { - return this.http .put<Boolean>(this.serverUrl + 'user', {n: name, p: password}) - .pipe(catchError(() => of(false))); + .pipe(catchError((err: ApiError) => { + console.warn(`addUser Api-Error: ${err.code} ${err.info} `); + return of(false) + })); } changePassword(userId: number, password: string): Observable<Boolean> { - return this.http .patch<Boolean>(this.serverUrl + `user/${userId}/password`, {p: password}) - .pipe(catchError(() => of(false))); + .pipe(catchError((err: ApiError) => { + console.warn(`changePassword Api-Error: ${err.code} ${err.info} `); + return of(false) + })); + } + + setSuperUserStatus(userId: number, changeToSuperUser: boolean, password: string): Observable<number> { + return this.http + .patch(this.serverUrl + `user/${userId}/super-admin/` + (changeToSuperUser ? 'on' : 'off'), {p: password}) + .pipe( + map(() => 0), + catchError((err: ApiError) => { + console.warn(`setSuperUserStatus Api-Error: ${err.code} ${err.info} `); + return of(err.code) + })); } deleteUsers(users: string[]): Observable<Boolean> { return this.http .request<boolean>('delete', this.serverUrl + 'users', {body: {u: users}}) - .pipe(catchError(() => of(false))); + .pipe(catchError((err: ApiError) => { + console.warn(`deleteUsers Api-Error: ${err.code} ${err.info} `); + return of(false) + })); } getWorkspacesByUser(userId: number): Observable<IdRoleData[]> { - return this.http .get<IdLabelSelectedData[]>(this.serverUrl + `user/${userId}/workspaces`) - .pipe(catchError(() => [])); + .pipe(catchError((err: ApiError) => { + console.warn(`getWorkspacesByUser Api-Error: ${err.code} ${err.info} `); + return [] + })); } setWorkspacesByUser(userId: number, accessTo: IdRoleData[]): Observable<Boolean> { - return this.http .patch<Boolean>(this.serverUrl + `user/${userId}/workspaces`, {ws: accessTo}) - .pipe(catchError(() => of(false))); + .pipe(catchError((err: ApiError) => { + console.warn(`setWorkspacesByUser Api-Error: ${err.code} ${err.info} `); + return of(false) + })); } addWorkspace(name: string): Observable<Boolean> { - return this.http .put<Boolean>(this.serverUrl + 'workspace', {name: name}) - .pipe(catchError(() => of(false))); + .pipe(catchError((err: ApiError) => { + console.warn(`addWorkspace Api-Error: ${err.code} ${err.info} `); + return of(false) + })); } renameWorkspace(workspaceId: number, wsName: string): Observable<Boolean> { - return this.http .patch<Boolean>(this.serverUrl + `workspace/${workspaceId}`, {name: wsName}) - .pipe(catchError(() => of(false))); + .pipe(catchError((err: ApiError) => { + console.warn(`renameWorkspace Api-Error: ${err.code} ${err.info} `); + return of(false) + })); } deleteWorkspaces(workspaces: number[]): Observable<Boolean> { - return this.http .request<Boolean>('delete', this.serverUrl + 'workspaces', {body: {ws: workspaces}}) - .pipe(catchError(() => of(false))); + .pipe(catchError((err: ApiError) => { + console.warn(`deleteWorkspaces Api-Error: ${err.code} ${err.info} `); + return of(false) + })); } getUsersByWorkspace(workspaceId: number): Observable<IdRoleData[]> { - return this.http .get<IdRoleData[]>(this.serverUrl + `workspace/${workspaceId}/users`) - .pipe(catchError(() => [])); + .pipe(catchError((err: ApiError) => { + console.warn(`getUsersByWorkspace Api-Error: ${err.code} ${err.info} `); + return [] + })); } setUsersByWorkspace(workspaceId: number, accessing: IdRoleData[]): Observable<Boolean> { - return this.http .patch<Boolean>(this.serverUrl + `workspace/${workspaceId}/users`, {u: accessing}) - .pipe(catchError(() => of(false))); + .pipe(catchError((err: ApiError) => { + console.warn(`setUsersByWorkspace Api-Error: ${err.code} ${err.info} `); + return of(false) + })); } getWorkspaces(): Observable<IdAndName[]> { - return this.http .get<IdAndName[]>(this.serverUrl + 'workspaces') - .pipe(catchError(() => [])); + .pipe(catchError((err: ApiError) => { + console.warn(`getWorkspaces Api-Error: ${err.code} ${err.info} `); + return [] + })); } } - - -export interface NameOnly { - name: string; -} - -export interface IdAndName { - id: number; - name: string; -} - -export interface IdLabelSelectedData { - id: number; - label: string; - selected: boolean; -} - -export interface IdRoleData { - id: number; - label: string; - role: string; -} diff --git a/src/app/superadmin/superadmin-password-request/superadmin-password-request.component.css b/src/app/superadmin/superadmin-password-request/superadmin-password-request.component.css new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/src/app/superadmin/superadmin-password-request/superadmin-password-request.component.html b/src/app/superadmin/superadmin-password-request/superadmin-password-request.component.html new file mode 100644 index 0000000000000000000000000000000000000000..d461c4face79b70857aab085ffdc3327eda83598 --- /dev/null +++ b/src/app/superadmin/superadmin-password-request/superadmin-password-request.component.html @@ -0,0 +1,20 @@ +<form [formGroup]="passwordform"> + <h1 mat-dialog-title>Sicherheitsabfrage Kennwort</h1> + + <mat-dialog-content> + <div class="infobox"> + <p>Für die Funktion "{{data}}" ist es zur Sicherheit notwendig, dass Sie Ihr Kennwort nocheinmal eingeben.</p> + </div> + <p> + <mat-form-field class="full-width"> + <input matInput type="password" formControlName="pw" placeholder="Kennwort"> + </mat-form-field> + </p> + </mat-dialog-content> + + <mat-dialog-actions> + <button mat-raised-button color="primary" type="submit" [mat-dialog-close]="passwordform" [disabled]="passwordform.invalid">Bestätigen</button> + <button mat-raised-button [mat-dialog-close]="false">Abbrechen</button> + </mat-dialog-actions> + +</form> diff --git a/src/app/superadmin/superadmin-password-request/superadmin-password-request.component.spec.ts b/src/app/superadmin/superadmin-password-request/superadmin-password-request.component.spec.ts new file mode 100644 index 0000000000000000000000000000000000000000..adb6f10e0aa2e2c661a37636415f556141f5bd65 --- /dev/null +++ b/src/app/superadmin/superadmin-password-request/superadmin-password-request.component.spec.ts @@ -0,0 +1,41 @@ +import { async, ComponentFixture, TestBed } from '@angular/core/testing'; + +import { SuperadminPasswordRequestComponent } from './superadmin-password-request.component'; +import {MAT_DIALOG_DATA, MatDialog, MatDialogModule} from "@angular/material/dialog"; +import {ReactiveFormsModule} from "@angular/forms"; +import {MatInputModule} from "@angular/material/input"; +import {MatFormFieldModule} from "@angular/material/form-field"; +import {NoopAnimationsModule} from "@angular/platform-browser/animations"; + +describe('SuperadminPasswordRequestComponent', () => { + let component: SuperadminPasswordRequestComponent; + let fixture: ComponentFixture<SuperadminPasswordRequestComponent>; + + beforeEach(async(() => { + TestBed.configureTestingModule({ + declarations: [ SuperadminPasswordRequestComponent ], + imports: [ + MatDialogModule, + ReactiveFormsModule, + MatInputModule, + MatFormFieldModule, + NoopAnimationsModule + ], + providers: [ + MatDialog, + { provide: MAT_DIALOG_DATA, useValue: 'fonk' } + ] + }) + .compileComponents(); + })); + + beforeEach(() => { + fixture = TestBed.createComponent(SuperadminPasswordRequestComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/src/app/superadmin/superadmin-password-request/superadmin-password-request.component.ts b/src/app/superadmin/superadmin-password-request/superadmin-password-request.component.ts new file mode 100644 index 0000000000000000000000000000000000000000..f7bcfb33d132519b7102ab82fa333c2a4290b8ea --- /dev/null +++ b/src/app/superadmin/superadmin-password-request/superadmin-password-request.component.ts @@ -0,0 +1,17 @@ +import { MAT_DIALOG_DATA } from '@angular/material/dialog'; +import { Component, Inject } from '@angular/core'; +import {FormGroup, Validators, FormControl} from '@angular/forms'; + +@Component({ + templateUrl: './superadmin-password-request.component.html', + styleUrls: ['./superadmin-password-request.component.css'] +}) + +export class SuperadminPasswordRequestComponent { + passwordform = new FormGroup({ + pw: new FormControl('', [Validators.required, Validators.minLength(3)]) + }); + + constructor( + @Inject(MAT_DIALOG_DATA) public data: string) { } +} diff --git a/src/app/superadmin/superadmin.component.html b/src/app/superadmin/superadmin.component.html index d1a5470ae8803453ab9ecf31da9a1067ec3d0a75..81c55274caa62899ba46b52a2d321ef6eb894223 100644 --- a/src/app/superadmin/superadmin.component.html +++ b/src/app/superadmin/superadmin.component.html @@ -1,12 +1,7 @@ -<div id="buttonsContainer" fxLayout="row" fxLayoutAlign="start center"> - <a [routerLink]="['/']"> - <img src="assets/IQB-LogoA.png" matTooltip="Startseite"/> - </a> - <div fxLayout="row wrap" fxLayoutAlign="space-around center" fxFlex> - <div class="error-msg">{{ (mds.globalErrorMsg$ | async)?.labelNice }}</div> - <div>IQB-Testcenter Systemverwaltung</div> - </div> +<div class="page-header"> + <p>IQB-Testcenter Systemverwaltung</p> </div> + <div class="page-body"> <div class="adminbackground"> diff --git a/src/app/superadmin/superadmin.component.spec.ts b/src/app/superadmin/superadmin.component.spec.ts index f81c64d011ad02b5c14497860bef5b5455066eea..7cc5cb65e10575dcc6d7f00b4eee6b8c43aeed62 100644 --- a/src/app/superadmin/superadmin.component.spec.ts +++ b/src/app/superadmin/superadmin.component.spec.ts @@ -1,6 +1,9 @@ import { async, ComponentFixture, TestBed } from '@angular/core/testing'; import { SuperadminComponent } from './superadmin.component'; +import {HttpClientModule} from "@angular/common/http"; +import {AppRoutingModule} from "../app-routing.module"; +import {MainDataService} from "../maindata.service"; describe('SuperadminComponent', () => { let component: SuperadminComponent; @@ -8,7 +11,9 @@ describe('SuperadminComponent', () => { beforeEach(async(() => { TestBed.configureTestingModule({ - declarations: [ SuperadminComponent ] + declarations: [ SuperadminComponent ], + imports: [HttpClientModule, AppRoutingModule], + providers: [MainDataService] }) .compileComponents(); })); diff --git a/src/app/superadmin/superadmin.interfaces.ts b/src/app/superadmin/superadmin.interfaces.ts new file mode 100644 index 0000000000000000000000000000000000000000..2c4d2633af4e433486f793df3421e3e289594a4b --- /dev/null +++ b/src/app/superadmin/superadmin.interfaces.ts @@ -0,0 +1,28 @@ +export interface NameOnly { + name: string; +} + +export interface IdAndName { + id: number; + name: string; +} + +export interface IdLabelSelectedData { + id: number; + label: string; + selected: boolean; +} + +export interface IdRoleData { + id: number; + label: string; + role: string; +} + +export interface UserData { + id: number; + name: string; + email: string; + isSuperadmin: boolean; + selected: boolean; +} diff --git a/src/app/superadmin/superadmin.module.ts b/src/app/superadmin/superadmin.module.ts index e53178adda953f574a53222685b07166e8c2763c..20807dca732e1e44f60196ac4c475d7fd985b368 100644 --- a/src/app/superadmin/superadmin.module.ts +++ b/src/app/superadmin/superadmin.module.ts @@ -29,6 +29,7 @@ import {NewpasswordComponent} from "./users/newpassword/newpassword.component"; import {NewuserComponent} from "./users/newuser/newuser.component"; import {NewworkspaceComponent} from "./workspaces/newworkspace/newworkspace.component"; import {EditworkspaceComponent} from "./workspaces/editworkspace/editworkspace.component"; +import { SuperadminPasswordRequestComponent } from './superadmin-password-request/superadmin-password-request.component'; @NgModule({ @@ -39,7 +40,8 @@ import {EditworkspaceComponent} from "./workspaces/editworkspace/editworkspace.c NewuserComponent, NewworkspaceComponent, EditworkspaceComponent, - WorkspacesComponent + WorkspacesComponent, + SuperadminPasswordRequestComponent ], imports: [ CommonModule, @@ -64,7 +66,7 @@ import {EditworkspaceComponent} from "./workspaces/editworkspace/editworkspace.c MatSnackBarModule, MatGridListModule, MatCardModule, - FlexLayoutModule, + FlexLayoutModule ], exports: [ SuperadminComponent @@ -76,7 +78,7 @@ import {EditworkspaceComponent} from "./workspaces/editworkspace/editworkspace.c EditworkspaceComponent ], providers: [ - BackendService, + BackendService ] }) export class SuperadminModule { } diff --git a/src/app/superadmin/users/newpassword/newpassword.component.html b/src/app/superadmin/users/newpassword/newpassword.component.html index 8685c172a39662b40f6a6734944552a13b17d09f..49bc44b867202f95f12e7f250e548ca7b1882548 100644 --- a/src/app/superadmin/users/newpassword/newpassword.component.html +++ b/src/app/superadmin/users/newpassword/newpassword.component.html @@ -3,7 +3,7 @@ <mat-dialog-content> <div class="infobox"> - <p>Ändern des Kennwortes für Nutzer/in "{{ data.name }}".</p> + <p>Ändern des Kennwortes für Nutzer/in "{{ data }}".</p> </div> <p> <mat-form-field class="full-width"> diff --git a/src/app/superadmin/users/newpassword/newpassword.component.spec.ts b/src/app/superadmin/users/newpassword/newpassword.component.spec.ts index 8e945c2cdf5d97e56a0ba76bf977b2020c428596..9e7ddf443e512b929c57abfce9e45b156147bef6 100644 --- a/src/app/superadmin/users/newpassword/newpassword.component.spec.ts +++ b/src/app/superadmin/users/newpassword/newpassword.component.spec.ts @@ -1,6 +1,11 @@ import { async, ComponentFixture, TestBed } from '@angular/core/testing'; import { NewpasswordComponent } from './newpassword.component'; +import {ReactiveFormsModule} from "@angular/forms"; +import {MAT_DIALOG_DATA, MatDialog, MatDialogModule} from "@angular/material/dialog"; +import {MatInputModule} from "@angular/material/input"; +import {MatFormFieldModule} from "@angular/material/form-field"; +import {NoopAnimationsModule} from "@angular/platform-browser/animations"; describe('NewpasswordComponent', () => { let component: NewpasswordComponent; @@ -8,7 +13,18 @@ describe('NewpasswordComponent', () => { beforeEach(async(() => { TestBed.configureTestingModule({ - declarations: [ NewpasswordComponent ] + declarations: [ NewpasswordComponent ], + imports: [ + MatDialogModule, + ReactiveFormsModule, + MatInputModule, + MatFormFieldModule, + NoopAnimationsModule + ], + providers: [ + MatDialog, + { provide: MAT_DIALOG_DATA, useValue: 'Harry Sack' } + ] }) .compileComponents(); })); diff --git a/src/app/superadmin/users/newpassword/newpassword.component.ts b/src/app/superadmin/users/newpassword/newpassword.component.ts index 3a001265d18cae4a65cf5de623c1ebfddff7f91d..c4b785f42eee61923e6308f50668d567495dfbc9 100644 --- a/src/app/superadmin/users/newpassword/newpassword.component.ts +++ b/src/app/superadmin/users/newpassword/newpassword.component.ts @@ -1,21 +1,17 @@ import { MAT_DIALOG_DATA } from '@angular/material/dialog'; -import { Component, OnInit, Inject } from '@angular/core'; -import { FormGroup, FormBuilder, Validators } from '@angular/forms'; +import { Component, Inject } from '@angular/core'; +import {FormGroup, Validators, FormControl} from '@angular/forms'; @Component({ templateUrl: './newpassword.component.html', styleUrls: ['./newpassword.component.css'] }) -export class NewpasswordComponent implements OnInit { - newpasswordform: FormGroup; +export class NewpasswordComponent { + newpasswordform = new FormGroup({ + pw: new FormControl('', [Validators.required, Validators.minLength(3)]) + }); - constructor(private fb: FormBuilder, - @Inject(MAT_DIALOG_DATA) public data: any) { } - - ngOnInit() { - this.newpasswordform = this.fb.group({ - pw: this.fb.control('', [Validators.required, Validators.minLength(3)]) - }); - } + constructor( + @Inject(MAT_DIALOG_DATA) public data: string) { } } diff --git a/src/app/superadmin/users/newuser/newuser.component.html b/src/app/superadmin/users/newuser/newuser.component.html index 4a4d5c11f20c5873192f60bf454c5193b1785ece..8ac041c21bb29f7f51dc1f432e2d110763adf6c5 100644 --- a/src/app/superadmin/users/newuser/newuser.component.html +++ b/src/app/superadmin/users/newuser/newuser.component.html @@ -4,12 +4,12 @@ <mat-dialog-content> <p> <mat-form-field class="full-width"> - <input matInput formControlName="name" placeholder="Name" [value]="data.name"> + <input matInput formControlName="name" placeholder="Name" autocomplete="off"> </mat-form-field> </p> <p> <mat-form-field class="full-width"> - <input matInput type="password" formControlName="pw" placeholder="Kennwort"> + <input matInput type="password" formControlName="pw" placeholder="Kennwort" autocomplete="off"> </mat-form-field> </p> <div class="infobox"> diff --git a/src/app/superadmin/users/newuser/newuser.component.spec.ts b/src/app/superadmin/users/newuser/newuser.component.spec.ts index fd37aa1b5db9f9dfc0a22a681ecb46ab7490302a..75c49da6a6323a759819d5bf932c793c5ebe8e9a 100644 --- a/src/app/superadmin/users/newuser/newuser.component.spec.ts +++ b/src/app/superadmin/users/newuser/newuser.component.spec.ts @@ -1,6 +1,12 @@ import { async, ComponentFixture, TestBed } from '@angular/core/testing'; import { NewuserComponent } from './newuser.component'; +import {ReactiveFormsModule} from "@angular/forms"; +import {MatDialog, MatDialogModule} from "@angular/material/dialog"; +import {MatInputModule} from "@angular/material/input"; +import {MatFormFieldModule} from "@angular/material/form-field"; +import {MatIconModule} from "@angular/material/icon"; +import {NoopAnimationsModule} from "@angular/platform-browser/animations"; describe('NewuserComponent', () => { let component: NewuserComponent; @@ -8,7 +14,18 @@ describe('NewuserComponent', () => { beforeEach(async(() => { TestBed.configureTestingModule({ - declarations: [ NewuserComponent ] + declarations: [ NewuserComponent ], + imports: [ + MatDialogModule, + ReactiveFormsModule, + MatInputModule, + MatFormFieldModule, + MatIconModule, + NoopAnimationsModule + ], + providers: [ + MatDialog + ] }) .compileComponents(); })); diff --git a/src/app/superadmin/users/newuser/newuser.component.ts b/src/app/superadmin/users/newuser/newuser.component.ts index 75ea8e3bfb23faf5dd77b480a98af7dde78c8b7a..615a84f02f6078d92c9de1783d02cc77d9b2cefe 100644 --- a/src/app/superadmin/users/newuser/newuser.component.ts +++ b/src/app/superadmin/users/newuser/newuser.component.ts @@ -1,21 +1,14 @@ -import { MAT_DIALOG_DATA } from '@angular/material/dialog'; -import { Component, OnInit, Inject } from '@angular/core'; -import { FormGroup, FormBuilder, Validators } from '@angular/forms'; +import { Component } from '@angular/core'; +import {FormControl, FormGroup, Validators} from '@angular/forms'; @Component({ templateUrl: './newuser.component.html', styleUrls: ['./newuser.component.css'] }) -export class NewuserComponent implements OnInit { - newuserform: FormGroup; - constructor(private fb: FormBuilder, - @Inject(MAT_DIALOG_DATA) public data: any) { } - - ngOnInit() { - this.newuserform = this.fb.group({ - name: this.fb.control('', [Validators.required, Validators.minLength(3)]), - pw: this.fb.control('', [Validators.required, Validators.minLength(3)]) - }); - } +export class NewuserComponent { + newuserform = new FormGroup({ + name: new FormControl('', [Validators.required, Validators.minLength(3)]), + pw: new FormControl('', [Validators.required, Validators.minLength(3)]) + }); } diff --git a/src/app/superadmin/users/users.component.html b/src/app/superadmin/users/users.component.html index 5e1b3d152aef627dc85bed86728eb7ae6920aaaa..3e633482a87711e4a98fe9a1f24be858d772cf20 100644 --- a/src/app/superadmin/users/users.component.html +++ b/src/app/superadmin/users/users.component.html @@ -1,25 +1,25 @@ <div class="columnhost" fxLayout="row" fxLayoutAlign="space-between start"> - <div class="spinner-container" *ngIf="dataLoading"> - <mat-spinner></mat-spinner> - </div> - <!-- ============================================= --> <div class="objectlist" fxLayout="column" fxFlex="50"> <div fxLayout="row"> - <button mat-raised-button (click)="addObject()" matTooltip="Nutzer hinzufügen" matTooltipPosition="above"> - <mat-icon>add</mat-icon> - </button> - <button mat-raised-button (click)="deleteObject()" - matTooltip="Markierte Nutzer löschen" matTooltipPosition="above"> - <mat-icon>delete</mat-icon> - </button> - <button mat-raised-button (click)="changePassword()" - matTooltip="Kennwort ändern" matTooltipPosition="above"> - <mat-icon>edit</mat-icon> + <button mat-raised-button (click)="addObject()" matTooltip="Nutzer hinzufügen" matTooltipPosition="above"> + <mat-icon>add</mat-icon> </button> + <button mat-raised-button (click)="deleteObject()" + matTooltip="Markierte Nutzer löschen" matTooltipPosition="above"> + <mat-icon>delete</mat-icon> + </button> + <button mat-raised-button (click)="changePassword()" + matTooltip="Kennwort ändern" matTooltipPosition="above"> + <mat-icon>edit</mat-icon> + </button> + <button mat-raised-button (click)="changeSuperadminStatus()" + matTooltip="Superadmin-Status ändern" matTooltipPosition="above"> + <mat-icon>edit</mat-icon> + </button> </div> - <mat-table *ngIf="isSuperadmin" [dataSource]="objectsDatasource" matSort> + <mat-table [dataSource]="objectsDatasource" matSort> <ng-container matColumnDef="selectCheckbox"> <mat-header-cell *matHeaderCellDef fxFlex="70px"> <mat-checkbox (change)="$event ? masterToggle() : null" @@ -37,7 +37,7 @@ <ng-container matColumnDef="name"> <mat-header-cell *matHeaderCellDef mat-sort-header> Name </mat-header-cell> - <mat-cell *matCellDef="let element"> {{element.name}} </mat-cell> + <mat-cell *matCellDef="let element"> {{element.name}} {{element.isSuperadmin ? '*' : ''}}</mat-cell> </ng-container> <mat-header-row *matHeaderRowDef="displayedColumns"></mat-header-row> @@ -47,7 +47,7 @@ </div> <!-- ============================================= --> - <div *ngIf="isSuperadmin" fxLayout="column" fxFlex="40"> + <div fxLayout="column" fxFlex="40"> <div *ngIf="selectedUser < 0"> <div>Zugriffsrechte für Arbeitsbereich(e):</div> diff --git a/src/app/superadmin/users/users.component.spec.ts b/src/app/superadmin/users/users.component.spec.ts index 909b5bafc36b01915898fbd0fe8b0d5568aba476..94d4bbf1981dd3e760af5c5124d6cfb7a65e02f5 100644 --- a/src/app/superadmin/users/users.component.spec.ts +++ b/src/app/superadmin/users/users.component.spec.ts @@ -1,6 +1,11 @@ import { async, ComponentFixture, TestBed } from '@angular/core/testing'; import { UsersComponent } from './users.component'; +import {HttpClientModule} from "@angular/common/http"; +import { BackendService } from '../backend.service'; +import {MatDialogModule} from "@angular/material/dialog"; +import {MatSnackBarModule} from "@angular/material/snack-bar"; +import {MainDataService} from "../../maindata.service"; describe('UsersComponent', () => { let component: UsersComponent; @@ -8,7 +13,16 @@ describe('UsersComponent', () => { beforeEach(async(() => { TestBed.configureTestingModule({ - declarations: [ UsersComponent ] + declarations: [ UsersComponent ], + imports: [ + HttpClientModule, + MatDialogModule, + MatSnackBarModule + ], + providers: [ + BackendService, + MainDataService + ] }) .compileComponents(); })); diff --git a/src/app/superadmin/users/users.component.ts b/src/app/superadmin/users/users.component.ts index cdcbb8a3843a7899c954c0964eaa0f95a3a01bae..deee5ea3b7fb4c1cd77a05e2a8adb48ac1cfc262 100644 --- a/src/app/superadmin/users/users.component.ts +++ b/src/app/superadmin/users/users.component.ts @@ -1,8 +1,8 @@ import { NewpasswordComponent } from './newpassword/newpassword.component'; import { NewuserComponent } from './newuser/newuser.component'; -import { BackendService, IdRoleData, IdAndName } from '../backend.service'; +import { BackendService } from '../backend.service'; import { MatTableDataSource } from '@angular/material/table'; -import { ViewChild, OnDestroy } from '@angular/core'; +import { ViewChild } from '@angular/core'; import { Component, OnInit } from '@angular/core'; import { MatDialog } from '@angular/material/dialog'; @@ -14,37 +14,36 @@ import { ConfirmDialogComponent, ConfirmDialogData, MessageDialogComponent, MessageDialogData, MessageType } from 'iqb-components'; -import { Subscription } from 'rxjs'; import { MainDataService } from 'src/app/maindata.service'; +import {IdRoleData, UserData} from "../superadmin.interfaces"; +import {SuperadminPasswordRequestComponent} from "../superadmin-password-request/superadmin-password-request.component"; @Component({ templateUrl: './users.component.html', styleUrls: ['./users.component.css'] }) -export class UsersComponent implements OnInit, OnDestroy { - public isSuperadmin = false; - public dataLoading = false; - public objectsDatasource: MatTableDataSource<IdAndName>; +export class UsersComponent implements OnInit { + public objectsDatasource: MatTableDataSource<UserData>; public displayedColumns = ['selectCheckbox', 'name']; - private tableselectionCheckbox = new SelectionModel<IdAndName>(true, []); - private tableselectionRow = new SelectionModel<IdAndName>(false, []); - private selectedUser = -1; + private tableselectionCheckbox = new SelectionModel<UserData>(true, []); + private tableselectionRow = new SelectionModel<UserData>(false, []); + public selectedUser = -1; private selectedUserName = ''; private pendingWorkspaceChanges = false; public WorkspacelistDatasource: MatTableDataSource<IdRoleData>; public displayedWorkspaceColumns = ['selectCheckbox', 'label']; - private logindataSubscription: Subscription = null; - @ViewChild(MatSort, { static: false }) sort: MatSort; + @ViewChild(MatSort) sort: MatSort; constructor( private bs: BackendService, private mds: MainDataService, private newuserDialog: MatDialog, private newpasswordDialog: MatDialog, - private deleteConfirmDialog: MatDialog, + private confirmDialog: MatDialog, + private superadminPasswordDialog: MatDialog, private messsageDialog: MatDialog, private snackBar: MatSnackBar ) { @@ -62,24 +61,22 @@ export class UsersComponent implements OnInit, OnDestroy { } ngOnInit() { - this.logindataSubscription = this.mds.loginData$.subscribe(ld => { - this.isSuperadmin = ld.isSuperadmin; + setTimeout(() => { + this.mds.setSpinnerOn(); this.updateObjectList(); - }); + }) } // *********************************************************************************** addObject() { const dialogRef = this.newuserDialog.open(NewuserComponent, { - width: '600px', - data: { - name: '' - } + width: '600px' }); dialogRef.afterClosed().subscribe(result => { if (typeof result !== 'undefined') { if (result !== false) { + this.mds.setSpinnerOn(); this.bs.addUser((<FormGroup>result).get('name').value, (<FormGroup>result).get('pw').value).subscribe( respOk => { @@ -87,6 +84,7 @@ export class UsersComponent implements OnInit, OnDestroy { this.snackBar.open('Nutzer hinzugefügt', '', {duration: 1000}); this.updateObjectList(); } else { + this.mds.setSpinnerOff(); this.snackBar.open('Konnte Nutzer nicht hinzufügen', 'Fehler', {duration: 1000}); } }); @@ -95,6 +93,67 @@ export class UsersComponent implements OnInit, OnDestroy { }); } + changeSuperadminStatus() { + let selectedRows = this.tableselectionRow.selected; + if (selectedRows.length === 0) { + selectedRows = this.tableselectionCheckbox.selected; + } + if (selectedRows.length === 0) { + this.messsageDialog.open(MessageDialogComponent, { + width: '400px', + data: <MessageDialogData>{ + title: 'Superadmin-Status ändern', + content: 'Bitte markieren Sie erst einen Nutzer!', + type: MessageType.error + } + }); + } else { + const userObject = <UserData>selectedRows[0]; + const confirmDialogRef = this.confirmDialog.open(ConfirmDialogComponent, { + width: '400px', + data: <ConfirmDialogData>{ + title: 'Ändern des Superadmin-Status', + content: 'Für "' + userObject.name + '" den Status auf "' + (userObject.isSuperadmin ? 'NICHT ' : '') + 'Superadmin" setzen?', + confirmbuttonlabel: 'Status ändern', + showcancel: true + } + }); + + confirmDialogRef.afterClosed().subscribe(result => { + if ((typeof result !== 'undefined') && (result !== false)) { + const passwdDialogRef = this.superadminPasswordDialog.open(SuperadminPasswordRequestComponent, { + width: '600px', + data: 'Superadmin-Status ' + (userObject.isSuperadmin ? 'entziehen' : 'setzen') + }); + + passwdDialogRef.afterClosed().subscribe(result => { + if (typeof result !== 'undefined') { + if (result !== false) { + this.mds.setSpinnerOn(); + this.bs.setSuperUserStatus( + selectedRows[0]['id'], + !userObject.isSuperadmin, + (<FormGroup>result).get('pw').value).subscribe( + respCode => { + if (respCode === 0) { + this.snackBar.open('Status geändert', '', {duration: 1000}); + this.updateObjectList(); + } else if (respCode === 403) { + this.mds.setSpinnerOff(); + this.snackBar.open('Konnte Status nicht ändern (fehlende Berechtigung)', 'Fehler', {duration: 1000}); + } else { + this.mds.setSpinnerOff(); + this.snackBar.open(`Konnte Status nicht ändern (Fehlercode ${respCode})`, 'Fehler', {duration: 1000}); + } + }); + } + } + }); + } + }); + } + } + changePassword() { let selectedRows = this.tableselectionRow.selected; if (selectedRows.length === 0) { @@ -112,24 +171,22 @@ export class UsersComponent implements OnInit, OnDestroy { } else { const dialogRef = this.newpasswordDialog.open(NewpasswordComponent, { width: '600px', - data: { - name: selectedRows[0]['name'] - } + data: selectedRows[0]['name'] }); dialogRef.afterClosed().subscribe(result => { if (typeof result !== 'undefined') { if (result !== false) { - this.dataLoading = true; + this.mds.setSpinnerOn(); this.bs.changePassword(selectedRows[0]['id'], (<FormGroup>result).get('pw').value).subscribe( respOk => { + this.mds.setSpinnerOff(); if (respOk !== false) { this.snackBar.open('Kennwort geändert', '', {duration: 1000}); } else { this.snackBar.open('Konnte Kennwort nicht ändern', 'Fehler', {duration: 1000}); } - this.dataLoading = false; }); } } @@ -158,7 +215,7 @@ export class UsersComponent implements OnInit, OnDestroy { } else { prompt = prompt + ' Nutzer "' + selectedRows[0].name + '" '; } - const dialogRef = this.deleteConfirmDialog.open(ConfirmDialogComponent, { + const dialogRef = this.confirmDialog.open(ConfirmDialogComponent, { width: '400px', data: <ConfirmDialogData>{ title: 'Löschen von Nutzern', @@ -171,20 +228,19 @@ export class UsersComponent implements OnInit, OnDestroy { dialogRef.afterClosed().subscribe(result => { if (result !== false) { // ========================================================= - this.dataLoading = true; const usersToDelete = []; - selectedRows.forEach((r: IdAndName) => usersToDelete.push(r.id)); + selectedRows.forEach((r: UserData) => usersToDelete.push(r.id)); + this.mds.setSpinnerOn(); this.bs.deleteUsers(usersToDelete).subscribe( respOk => { if (respOk !== false) { this.snackBar.open('Nutzer gelöscht', '', {duration: 1000}); this.updateObjectList(); - this.dataLoading = false; } else { + this.mds.setSpinnerOff(); this.snackBar.open('Konnte Nutzer nicht löschen', 'Fehler', {duration: 2000}); - this.dataLoading = false; } - }); + }); } }); } @@ -194,11 +250,11 @@ export class UsersComponent implements OnInit, OnDestroy { updateWorkspaceList() { this.pendingWorkspaceChanges = false; if (this.selectedUser > -1) { - this.dataLoading = true; + this.mds.setSpinnerOn(); this.bs.getWorkspacesByUser(this.selectedUser).subscribe(dataresponse => { - this.WorkspacelistDatasource = new MatTableDataSource(dataresponse); - this.dataLoading = false; - }); + this.WorkspacelistDatasource = new MatTableDataSource(dataresponse); + this.mds.setSpinnerOff(); + }) } else { this.WorkspacelistDatasource = null; } @@ -216,15 +272,15 @@ export class UsersComponent implements OnInit, OnDestroy { saveWorkspaces() { this.pendingWorkspaceChanges = false; if (this.selectedUser > -1) { - this.dataLoading = true; + this.mds.setSpinnerOn(); this.bs.setWorkspacesByUser(this.selectedUser, this.WorkspacelistDatasource.data).subscribe( respOk => { + this.mds.setSpinnerOff(); if (respOk !== false) { this.snackBar.open('Zugriffsrechte geändert', '', {duration: 1000}); } else { this.snackBar.open('Konnte Zugriffsrechte nicht ändern', 'Fehler', {duration: 2000}); } - this.dataLoading = false; }); } else { this.WorkspacelistDatasource = null; @@ -233,17 +289,13 @@ export class UsersComponent implements OnInit, OnDestroy { // *********************************************************************************** updateObjectList() { - if (this.isSuperadmin) { - this.dataLoading = true; - this.tableselectionCheckbox.clear(); - this.tableselectionRow.clear(); - this.bs.getUsers().subscribe(dataresponse => { - this.objectsDatasource = new MatTableDataSource(dataresponse); - this.objectsDatasource.sort = this.sort; - this.dataLoading = false; - } - ); - } + this.tableselectionCheckbox.clear(); + this.tableselectionRow.clear(); + this.bs.getUsers().subscribe(dataresponse => { + this.objectsDatasource = new MatTableDataSource(dataresponse); + this.objectsDatasource.sort = this.sort; + this.mds.setSpinnerOff(); + }); } isAllSelected() { @@ -261,11 +313,4 @@ export class UsersComponent implements OnInit, OnDestroy { selectRow(row) { this.tableselectionRow.select(row); } - - // % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % - ngOnDestroy() { - if (this.logindataSubscription !== null) { - this.logindataSubscription.unsubscribe(); - } - } } diff --git a/src/app/superadmin/workspaces/editworkspace/editworkspace.component.html b/src/app/superadmin/workspaces/editworkspace/editworkspace.component.html index ea8a177147f15f24e8abc97b062d00d6f756d950..4d5d55c7bb77168ba3697bd3b07416c479da1e73 100644 --- a/src/app/superadmin/workspaces/editworkspace/editworkspace.component.html +++ b/src/app/superadmin/workspaces/editworkspace/editworkspace.component.html @@ -1,10 +1,10 @@ <form [formGroup]="editworkspaceform"> - <h1 mat-dialog-title>Arbeitsbereich "{{data.oldname}}" ändern</h1> + <h1 mat-dialog-title>Arbeitsbereich "{{data}}" ändern</h1> <mat-dialog-content> <p> <mat-form-field class="full-width"> - <input matInput formControlName="name" placeholder="Name" [value]="data.name"> + <input matInput formControlName="name" placeholder="Name" [value]="data"> </mat-form-field> </p> </mat-dialog-content> diff --git a/src/app/superadmin/workspaces/editworkspace/editworkspace.component.spec.ts b/src/app/superadmin/workspaces/editworkspace/editworkspace.component.spec.ts index 8b464397d576671f928a425c97168ea1a556d723..e3ac6df1235284ff7634fc7884ac3cad7d79e7fe 100644 --- a/src/app/superadmin/workspaces/editworkspace/editworkspace.component.spec.ts +++ b/src/app/superadmin/workspaces/editworkspace/editworkspace.component.spec.ts @@ -1,6 +1,11 @@ import { async, ComponentFixture, TestBed } from '@angular/core/testing'; import { EditworkspaceComponent } from './editworkspace.component'; +import {ReactiveFormsModule} from "@angular/forms"; +import {MAT_DIALOG_DATA, MatDialog, MatDialogModule} from "@angular/material/dialog"; +import {MatInputModule} from "@angular/material/input"; +import {MatFormFieldModule} from "@angular/material/form-field"; +import {NoopAnimationsModule} from "@angular/platform-browser/animations"; describe('EditworkspaceComponent', () => { let component: EditworkspaceComponent; @@ -8,7 +13,18 @@ describe('EditworkspaceComponent', () => { beforeEach(async(() => { TestBed.configureTestingModule({ - declarations: [ EditworkspaceComponent ] + declarations: [ EditworkspaceComponent ], + imports: [ + MatDialogModule, + ReactiveFormsModule, + MatInputModule, + MatFormFieldModule, + NoopAnimationsModule + ], + providers: [ + MatDialog, + { provide: MAT_DIALOG_DATA, useValue: 'VERA 2020' } + ] }) .compileComponents(); })); diff --git a/src/app/superadmin/workspaces/editworkspace/editworkspace.component.ts b/src/app/superadmin/workspaces/editworkspace/editworkspace.component.ts index 55013ca244f4916715a8f6c2baa906dc17fe08ed..819f1299c21c5d63872bc61973b2c64098899938 100644 --- a/src/app/superadmin/workspaces/editworkspace/editworkspace.component.ts +++ b/src/app/superadmin/workspaces/editworkspace/editworkspace.component.ts @@ -1,20 +1,16 @@ import { MAT_DIALOG_DATA } from '@angular/material/dialog'; -import { Component, OnInit, Inject } from '@angular/core'; -import { FormGroup, FormBuilder, Validators } from '@angular/forms'; +import { Component, Inject } from '@angular/core'; +import {FormGroup, Validators, FormControl} from '@angular/forms'; @Component({ templateUrl: './editworkspace.component.html', styleUrls: ['./editworkspace.component.css'] }) -export class EditworkspaceComponent implements OnInit { - editworkspaceform: FormGroup; +export class EditworkspaceComponent { + editworkspaceform = new FormGroup({ + name: new FormControl('', [Validators.required, Validators.minLength(3)]) + }); - constructor(private fb: FormBuilder, - @Inject(MAT_DIALOG_DATA) public data: any) { } - - ngOnInit() { - this.editworkspaceform = this.fb.group({ - name: this.fb.control('', [Validators.required, Validators.minLength(3)]) - }); - } + constructor( + @Inject(MAT_DIALOG_DATA) public data: string) { } } diff --git a/src/app/superadmin/workspaces/newworkspace/newworkspace.component.html b/src/app/superadmin/workspaces/newworkspace/newworkspace.component.html index 5f6e7c282656460604295e5c11967e1cdc23b421..00ad5848b717f75aba486ae82cb202cfe00d6294 100644 --- a/src/app/superadmin/workspaces/newworkspace/newworkspace.component.html +++ b/src/app/superadmin/workspaces/newworkspace/newworkspace.component.html @@ -4,7 +4,7 @@ <mat-dialog-content> <p> <mat-form-field class="full-width"> - <input matInput formControlName="name" placeholder="Name" [value]="data.name"> + <input matInput formControlName="name" placeholder="Name"> </mat-form-field> </p> <div class="infobox"> diff --git a/src/app/superadmin/workspaces/newworkspace/newworkspace.component.spec.ts b/src/app/superadmin/workspaces/newworkspace/newworkspace.component.spec.ts index a2c645598677fe1b8f3ae62356d7f93912b3db31..0bf0a5c92355d84dcb866199a929a1cbde3b938d 100644 --- a/src/app/superadmin/workspaces/newworkspace/newworkspace.component.spec.ts +++ b/src/app/superadmin/workspaces/newworkspace/newworkspace.component.spec.ts @@ -1,14 +1,29 @@ import { async, ComponentFixture, TestBed } from '@angular/core/testing'; import { NewworkspaceComponent } from './newworkspace.component'; +import {ReactiveFormsModule} from "@angular/forms"; +import {MatDialog, MatDialogModule} from "@angular/material/dialog"; +import {MatInputModule} from "@angular/material/input"; +import {MatFormFieldModule} from "@angular/material/form-field"; +import {NoopAnimationsModule} from "@angular/platform-browser/animations"; -describe('NewworkspaceComponent', () => { +describe('NewWorkspaceComponent', () => { let component: NewworkspaceComponent; let fixture: ComponentFixture<NewworkspaceComponent>; beforeEach(async(() => { TestBed.configureTestingModule({ - declarations: [ NewworkspaceComponent ] + declarations: [ NewworkspaceComponent ], + imports: [ + MatDialogModule, + ReactiveFormsModule, + MatInputModule, + MatFormFieldModule, + NoopAnimationsModule + ], + providers: [ + MatDialog + ] }) .compileComponents(); })); diff --git a/src/app/superadmin/workspaces/newworkspace/newworkspace.component.ts b/src/app/superadmin/workspaces/newworkspace/newworkspace.component.ts index 02cf6f563b7dd474d94a3fd2546591baf9aaef28..6fd83574628b7214ad4c8f9447dcb25ba5520428 100644 --- a/src/app/superadmin/workspaces/newworkspace/newworkspace.component.ts +++ b/src/app/superadmin/workspaces/newworkspace/newworkspace.component.ts @@ -1,20 +1,12 @@ -import { MAT_DIALOG_DATA } from '@angular/material/dialog'; -import { Component, OnInit, Inject } from '@angular/core'; -import { FormGroup, FormBuilder, Validators } from '@angular/forms'; +import { Component } from '@angular/core'; +import {FormGroup, Validators, FormControl} from '@angular/forms'; @Component({ templateUrl: './newworkspace.component.html', styleUrls: ['./newworkspace.component.css'] }) -export class NewworkspaceComponent implements OnInit { - newworkspaceform: FormGroup; - - constructor(private fb: FormBuilder, - @Inject(MAT_DIALOG_DATA) public data: any) { } - - ngOnInit() { - this.newworkspaceform = this.fb.group({ - name: this.fb.control('', [Validators.required, Validators.minLength(3)]) - }); - } +export class NewworkspaceComponent { + newworkspaceform = new FormGroup({ + name: new FormControl('', [Validators.required, Validators.minLength(3)]) + }) } diff --git a/src/app/superadmin/workspaces/workspaces.component.html b/src/app/superadmin/workspaces/workspaces.component.html index 2aaf15439c741c971c81efc9a7e0bbf346451b82..9c62182bc765904d40e8495d7f555dedab121f29 100644 --- a/src/app/superadmin/workspaces/workspaces.component.html +++ b/src/app/superadmin/workspaces/workspaces.component.html @@ -1,9 +1,4 @@ <div class="columnhost" fxLayout="row" fxLayoutAlign="space-between start"> - <div class="spinner-container" *ngIf="dataLoading"> - <mat-spinner></mat-spinner> - </div> - - <!-- ============================================= --> <div class="objectlist" fxLayout="column" fxFlex="50"> <div fxLayout="row"> <button mat-raised-button (click)="addObject()" matTooltip="Arbeitsbereich hinzufügen" matTooltipPosition="above"> @@ -18,7 +13,7 @@ </button> </div> - <mat-table *ngIf="isSuperadmin" [dataSource]="objectsDatasource" matSort> + <mat-table [dataSource]="objectsDatasource" matSort> <ng-container matColumnDef="selectCheckbox"> <mat-header-cell *matHeaderCellDef fxFlex="70px"> <mat-checkbox (change)="$event ? masterToggle() : null" @@ -46,7 +41,7 @@ </div> <!-- ============================================= --> - <div *ngIf="isSuperadmin" fxLayout="column" fxFlex="40"> + <div fxLayout="column" fxFlex="40"> <div *ngIf="selectedWorkspaceId == 0"> <div>Zugriffsberechtigte für Arbeitsbereich:</div> diff --git a/src/app/superadmin/workspaces/workspaces.component.spec.ts b/src/app/superadmin/workspaces/workspaces.component.spec.ts index 36be59aab54ec2b9163c8efa5870b62e2c9ea71d..162c69df4195920fd2a942120be5a4cc7398142f 100644 --- a/src/app/superadmin/workspaces/workspaces.component.spec.ts +++ b/src/app/superadmin/workspaces/workspaces.component.spec.ts @@ -1,6 +1,11 @@ import { async, ComponentFixture, TestBed } from '@angular/core/testing'; import { WorkspacesComponent } from './workspaces.component'; +import {HttpClientModule} from "@angular/common/http"; +import { BackendService } from '../backend.service'; +import {MatDialogModule} from "@angular/material/dialog"; +import {MatSnackBarModule} from "@angular/material/snack-bar"; +import {MainDataService} from "../../maindata.service"; describe('WorkspacesComponent', () => { let component: WorkspacesComponent; @@ -8,7 +13,16 @@ describe('WorkspacesComponent', () => { beforeEach(async(() => { TestBed.configureTestingModule({ - declarations: [ WorkspacesComponent ] + declarations: [ WorkspacesComponent ], + imports: [ + HttpClientModule, + MatDialogModule, + MatSnackBarModule + ], + providers: [ + BackendService, + MainDataService + ] }) .compileComponents(); })); diff --git a/src/app/superadmin/workspaces/workspaces.component.ts b/src/app/superadmin/workspaces/workspaces.component.ts index 45b823bb7c93edc25967de73c151ba9c12ca7149..dfecfd25f4e610c32ae98b8f148985d934ca385e 100644 --- a/src/app/superadmin/workspaces/workspaces.component.ts +++ b/src/app/superadmin/workspaces/workspaces.component.ts @@ -1,9 +1,8 @@ import { EditworkspaceComponent } from './editworkspace/editworkspace.component'; import { NewworkspaceComponent } from './newworkspace/newworkspace.component'; -import { BackendService, IdAndName, IdRoleData } from '../backend.service'; +import { BackendService } from '../backend.service'; import { MatTableDataSource } from '@angular/material/table'; -import { ViewChild, OnDestroy } from '@angular/core'; - +import { ViewChild } from '@angular/core'; import { Component, OnInit } from '@angular/core'; import { MatDialog } from '@angular/material/dialog'; import { MatSnackBar } from '@angular/material/snack-bar'; @@ -14,29 +13,25 @@ import { ConfirmDialogComponent, ConfirmDialogData, MessageDialogComponent, MessageDialogData, MessageType } from 'iqb-components'; -import { Subscription } from 'rxjs'; import { MainDataService } from 'src/app/maindata.service'; +import {IdAndName, IdRoleData} from "../superadmin.interfaces"; @Component({ templateUrl: './workspaces.component.html', styleUrls: ['./workspaces.component.css'] }) -export class WorkspacesComponent implements OnInit, OnDestroy { - public isSuperadmin = false; - public dataLoading = false; +export class WorkspacesComponent implements OnInit { public objectsDatasource: MatTableDataSource<IdAndName>; public displayedColumns = ['selectCheckbox', 'name']; private tableselectionCheckbox = new SelectionModel <IdAndName>(true, []); private tableselectionRow = new SelectionModel <IdAndName>(false, []); - private selectedWorkspaceId = 0; + public selectedWorkspaceId = 0; private selectedWorkspaceName = ''; - private logindataSubscription: Subscription = null; - private pendingUserChanges = false; public UserlistDatasource: MatTableDataSource<IdRoleData>; public displayedUserColumns = ['selectCheckbox', 'name']; - @ViewChild(MatSort, { static: false }) sort: MatSort; + @ViewChild(MatSort) sort: MatSort; constructor( private bs: BackendService, @@ -61,10 +56,10 @@ export class WorkspacesComponent implements OnInit, OnDestroy { } ngOnInit() { - this.logindataSubscription = this.mds.loginData$.subscribe(ld => { - this.isSuperadmin = ld.isSuperadmin; + setTimeout(() => { + this.mds.setSpinnerOn(); this.updateObjectList(); - }); + }) } // *********************************************************************************** @@ -79,17 +74,17 @@ export class WorkspacesComponent implements OnInit, OnDestroy { dialogRef.afterClosed().subscribe(result => { if (typeof result !== 'undefined') { if (result !== false) { - this.dataLoading = true; + this.mds.setSpinnerOn(); this.bs.addWorkspace((<FormGroup>result).get('name').value).subscribe( - respOk => { - if (respOk !== false) { - this.snackBar.open('Arbeitsbereich hinzugefügt', '', {duration: 1000}); - this.updateObjectList(); - } else { - this.snackBar.open('Konnte Arbeitsbereich nicht hinzufügen', 'Fehler', {duration: 1000}); - } - this.dataLoading = false; - }); + respOk => { + if (respOk !== false) { + this.snackBar.open('Arbeitsbereich hinzugefügt', '', {duration: 1000}); + this.updateObjectList(); + } else { + this.mds.setSpinnerOff(); + this.snackBar.open('Konnte Arbeitsbereich nicht hinzufügen', 'Fehler', {duration: 1000}); + } + }); } } }); @@ -112,16 +107,13 @@ export class WorkspacesComponent implements OnInit, OnDestroy { } else { const dialogRef = this.editworkspaceDialog.open(EditworkspaceComponent, { width: '600px', - data: { - name: selectedRows[0].name, - oldname: selectedRows[0].name - } + data: selectedRows[0].name }); dialogRef.afterClosed().subscribe(result => { if (typeof result !== 'undefined') { if (result !== false) { - this.dataLoading = true; + this.mds.setSpinnerOn(); this.bs.renameWorkspace(selectedRows[0].id, (<FormGroup>result).get('name').value).subscribe( respOk => { @@ -129,9 +121,9 @@ export class WorkspacesComponent implements OnInit, OnDestroy { this.snackBar.open('Arbeitsbereich geändert', '', {duration: 1000}); this.updateObjectList(); } else { + this.mds.setSpinnerOff(); this.snackBar.open('Konnte Arbeitsbereich nicht ändern', 'Fehler', {duration: 2000}); } - this.dataLoading = false; }); } } @@ -173,18 +165,17 @@ export class WorkspacesComponent implements OnInit, OnDestroy { dialogRef.afterClosed().subscribe(result => { if (result !== false) { // ========================================================= - this.dataLoading = true; const workspacesToDelete = []; selectedRows.forEach((r: IdAndName) => workspacesToDelete.push(r.id)); + this.mds.setSpinnerOn(); this.bs.deleteWorkspaces(workspacesToDelete).subscribe( respOk => { if (respOk !== false) { this.snackBar.open('Arbeitsbereich/e gelöscht', '', {duration: 1000}); this.updateObjectList(); - this.dataLoading = false; } else { + this.mds.setSpinnerOff(); this.snackBar.open('Konnte Arbeitsbereich/e nicht löschen', 'Fehler', {duration: 1000}); - this.dataLoading = false; } }); } @@ -196,11 +187,11 @@ export class WorkspacesComponent implements OnInit, OnDestroy { updateUserList() { this.pendingUserChanges = false; if (this.selectedWorkspaceId > 0) { - this.dataLoading = true; + this.mds.setSpinnerOn(); this.bs.getUsersByWorkspace(this.selectedWorkspaceId).subscribe(dataresponse => { - this.UserlistDatasource = new MatTableDataSource(dataresponse); - this.dataLoading = false; - }); + this.UserlistDatasource = new MatTableDataSource(dataresponse); + this.mds.setSpinnerOff(); + }); } else { this.UserlistDatasource = null; } @@ -218,15 +209,15 @@ export class WorkspacesComponent implements OnInit, OnDestroy { saveUsers() { this.pendingUserChanges = false; if (this.selectedWorkspaceId > 0) { - this.dataLoading = true; + this.mds.setSpinnerOn(); this.bs.setUsersByWorkspace(this.selectedWorkspaceId, this.UserlistDatasource.data).subscribe( respOk => { + this.mds.setSpinnerOff(); if (respOk !== false) { this.snackBar.open('Zugriffsrechte geändert', '', {duration: 1000}); } else { this.snackBar.open('Konnte Zugriffsrechte nicht ändern', 'Fehler', {duration: 2000}); } - this.dataLoading = false; }); } else { this.UserlistDatasource = null; @@ -235,17 +226,13 @@ export class WorkspacesComponent implements OnInit, OnDestroy { // *********************************************************************************** updateObjectList() { - if (this.isSuperadmin) { - this.dataLoading = true; - this.bs.getWorkspaces().subscribe(dataresponse => { - this.objectsDatasource = new MatTableDataSource(dataresponse); - this.objectsDatasource.sort = this.sort; - this.tableselectionCheckbox.clear(); - this.tableselectionRow.clear(); - this.dataLoading = false; - } - ); - } + this.bs.getWorkspaces().subscribe(dataresponse => { + this.objectsDatasource = new MatTableDataSource(dataresponse); + this.objectsDatasource.sort = this.sort; + this.tableselectionCheckbox.clear(); + this.tableselectionRow.clear(); + this.mds.setSpinnerOff(); + }); } isAllSelected() { @@ -263,11 +250,4 @@ export class WorkspacesComponent implements OnInit, OnDestroy { selectRow(row) { this.tableselectionRow.select(row); } - - // % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % - ngOnDestroy() { - if (this.logindataSubscription !== null) { - this.logindataSubscription.unsubscribe(); - } - } } diff --git a/src/app/sys-check/backend.service.spec.ts b/src/app/sys-check/backend.service.spec.ts index c31039d7e5bcc7bc70e7213ce06744a0dc6ed009..ffdc1397ca5ced3a08516d7183bbc820c1001627 100644 --- a/src/app/sys-check/backend.service.spec.ts +++ b/src/app/sys-check/backend.service.spec.ts @@ -1,14 +1,16 @@ import { TestBed, inject } from '@angular/core/testing'; import { BackendService } from './backend.service'; +import {HttpClientModule} from "@angular/common/http"; -describe('BackendService', () => { + +describe('HttpClient testing', () => { beforeEach(() => { TestBed.configureTestingModule({ + imports: [HttpClientModule], providers: [BackendService] }); }); - it('should be created', inject([BackendService], (service: BackendService) => { expect(service).toBeTruthy(); })); diff --git a/src/app/sys-check/backend.service.ts b/src/app/sys-check/backend.service.ts index 861f8ddf76e0f0ebf6b4599ccb3457ebeb728d2c..ced27bc09e2f8668e06697738948d9acbc5121db 100644 --- a/src/app/sys-check/backend.service.ts +++ b/src/app/sys-check/backend.service.ts @@ -1,5 +1,4 @@ import { - CheckConfigAbstract, CheckConfig, NetworkRequestTestResult, UnitAndPlayerContainer, @@ -23,19 +22,6 @@ export class BackendService { ) {} - public getCheckConfigs(): Observable<CheckConfigAbstract[]> { - - return this.http - .get<CheckConfigAbstract[]>(this.serverUrl + 'sys-checks') - .pipe( - catchError(() => { - const myreturn: CheckConfigAbstract[] = []; - return of(myreturn); - }) - ); - } - - public getCheckConfigData(workspaceId: number, sysCheckName: string): Observable<CheckConfig> { return this.http diff --git a/src/app/sys-check/environment-check/environment-check.component.spec.ts b/src/app/sys-check/environment-check/environment-check.component.spec.ts index bd2f643af7dd6a00cc24289814b4fdc278375663..c1b1ed9951f6bff845beb5b87b09e93fa3224a54 100644 --- a/src/app/sys-check/environment-check/environment-check.component.spec.ts +++ b/src/app/sys-check/environment-check/environment-check.component.spec.ts @@ -1,6 +1,7 @@ import { async, ComponentFixture, TestBed } from '@angular/core/testing'; import { EnvironmentCheckComponent } from './environment-check.component'; +import {MatCardModule} from "@angular/material/card"; describe('EnvironmentCheckComponent', () => { let component: EnvironmentCheckComponent; @@ -8,7 +9,8 @@ describe('EnvironmentCheckComponent', () => { beforeEach(async(() => { TestBed.configureTestingModule({ - declarations: [ EnvironmentCheckComponent ] + declarations: [ EnvironmentCheckComponent ], + imports: [MatCardModule] }) .compileComponents(); })); diff --git a/src/app/sys-check/index.ts b/src/app/sys-check/index.ts deleted file mode 100644 index d8b21a2c8ea6fe74ef7b00e33a6235bd8e02a01d..0000000000000000000000000000000000000000 --- a/src/app/sys-check/index.ts +++ /dev/null @@ -1 +0,0 @@ -export { StartComponent } from './start.component'; diff --git a/src/app/sys-check/network-check/network-check.component.spec.ts b/src/app/sys-check/network-check/network-check.component.spec.ts index 843c35b51b167a99adc6082ac13b44405fc02791..63e025d13c4a22751090a9fb3c68fc60cf51131c 100644 --- a/src/app/sys-check/network-check/network-check.component.spec.ts +++ b/src/app/sys-check/network-check/network-check.component.spec.ts @@ -1,6 +1,8 @@ import { async, ComponentFixture, TestBed } from '@angular/core/testing'; import { NetworkCheckComponent } from './network-check.component'; +import {HttpClientModule} from "@angular/common/http"; +import {BackendService} from "../backend.service"; describe('NetworkCheckComponent', () => { let component: NetworkCheckComponent; @@ -8,7 +10,13 @@ describe('NetworkCheckComponent', () => { beforeEach(async(() => { TestBed.configureTestingModule({ - declarations: [ NetworkCheckComponent ] + declarations: [ NetworkCheckComponent ], + imports: [ + HttpClientModule + ], + providers: [ + BackendService + ] }) .compileComponents(); })); diff --git a/src/app/sys-check/network-check/network-check.component.ts b/src/app/sys-check/network-check/network-check.component.ts index e6998619741bd3d69f2ea77760be8262f1e6f9d7..ed20b077be6e08396aba4490c45e75ae4baecb88 100644 --- a/src/app/sys-check/network-check/network-check.component.ts +++ b/src/app/sys-check/network-check/network-check.component.ts @@ -78,9 +78,7 @@ export class NetworkCheckComponent implements OnInit { avgDownloadSpeedBytesPerSecond: -1 }; - console.log('start the loop: '); - const myConfig = this.ds.checkConfig$.getValue(); - console.log(myConfig); + // ?? const myConfig = this.ds.checkConfig$.getValue(); this.plotPrepare(true); this.plotPrepare(false); @@ -131,8 +129,6 @@ export class NetworkCheckComponent implements OnInit { .then(results => { const averageBytesPerSecond = NetworkCheckComponent.calculateAverageSpeedBytePerSecond(results); const averageOfPreviousLoops = this.getAverageNetworkStat(isDownloadPart); - - console.log({type: isDownloadPart ? 'download' : 'upload', results: results, avg: averageBytesPerSecond}); const errors = results.reduce((a, r) => a + ((r.error !== null) ? 1 : 0), 0); let statsLength; if (isDownloadPart) { @@ -145,12 +141,12 @@ export class NetworkCheckComponent implements OnInit { this.showBenchmarkSequenceResults(isDownloadPart, this.getAverageNetworkStat(isDownloadPart), results); if (errors > benchmarkDefinition.maxErrorsPerSequence) { - console.warn('some errors occurred', results); + console.warn('network check: some errors occurred during', results); return reject(errors); } if (statsLength > benchmarkDefinition.maxSequenceRepetitions) { - console.warn(`looped ${benchmarkDefinition.maxSequenceRepetitions} times, but could not get reliable average`); + console.warn(`network check: looped ${benchmarkDefinition.maxSequenceRepetitions} times, but could not get reliable average`); return resolve(); } @@ -189,8 +185,6 @@ export class NetworkCheckComponent implements OnInit { private benchmark(isDownloadPart: boolean, requestSize: number): Promise<NetworkRequestTestResult> { - - // console.log(`run benchmark ${benchmarkType} for ${requestSize}`); const testRound = (isDownloadPart) ? (this.networkStatsDownload.length + 1) : (this.networkStatsUpload.length + 1); const testPackage = this.humanReadableBytes(requestSize); if (isDownloadPart) { @@ -295,7 +289,6 @@ export class NetworkCheckComponent implements OnInit { avgDownloadSpeed: this.getAverageNetworkStat(true), avgUploadSpeed: this.getAverageNetworkStat(false), }; - console.log('measured averages', nd); // the ratings are calculated individually, by a "how low can you go" approach @@ -331,7 +324,6 @@ export class NetworkCheckComponent implements OnInit { private getBrowsersNativeNetworkInformation() { const connection = navigator['connection'] || navigator['mozConnection'] || navigator['webkitConnection']; - console.log('connection', connection); if (connection) { this.detectedNetworkInformations = { available: true, diff --git a/src/app/sys-check/questionnaire/questionnaire.component.html b/src/app/sys-check/questionnaire/questionnaire.component.html index 1d51f4a05dfd86cb18c66de242827f2bde47505b..700388b33e2e79cfd5741b3222ccf30477d78088 100644 --- a/src/app/sys-check/questionnaire/questionnaire.component.html +++ b/src/app/sys-check/questionnaire/questionnaire.component.html @@ -1,6 +1,6 @@ <mat-card-header> <mat-card-title>Fragen</mat-card-title> - <mat-card-subtitle>{{'Bitte bearbeiten Sie die nachfolgenden Fragen.'| customtext:'QuestionsIntro':cts.updateCount}}</mat-card-subtitle> + <mat-card-subtitle>{{'Bitte bearbeiten Sie die nachfolgenden Fragen.'| customtext:'syscheck_questionsintro':cts.updateCount}}</mat-card-subtitle> </mat-card-header> <mat-card-content style="height: 610px; overflow: auto"> diff --git a/src/app/sys-check/questionnaire/questionnaire.component.spec.ts b/src/app/sys-check/questionnaire/questionnaire.component.spec.ts index dedbd4635da0f25d652d2076b100eb43b0384653..fa3085144e68ffb62bd0e96de6c90f213eb218c1 100644 --- a/src/app/sys-check/questionnaire/questionnaire.component.spec.ts +++ b/src/app/sys-check/questionnaire/questionnaire.component.spec.ts @@ -1,6 +1,7 @@ import { async, ComponentFixture, TestBed } from '@angular/core/testing'; import { QuestionnaireComponent } from './questionnaire.component'; +import {IqbComponentsModule} from "iqb-components"; describe('QuestionnaireComponent', () => { let component: QuestionnaireComponent; @@ -8,7 +9,8 @@ describe('QuestionnaireComponent', () => { beforeEach(async(() => { TestBed.configureTestingModule({ - declarations: [ QuestionnaireComponent ] + declarations: [ QuestionnaireComponent ], + imports: [IqbComponentsModule] }) .compileComponents(); })); diff --git a/src/app/sys-check/report/report.component.spec.ts b/src/app/sys-check/report/report.component.spec.ts index dc62bcfa02b893b61cf6562296ce9e8895030b08..9ade101e77a52f391c895458aace04bea596f991 100644 --- a/src/app/sys-check/report/report.component.spec.ts +++ b/src/app/sys-check/report/report.component.spec.ts @@ -1,6 +1,10 @@ import { async, ComponentFixture, TestBed } from '@angular/core/testing'; import { ReportComponent } from './report.component'; +import {HttpClientModule} from "@angular/common/http"; +import {BackendService} from "../backend.service"; +import {MatDialogModule} from "@angular/material/dialog"; +import {MatSnackBarModule} from "@angular/material/snack-bar"; describe('ReportComponent', () => { let component: ReportComponent; @@ -8,7 +12,15 @@ describe('ReportComponent', () => { beforeEach(async(() => { TestBed.configureTestingModule({ - declarations: [ ReportComponent ] + declarations: [ ReportComponent ], + imports: [ + HttpClientModule, + MatDialogModule, + MatSnackBarModule + ], + providers: [ + BackendService + ] }) .compileComponents(); })); diff --git a/src/app/sys-check/report/report.component.ts b/src/app/sys-check/report/report.component.ts index 8e96aadd8f30ebc370bcd5d9bee2678106c8b64b..8e419413f659c5ed415eb42e55fd6170bada1bf7 100644 --- a/src/app/sys-check/report/report.component.ts +++ b/src/app/sys-check/report/report.component.ts @@ -2,10 +2,11 @@ import { BackendService } from '../backend.service'; import { SysCheckDataService } from '../sys-check-data.service'; import { Component, Input } from '@angular/core'; import { SaveReportComponent } from './save-report/save-report.component'; -import { MatDialog, MatSnackBar } from '@angular/material'; import { ReportEntry } from '../sys-check.interfaces'; import { Subscription } from 'rxjs'; import {ServerError} from 'iqb-components'; +import {MatDialog} from "@angular/material/dialog"; +import {MatSnackBar} from "@angular/material/snack-bar"; @Component({ selector: 'iqb-report', @@ -53,33 +54,34 @@ export class ReportComponent { const dialogRef = this.saveDialog.open(SaveReportComponent, { width: '500px', - height: '600px', - data: 'jojo' + height: '600px' }); dialogRef.afterClosed().subscribe(result => { - if (result !== false) { - const reportKey = result.get('key').value as string; - const reportTitle = result.get('title').value as string; - const cd = this.ds.checkConfig$.getValue(); - console.log('result', result); - this.bs.saveReport( - cd.workspaceId, - cd.name, - { - keyPhrase: reportKey, - title: reportTitle, - environment: this.ds.environmentData$.getValue(), - network: this.ds.networkData$.getValue(), - questionnaire: this.ds.questionnaireData$.getValue(), - unit: this.ds.unitData$.getValue() + if (typeof result !== 'undefined') { + if (result !== false) { + const reportKey = result.get('key').value as string; + const reportTitle = result.get('title').value as string; + const cd = this.ds.checkConfig$.getValue(); + console.log('result', result); + this.bs.saveReport( + cd.workspaceId, + cd.name, + { + keyPhrase: reportKey, + title: reportTitle, + environment: this.ds.environmentData$.getValue(), + network: this.ds.networkData$.getValue(), + questionnaire: this.ds.questionnaireData$.getValue(), + unit: this.ds.unitData$.getValue() + } + ).subscribe((result: boolean|ServerError) => { + if (result instanceof ServerError) { + this.snackBar.open('Konnte Bericht nicht speichern.', '', {duration: 3000}); + } else { + this.snackBar.open('Bericht gespeichert.', '', {duration: 3000}); } - ).subscribe((result: boolean|ServerError) => { - if (result instanceof ServerError) { - this.snackBar.open('Konnte Bericht nicht speichern.', '', {duration: 3000}); - } else { - this.snackBar.open('Bericht gespeichert.', '', {duration: 3000}); - } - }); + }); + } } }); } diff --git a/src/app/sys-check/report/save-report/save-report.component.spec.ts b/src/app/sys-check/report/save-report/save-report.component.spec.ts index 0d0a5a6a793ec7eb2b3fa2c4a1ffcdfe9ddeff27..e996a0b2f01cbb15f470a65ace527cd12d45dbea 100644 --- a/src/app/sys-check/report/save-report/save-report.component.spec.ts +++ b/src/app/sys-check/report/save-report/save-report.component.spec.ts @@ -1,13 +1,28 @@ import { SaveReportComponent } from './save-report.component'; import { async, ComponentFixture, TestBed } from '@angular/core/testing'; +import {ReactiveFormsModule} from "@angular/forms"; +import {MatDialog, MatDialogModule} from "@angular/material/dialog"; +import {MatInputModule} from "@angular/material/input"; +import {MatFormFieldModule} from "@angular/material/form-field"; +import {NoopAnimationsModule} from "@angular/platform-browser/animations"; -describe('EmailComponent', () => { +describe('SaveReportComponent', () => { let component: SaveReportComponent; let fixture: ComponentFixture<SaveReportComponent>; beforeEach(async(() => { TestBed.configureTestingModule({ - declarations: [ SaveReportComponent ] + declarations: [ SaveReportComponent ], + imports: [ + MatDialogModule, + ReactiveFormsModule, + MatInputModule, + MatFormFieldModule, + NoopAnimationsModule + ], + providers: [ + MatDialog, + ] }) .compileComponents(); })); diff --git a/src/app/sys-check/report/save-report/save-report.component.ts b/src/app/sys-check/report/save-report/save-report.component.ts index f71a23a655349b2a6789652d15aaea2a6e63cbf1..f5c5f7ed5ef7224ef8de832ed432b1f001a80ff8 100644 --- a/src/app/sys-check/report/save-report/save-report.component.ts +++ b/src/app/sys-check/report/save-report/save-report.component.ts @@ -1,22 +1,15 @@ -import { MAT_DIALOG_DATA } from '@angular/material'; -import { FormBuilder, FormGroup, Validators } from '@angular/forms'; -import { Component, OnInit, Inject } from '@angular/core'; +import { FormControl, FormGroup, Validators} from '@angular/forms'; +import { Component } from '@angular/core'; @Component({ selector: 'app-save-report', templateUrl: './save-report.component.html', styleUrls: ['./save-report.component.css'] }) -export class SaveReportComponent implements OnInit { - savereportform: FormGroup; - constructor(private fb: FormBuilder, - @Inject(MAT_DIALOG_DATA) public data: string) { } - - ngOnInit() { - this.savereportform = this.fb.group({ - title: this.fb.control('', [Validators.required, Validators.minLength(3)]), - key: this.fb.control('', [Validators.required, Validators.minLength(3)]) - }); - } +export class SaveReportComponent { + savereportform = new FormGroup({ + title: new FormControl('', [Validators.required, Validators.minLength(3)]), + key: new FormControl('', [Validators.required, Validators.minLength(3)]) + }); } diff --git a/src/app/sys-check/start.component.css b/src/app/sys-check/start.component.css deleted file mode 100644 index 603396779e9d8d6d9e15900bff48f3e134bd06e3..0000000000000000000000000000000000000000 --- a/src/app/sys-check/start.component.css +++ /dev/null @@ -1,19 +0,0 @@ -.check_title { - font-size: 16pt; - margin-bottom: 0px; - height: 24px - } - -.check_descr { - font-size: 9pt; - margin-top: 8px; - color: lightgray; - height: 24px; - margin-bottom: 18px; - white-space: normal; - line-height: 16px; - } - -.mat-card { - margin: 10px - } diff --git a/src/app/sys-check/start.component.html b/src/app/sys-check/start.component.html deleted file mode 100644 index ca7c04bde32b020add633adf0cfd0dbc78b38d43..0000000000000000000000000000000000000000 --- a/src/app/sys-check/start.component.html +++ /dev/null @@ -1,43 +0,0 @@ -<div class="logo"> - <a [routerLink]="['/']"> - <img src="assets/IQB-LogoA.png" matTooltip="Startseite" alt="IQB-logo"/> - </a> -</div> -<div class="spinner-container" *ngIf="dataLoading"> - <mat-spinner></mat-spinner> -</div> -<div class="page-body"> - <div fxLayout="row" fxLayoutAlign="center start"> - <mat-card fxFlex="0 2 500px"> - <mat-card-title>{{ 'app_title' | customtext:'app_title':cts.updateCount }}: System-Check</mat-card-title> - <mat-card-content> - <p>Hier können Sie ermitteln, ob das Computersystem, das Sie gerade benutzen, für - die hier vorgesehenen Testungen geeignet ist.</p> - <p *ngIf="dataLoading"> - Bitte warten... Konfiguration wird geladen - </p> - <p *ngIf="!dataLoading && (checkConfigList.length === 0)"> - Auf diesem Server ist aktuell kein System-Check verfügbar. - </p> - <p *ngIf="!dataLoading && (checkConfigList.length > 1)"> - Bitte wählen Sie einen Check aus! - </p> - <p *ngIf="!dataLoading && (checkConfigList.length === 1)"> - Bitte klicken Sie auf den Schalter, um den Check zu starten! - </p> - <div fxLayout="column" fxLayoutGap="10px"> - <button mat-raised-button color="primary" (click)="buttonStartCheck(c)" - *ngFor="let c of checkConfigList"> - <div fxLayout="column"> - <p class="check_title">{{c.label}}</p> - <p class="check_descr">{{c.description}}</p> - </div> - </button> - </div> - </mat-card-content> - <mat-card-actions> - <button (click)="goBack()" mat-raised-button color="primary"><i class="material-icons">arrow_back</i> zurück zur Startseite</button> - </mat-card-actions> - </mat-card> - </div> -</div> diff --git a/src/app/sys-check/start.component.ts b/src/app/sys-check/start.component.ts deleted file mode 100644 index 6862c4572474624ef8a74fc552c4f72e30bd118c..0000000000000000000000000000000000000000 --- a/src/app/sys-check/start.component.ts +++ /dev/null @@ -1,46 +0,0 @@ -import { SysCheckDataService } from './sys-check-data.service'; -import { Router, ActivatedRoute } from '@angular/router'; -import { BackendService } from './backend.service'; -import { Component, OnInit, SkipSelf } from '@angular/core'; -import { CheckConfigAbstract } from './sys-check.interfaces'; -import { CustomtextService } from 'iqb-components'; - - - -@Component({ - templateUrl: './start.component.html', - styleUrls: ['./start.component.css'] -}) - -export class StartComponent implements OnInit { - checkConfigList: CheckConfigAbstract[] = []; - public dataLoading = false; - - constructor( - private bs: BackendService, - private ds: SysCheckDataService, - private route: ActivatedRoute, - private router: Router, - @SkipSelf() public cts: CustomtextService) { } - - ngOnInit() { - this.dataLoading = true; - this.bs.getCheckConfigs().subscribe(myConfigs => { - this.checkConfigList = myConfigs; - this.dataLoading = false; - }); - } - - buttonStartCheck(checkConfigAbstract: CheckConfigAbstract) { - - console.log('checkConfigAbstract', checkConfigAbstract); - this.router.navigate( - [`../run/${checkConfigAbstract.workspaceId}/${checkConfigAbstract.name}`], - {relativeTo: this.route} - ); - } - - goBack() { - this.router.navigate(['/']); - } -} diff --git a/src/app/sys-check/syscheck-data.service.spec.ts b/src/app/sys-check/sys-check-data.service.spec.ts similarity index 100% rename from src/app/sys-check/syscheck-data.service.spec.ts rename to src/app/sys-check/sys-check-data.service.spec.ts diff --git a/src/app/sys-check/sys-check-data.service.ts b/src/app/sys-check/sys-check-data.service.ts index 9b8d76e51239d70fde031a9073221ebb8a55e9fe..35cd1ac1361a5b9341717f0804c08362cc641615 100644 --- a/src/app/sys-check/sys-check-data.service.ts +++ b/src/app/sys-check/sys-check-data.service.ts @@ -9,34 +9,7 @@ type Task = 'loadunit' | 'speedtest' | null; }) export class SysCheckDataService { - public checkConfig$ = new BehaviorSubject<CheckConfig>( - { - name: 'Basistest', - label: 'Basistest', - questions: [], - hasUnit: false, - canSave: false, - customTexts: [], - skipNetwork: false, - downloadSpeed : { - min: 1.875e+6, // 15Mbit/s ~> typical dl speed 4G CAT4 - good: 3.75e+6, // 30Mbit/s ~> typical dl speed 4G+ CAT6 - maxDevianceBytesPerSecond: 100000, - maxErrorsPerSequence: 0, - maxSequenceRepetitions: 15, - sequenceSizes: [400000, 800000, 1600000, 3200000] - }, - uploadSpeed : { - min: 250000, // 2Mbit/s - good: 1.25e+6, // 10Mbit/s - maxDevianceBytesPerSecond: 5000, - maxErrorsPerSequence: 0, - maxSequenceRepetitions: 15, - sequenceSizes: [100000, 200000, 400000, 800000] - }, - workspaceId: 0 - } - ); + public checkConfig$ = new BehaviorSubject<CheckConfig>(null); public task$ = new BehaviorSubject<Task>(null); public taskQueue: Task[]; diff --git a/src/app/sys-check/sys-check-routing.module.ts b/src/app/sys-check/sys-check-routing.module.ts index a7ff4fab47cac4484f263c27689fac7ee035a20b..b01691229038e1f25a83dbfe9017e8a5b17ab505 100644 --- a/src/app/sys-check/sys-check-routing.module.ts +++ b/src/app/sys-check/sys-check-routing.module.ts @@ -1,19 +1,10 @@ import { SysCheckComponent } from './sys-check.component'; import { NgModule } from '@angular/core'; import { Routes, RouterModule } from '@angular/router'; -import { StartComponent } from './start.component'; const routes: Routes = [ { - path: '', - redirectTo: 'start' - }, - { - path: 'start', - component: StartComponent - }, - { - path: 'run/:workspace-id/:sys-check-name', + path: ':workspace-id/:sys-check-name', component: SysCheckComponent }]; diff --git a/src/app/sys-check/sys-check.component.html b/src/app/sys-check/sys-check.component.html index 1f86c79bc078cf54b3061de48ef0be36957bc696..e468d098ee33915bf27e0d3816b15cb6a6523b1a 100644 --- a/src/app/sys-check/sys-check.component.html +++ b/src/app/sys-check/sys-check.component.html @@ -1,35 +1,27 @@ -<div class="logo"> - <a [routerLink]="['/']"> - <img src="assets/IQB-LogoA.png" matTooltip="Startseite" alt="iqb-logo"/> - </a> +<div class="page-header"> + <p>System-Check: {{title}}</p> </div> -<div class="pagetitle">System-Check: {{title}}</div> - <div class="page-body"> - <div class="spinner-container-local" *ngIf="dataLoading"> - <mat-spinner></mat-spinner> - </div> <div fxLayout="column" fxLayoutAlign="center stretch" class="cardhost"> <div fxLayout="raw wrap" fxLayoutAlign="center stretch" fxFlex> - <mat-card fxFlex> + <mat-card fxFlex *ngIf="!loading"> <iqb-environment-check></iqb-environment-check> </mat-card> - <mat-card fxFlex="2 0 800px"> - <iqb-network-check [measureNetwork]="checks.network"></iqb-network-check> + <mat-card fxFlex="2 0 800px" *ngIf="networkCheck"> + <iqb-network-check [measureNetwork]="networkCheck"></iqb-network-check> </mat-card> </div> - <div fxLayout="row" fxLayoutAlign="center stretch"> - <mat-card [fxFlex]="(checks.questions) ? '2 0 800px' : ''" *ngIf="checks.unit"> + <div fxLayout="row" fxLayoutAlign="center stretch" *ngIf="unitCheck || questions"> + <mat-card [fxFlex]="(questions) ? '2 0 800px' : ''" *ngIf="unitCheck"> <iqb-unit-check></iqb-unit-check> </mat-card> - <mat-card fxFlex *ngIf="checks.questions"> + <mat-card fxFlex *ngIf="questions"> <iqb-questionnaire></iqb-questionnaire> </mat-card> </div> - <mat-card> - <iqb-report [canSave]="checks.report"></iqb-report> + <mat-card *ngIf="reportEnabled"> + <iqb-report [canSave]="reportEnabled"></iqb-report> </mat-card> </div> - </div> diff --git a/src/app/sys-check/sys-check.component.scss b/src/app/sys-check/sys-check.component.scss index 8c5e8094d2e692970668c9f557164fa2063aad84..6dc3520dd6a8694c5235ec35e1d77ff94f96ffc0 100644 --- a/src/app/sys-check/sys-check.component.scss +++ b/src/app/sys-check/sys-check.component.scss @@ -1,4 +1,4 @@ -::ng-deep .scrollable { +::ng-deep .scrollable { /* TODO ng-deep is deprecated */ overflow: auto; box-sizing: border-box; position: absolute; @@ -16,6 +16,6 @@ mat-card { margin: 10px; } -::ng-deep .mat-card-header-text { +::ng-deep .mat-card-header-text { /* TODO ng-deep is deprecated */ margin-left: 0 !important; } diff --git a/src/app/sys-check/sys-check.component.spec.ts b/src/app/sys-check/sys-check.component.spec.ts index bf1b59b5397ce96affe8187e212b5cfe3388649f..62b6b93b62c67c60b17351eeeb86f2e22b1b133a 100644 --- a/src/app/sys-check/sys-check.component.spec.ts +++ b/src/app/sys-check/sys-check.component.spec.ts @@ -1,14 +1,28 @@ import { async, ComponentFixture, TestBed } from '@angular/core/testing'; import { SysCheckComponent } from './sys-check.component'; +import {HttpClientModule} from "@angular/common/http"; +import {BackendService} from "./backend.service"; +import {AppRoutingModule} from "../app-routing.module"; +import {MatDialogModule} from "@angular/material/dialog"; -describe('RunComponent', () => { +describe('SysCheck.SysCheckComponent', () => { let component: SysCheckComponent; let fixture: ComponentFixture<SysCheckComponent>; beforeEach(async(() => { TestBed.configureTestingModule({ - declarations: [ SysCheckComponent ] + declarations: [ + SysCheckComponent + ], + imports: [ + HttpClientModule, + AppRoutingModule, + MatDialogModule + ], + providers: [ + BackendService + ] }) .compileComponents(); })); diff --git a/src/app/sys-check/sys-check.component.ts b/src/app/sys-check/sys-check.component.ts index 53e0d99b042d051bf83acb4cee8f41bf1ca79554..2c8b26d90bd735a900a0e355607a744f89920d30 100644 --- a/src/app/sys-check/sys-check.component.ts +++ b/src/app/sys-check/sys-check.component.ts @@ -4,39 +4,30 @@ import {Component, OnDestroy, OnInit} from '@angular/core'; import { BackendService } from './backend.service'; import { Subscription } from 'rxjs'; import { CustomtextService } from 'iqb-components'; - - -interface Checks { - environment: boolean; - unit: boolean; - questions: boolean; - network: boolean; - report: boolean; -} +import {MainDataService} from "../maindata.service"; @Component({ - selector: 'app-run', templateUrl: './sys-check.component.html', styleUrls: ['./sys-check.component.scss'] }) + export class SysCheckComponent implements OnInit, OnDestroy { private taskSubscription: Subscription = null; - dataLoading = false; - checks: Checks = { - environment: true, - unit: false, - questions: false, - network: false, - report: true - }; + loading = false; + unitCheck = false; + questions = false; + networkCheck = false; + reportEnabled = false; + isError = false; - title: String = ''; + title = 'Lade - bitte warten'; constructor( private bs: BackendService, private ds: SysCheckDataService, private route: ActivatedRoute, + private mds: MainDataService, private cts: CustomtextService ) { } @@ -46,34 +37,42 @@ export class SysCheckComponent implements OnInit, OnDestroy { const sysCheckName = params.get('sys-check-name'); const workspaceId = parseInt(params.get('workspace-id')); - this.bs.getCheckConfigData(workspaceId, sysCheckName).subscribe(checkConfig => { - this.ds.checkConfig$.next(checkConfig); - - this.title = checkConfig.label; - this.checks.unit = checkConfig.hasUnit; - this.checks.network = !checkConfig.skipNetwork; - this.checks.questions = checkConfig.questions.length > 0; - this.checks.report = checkConfig.canSave; + setTimeout(() => { + this.loading = true; + this.bs.getCheckConfigData(workspaceId, sysCheckName).subscribe(checkConfig => { + this.ds.checkConfig$.next(checkConfig); + if (checkConfig) { + this.title = checkConfig.label; + this.unitCheck = checkConfig.hasUnit; + this.networkCheck = !checkConfig.skipNetwork; + this.questions = checkConfig.questions.length > 0; + this.reportEnabled = checkConfig.canSave; - if (this.checks.unit) { - this.ds.taskQueue.push('loadunit'); - } - if (this.checks.network) { - this.ds.taskQueue.push('speedtest'); - } - if (checkConfig.customTexts.length > 0) { - const myCustomTexts: {[key: string]: string} = {}; - checkConfig.customTexts.forEach(ct => { - myCustomTexts[ct.key] = ct.value; - }); - this.cts.addCustomTexts(myCustomTexts); - } - this.ds.nextTask(); - this.taskSubscription = this.ds.task$.subscribe(task => { - this.dataLoading = (typeof task !== 'undefined') && (this.ds.taskQueue.length > 0); + if (this.unitCheck) { + this.ds.taskQueue.push('loadunit'); + } + if (this.networkCheck) { + this.ds.taskQueue.push('speedtest'); + } + if (checkConfig.customTexts.length > 0) { + const myCustomTexts: {[key: string]: string} = {}; + checkConfig.customTexts.forEach(ct => { + myCustomTexts[ct.key] = ct.value; + }); + this.cts.addCustomTexts(myCustomTexts); + } + this.ds.nextTask(); + this.taskSubscription = this.ds.task$.subscribe(task => { + this.loading = (typeof task !== 'undefined') && (this.ds.taskQueue.length > 0); + }); + this.isError = false; + } else { + this.title = 'Fehler beim Laden der Daten für den System-Check'; + this.loading = false; + this.isError = true; + } }); - - }); + }) }); } diff --git a/src/app/sys-check/sys-check.interfaces.ts b/src/app/sys-check/sys-check.interfaces.ts index 0159a0a4165cc7806f1997276629cfe032da0f55..f20a781c95a2474d85d40b21e34edd568f4a0c5e 100644 --- a/src/app/sys-check/sys-check.interfaces.ts +++ b/src/app/sys-check/sys-check.interfaces.ts @@ -1,10 +1,3 @@ -export interface CheckConfigAbstract { - workspaceId: string; - name: string; - label: string; - description: string; -} - export interface SpeedParameters { min: number; good: number; diff --git a/src/app/sys-check/sys-check.module.ts b/src/app/sys-check/sys-check.module.ts index 3f5e1f0fbd963d149eeb4916b8c58d5d7b3cdc5e..251934545b0e22d8db99c6f0e6db1ef6d9d23b73 100644 --- a/src/app/sys-check/sys-check.module.ts +++ b/src/app/sys-check/sys-check.module.ts @@ -5,12 +5,8 @@ import { NgModule } from '@angular/core'; import { CommonModule } from '@angular/common'; import { SysCheckRoutingModule } from './sys-check-routing.module'; -import { StartComponent } from './start.component'; import { SysCheckComponent } from './sys-check.component'; import { FlexLayoutModule } from '@angular/flex-layout'; -import { MatButtonModule, MatCheckboxModule, MatCardModule, MatStepperModule, - MatIconModule, MatDialogModule, MatFormFieldModule, MatInputModule, MatSelectModule, - MatProgressSpinnerModule, MatSnackBarModule, MatRadioModule } from '@angular/material'; import {MatDividerModule} from '@angular/material/divider'; import {MatListModule} from '@angular/material/list'; import { ReactiveFormsModule } from '@angular/forms'; @@ -26,32 +22,43 @@ import { UnitNaviButtonsComponent } from './unit-check/tc-navi-buttons/unit-navi import { TcSpeedChartComponent } from './network-check/tc-speed-chart.component'; import {MatTooltipModule} from "@angular/material/tooltip"; import {IqbComponentsModule} from "iqb-components"; +import {MatButtonModule} from "@angular/material/button"; +import {MatCardModule} from "@angular/material/card"; +import {MatCheckboxModule} from "@angular/material/checkbox"; +import {MatDialogModule} from "@angular/material/dialog"; +import {MatFormFieldModule} from "@angular/material/form-field"; +import {MatIconModule} from "@angular/material/icon"; +import {MatInputModule} from "@angular/material/input"; +import {MatProgressSpinnerModule} from "@angular/material/progress-spinner"; +import {MatRadioModule} from "@angular/material/radio"; +import {MatSelectModule} from "@angular/material/select"; +import {MatSnackBarModule} from "@angular/material/snack-bar"; +import {MatStepperModule} from "@angular/material/stepper"; @NgModule({ imports: [ CommonModule, - MatCardModule, FlexLayoutModule, + MatButtonModule, + MatCardModule, MatCheckboxModule, + MatDialogModule, + MatDividerModule, MatFormFieldModule, + MatIconModule, MatInputModule, - SysCheckRoutingModule, - MatProgressSpinnerModule, - MatStepperModule, - MatButtonModule, - MatDividerModule, MatListModule, - MatIconModule, - MatSelectModule, + MatProgressSpinnerModule, MatRadioModule, - MatTooltipModule, + MatSelectModule, MatSnackBarModule, - MatDialogModule, + MatStepperModule, + MatTooltipModule, ReactiveFormsModule, + SysCheckRoutingModule, IqbComponentsModule.forChild() ], declarations: [ - StartComponent, SysCheckComponent, EnvironmentCheckComponent, NetworkCheckComponent, @@ -63,9 +70,6 @@ import {IqbComponentsModule} from "iqb-components"; UnitNaviButtonsComponent, TcSpeedChartComponent ], - exports: [ - StartComponent - ], entryComponents: [ SaveReportComponent ], diff --git a/src/app/sys-check/unit-check/unit-check.component.spec.ts b/src/app/sys-check/unit-check/unit-check.component.spec.ts index b666a6cfc00b445d4440fff441cf23c2a7f4013d..de4e5944d647198f4d5865573a4c4f6afd49d240 100644 --- a/src/app/sys-check/unit-check/unit-check.component.spec.ts +++ b/src/app/sys-check/unit-check/unit-check.component.spec.ts @@ -1,6 +1,8 @@ import { async, ComponentFixture, TestBed } from '@angular/core/testing'; import { UnitCheckComponent } from './unit-check.component'; +import {HttpClientModule} from "@angular/common/http"; +import {BackendService} from "../backend.service"; describe('UnitCheckComponent', () => { let component: UnitCheckComponent; @@ -8,7 +10,13 @@ describe('UnitCheckComponent', () => { beforeEach(async(() => { TestBed.configureTestingModule({ - declarations: [ UnitCheckComponent ] + declarations: [ UnitCheckComponent ], + imports: [ + HttpClientModule + ], + providers: [ + BackendService + ] }) .compileComponents(); })); diff --git a/src/app/test-controller/backend.service.spec.ts b/src/app/test-controller/backend.service.spec.ts index c31039d7e5bcc7bc70e7213ce06744a0dc6ed009..ffdc1397ca5ced3a08516d7183bbc820c1001627 100644 --- a/src/app/test-controller/backend.service.spec.ts +++ b/src/app/test-controller/backend.service.spec.ts @@ -1,14 +1,16 @@ import { TestBed, inject } from '@angular/core/testing'; import { BackendService } from './backend.service'; +import {HttpClientModule} from "@angular/common/http"; -describe('BackendService', () => { + +describe('HttpClient testing', () => { beforeEach(() => { TestBed.configureTestingModule({ + imports: [HttpClientModule], providers: [BackendService] }); }); - it('should be created', inject([BackendService], (service: BackendService) => { expect(service).toBeTruthy(); })); diff --git a/src/app/test-controller/backend.service.ts b/src/app/test-controller/backend.service.ts index 67d1863253ac61c7f02a35c282e9a80add026d36..5bc6f8cdf7e0b669072b1eb2eaf3ed4d308ccc63 100644 --- a/src/app/test-controller/backend.service.ts +++ b/src/app/test-controller/backend.service.ts @@ -1,9 +1,9 @@ import { Injectable, Inject } from '@angular/core'; -import { HttpClient, HttpErrorResponse, HttpParams } from '@angular/common/http'; +import { HttpClient, HttpParams } from '@angular/common/http'; import { Observable, of } from 'rxjs'; import { catchError, map } from 'rxjs/operators'; -import { BookletData, UnitData, TaggedString } from './test-controller.interfaces'; -import { ServerError } from 'iqb-components'; +import {UnitData, TaggedString, TestData} from './test-controller.interfaces'; +import {ApiError} from "../app.interfaces"; @Injectable({ @@ -14,45 +14,56 @@ export class BackendService { constructor( @Inject('SERVER_URL') private serverUrl: string, private http: HttpClient - ) { - } - - - saveUnitReview(testId: number, unitName: string, priority: number, categories: string, entry: string) - : Observable<boolean | ServerError> { + ) { } + saveUnitReview(testId: string, unitName: string, priority: number, categories: string, entry: string) + : Observable<boolean> { return this.http - .put<boolean>(this.serverUrl + `test/${testId}/unit/${unitName}/review`, {priority, categories, entry}) - .pipe(catchError(this.handle)); + .put(this.serverUrl + `test/${testId}/unit/${unitName}/review`, {priority, categories, entry}) + .pipe( + map(() => true), + catchError((err: ApiError) => { + console.warn(`saveUnitReview Api-Error: ${err.code} ${err.info} `); + return of(false) + }) + ); } - - saveBookletReview(testId: number, priority: number, categories: string, entry: string): Observable<boolean | ServerError> { - + saveBookletReview(testId: string, priority: number, categories: string, entry: string): Observable<boolean> { return this.http - .put<boolean>(this.serverUrl + `test/${testId}/review`, {priority, categories, entry}) - .pipe(catchError(this.handle)); + .put(this.serverUrl + `test/${testId}/review`, {priority, categories, entry}) + .pipe( + map(() => true), + catchError((err: ApiError) => { + console.warn(`saveBookletReview Api-Error: ${err.code} ${err.info} `); + return of(false) + }) + ); } - - getBookletData(testId: number): Observable<BookletData | ServerError> { - + getTestData(testId: string): Observable<TestData | boolean> { return this.http - .get<BookletData>(this.serverUrl + 'test/' + testId) - .pipe(catchError(this.handle)); + .get<TestData>(this.serverUrl + 'test/' + testId) + .pipe( + catchError((err: ApiError) => { + console.warn(`getTestData Api-Error: ${err.code} ${err.info} `); + return of(false) + }) + ); } - - getUnitData(testId: number, unitid: string): Observable<UnitData | ServerError> { - + getUnitData(testId: string, unitid: string): Observable<UnitData | boolean> { return this.http .get<UnitData>(this.serverUrl + 'test/' + testId + '/unit/' + unitid) - .pipe(catchError(this.handle)); + .pipe( + catchError((err: ApiError) => { + console.warn(`getUnitData Api-Error: ${err.code} ${err.info} `); + return of(false) + }) + ); } - - getResource(testId: number, internalKey: string, resId: string, versionning = false): Observable<TaggedString | ServerError> { - + getResource(testId: string, internalKey: string, resId: string, versionning = false): Observable<TaggedString | number> { return this.http .get( this.serverUrl + `test/${testId}/resource/${resId}`, @@ -62,75 +73,95 @@ export class BackendService { }) .pipe( map(def => <TaggedString>{tag: internalKey, value: def}), - catchError(this.handle) + catchError((err: ApiError) => { + console.warn(`getResource Api-Error: ${err.code} ${err.info} `); + return of(err.code) + }) ); } - - addUnitLog(testId: number, timestamp: number, unitName: string, entry: string): Observable<boolean | ServerError> { - + addUnitLog(testId: string, timestamp: number, unitName: string, entry: string): Observable<boolean> { return this.http - .put<boolean>(this.serverUrl + `test/${testId}/unit/${unitName}/log`, {timestamp, entry}) - .pipe(catchError(this.handle)); + .put(this.serverUrl + `test/${testId}/unit/${unitName}/log`, {timestamp, entry}) + .pipe( + map(() => true), + catchError((err: ApiError) => { + console.warn(`addUnitLog Api-Error: ${err.code} ${err.info} `); + return of(false) + }) + ); } - - addBookletLog(testId: number, timestamp: number, entry: string): Observable<boolean | ServerError> { - + addBookletLog(testId: string, timestamp: number, entry: string): Observable<boolean> { return this.http - .put<boolean>(this.serverUrl + `test/${testId}/log`, {timestamp, entry}) - .pipe(catchError(this.handle)); + .put(this.serverUrl + `test/${testId}/log`, {timestamp, entry}) + .pipe( + map(() => true), + catchError((err: ApiError) => { + console.warn(`addBookletLog Api-Error: ${err.code} ${err.info} `); + return of(false) + }) + ); } - - setUnitState(testId: number, unitName: string, stateKey: string, state: string): Observable<boolean | ServerError> { - + setUnitState(testId: string, unitName: string, stateKey: string, state: string): Observable<boolean> { return this.http - .patch<boolean>(this.serverUrl + `test/${testId}/unit/${unitName}/state`, {key: stateKey, value: state}) - .pipe(catchError(this.handle)); + .patch(this.serverUrl + `test/${testId}/unit/${unitName}/state`, {key: stateKey, value: state}) + .pipe( + map(() => true), + catchError((err: ApiError) => { + console.warn(`setUnitState Api-Error: ${err.code} ${err.info} `); + return of(false) + }) + ); } - - setBookletState(testId: number, stateKey: string, state: string): Observable<boolean | ServerError> { - + setBookletState(testId: string, stateKey: string, state: string): Observable<boolean> { return this.http - .patch<boolean>(this.serverUrl + `test/${testId}/state`, {key: stateKey, value: state}) - .pipe(catchError(this.handle)); + .patch(this.serverUrl + `test/${testId}/state`, {key: stateKey, value: state}) + .pipe( + map(() => true), + catchError((err: ApiError) => { + console.warn(`setBookletState Api-Error: ${err.code} ${err.info} `); + return of(false) + }) + ); } - - newUnitResponse(testId: number, timestamp: number, unitName: string, response: string, responseType: string) - : Observable<boolean | ServerError> { - + newUnitResponse(testId: string, timestamp: number, unitName: string, response: string, responseType: string) + : Observable<boolean> { return this.http - .put<boolean>(this.serverUrl + `test/${testId}/unit/${unitName}/response`, {timestamp, response, responseType}) - .pipe(catchError(this.handle)); + .put(this.serverUrl + `test/${testId}/unit/${unitName}/response`, {timestamp, response, responseType}) + .pipe( + map(() => true), + catchError((err: ApiError) => { + console.warn(`newUnitResponse Api-Error: ${err.code} ${err.info} `); + return of(false) + }) + ); } - - newUnitRestorePoint(testId: number, unitName: string, timestamp: number, restorePoint: string): Observable<boolean | ServerError> { - + newUnitRestorePoint(testId: string, unitName: string, timestamp: number, restorePoint: string): Observable<boolean> { return this.http - .patch<boolean>(this.serverUrl + `test/${testId}/unit/${unitName}/restorepoint`, {timestamp, restorePoint}) - .pipe(catchError(this.handle)); + .patch(this.serverUrl + `test/${testId}/unit/${unitName}/restorepoint`, {timestamp, restorePoint}) + .pipe( + map(() => true), + catchError((err: ApiError) => { + console.warn(`newUnitRestorePoint Api-Error: ${err.code} ${err.info} `); + return of(false) + }) + ); } - - - // 7777777777777777777777777777777777777777777777777777777777777777777777 - handle(errorObj: HttpErrorResponse): Observable<ServerError> { - let myreturn; - if (errorObj.error instanceof ErrorEvent) { - myreturn = new ServerError(500, 'Verbindungsproblem', (<ErrorEvent>errorObj.error).message); - } else { - myreturn = new ServerError(errorObj.status, 'Verbindungsproblem', errorObj.message); - if (errorObj.status === 401) { - myreturn.labelNice = 'Zugriff verweigert - bitte (neu) anmelden!'; - } else if (errorObj.status === 504) { - myreturn.labelNice = 'Achtung: Server meldet Datenbankproblem.'; - } - } - - return of(myreturn); + lockBooklet(testId: string): Observable<boolean> { + return this.http + .patch<boolean>(this.serverUrl + `test/${testId}/lock`, {}) + .pipe( + map(() => true), + catchError((err: ApiError) => { + console.warn(`lockBooklet Api-Error: ${err.code} ${err.info} `); + return of(false) + }) + ); } } diff --git a/src/app/test-controller/review-dialog/review-dialog.component.html b/src/app/test-controller/review-dialog/review-dialog.component.html index 5ad4daf64f07c48a39e7102925479a3829d7ea35..98542936c938c71e4304a55d56a7f32795dd3376 100644 --- a/src/app/test-controller/review-dialog/review-dialog.component.html +++ b/src/app/test-controller/review-dialog/review-dialog.component.html @@ -23,6 +23,9 @@ <mat-checkbox formControlName="content">Inhaltlich</mat-checkbox> <mat-checkbox formControlName="design">Gestaltung</mat-checkbox> </div> + <mat-form-field> + <input matInput formControlName="sender" placeholder="Mein Name"> + </mat-form-field> <mat-form-field> <textarea matInput formControlName="entry" placeholder="Kommentar" rows="15"></textarea> <mat-icon matSuffix>mode_edit</mat-icon> @@ -30,7 +33,7 @@ </mat-dialog-content> <mat-dialog-actions> - <button mat-raised-button color="primary" type="submit" [mat-dialog-close]="reviewform" [disabled]="reviewform.invalid">Speichern</button> + <button mat-raised-button color="primary" type="submit" [mat-dialog-close]="reviewform.value" [disabled]="reviewform.invalid">Speichern</button> <button mat-raised-button [mat-dialog-close]="false">Abbrechen</button> </mat-dialog-actions> </form> diff --git a/src/app/test-controller/review-dialog/review-dialog.component.spec.ts b/src/app/test-controller/review-dialog/review-dialog.component.spec.ts index 20d64fe21de760ffa96b000cd099cea74c34ab20..6946039c52f5eddeacf513b92575838147cc88eb 100644 --- a/src/app/test-controller/review-dialog/review-dialog.component.spec.ts +++ b/src/app/test-controller/review-dialog/review-dialog.component.spec.ts @@ -1,14 +1,44 @@ import { async, ComponentFixture, TestBed } from '@angular/core/testing'; import { ReviewDialogComponent } from './review-dialog.component'; +import {ReactiveFormsModule} from "@angular/forms"; +import {MAT_DIALOG_DATA, MatDialog, MatDialogModule} from "@angular/material/dialog"; +import {MatRadioModule} from "@angular/material/radio"; +import {MatCheckboxModule} from "@angular/material/checkbox"; +import {MatInputModule} from "@angular/material/input"; +import {MatFormFieldModule} from "@angular/material/form-field"; +import {ReviewDialogData} from "../test-controller.interfaces"; +import {MatIconModule} from "@angular/material/icon"; +import {NoopAnimationsModule} from "@angular/platform-browser/animations"; describe('ReviewDialogComponent', () => { let component: ReviewDialogComponent; let fixture: ComponentFixture<ReviewDialogComponent>; + const matDialogDataStub = <ReviewDialogData> { + loginname: 'loginname', + bookletname: 'bookletname', + unitDbKey: 'unitDbKey', + unitTitle: 'unitTitle' + }; + beforeEach(async(() => { TestBed.configureTestingModule({ - declarations: [ ReviewDialogComponent ] + declarations: [ ReviewDialogComponent ], + imports: [ + MatDialogModule, + ReactiveFormsModule, + MatRadioModule, + MatInputModule, + MatFormFieldModule, + MatIconModule, + MatCheckboxModule, + NoopAnimationsModule + ], + providers: [ + MatDialog, + { provide: MAT_DIALOG_DATA, useValue: matDialogDataStub } + ] }) .compileComponents(); })); diff --git a/src/app/test-controller/review-dialog/review-dialog.component.ts b/src/app/test-controller/review-dialog/review-dialog.component.ts index 5729f5528f18d0d4538fae3d25ab6fe13b38a913..4e76ad06a114a780c08006e8078164379a23ecba 100644 --- a/src/app/test-controller/review-dialog/review-dialog.component.ts +++ b/src/app/test-controller/review-dialog/review-dialog.component.ts @@ -1,27 +1,25 @@ -import { FormGroup, FormBuilder, Validators } from '@angular/forms'; -import { MAT_DIALOG_DATA } from '@angular/material'; -import { Component, OnInit, Inject } from '@angular/core'; +import {FormGroup, Validators, FormControl} from '@angular/forms'; +import { MAT_DIALOG_DATA } from '@angular/material/dialog'; +import { Component, Inject } from '@angular/core'; +import {ReviewDialogData} from "../test-controller.interfaces"; @Component({ templateUrl: './review-dialog.component.html' }) -export class ReviewDialogComponent implements OnInit { - reviewform: FormGroup; +export class ReviewDialogComponent { + reviewform = new FormGroup({ + target: new FormControl ('b', Validators.required), + priority: new FormControl('', Validators.required), + tech: new FormControl(''), + content: new FormControl(''), + design: new FormControl(''), + entry: new FormControl('', Validators.required), + sender: new FormControl(ReviewDialogComponent.oldName) + }); + static oldName = ''; constructor( - private fb: FormBuilder, - @Inject(MAT_DIALOG_DATA) public data: any) { } - - ngOnInit() { - this.reviewform = this.fb.group({ - target: this.fb.control('b', Validators.required), - priority: this.fb.control('', Validators.required), - tech: this.fb.control(''), - content: this.fb.control(''), - design: this.fb.control(''), - entry: this.fb.control('', Validators.required) - }); - } + @Inject(MAT_DIALOG_DATA) public data: ReviewDialogData) { } getCategories(): string { let myreturn = ''; diff --git a/src/app/test-controller/start-lock-input/start-lock-input.component.html b/src/app/test-controller/start-lock-input/start-lock-input.component.html index f2b53dca8f993d86052842409839849e698079dc..3678754c112181263ad13b9d7d9843a234024c9f 100644 --- a/src/app/test-controller/start-lock-input/start-lock-input.component.html +++ b/src/app/test-controller/start-lock-input/start-lock-input.component.html @@ -1,18 +1,19 @@ -<form [formGroup]="startkeyform" fxLayout="column"> +<form #matform [formGroup]="startkeyform" fxLayout="column"> <h1 mat-dialog-title>{{ data.title }}</h1> <mat-dialog-content> <p>{{ data.prompt }}</p> <mat-form-field *ngFor="let c of data.codes" fxLayout="column"> <p>{{ c.prompt }}</p> - <input matInput [formControlName]="c.testletId" [(ngModel)]="c.value" (keyup.enter)="close()"> + <input matInput [formControlName]="c.testletId" (keyup.enter)="matform.submit()"> </mat-form-field> </mat-dialog-content> <mat-dialog-actions> - <button mat-raised-button #okButton color="primary" - [disabled]="startkeyform.invalid" - type="submit" [mat-dialog-close]="data.codes">Weiter</button> + <button mat-raised-button color="primary" + [disabled]="!startkeyform.valid" + type="submit" + [mat-dialog-close]="startkeyform.value">Weiter</button> <button mat-raised-button [mat-dialog-close]="false">Abbrechen</button> </mat-dialog-actions> </form> diff --git a/src/app/test-controller/start-lock-input/start-lock-input.component.spec.ts b/src/app/test-controller/start-lock-input/start-lock-input.component.spec.ts index fba2a3158e984085aeca83242af163d1f1aca2aa..af6a17e5e687dae7fea85c7c3812316de6def0ee 100644 --- a/src/app/test-controller/start-lock-input/start-lock-input.component.spec.ts +++ b/src/app/test-controller/start-lock-input/start-lock-input.component.spec.ts @@ -1,14 +1,53 @@ import { async, ComponentFixture, TestBed } from '@angular/core/testing'; import { StartLockInputComponent } from './start-lock-input.component'; +import {ReactiveFormsModule} from "@angular/forms"; +import {MAT_DIALOG_DATA, MatDialog, MatDialogModule, MatDialogRef} from "@angular/material/dialog"; +import {StartLockData} from "../test-controller.interfaces"; +import {MatInputModule} from "@angular/material/input"; +import {MatFormFieldModule} from "@angular/material/form-field"; +import {MatIconModule} from "@angular/material/icon"; +import {NoopAnimationsModule} from "@angular/platform-browser/animations"; describe('StartLockInputComponent', () => { let component: StartLockInputComponent; let fixture: ComponentFixture<StartLockInputComponent>; beforeEach(async(() => { + const matDialogRefStub = {}; + const matDialogDataStub = <StartLockData>{ + title: 'title', + prompt: 'prompt', + codes: [ + { + testletId: 'testletA', + prompt: 'promptA', + code: 'codeA', + value: 'valueA' + }, + { + testletId: 'testletB', + prompt: 'promptB', + code: 'codeB', + value: 'valueB' + } + ] + }; TestBed.configureTestingModule({ - declarations: [ StartLockInputComponent ] + declarations: [ StartLockInputComponent ], + imports: [ + MatDialogModule, + ReactiveFormsModule, + MatInputModule, + MatFormFieldModule, + MatIconModule, + NoopAnimationsModule + ], + providers: [ + MatDialog, + { provide: MatDialogRef, useValue: matDialogRefStub }, + { provide: MAT_DIALOG_DATA, useValue: matDialogDataStub } + ] }) .compileComponents(); })); diff --git a/src/app/test-controller/start-lock-input/start-lock-input.component.ts b/src/app/test-controller/start-lock-input/start-lock-input.component.ts index 07a01da18a7500a0745b27c17023e79c14a17772..31afbaa14d97358a737fbc73ed49e43f3916bffa 100644 --- a/src/app/test-controller/start-lock-input/start-lock-input.component.ts +++ b/src/app/test-controller/start-lock-input/start-lock-input.component.ts @@ -1,29 +1,22 @@ -import { MAT_DIALOG_DATA, MatDialogRef } from '@angular/material'; -import { FormBuilder, FormGroup, Validators } from '@angular/forms'; -import { Component, OnInit, Inject } from '@angular/core'; -import { StartLockData } from '../test-controller.interfaces'; - +import {Component, Inject} from '@angular/core'; +import {MAT_DIALOG_DATA} from '@angular/material/dialog'; +import {FormControl, FormGroup, Validators} from "@angular/forms"; +import {StartLockData} from "../test-controller.interfaces"; @Component({ templateUrl: './start-lock-input.component.html', styleUrls: ['./start-lock-input.component.css'] }) -export class StartLockInputComponent implements OnInit { +export class StartLockInputComponent { startkeyform: FormGroup; - constructor(private fb: FormBuilder, - private dialogRef: MatDialogRef<StartLockInputComponent>, - @Inject(MAT_DIALOG_DATA) public data: StartLockData) { } + constructor( + @Inject(MAT_DIALOG_DATA) public data: StartLockData) { - ngOnInit() { - const controlsConfig = {}; + const myFormControls = {}; this.data.codes.forEach(c => { - controlsConfig[c.testletId] = this.fb.control('', [Validators.required, Validators.minLength(3)]); + myFormControls[c.testletId] = new FormControl(c.value, [Validators.required, Validators.minLength(3)]); }); - this.startkeyform = this.fb.group(controlsConfig); - } - - close() { - this.dialogRef.close(this.data.codes); + this.startkeyform = new FormGroup(myFormControls); } } diff --git a/src/app/test-controller/test-controller-route-guards.spec.ts b/src/app/test-controller/test-controller-route-guards.spec.ts new file mode 100644 index 0000000000000000000000000000000000000000..7a2ca3d7c49595f6b1598d72269d5cd042c285e0 --- /dev/null +++ b/src/app/test-controller/test-controller-route-guards.spec.ts @@ -0,0 +1,23 @@ +import { TestBed } from '@angular/core/testing'; + +import { TestControllerDeactivateGuard } from './test-controller-route-guards'; +import {AppRoutingModule} from "../app-routing.module"; +import {TestControllerService} from "./test-controller.service"; +import {BackendService} from "./backend.service"; +import {HttpClientModule} from "@angular/common/http"; + +describe('TestControllerDeactivateGuard', () => { + let guard: TestControllerDeactivateGuard; + + beforeEach(() => { + TestBed.configureTestingModule({ + providers: [TestControllerService, BackendService], + imports: [HttpClientModule, AppRoutingModule] + }); + guard = TestBed.inject(TestControllerDeactivateGuard); + }); + + it('should be created', () => { + expect(guard).toBeTruthy(); + }); +}); diff --git a/src/app/test-controller/test-controller-route-guards.ts b/src/app/test-controller/test-controller-route-guards.ts new file mode 100644 index 0000000000000000000000000000000000000000..0ecfdd23baa443a6337ab582f6c92513933c069a --- /dev/null +++ b/src/app/test-controller/test-controller-route-guards.ts @@ -0,0 +1,35 @@ +import {Injectable} from '@angular/core'; +import {ActivatedRouteSnapshot, CanDeactivate, RouterStateSnapshot} from '@angular/router'; +import {Observable} from 'rxjs'; +import {TestControllerComponent} from "./test-controller.component"; +import {TestStatus, UnitNavigationTarget} from "./test-controller.interfaces"; +import {TestControllerService} from "./test-controller.service"; + +@Injectable({ + providedIn: 'root' +}) +export class TestControllerDeactivateGuard implements CanDeactivate<TestControllerComponent> { + constructor( + private tcs: TestControllerService, + ) { + } + + canDeactivate( + component: TestControllerComponent, + currentRoute: ActivatedRouteSnapshot, + state: RouterStateSnapshot): Observable<boolean> | Promise<boolean> | boolean { + + if (this.tcs.testMode.saveResponses) { + const testStatus: TestStatus = this.tcs.testStatus$.getValue(); + if ((testStatus !== TestStatus.ERROR) && (testStatus !== TestStatus.TERMINATED)) { + this.tcs.setUnitNavigationRequest(UnitNavigationTarget.MENU); + } else { + localStorage.removeItem(TestControllerComponent.localStorageTestKey); + return true; + } + } else { + localStorage.removeItem(TestControllerComponent.localStorageTestKey); + return true; + } + } +} diff --git a/src/app/test-controller/test-controller-routing.module.ts b/src/app/test-controller/test-controller-routing.module.ts index 9033e3a260b89bf526aa489b801b625332d7613b..25a74a43659d661756911ffb0b8df70a1b8e6059 100644 --- a/src/app/test-controller/test-controller-routing.module.ts +++ b/src/app/test-controller/test-controller-routing.module.ts @@ -1,16 +1,23 @@ -import { UnitActivateGuard, UnitDeactivateGuard } from './unithost/unit-routing-guards'; +import { UnitActivateGuard, UnitDeactivateGuard } from './unithost/unit-route-guards'; import { UnithostComponent } from './unithost/unithost.component'; import { TestControllerComponent } from './test-controller.component'; import { NgModule } from '@angular/core'; import { Routes, RouterModule } from '@angular/router'; +import {TestStatusComponent} from "./test-status/test-status.component"; +import {TestControllerDeactivateGuard} from "./test-controller-route-guards"; const routes: Routes = [ { - path: '', + path: ':t', component: TestControllerComponent, + canDeactivate: [TestControllerDeactivateGuard], children: [ + { + path: '', + component: TestStatusComponent + }, { path: 'u/:u', component: UnithostComponent, diff --git a/src/app/test-controller/test-controller.classes.ts b/src/app/test-controller/test-controller.classes.ts index b4a49f6a090c133797b61cfb43369beaefe2d313..f827f6e34ae1794a2b4ab09cfe9aeafdc7627d24 100644 --- a/src/app/test-controller/test-controller.classes.ts +++ b/src/app/test-controller/test-controller.classes.ts @@ -134,6 +134,7 @@ export class UnitControllerData { unitDef: UnitDef = null; codeRequiringTestlets: Testlet[] = []; maxTimerRequiringTestlet: Testlet = null; + testletLabel = ''; constructor(unitDef: UnitDef) { this.unitDef = unitDef; } @@ -167,12 +168,12 @@ export class Testlet extends TestletContentElement { // ..................................................................... // first looking for the unit, then on the way back adding restrictions - getUnitAt(sequenceId: number): UnitControllerData { + getUnitAt(sequenceId: number, isEntryPoint = true): UnitControllerData { let myreturn: UnitControllerData = null; for (const tce of this.children) { if (tce instanceof Testlet) { const localTestlet = tce as Testlet; - myreturn = localTestlet.getUnitAt(sequenceId); + myreturn = localTestlet.getUnitAt(sequenceId, false); if (myreturn !== null) { break; } @@ -190,6 +191,13 @@ export class Testlet extends TestletContentElement { if (this.maxTimeLeft > 0) { myreturn.maxTimerRequiringTestlet = this; } + if (!isEntryPoint) { + const label = this.title.trim(); + if (label) { + myreturn.testletLabel = label + } + + } } return myreturn; } @@ -398,7 +406,7 @@ export class EnvironmentData { const deviceInfo = window.navigator.userAgent; // browser + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - // tslint:disable-next-line:max-line-length + // @ts-ignore const regex = /(MSIE|Trident|(?!Gecko.+)Firefox|(?!AppleWebKit.+Chrome.+)Safari(?!.+Edge)|(?!AppleWebKit.+)Chrome(?!.+Edge)|(?!AppleWebKit.+Chrome.+Safari.+)Edge|AppleWebKit(?!.+Chrome|.+Safari)|Gecko(?!.+Firefox))(?: |\/)([\d\.apre]+)/; // credit due to: https://gist.github.com/ticky/3909462#gistcomment-2245669 const deviceInfoSplits = regex.exec(deviceInfo); @@ -462,11 +470,6 @@ export class MaxTimerData { } } -// 7777777777777777777777777777777777777777777777777777777777777 -export class BookletConfig { - showMainNaviButtons: boolean; -} - // 7777777777777777777777777777777777777777777777777777777777777 export class UnitDefLoadQueue { private unitsToLoad: {[sequenceId: string]: string} = {}; diff --git a/src/app/test-controller/test-controller.component.css b/src/app/test-controller/test-controller.component.css index 7ca99a39815da9cd1b2117e5e16b480f96d311b9..bf56d7b1cbb07681e6384fd112dccf1122468808 100644 --- a/src/app/test-controller/test-controller.component.css +++ b/src/app/test-controller/test-controller.component.css @@ -3,6 +3,7 @@ right: 50px; top: 300px; left: 50px; + z-index: 999; } .timer { @@ -18,7 +19,7 @@ } .tcSidenav > p, .tcSidenav > button { - margin: 15px 10px 0px 10px; + margin: 15px 10px 0 10px; } .errorMsg, .statusMsg { @@ -34,7 +35,7 @@ overflow-x: auto; position: absolute; width: 100%; - top: 65px; + top: var(--tc-topmargin); bottom: 0; } diff --git a/src/app/test-controller/test-controller.component.html b/src/app/test-controller/test-controller.component.html index c06731e685a5a427f73af6923b3b4392de0a316e..86a71bc56a6a104e6e3d0d782f834e7d3a70adf2 100644 --- a/src/app/test-controller/test-controller.component.html +++ b/src/app/test-controller/test-controller.component.html @@ -3,43 +3,49 @@ <img src="assets/IQB-LogoA.png" matTooltip="Startseite"/> </a> <div fxLayout="row" fxLayoutAlign="end center"> - <p class="timer" *ngIf="tcs.mode !== 'hot'">{{ timerValue?.timeLeftString }}</p> - <button mat-fab [disabled]="!(tcs.unitPrevEnabled$ | async)" *ngIf="tcs.navArrows" color="accent" - (click)="tcs.setUnitNavigationRequest('#previous')" matTooltip="Zurück" fxFlex="none"> + <p class="timer" *ngIf="tcs.testMode.showTimeLeft">{{ timerValue?.timeLeftString }}</p> + <button mat-fab [disabled]="!tcs.unitPrevEnabled" *ngIf="(tcs.bookletConfig.unit_navibuttons !== 'OFF') && ((tcs.testStatus$ | async) === tcs.testStatusEnum.RUNNING)" color="accent" + (click)="tcs.setUnitNavigationRequest(unitNavigationTarget.PREVIOUS)" matTooltip="Zurück" fxFlex="none"> <i class="material-icons">chevron_left</i> </button> - <div *ngIf="tcs.navButtons" fxLayout="row wrap" fxLayoutAlign="start center" fxFlex="0 3 100%"> - <div *ngFor="let u of (tcs.unitListForNaviButtons$ | async)"> + <div *ngIf="(tcs.bookletConfig.unit_navibuttons === 'FULL') && ((tcs.testStatus$ | async) === tcs.testStatusEnum.RUNNING)" fxLayout="row wrap" fxLayoutAlign="start center" fxFlex="0 3 100%"> + <div *ngFor="let u of tcs.unitListForNaviButtons"> <div fxLayout="column" fxLayoutAlign="start center"> - <button (click)="gotoUnit(u.sequenceId)" class="unit-button" [disabled]="u.disabled">{{ u.label }}</button> + <button (click)="tcs.setUnitNavigationRequest(u.sequenceId.toString())" class="unit-button" [disabled]="u.disabled">{{ u.shortLabel }}</button> <span class="current-unit-dot" *ngIf="u.isCurrent"></span> <span class="notcurrent-unit-dot" *ngIf="!u.isCurrent"></span> </div> </div> </div> - <button mat-fab [disabled]="!(tcs.unitNextEnabled$ | async)" *ngIf="tcs.navArrows" color="accent" - (click)="tcs.setUnitNavigationRequest('#next')" matTooltip="Weiter" fxFlex="none"> + <button mat-fab [disabled]="!tcs.unitNextEnabled" *ngIf="(tcs.bookletConfig.unit_navibuttons !== 'OFF') && ((tcs.testStatus$ | async) === tcs.testStatusEnum.RUNNING)" color="accent" + (click)="tcs.setUnitNavigationRequest(unitNavigationTarget.NEXT)" matTooltip="Weiter" fxFlex="none"> <i class="material-icons">chevron_right</i> </button> - <button mat-button (click)="showReviewDialog()" *ngIf="tcs.mode === 'run-review'" matTooltip="Kommentar senden" fxFlex="none"> + <button mat-button (click)="showReviewDialog()" *ngIf="tcs.testMode.canReview" matTooltip="Kommentar senden" fxFlex="none"> <mat-icon>rate_review</mat-icon> </button> - <button mat-button (click)="tcs.setUnitNavigationRequest('#end')" *ngIf="tcs.mode !== 'hot'" - matTooltip="Zur Testheft-Auswahl zurückkehren" fxFlex="none"> - <mat-icon>exit_to_app</mat-icon> + <button mat-button (click)="tcs.setUnitNavigationRequest(unitNavigationTarget.MENU)" + *ngIf="(tcs.bookletConfig.unit_menu !== 'OFF') || tcs.testMode.showUnitMenu" + matTooltip="Zur Aufgabenliste" fxFlex="none"> + <mat-icon>menu</mat-icon> </button> + <!-- + <button mat-button (click)="topMargin()" fxFlex="none" style="z-index: 888;"> + <mat-icon>vertical_align_top</mat-icon> + </button> + <button mat-button (click)="bottomMargin()" fxFlex="none" style="z-index: 888;"> + <mat-icon>vertical_align_bottom</mat-icon> + </button> + --> </div> </div> -<div class="spinner-container" *ngIf="tcs.dataLoading"> - <mat-spinner></mat-spinner> -</div> -<mat-card *ngIf="showProgress" class="progress-bar"> - <mat-card-content fxLaxout="column"> +<mat-card *ngIf="(tcs.testStatus$ | async) === tcs.testStatusEnum.WAITING_LOAD_COMPLETE" class="progress-bar"> + <mat-card-content fxLayout="column"> <h2>Lade Aufgaben... bitte warten</h2> <mat-progress-bar color="primary" mode="determinate" - [value]="progressValue"> + [value]="loadProgressValue"> </mat-progress-bar> </mat-card-content> </mat-card> diff --git a/src/app/test-controller/test-controller.component.spec.ts b/src/app/test-controller/test-controller.component.spec.ts index 3e6a50821c26734391eff008ce7dda24c72c9fc9..583065711c48bc00b09eaa5ddb098dc3cfe40380 100644 --- a/src/app/test-controller/test-controller.component.spec.ts +++ b/src/app/test-controller/test-controller.component.spec.ts @@ -1,6 +1,11 @@ import { async, ComponentFixture, TestBed } from '@angular/core/testing'; import { TestControllerComponent } from './test-controller.component'; +import {HttpClientModule} from "@angular/common/http"; +import {BackendService} from "./backend.service"; +import {MatDialogModule} from "@angular/material/dialog"; +import {MatSnackBarModule} from "@angular/material/snack-bar"; +import {AppRoutingModule} from "../app-routing.module"; describe('TestControllerComponent', () => { let component: TestControllerComponent; @@ -8,7 +13,16 @@ describe('TestControllerComponent', () => { beforeEach(async(() => { TestBed.configureTestingModule({ - declarations: [ TestControllerComponent ] + declarations: [ TestControllerComponent ], + imports: [ + HttpClientModule, + MatDialogModule, + MatSnackBarModule, + AppRoutingModule + ], + providers: [ + BackendService + ] }) .compileComponents(); })); diff --git a/src/app/test-controller/test-controller.component.ts b/src/app/test-controller/test-controller.component.ts index e156b6e79fa0090d2cfc0cc77f1b2fe3f84dd519..9b55b35112a76000303096081300b7a96a843685 100644 --- a/src/app/test-controller/test-controller.component.ts +++ b/src/app/test-controller/test-controller.component.ts @@ -1,49 +1,66 @@ -import { ReviewDialogComponent } from './review-dialog/review-dialog.component'; -import { MatDialog, MatSnackBar } from '@angular/material'; -import { FormGroup } from '@angular/forms'; -import { Router } from '@angular/router'; -import { MainDataService } from '../maindata.service'; -import { BackendService } from './backend.service'; - -import { TestControllerService } from './test-controller.service'; -import { Component, OnInit, OnDestroy, Inject } from '@angular/core'; -import { UnitDef, Testlet, EnvironmentData, MaxTimerData } from './test-controller.classes'; -import { LastStateKey, LogEntryKey, BookletData, UnitData, MaxTimerDataType, TaggedString } from './test-controller.interfaces'; -import { Subscription, Observable, of, from } from 'rxjs'; -import { switchMap, concatMap } from 'rxjs/operators'; -import { CustomtextService, ServerError } from 'iqb-components'; -import { appconfig } from '../app.config'; +import {ReviewDialogComponent} from './review-dialog/review-dialog.component'; +import {ActivatedRoute, Router} from '@angular/router'; +import {MainDataService} from '../maindata.service'; +import {BackendService} from './backend.service'; + +import {TestControllerService} from './test-controller.service'; +import {Component, Inject, OnDestroy, OnInit} from '@angular/core'; +import {EnvironmentData, MaxTimerData, Testlet, UnitDef} from './test-controller.classes'; +import { + LastStateKey, + LogEntryKey, + MaxTimerDataType, + ReviewDialogData, + TaggedString, + TestData, + TestStatus, + UnitData, + UnitNavigationTarget +} from './test-controller.interfaces'; +import {from, Observable, of, Subscription, throwError} from 'rxjs'; +import {concatMap, map, switchMap} from 'rxjs/operators'; +import {CustomtextService} from 'iqb-components'; +import {MatDialog} from "@angular/material/dialog"; +import {MatSnackBar} from '@angular/material/snack-bar'; +import {BookletConfig} from "../config/booklet-config"; +import { TestMode } from '../config/test-mode'; + @Component({ templateUrl: './test-controller.component.html', styleUrls: ['./test-controller.component.css'] }) export class TestControllerComponent implements OnInit, OnDestroy { - private loginDataSubscription: Subscription = null; - private navigationRequestSubsription: Subscription = null; + static localStorageTestKey = 'iqb-tc-t'; + private errorReportingSubscription: Subscription = null; + private testStatusSubscription: Subscription = null; + private routingSubscription: Subscription = null; private maxTimerSubscription: Subscription = null; - private unitLoadQueueSubscription1: Subscription = null; - private unitLoadQueueSubscription2: Subscription = null; - - public showProgress = true; + private unitLoadXmlSubscription: Subscription = null; + private unitLoadBlobSubscription: Subscription = null; private lastUnitSequenceId = 0; + public loadProgressValue = 0; private lastTestletIndex = 0; private timerValue: MaxTimerData = null; private timerRunning = false; private allUnitIds: string[] = []; - private progressValue = 0; private loadedUnitCount = 0; private unitLoadQueue: TaggedString[] = []; + unitNavigationTarget = UnitNavigationTarget; + isTopMargin = true; + isBottomMargin = true; constructor ( @Inject('APP_VERSION') public appVersion: string, + @Inject('IS_PRODUCTION_MODE') public isProductionMode, private mds: MainDataService, public tcs: TestControllerService, private bs: BackendService, private reviewDialog: MatDialog, private snackBar: MatSnackBar, private router: Router, + private route: ActivatedRoute, private cts: CustomtextService ) { } @@ -128,9 +145,8 @@ export class TestControllerComponent implements OnInit, OnDestroy { this.lastTestletIndex += 1; } let testletLabel: string = childElements[childIndex].getAttribute('label'); - if ((typeof testletLabel !== 'undefined') && (testletLabel !== null)) { - testletLabel = testletId; - } + testletLabel = testletLabel ? testletLabel.trim() : ''; + console.log('+ >' + testletLabel + '<'); this.addTestletContentFromBookletXml(targetTestlet.addTestlet(testletId, testletLabel), childElements[childIndex]); } @@ -141,7 +157,7 @@ export class TestControllerComponent implements OnInit, OnDestroy { // '''''''''''''''''''''''''''''''''''''''''''''''''''' // private: reading booklet from xml // '''''''''''''''''''''''''''''''''''''''''''''''''''' - private getBookletFromXml(xmlString: string): Testlet { + private getBookletFromXml(xmlString: string, loginMode: string): Testlet { let rootTestlet: Testlet = null; try { @@ -174,74 +190,12 @@ export class TestControllerComponent implements OnInit, OnDestroy { const bookletConfigElements = oDOM.documentElement.getElementsByTagName('BookletConfig'); + this.tcs.bookletConfig = new BookletConfig(); + this.tcs.bookletConfig.setFromKeyValuePairs(MainDataService.getTestConfig()); if (bookletConfigElements.length > 0) { - const bookletConfigs = TestControllerComponent.getChildElements(bookletConfigElements[0]); - for (let childIndex = 0; childIndex < bookletConfigs.length; childIndex++) { - const configParameter = bookletConfigs[childIndex].getAttribute('parameter'); - // const configValue = bookletConfigs[childIndex].textContent; - - switch (bookletConfigs[childIndex].nodeName) { - // ---------------------- - case 'NavPolicy': - if (configParameter) { - if (configParameter.toUpperCase() === 'NextOnlyIfPresentationComplete'.toUpperCase()) { - this.tcs.navPolicyNextOnlyIfPresentationComplete = true; - } - } - break; - // ---------------------- - case 'NavButtons': - if (configParameter) { - switch (configParameter.toUpperCase()) { - case 'ON': - this.tcs.navButtons = true; - this.tcs.navArrows = true; - break; - case 'OFF': - this.tcs.navButtons = false; - this.tcs.navArrows = false; - break; - case 'ARROWSONLY': // default - this.tcs.navButtons = false; - this.tcs.navArrows = true; - break; - default: - console.log('unknown booklet configParameter NavButtons "' + configParameter + '"'); - break; - } - } - break; - // ---------------------- - case 'PageNavBar': - if (configParameter) { - if (configParameter.toUpperCase() === 'OFF') { - this.tcs.pageNav = false; - } - } - break; - // ---------------------- - case 'Logging': - if (configParameter) { - if (configParameter.toUpperCase() === 'OFF') { - this.tcs.logging = false; - } - } - break; - // ---------------------- - case 'Loading': - if (configParameter) { - if (configParameter.toUpperCase() === 'EAGER') { - this.tcs.lazyloading = false; - } - } - break; - // ---------------------- - default: - console.log('unknown booklet config "' + bookletConfigs[childIndex].nodeName + '"'); - break; - } - } + this.tcs.bookletConfig.setFromXml(bookletConfigElements[0]); } + this.tcs.testMode = new TestMode(loginMode); // recursive call through all testlets this.lastUnitSequenceId = 1; @@ -260,52 +214,21 @@ export class TestControllerComponent implements OnInit, OnDestroy { return rootTestlet; } - // '''''''''''''''''''''''''''''''''''''''''''''''''''' - // private: get player if not already available - // '''''''''''''''''''''''''''''''''''''''''''''''''''' - private loadPlayerOk(playerId: string): Observable<boolean> { - if (this.tcs.hasPlayer(playerId)) { - return of(true); - } else { - // to avoid multiple calls before returning: - this.tcs.addPlayer(playerId, ''); - return this.bs.getResource(this.tcs.bookletDbId, '', this.tcs.normaliseId(playerId, 'html'), true) - .pipe( - switchMap(myData => { - if (myData instanceof ServerError) { - console.log('## problem getting player "' + playerId + '"'); - return of(false); - } else { - const player = myData as TaggedString; - if (player.value.length > 0) { - this.tcs.addPlayer(playerId, player.value); - return of(true); - } else { - console.log('## size of player "' + playerId + '" = 0'); - return of(false); - } - } - })); - } - } - private incrementProgressValueBy1() { this.loadedUnitCount += 1; - this.progressValue = this.loadedUnitCount * 100 / this.lastUnitSequenceId; + this.loadProgressValue = this.loadedUnitCount * 100 / this.lastUnitSequenceId; } // '''''''''''''''''''''''''''''''''''''''''''''''''''' // private: read unitdata // '''''''''''''''''''''''''''''''''''''''''''''''''''' - private loadUnitOk (myUnit: UnitDef, sequenceId: number): Observable<boolean> { + private loadUnitOk (myUnit: UnitDef, sequenceId: number): Observable<number> { myUnit.setCanEnter('n', 'Fehler beim Laden'); - return this.bs.getUnitData(this.mds.getBookletDbId(), myUnit.id) + return this.bs.getUnitData(this.tcs.testId, myUnit.id) .pipe( switchMap(myData => { - if (myData instanceof ServerError) { - const e = myData as ServerError; - console.log('error getting unit "' + myUnit.id + '": ' + e.code.toString() + ' - ' + e.labelNice); - return of(false); + if (myData === false) { + return throwError(`error requesting unit ${this.tcs.testId}/${myUnit.id}`); } else { const myUnitData = myData as UnitData; if (myUnitData.restorepoint) { @@ -337,35 +260,42 @@ export class TestControllerComponent implements OnInit, OnDestroy { } } } catch (error) { - console.log('error parsing xml for unit "' + myUnit.id + '": ' + error.toString()); - playerId = null; - definitionRef = ''; + return throwError(`error parsing unit def ${this.tcs.testId}/${myUnit.id} (${error.toString()})`); } - this.incrementProgressValueBy1(); if (playerId) { myUnit.playerId = playerId; + if (definitionRef.length > 0) { + this.unitLoadQueue.push(<TaggedString>{ + tag: sequenceId.toString(), + value: definitionRef + }); + } + myUnit.setCanEnter('y', ''); - return this.loadPlayerOk(playerId).pipe( - switchMap(ok => { - if (ok && definitionRef.length > 0) { - const newUnditDef: TaggedString = { - tag: sequenceId.toString(), - value: definitionRef - }; - this.unitLoadQueue.push(newUnditDef); - myUnit.setCanEnter('y', ''); - return of(true); - } else { - if (ok) { - myUnit.setCanEnter('y', ''); - } - return of(ok); - } - })); + if (this.tcs.hasPlayer(playerId)) { + return of(sequenceId) + } else { + // to avoid multiple calls before returning: + this.tcs.addPlayer(playerId, ''); + return this.bs.getResource(this.tcs.testId, '', this.tcs.normaliseId(playerId, 'html'), true) + .pipe( + switchMap(myData => { + if (typeof myData === 'number') { + return throwError(`error getting player "${playerId}"`); + } else { + const player = myData as TaggedString; + if (player.value.length > 0) { + this.tcs.addPlayer(playerId, player.value); + return of(sequenceId); + } else { + return throwError(`error getting player "${playerId}" (size = 0)`); + } + } + })); + } } else { - console.log('error getting unit "' + myUnit.id + '": no player'); - return of(false); + return throwError(`player def missing for unit ${this.tcs.testId}/${myUnit.id}`); } } }) @@ -375,223 +305,201 @@ export class TestControllerComponent implements OnInit, OnDestroy { // ##################################################################################### // ##################################################################################### ngOnInit() { - this.router.navigateByUrl('/t'); - - this.maxTimerSubscription = this.tcs.maxTimeTimer$.subscribe(maxTimerData => { - if (maxTimerData.type === MaxTimerDataType.STARTED) { - this.snackBar.open(this.cts.getCustomText('booklet_msgTimerStarted') + maxTimerData.timeLeftMinString, '', {duration: 3000}); - this.timerValue = maxTimerData; - } else if (maxTimerData.type === MaxTimerDataType.ENDED) { - this.snackBar.open(this.cts.getCustomText('booklet_msgTimeOver'), '', {duration: 3000}); - this.tcs.rootTestlet.setTimeLeftNull(maxTimerData.testletId); - this.tcs.LastMaxTimerState[maxTimerData.testletId] = 0; - this.tcs.setBookletState(LastStateKey.MAXTIMELEFT, JSON.stringify(this.tcs.LastMaxTimerState)); - this.timerRunning = false; - this.timerValue = null; - if (this.tcs.mode !== 'run-review') { - this.tcs.setUnitNavigationRequest('#next'); - } - } else if (maxTimerData.type === MaxTimerDataType.CANCELLED) { - this.snackBar.open(this.cts.getCustomText('booklet_msgTimerCancelled'), '', {duration: 3000}); - this.tcs.rootTestlet.setTimeLeftNull(maxTimerData.testletId); - this.tcs.LastMaxTimerState[maxTimerData.testletId] = 0; - this.tcs.setBookletState(LastStateKey.MAXTIMELEFT, JSON.stringify(this.tcs.LastMaxTimerState)); - this.timerValue = null; - } else { - this.timerValue = maxTimerData; - if ((maxTimerData.timeLeftSeconds % 15) === 0) { - this.tcs.LastMaxTimerState[maxTimerData.testletId] = Math.round(maxTimerData.timeLeftSeconds / 60); - this.tcs.setBookletState(LastStateKey.MAXTIMELEFT, JSON.stringify(this.tcs.LastMaxTimerState)); - } - if ((maxTimerData.timeLeftSeconds / 60) === 5) { - this.snackBar.open(this.cts.getCustomText('booklet_msgSoonTimeOver5Minutes'), '', {duration: 3000}); - } else if ((maxTimerData.timeLeftSeconds / 60) === 1) { - this.snackBar.open(this.cts.getCustomText('booklet_msgSoonTimeOver1Minute'), '', {duration: 3000}); - } + setTimeout(() => { + this.mds.progressVisualEnabled = false; + + if (this.isProductionMode && this.tcs.testMode.saveResponses) { + this.mds.errorReportingSilent = true; } - }); - - // ========================================================== - // navigation between units and end booklet - this.navigationRequestSubsription = this.tcs.navigationRequest$.subscribe((navString: string) => { - if (this.tcs.rootTestlet === null) { - this.snackBar.open('Kein Testheft verfügbar.', '', {duration: 3000}); - } else { - if (!navString) { - navString = '#next'; + this.errorReportingSubscription = this.mds.appError$.subscribe(e => { + if (this.isProductionMode && this.tcs.testMode.saveResponses) { + console.error(e.label + " / " + e.description); } - switch (navString) { - case '#next': - if (this.tcs.rootTestlet) { - let startWith = this.tcs.currentUnitSequenceId; - if (startWith < this.tcs.minUnitSequenceId) { - startWith = this.tcs.minUnitSequenceId - 1; - } - const nextUnitSequenceId = this.tcs.rootTestlet.getNextUnlockedUnitSequenceId(startWith); - if (nextUnitSequenceId > 0) { - this.router.navigateByUrl('/t/u/' + (nextUnitSequenceId).toString()); - } - } - break; - case '#previous': - if (this.tcs.rootTestlet) { - this.router.navigateByUrl('/t/u/' + (this.tcs.currentUnitSequenceId - 1).toString()); - } - break; - case '#first': - if (this.tcs.rootTestlet) { - this.router.navigateByUrl('/t/u/' + this.tcs.minUnitSequenceId.toString()); - } - break; - case '#last': - if (this.tcs.rootTestlet) { - this.router.navigateByUrl('/t/u/' + this.tcs.maxUnitSequenceId.toString()); - } - break; - case '#end': - this.mds.endBooklet(); + this.tcs.testStatus$.next(TestStatus.ERROR); + }); + this.testStatusSubscription = this.tcs.testStatus$.subscribe(ts => { + switch (ts) { + case TestStatus.ERROR: + this.loadProgressValue = 0; + this.tcs.setUnitNavigationRequest(UnitNavigationTarget.ERROR); break; - - default: - if (this.tcs.rootTestlet) { - this.router.navigateByUrl('/t/u/' + navString); - } + case TestStatus.PAUSED: + this.tcs.setUnitNavigationRequest(UnitNavigationTarget.PAUSE); break; } - } - }); - - - // ========================================================== - // loading booklet data and all unit content - // navigation to first unit - this.loginDataSubscription = this.mds.loginData$.subscribe(loginData => { - this.tcs.resetDataStore(); - if ((loginData.personToken.length > 0) && (loginData.testId > 0)) { - const envData = new EnvironmentData(this.appVersion); - - // we have to provide bookletDbId (testId) here manually, because this.tcs.bookletDbId is set after bs.getBookletData is resolved - // TODO instead, prove if this.tcs.bookletDbId could be set here without side effects, which would be a more consistent solution - this.tcs.addBookletLog(LogEntryKey.BOOKLETLOADSTART, JSON.stringify(envData), this.mds.getBookletDbId()); - - this.tcs.mode = loginData.mode; - this.tcs.loginname = loginData.name; - - this.tcs.dataLoading = true; - this.bs.getBookletData(this.mds.getBookletDbId()).subscribe(myData => { - if (myData instanceof ServerError) { - const e = myData as ServerError; - this.mds.globalErrorMsg$.next(e); - this.mds.addCustomtextsFromDefList(appconfig.customtextsBooklet); - this.tcs.dataLoading = false; - } else { - const bookletData = myData as BookletData; - console.log('#2'); + }); - if (bookletData.locked) { - console.log('loading failed'); - this.mds.globalErrorMsg$.next(new ServerError(0, 'Das Testheft ist für die Bearbeitung gesperrt.', '')); - this.tcs.resetDataStore(); + this.routingSubscription = this.route.params.subscribe(params => { + console.log(this.tcs.testStatus$.getValue()); + if (this.tcs.testStatus$.getValue() !== TestStatus.ERROR) { + this.tcs.testId = params['t']; + localStorage.setItem(TestControllerComponent.localStorageTestKey, params['t']); + + this.unsubscribeTestSubscriptions(); + + this.maxTimerSubscription = this.tcs.maxTimeTimer$.subscribe(maxTimerData => { + if (maxTimerData.type === MaxTimerDataType.STARTED) { + this.snackBar.open(this.cts.getCustomText('booklet_msgTimerStarted') + maxTimerData.timeLeftMinString, '', {duration: 3000}); + this.timerValue = maxTimerData; + } else if (maxTimerData.type === MaxTimerDataType.ENDED) { + this.snackBar.open(this.cts.getCustomText('booklet_msgTimeOver'), '', {duration: 3000}); + this.tcs.rootTestlet.setTimeLeftNull(maxTimerData.testletId); + this.tcs.LastMaxTimerState[maxTimerData.testletId] = 0; + this.tcs.setBookletState(LastStateKey.MAXTIMELEFT, JSON.stringify(this.tcs.LastMaxTimerState)); + this.timerRunning = false; + this.timerValue = null; + if (this.tcs.testMode.forceTimeRestrictions) { + this.tcs.setUnitNavigationRequest(UnitNavigationTarget.NEXT); + } + } else if (maxTimerData.type === MaxTimerDataType.CANCELLED) { + this.snackBar.open(this.cts.getCustomText('booklet_msgTimerCancelled'), '', {duration: 3000}); + this.tcs.rootTestlet.setTimeLeftNull(maxTimerData.testletId); + this.tcs.LastMaxTimerState[maxTimerData.testletId] = 0; + this.tcs.setBookletState(LastStateKey.MAXTIMELEFT, JSON.stringify(this.tcs.LastMaxTimerState)); + this.timerValue = null; } else { + this.timerValue = maxTimerData; + if ((maxTimerData.timeLeftSeconds % 15) === 0) { + this.tcs.LastMaxTimerState[maxTimerData.testletId] = Math.round(maxTimerData.timeLeftSeconds / 60); + this.tcs.setBookletState(LastStateKey.MAXTIMELEFT, JSON.stringify(this.tcs.LastMaxTimerState)); + } + if ((maxTimerData.timeLeftSeconds / 60) === 5) { + this.snackBar.open(this.cts.getCustomText('booklet_msgSoonTimeOver5Minutes'), '', {duration: 3000}); + } else if ((maxTimerData.timeLeftSeconds / 60) === 1) { + this.snackBar.open(this.cts.getCustomText('booklet_msgSoonTimeOver1Minute'), '', {duration: 3000}); + } + } + }); + + this.tcs.resetDataStore(); + const envData = new EnvironmentData(this.appVersion); + + this.tcs.addBookletLog(LogEntryKey.BOOKLETLOADSTART, JSON.stringify(envData)); + this.tcs.testStatus$.next(TestStatus.WAITING_LOAD_COMPLETE); + this.loadProgressValue = 0; + this.tcs.loadComplete = false; + + this.bs.getTestData(this.tcs.testId).subscribe(testDataUntyped => { + if (testDataUntyped === false) { + this.mds.appError$.next({ + label: "Konnte Testinformation nicht laden", + description: "TestController.Component: getTestData()", + category: "PROBLEM" + }); + } else { + const testData = testDataUntyped as TestData; + let navTarget = 1; - if (bookletData.laststate !== null) { - if (bookletData.laststate.hasOwnProperty(LastStateKey.LASTUNIT)) { - const navTargetTemp = Number(bookletData.laststate[LastStateKey.LASTUNIT]); + if (testData.laststate !== null) { + if (testData.laststate.hasOwnProperty(LastStateKey.LASTUNIT)) { + const navTargetTemp = Number(testData.laststate[LastStateKey.LASTUNIT]); if (!isNaN(navTargetTemp)) { navTarget = navTargetTemp; } } - if (bookletData.laststate.hasOwnProperty(LastStateKey.MAXTIMELEFT) && (loginData.mode === 'hot')) { - this.tcs.LastMaxTimerState = JSON.parse(bookletData.laststate[LastStateKey.MAXTIMELEFT]); + if (testData.laststate.hasOwnProperty(LastStateKey.MAXTIMELEFT) && (this.tcs.testMode.saveResponses)) { + this.tcs.LastMaxTimerState = JSON.parse(testData.laststate[LastStateKey.MAXTIMELEFT]); } } - this.tcs.rootTestlet = this.getBookletFromXml(bookletData.xml); + this.tcs.rootTestlet = this.getBookletFromXml(testData.xml, testData.mode); + + document.documentElement.style.setProperty('--tc-unithost-bottommargin', this.tcs.bookletConfig.page_navibuttons === 'SEPARATE_BOTTOM' ? '45px' : '0'); + document.documentElement.style.setProperty('--tc-unithost-topmargin', this.tcs.bookletConfig.unit_title === 'ON' ? '40px' : '0'); + document.documentElement.style.setProperty('--tc-topmargin', this.tcs.bookletConfig.unit_screenheader === 'OFF' ? '0' : '65px'); if (this.tcs.rootTestlet === null) { - console.log('rootTestlet = null'); - this.mds.globalErrorMsg$.next(new ServerError(0, 'Error Parsing Booklet Xml', '')); - this.tcs.dataLoading = false; + this.mds.appError$.next({ + label: "Problem beim Laden der Testinformation", + description: "TestController.Component: getBookletFromXml(testData.xml)", + category: "PROBLEM" + }); } else { - this.mds.globalErrorMsg$.next(null); this.tcs.maxUnitSequenceId = this.lastUnitSequenceId - 1; - this.showProgress = true; this.loadedUnitCount = 0; const sequArray = []; for (let i = 1; i < this.tcs.maxUnitSequenceId + 1; i++) { sequArray.push(i); } - this.unitLoadQueueSubscription1 = from(sequArray).pipe( + + this.unitLoadXmlSubscription = from(sequArray).pipe( concatMap(uSequ => { const ud = this.tcs.rootTestlet.getUnitAt(uSequ); return this.loadUnitOk(ud.unitDef, uSequ); }) - ).subscribe(ok => { - if (!ok) { - console.log('unit load problem from loadUnitOk'); - } - }, - err => console.error('unit load error from loadUnitOk: ' + err), - () => { - - // ===================== - this.tcs.bookletDbId = loginData.testId; - this.tcs.rootTestlet.lockUnitsIfTimeLeftNull(); - this.tcs.updateMinMaxUnitSequenceId(navTarget); - this.loadedUnitCount = 0; - - // ===================== - this.unitLoadQueueSubscription2 = from(this.unitLoadQueue).pipe( - concatMap(queueEntry => { - const unitSequ = Number(queueEntry.tag); - if (!this.tcs.lazyloading) { - this.incrementProgressValueBy1(); - } - // avoid to load unit def if not necessary - if (unitSequ < this.tcs.minUnitSequenceId) { - return of({tag: unitSequ.toString(), value: ''}); - } else { - return this.bs.getResource(this.mds.getBookletDbId(), queueEntry.tag, queueEntry.value); - } - }) - ).subscribe( - def => { - if (def instanceof ServerError) { - console.log('getting unit data failed ' + def.labelNice + '/' + def.labelSystem); - } else { - const udef = def as TaggedString; - this.tcs.addUnitDefinition(Number(udef.tag), udef.value); - } - }, - err => console.error('unit load error: ' + err), - () => { // complete - this.tcs.addBookletLog(LogEntryKey.BOOKLETLOADCOMPLETE); - this.tcs.bookletLoadComplete = true; - if (!this.tcs.lazyloading) { - this.showProgress = false; - this.tcs.dataLoading = false; - this.tcs.setUnitNavigationRequest(navTarget.toString()); - } + ).subscribe(() => { + this.incrementProgressValueBy1(); + }, + errorMessage => { + this.mds.appError$.next({ + label: "Problem beim Laden der Testinformation", + description: errorMessage, + category: "PROBLEM" + }); + }, + () => { + this.tcs.rootTestlet.lockUnitsIfTimeLeftNull(); + this.tcs.updateMinMaxUnitSequenceId(navTarget); + this.loadedUnitCount = 0; + + this.unitLoadBlobSubscription = from(this.unitLoadQueue).pipe( + concatMap(queueEntry => { + const unitSequ = Number(queueEntry.tag); + if (this.tcs.bookletConfig.loading_mode === "EAGER") { + this.incrementProgressValueBy1(); + } + // avoid to load unit def if not necessary + if (unitSequ < this.tcs.minUnitSequenceId) { + return of(<TaggedString>{tag: unitSequ.toString(), value: ''}); + } else { + return this.bs.getResource(this.tcs.testId, queueEntry.tag, queueEntry.value).pipe( + map(response => { + if (typeof response === 'number') { + return throwError(`error loading voud ${this.tcs.testId} / ${queueEntry.tag} / ${queueEntry.value}: status ${response}`) + } else { + return response + } + }) + ); + } + }) + ).subscribe( + (def: TaggedString) => { + this.tcs.addUnitDefinition(Number(def.tag), def.value); + }, + errorMessage => { + this.mds.appError$.next({ + label: "Problem beim Laden der Testinformation", + description: errorMessage, + category: "PROBLEM" + }); + }, + () => { // complete + this.tcs.addBookletLog(LogEntryKey.BOOKLETLOADCOMPLETE); + this.loadProgressValue = 100; + + this.tcs.loadComplete = true; + if (this.tcs.bookletConfig.loading_mode === "EAGER") { + this.tcs.setUnitNavigationRequest(navTarget.toString()); + this.tcs.testStatus$.next(TestStatus.RUNNING); } - ); - - if (this.tcs.lazyloading) { - this.showProgress = false; - this.tcs.dataLoading = false; - this.tcs.setUnitNavigationRequest(navTarget.toString()); } + ); - } // complete + if (this.tcs.bookletConfig.loading_mode === "LAZY") { + this.tcs.setUnitNavigationRequest(navTarget.toString()); + this.tcs.testStatus$.next(TestStatus.RUNNING); + } + + } // complete ); } } - } - }); - } else { - this.router.navigateByUrl('/'); - } - }); + }); // getTestData + } + }) // routingSubscription + }) // setTimeOut } @@ -600,10 +508,11 @@ export class TestControllerComponent implements OnInit, OnDestroy { if (this.tcs.rootTestlet === null) { this.snackBar.open('Kein Testheft verfügbar.', '', {duration: 3000}); } else { + const authData = MainDataService.getAuthData(); const dialogRef = this.reviewDialog.open(ReviewDialogComponent, { width: '700px', - data: { - loginname: this.tcs.loginname, + data: <ReviewDialogData>{ + loginname: authData.displayName, bookletname: this.tcs.rootTestlet.title, unitTitle: this.tcs.currentUnitTitle, unitDbKey: this.tcs.currentUnitDbKey @@ -613,32 +522,30 @@ export class TestControllerComponent implements OnInit, OnDestroy { dialogRef.afterClosed().subscribe(result => { if (typeof result !== 'undefined') { if (result !== false) { - const targetSelection = (<FormGroup>result).get('target').value; + const targetSelection = result['target']; if (targetSelection === 'u') { this.bs.saveUnitReview( - this.mds.getBookletDbId(), - this.tcs.currentUnitDbKey, - (<FormGroup>result).get('priority').value, - dialogRef.componentInstance.getCategories(), - (<FormGroup>result).get('entry').value - ).subscribe(myData => { - if (myData instanceof ServerError) { - this.snackBar.open('Konnte Kommentar nicht speichern (' + - myData.code.toString() + ': ' + myData.labelNice, '', {duration: 3000}); + this.tcs.testId, + this.tcs.currentUnitDbKey, + result['priority'], + dialogRef.componentInstance.getCategories(), + result['sender'] ? result['sender'] + ': ' + result['entry'] : result['entry'] + ).subscribe(ok => { + if (!ok) { + this.snackBar.open('Konnte Kommentar nicht speichern', '', {duration: 3000}); } else { this.snackBar.open('Kommentar gespeichert', '', {duration: 1000}); } }); } else { this.bs.saveBookletReview( - this.mds.getBookletDbId(), - (<FormGroup>result).get('priority').value, + this.tcs.testId, + result['priority'], dialogRef.componentInstance.getCategories(), - (<FormGroup>result).get('entry').value - ).subscribe(myData => { - if (myData instanceof ServerError) { - this.snackBar.open('Konnte Kommentar nicht speichern (' + myData.code.toString() - + ': ' + myData.labelNice, '', {duration: 3000}); + result['sender'] ? result['sender'] + ': ' + result['entry'] : result['entry'] + ).subscribe(ok => { + if (!ok) { + this.snackBar.open('Konnte Kommentar nicht speichern', '', {duration: 3000}); } else { this.snackBar.open('Kommentar gespeichert', '', {duration: 1000}); } @@ -650,27 +557,43 @@ export class TestControllerComponent implements OnInit, OnDestroy { } } - // ##################################################################################### - gotoUnit(newSequenceId: number) { - this.tcs.setUnitNavigationRequest(newSequenceId.toString()); + private unsubscribeTestSubscriptions() { + if (this.maxTimerSubscription !== null) { + this.maxTimerSubscription.unsubscribe(); + this.maxTimerSubscription = null + } + if (this.unitLoadXmlSubscription !== null) { + this.unitLoadXmlSubscription.unsubscribe(); + this.unitLoadXmlSubscription = null + } + if (this.unitLoadBlobSubscription !== null) { + this.unitLoadBlobSubscription.unsubscribe(); + this.unitLoadBlobSubscription = null + } + } + + topMargin() { + this.isTopMargin = !this.isTopMargin; + } + + bottomMargin() { + this.isBottomMargin = !this.isBottomMargin; + } // % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % ngOnDestroy() { - if (this.loginDataSubscription !== null) { - this.loginDataSubscription.unsubscribe(); - } - if (this.navigationRequestSubsription !== null) { - this.navigationRequestSubsription.unsubscribe(); - } - if (this.maxTimerSubscription !== null) { - this.maxTimerSubscription.unsubscribe(); + if (this.routingSubscription !== null) { + this.routingSubscription.unsubscribe(); } - if (this.unitLoadQueueSubscription1 !== null) { - this.unitLoadQueueSubscription1.unsubscribe(); + if (this.errorReportingSubscription !== null) { + this.errorReportingSubscription.unsubscribe(); } - if (this.unitLoadQueueSubscription2 !== null) { - this.unitLoadQueueSubscription2.unsubscribe(); + if (this.testStatusSubscription !== null) { + this.testStatusSubscription.unsubscribe(); } + this.unsubscribeTestSubscriptions(); + this.mds.progressVisualEnabled = true; + this.mds.errorReportingSilent = false; } } diff --git a/src/app/test-controller/test-controller.interfaces.ts b/src/app/test-controller/test-controller.interfaces.ts index 18809f46f56c6490d3d8bb9c7795bf6850f84233..4297d25c016e331925a9f56b3db2bbd7cc2861d8 100644 --- a/src/app/test-controller/test-controller.interfaces.ts +++ b/src/app/test-controller/test-controller.interfaces.ts @@ -34,18 +34,36 @@ export interface KeyValuePair { [K: string]: string; } -export interface BookletData { - xml: string; - locked: boolean; - laststate: KeyValuePair[]; -} - export interface UnitData { xml: string; restorepoint: string; laststate: KeyValuePair[]; } +export interface TestData { + xml: string; + mode: string; + laststate: KeyValuePair[]; +} + +export enum TestStatus { + RUNNING = "RUNNING", + WAITING_LOAD_COMPLETE = "WAITING_LOAD_COMPLETE", + TERMINATED = "TERMINATED", + PAUSED = "PAUSED", + WAITING_LOAD_START = "WAITING_LOAD_START", + ERROR = "ERROR" +} + +export interface UnitMenuButtonData { + sequenceId: number; + label: string; + isCurrent: boolean; + isDisabled: boolean; + testletLabel: string; + testletMarker: string +} + // for testcontroller service ++++++++++++++++++++++++++++++++++++++++ export interface BookletStateEntry { bookletDbId: number; @@ -94,7 +112,9 @@ export enum MaxTimerDataType { export interface UnitNaviButtonData { sequenceId: number; disabled: boolean; - label: string; + shortLabel: string; + longLabel: string; + testletLabel: string; isCurrent: boolean; } @@ -105,3 +125,30 @@ export interface PageData { type: '#next' | '#previous' | '#goto'; disabled: boolean; } + +export interface ReviewDialogData { + loginname: string; + bookletname: string; + unitDbKey: string; + unitTitle: string; +} + +export enum NoUnitFlag { + END = "end", + ERROR = "error" +} + +export interface KeyValuePairNumber { + [K: string]: number; +} + +export enum UnitNavigationTarget { + NEXT = "#next", + ERROR = "#error", + PREVIOUS = "#previous", + FIRST = "#first", + LAST = "#last", + END = "#end", + MENU = "#menu", + PAUSE = "#pause" +} diff --git a/src/app/test-controller/test-controller.module.spec.ts b/src/app/test-controller/test-controller.module.spec.ts new file mode 100644 index 0000000000000000000000000000000000000000..ba8159bd39c55e9130e733a267a436ffcf4ec334 --- /dev/null +++ b/src/app/test-controller/test-controller.module.spec.ts @@ -0,0 +1,13 @@ +import {TestControllerModule} from "./test-controller.module"; + +describe('TestControllerModule', () => { + let testControllerModule: TestControllerModule; + + beforeEach(() => { + testControllerModule = new TestControllerModule(); + }); + + it('should create an instance', () => { + expect(testControllerModule).toBeTruthy(); + }); +}); diff --git a/src/app/test-controller/test-controller.module.ts b/src/app/test-controller/test-controller.module.ts index 7deb84e54b55c2a4011b6363076ff3d0c4a8d0c9..2f87d927c14ce1da21127d0e60cddea47c02e196 100644 --- a/src/app/test-controller/test-controller.module.ts +++ b/src/app/test-controller/test-controller.module.ts @@ -6,16 +6,28 @@ import { CommonModule } from '@angular/common'; import { TestControllerRoutingModule } from './test-controller-routing.module'; import { UnithostComponent } from './unithost/unithost.component'; -import { MatProgressSpinnerModule, MatIconModule, MatMenuModule, MatTooltipModule, MatButtonModule, - MatDialogModule, MatSnackBarModule, MatCheckboxModule, MatRadioModule, MatFormFieldModule, MatInputModule, - MatToolbarModule, MatProgressBarModule, MatCardModule } from '@angular/material'; import { TestControllerComponent } from './test-controller.component'; import { ResizeIFrameChildDirective } from './resize-IFrameChild/resize-IFrameChild.directive'; -import { unitRoutingGuards } from './unithost/unit-routing-guards'; +import { unitRouteGuards } from './unithost/unit-route-guards'; import { FlexLayoutModule } from '@angular/flex-layout'; import { ReviewDialogComponent } from './review-dialog/review-dialog.component'; import { ReactiveFormsModule } from '@angular/forms'; import { StartLockInputComponent } from './start-lock-input/start-lock-input.component'; +import {MatProgressSpinnerModule} from "@angular/material/progress-spinner"; +import { MatTooltipModule } from '@angular/material/tooltip'; +import {MatSnackBarModule} from "@angular/material/snack-bar"; +import {MatCheckboxModule} from "@angular/material/checkbox"; +import { MatRadioModule } from '@angular/material/radio'; +import {MatCardModule} from "@angular/material/card"; +import {MatDialogModule} from "@angular/material/dialog"; +import {MatProgressBarModule} from "@angular/material/progress-bar"; +import {MatInputModule} from "@angular/material/input"; +import {MatFormFieldModule} from "@angular/material/form-field"; +import {MatMenuModule} from "@angular/material/menu"; +import {MatButtonModule} from "@angular/material/button"; +import {MatToolbarModule} from "@angular/material/toolbar"; +import {MatIconModule} from "@angular/material/icon"; +import { TestStatusComponent } from './test-status/test-status.component'; @NgModule({ @@ -45,14 +57,15 @@ import { StartLockInputComponent } from './start-lock-input/start-lock-input.com TestControllerComponent, ResizeIFrameChildDirective, ReviewDialogComponent, - StartLockInputComponent + StartLockInputComponent, + TestStatusComponent ], entryComponents: [ ReviewDialogComponent, StartLockInputComponent ], providers: [ - unitRoutingGuards + unitRouteGuards ], exports: [ TestControllerComponent diff --git a/src/app/test-controller/test-controller.service.spec.ts b/src/app/test-controller/test-controller.service.spec.ts index 41e4140e053fc585c77eab4cbc9fb98aa8dddfed..ae136e0d4a810504eb2d3899d1e05b64f69103c5 100644 --- a/src/app/test-controller/test-controller.service.spec.ts +++ b/src/app/test-controller/test-controller.service.spec.ts @@ -1,11 +1,21 @@ import { TestBed, inject } from '@angular/core/testing'; import { TestControllerService } from './test-controller.service'; +import {HttpClientModule} from "@angular/common/http"; +import {BackendService} from "./backend.service"; +import {AppRoutingModule} from "../app-routing.module"; describe('TestControllerService', () => { beforeEach(() => { TestBed.configureTestingModule({ - providers: [TestControllerService] + providers: [ + TestControllerService, + BackendService + ], + imports: [ + HttpClientModule, + AppRoutingModule + ] }); }); diff --git a/src/app/test-controller/test-controller.service.ts b/src/app/test-controller/test-controller.service.ts index 59639912e79d8bde94af88dc118ad546010302cd..f19b3e5cb6f0b5421b0763db836ff484ed8f61b6 100644 --- a/src/app/test-controller/test-controller.service.ts +++ b/src/app/test-controller/test-controller.service.ts @@ -1,33 +1,38 @@ -import { debounceTime, takeUntil, map } from 'rxjs/operators'; -import { BehaviorSubject, Subject, Subscription, interval, timer } from 'rxjs'; -import { Injectable } from '@angular/core'; -import { Testlet, BookletConfig, MaxTimerData } from './test-controller.classes'; -import { LastStateKey, LogEntryKey, UnitRestorePointData, UnitResponseData, - MaxTimerDataType, UnitNaviButtonData } from './test-controller.interfaces'; -import { BackendService } from './backend.service'; -import { KeyValuePairNumber } from '../app.interfaces'; -import { ServerError } from 'iqb-components'; +import {debounceTime, map, takeUntil} from 'rxjs/operators'; +import {BehaviorSubject, interval, Subject, Subscription, timer} from 'rxjs'; +import {Injectable} from '@angular/core'; +import {MaxTimerData, Testlet} from './test-controller.classes'; +import { + KeyValuePairNumber, + LastStateKey, + LogEntryKey, + MaxTimerDataType, + TestStatus, + UnitNaviButtonData, + UnitNavigationTarget, + UnitResponseData, + UnitRestorePointData +} from './test-controller.interfaces'; +import {BackendService} from './backend.service'; +import {Router} from "@angular/router"; +import {TestMode} from "../config/test-mode"; +import { BookletConfig } from '../config/booklet-config'; @Injectable({ providedIn: 'root' }) export class TestControllerService { - private standardBookletConfig: BookletConfig = { - showMainNaviButtons: true - }; - public bookletConfig$ = new BehaviorSubject<BookletConfig>(this.standardBookletConfig); + public testId = ''; + public testStatus$ = new BehaviorSubject<TestStatus>(TestStatus.WAITING_LOAD_START); + public testStatusEnum = TestStatus; + public loadComplete = false; + + public testMode = new TestMode(); + public bookletConfig = new BookletConfig(); public rootTestlet: Testlet = null; - public bookletDbId = 0; public maxUnitSequenceId = 0; public minUnitSequenceId = 0; - public loginname = ''; - public mode = ''; - public logging = true; - public lazyloading = true; - public dataLoading = false; - public bookletLoadComplete = false; - public navigationRequest$ = new Subject<string>(); public maxTimeTimer$ = new Subject<MaxTimerData>(); public currentMaxTimerTestletId = ''; private maxTimeIntervalSubscription: Subscription = null; @@ -35,21 +40,17 @@ export class TestControllerService { private _currentUnitSequenceId: number; public currentUnitDbKey = ''; public currentUnitTitle = ''; - public unitPrevEnabled$ = new BehaviorSubject<boolean>(false); - public unitNextEnabled$ = new BehaviorSubject<boolean>(false); - public unitListForNaviButtons$ = new BehaviorSubject<UnitNaviButtonData[]>([]); - public navPolicyNextOnlyIfPresentationComplete = false; - public navButtons = false; - public navArrows = true; - public pageNav = true; + public unitPrevEnabled = false; + public unitNextEnabled = false; + public unitListForNaviButtons: UnitNaviButtonData[] = []; public get currentUnitSequenceId(): number { return this._currentUnitSequenceId; } public set currentUnitSequenceId(v: number) { - this.unitPrevEnabled$.next(v > this.minUnitSequenceId); - this.unitNextEnabled$.next(v < this.maxUnitSequenceId); - if (this.rootTestlet && this.navButtons) { + this.unitPrevEnabled = v > this.minUnitSequenceId; + this.unitNextEnabled = v < this.maxUnitSequenceId; + if (this.rootTestlet && (this.bookletConfig.unit_navibuttons !== 'OFF') ) { const myUnitListForNaviButtons: UnitNaviButtonData[] = []; for (let sequ = 1; sequ <= this.rootTestlet.getMaxSequenceId(); sequ++) { const myUnitData = this.rootTestlet.getUnitAt(sequ); @@ -57,13 +58,15 @@ export class TestControllerService { const disabled = (sequ < this.minUnitSequenceId) || (sequ > this.maxUnitSequenceId) || myUnitData.unitDef.locked; myUnitListForNaviButtons.push({ sequenceId: sequ, - label: myUnitData.unitDef.naviButtonLabel, // myUnitData.unitDef.naviButtonLabel,disabled ? '' : + shortLabel: myUnitData.unitDef.naviButtonLabel, + longLabel: myUnitData.unitDef.title, + testletLabel: myUnitData.testletLabel, disabled: disabled, isCurrent: sequ === v }); } } - this.unitListForNaviButtons$.next(myUnitListForNaviButtons); + this.unitListForNaviButtons = myUnitListForNaviButtons; } this._currentUnitSequenceId = v; } @@ -80,14 +83,15 @@ export class TestControllerService { private responsesToSave$ = new Subject<UnitResponseData>(); constructor ( + private router: Router, private bs: BackendService ) { this.restorePointsToSave$.pipe( debounceTime(200)).subscribe(restorePoint => { - this.bs.newUnitRestorePoint(this.bookletDbId, restorePoint.unitDbKey, Date.now(), + this.bs.newUnitRestorePoint(this.testId, restorePoint.unitDbKey, Date.now(), JSON.stringify(restorePoint.restorePoint)).subscribe(ok => { - if (ok instanceof ServerError) { - console.log('((((((((((((((((newUnitRestorePoint'); + if (!ok) { + console.warn('newUnitRestorePoint failed'); } }); } @@ -96,10 +100,10 @@ export class TestControllerService { // -- -- -- -- -- -- -- -- -- -- -- -- -- -- this.responsesToSave$.pipe( debounceTime(200)).subscribe(response => { - this.bs.newUnitResponse(this.bookletDbId, Date.now(), response.unitDbKey, + this.bs.newUnitResponse(this.testId, Date.now(), response.unitDbKey, JSON.stringify(response.response), response.responseType).subscribe(ok => { - if (ok instanceof ServerError) { - console.log('((((((((((((((((newUnitResponse'); + if (!ok) { + console.warn('newUnitResponse failed'); } }); } @@ -108,35 +112,25 @@ export class TestControllerService { // 7777777777777777777777777777777777777777777777777777777777777777777777 public resetDataStore() { - this.bookletConfig$.next(this.standardBookletConfig); - this.bookletDbId = 0; this.players = {}; this.unitDefinitions = {}; this.unitRestorePoints = {}; this.rootTestlet = null; this.maxUnitSequenceId = 0; - this.mode = ''; - this.logging = true; - this.loginname = ''; this.currentUnitSequenceId = 0; this.currentUnitDbKey = ''; this.currentUnitTitle = ''; - this.unitPrevEnabled$.next(false); - this.unitNextEnabled$.next(false); + this.unitPrevEnabled = false; + this.unitNextEnabled = false; if (this.maxTimeIntervalSubscription !== null) { this.maxTimeIntervalSubscription.unsubscribe(); this.maxTimeIntervalSubscription = null; } this.currentMaxTimerTestletId = ''; this.LastMaxTimerState = {}; - this.unitListForNaviButtons$.next([]); - this.navPolicyNextOnlyIfPresentationComplete = false; - this.navButtons = false; - this.navArrows = true; - this.pageNav = true; - this.lazyloading = true; - this.dataLoading = false; - this.bookletLoadComplete = false; + this.unitListForNaviButtons = []; + // this.dataLoading = false; TODO set test status? + // this.bookletLoadComplete = false; } // 7777777777777777777777777777777777777777777777777777777777777777777777 @@ -199,47 +193,38 @@ export class TestControllerService { return this.unitPresentationCompleteStates[sequenceId]; } - // 7777777777777777777777777777777777777777777777777777777777777777777777 - public setUnitNavigationRequest(RequestKey: string) { - this.navigationRequest$.next(RequestKey); - } - - - // 7777777777777777777777777777777777777777777777777777777777777777777777 - public addBookletLog(logKey: LogEntryKey, entry = '', overwriteBookletDbId = -1) { - if ((this.mode !== 'run-review') && this.logging) { - + public addBookletLog(logKey: LogEntryKey, entry = '') { + if (this.testMode.saveResponses) { const entryData = entry.length > 0 ? logKey + ': ' + JSON.stringify(entry) : logKey; - const bookletDbId = overwriteBookletDbId > -1 ? overwriteBookletDbId : this.bookletDbId; - this.bs.addBookletLog(bookletDbId, Date.now(), entryData).subscribe(ok => { - if (ok instanceof ServerError) { - console.log('((((((((((((((((addBookletLog'); + this.bs.addBookletLog(this.testId, Date.now(), entryData).subscribe(ok => { + if (!ok) { + console.warn('addBookletLog failed'); } }); } } public setBookletState(stateKey: LastStateKey, state: string) { - if (this.mode !== 'run-review') { - this.bs.setBookletState(this.bookletDbId, stateKey, state).subscribe(ok => { - if (ok instanceof ServerError) { - console.log('((((((((((((((((setBookletState'); + if (this.testMode.saveResponses) { + this.bs.setBookletState(this.testId, stateKey, state).subscribe(ok => { + if (!ok) { + console.warn('setBookletState failed'); } }); } } public addUnitLog(unitDbKey: string, logKey: LogEntryKey, entry = '') { - if ((this.mode !== 'run-review') && this.logging) { - this.bs.addUnitLog(this.bookletDbId, Date.now(), unitDbKey, + if (this.testMode.saveResponses) { + this.bs.addUnitLog(this.testId, Date.now(), unitDbKey, entry.length > 0 ? logKey + ': ' + JSON.stringify(entry) : logKey).subscribe(ok => { - if (ok instanceof ServerError) { - console.log('((((((((((((((((addUnitLog'); + if (!ok) { + console.warn('addUnitLog failed'); } }); } } public newUnitResponse(unitDbKey: string, response: string, responseType: string) { - if (this.mode !== 'run-review') { + if (this.testMode.saveResponses) { this.responsesToSave$.next({ unitDbKey: unitDbKey, response: response, @@ -249,7 +234,7 @@ export class TestControllerService { } public newUnitRestorePoint(unitDbKey: string, unitSequenceId: number, restorePoint: string, postToServer: boolean) { this.unitRestorePoints[unitSequenceId] = restorePoint; - if (postToServer && this.mode !== 'run-review') { + if (postToServer && this.testMode.saveResponses) { this.restorePointsToSave$.next({ unitDbKey: unitDbKey, restorePoint: restorePoint @@ -258,17 +243,17 @@ export class TestControllerService { } public newUnitStatePresentationComplete(unitDbKey: string, unitSequenceId: number, presentationComplete: string) { this.unitPresentationCompleteStates[unitSequenceId] = presentationComplete; - if (this.mode !== 'run-review') { + if (this.testMode.saveResponses) { this.addUnitLog(unitDbKey, LogEntryKey.PRESENTATIONCOMPLETE, presentationComplete); - this.bs.setUnitState(this.bookletDbId, unitDbKey, LastStateKey.PRESENTATIONCOMPLETE, presentationComplete).subscribe(ok => { - if (ok instanceof ServerError) { - console.log('((((((((((((((((setUnitState'); + this.bs.setUnitState(this.testId, unitDbKey, LastStateKey.PRESENTATIONCOMPLETE, presentationComplete).subscribe(ok => { + if (!ok) { + console.warn('setUnitState failed'); } }); } } public newUnitStateResponsesGiven(unitDbKey: string, unitSequenceId: number, responsesGiven: string) { - if (this.mode !== 'run-review') { + if (this.testMode.saveResponses) { this.addUnitLog(unitDbKey, LogEntryKey.RESPONSESCOMPLETE, responsesGiven); } } @@ -313,4 +298,64 @@ export class TestControllerService { this.maxUnitSequenceId = this.rootTestlet.getLastUnlockedUnitSequenceId(startWith); } } + + public terminateTest() { + if (this.testMode.saveResponses) { + this.bs.addBookletLog(this.testId, Date.now(), 'BOOKLETLOCKEDbyTESTEE').subscribe(OK =>{ + // TODO who evaluates TestStatus when navigating to root? + if (OK) { + this.bs.lockBooklet(this.testId).subscribe(bsOk => { + this.testStatus$.next(bsOk ? TestStatus.TERMINATED : TestStatus.ERROR); + this.router.navigate(['/']); + }) + } else { + this.testStatus$.next(TestStatus.ERROR); + this.router.navigate(['/']); + } + }) + } else { + this.testStatus$.next(TestStatus.TERMINATED); + this.router.navigate(['/']); + } + } + + public setUnitNavigationRequest(navString: string = UnitNavigationTarget.NEXT) { + if (!this.rootTestlet) { + this.router.navigateByUrl(`/t/${this.testId}`); + } else { + switch (navString) { + case UnitNavigationTarget.MENU: + case UnitNavigationTarget.ERROR: + case UnitNavigationTarget.PAUSE: + this.router.navigateByUrl(`/t/${this.testId}`); + break; + case UnitNavigationTarget.NEXT: + let startWith = this.currentUnitSequenceId; + if (startWith < this.minUnitSequenceId) { + startWith = this.minUnitSequenceId - 1; + } + const nextUnitSequenceId = this.rootTestlet.getNextUnlockedUnitSequenceId(startWith); + if (nextUnitSequenceId > 0) { + this.router.navigateByUrl(`/t/${this.testId}/u/${nextUnitSequenceId}`); + } + break; + case UnitNavigationTarget.PREVIOUS: + this.router.navigateByUrl(`/t/${this.testId}/u/${this.currentUnitSequenceId - 1}`); + break; + case UnitNavigationTarget.FIRST: + this.router.navigateByUrl(`/t/${this.testId}/u/${this.minUnitSequenceId}`); + break; + case UnitNavigationTarget.LAST: + this.router.navigateByUrl(`/t/${this.testId}/u/${this.maxUnitSequenceId}`); + break; + case UnitNavigationTarget.END: + this.terminateTest(); + break; + + default: + this.router.navigateByUrl(`/t/${this.testId}/u/${navString}`); + break; + } + } + } } diff --git a/src/app/test-controller/test-status/test-status.component.css b/src/app/test-controller/test-status/test-status.component.css new file mode 100644 index 0000000000000000000000000000000000000000..ac64082fc7fdea8b44c077ea1646b7e2da5d7d0c --- /dev/null +++ b/src/app/test-controller/test-status/test-status.component.css @@ -0,0 +1,41 @@ +.status-body { + position: absolute; + width: 100%; + top: 40px; + bottom: 45px; + padding: 0; +} + +mat-card { + margin: 10px; +} + +.mat-card-gray { + background-color: lightgray +} + +.active-unit { + background-color: #b2ff59; + padding: 4px; + overflow: hidden; + text-overflow: ellipsis; +} + +.non-active-unit { + background-color: transparent; + padding: 4px; + overflow: hidden; + text-overflow: ellipsis; +} + +.testlet-marker-non { + background-color: transparent; +} + +.testlet-marker-a { + background-color: royalblue; +} + +.testlet-marker-b { + background-color: mediumorchid; +} diff --git a/src/app/test-controller/test-status/test-status.component.html b/src/app/test-controller/test-status/test-status.component.html new file mode 100644 index 0000000000000000000000000000000000000000..d397cfaa0ec98b6cd27d943a555bd6ffdc8d43ec --- /dev/null +++ b/src/app/test-controller/test-status/test-status.component.html @@ -0,0 +1,39 @@ +<div class="status-body"> + <div fxLayout="row wrap" fxLayoutAlign="center stretch"> + <mat-card fxFlex="0 0 400px" fxLayout="column" *ngIf="((tcs.testStatus$ | async) === tcs.testStatusEnum.RUNNING) && (tcs.unitListForNaviButtons.length > 0)"> + <mat-card-title>{{ 'Aufgaben' | customtext:'booklet_tasklisttitle':cts.updateCount }}</mat-card-title> + <mat-card-content> + <div fxLayout="column" fxLayoutAlign="center stretch"> + <div *ngFor="let u of unitMenuButtonList" fxLayout="column" fxLayoutAlign="center stretch"> + <div fxLayout="row" fxLayoutAlign="space-between stretch"> + <div [class]="u.testletMarker" [matTooltip]="u.testletLabel" fxFlex="0 0 10px"></div> + <div [class]="u.isCurrent ? 'active-unit' : 'non-active-unit'" fxFlex fxLayout="column"> + <button mat-flat-button (click)="tcs.setUnitNavigationRequest(u.sequenceId.toString())" [disabled]="u.isDisabled"> + {{u.label}} + </button> + </div> + </div> + </div> + </div> + </mat-card-content> + </mat-card> + + <mat-card fxFlex="0 0 400px" fxLayout="column" class="mat-card-gray" + *ngIf="((tcs.testStatus$ | async) === tcs.testStatusEnum.RUNNING) || ((tcs.testStatus$ | async) === tcs.testStatusEnum.ERROR) || ((tcs.testStatus$ | async) === tcs.testStatusEnum.PAUSED)"> + <mat-card-title>{{ tcs.rootTestlet?.title }}</mat-card-title> + <mat-card-content> + <p><b>Angemeldet als "{{loginName}}"</b></p> + <p><b>{{tcs.testMode.modeLabel}}</b></p> + <p *ngIf="(tcs.testStatus$ | async) === tcs.testStatusEnum.ERROR" style="color: chocolate"> + <b>{{ 'Es ist ein Fehler aufgetreten.' | customtext:'booklet_errormessage':cts.updateCount }} </b> + </p> + <p *ngIf="(tcs.testStatus$ | async) === tcs.testStatusEnum.PAUSED" style="color: chocolate"> + <b>{{ 'Testpause' | customtext:'booklet_pausedmessage':cts.updateCount }} </b> + </p> + </mat-card-content> + <mat-card-actions> + <button mat-raised-button color="primary" (click)="terminateTest()">{{ 'Test beenden' | customtext:'login_testEndButtonLabel':cts.updateCount}}</button> + </mat-card-actions> + </mat-card> + </div> +</div> diff --git a/src/app/test-controller/test-status/test-status.component.spec.ts b/src/app/test-controller/test-status/test-status.component.spec.ts new file mode 100644 index 0000000000000000000000000000000000000000..d867e4ea0f410d11dd3833c07bdd7600054c8306 --- /dev/null +++ b/src/app/test-controller/test-status/test-status.component.spec.ts @@ -0,0 +1,28 @@ +import { async, ComponentFixture, TestBed } from '@angular/core/testing'; + +import { TestStatusComponent } from './test-status.component'; +import {AppRoutingModule} from "../../app-routing.module"; +import {HttpClientModule} from "@angular/common/http"; + +describe('TestStatusComponent', () => { + let component: TestStatusComponent; + let fixture: ComponentFixture<TestStatusComponent>; + + beforeEach(async(() => { + TestBed.configureTestingModule({ + declarations: [ TestStatusComponent ], + imports: [HttpClientModule, AppRoutingModule] + }) + .compileComponents(); + })); + + beforeEach(() => { + fixture = TestBed.createComponent(TestStatusComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/src/app/test-controller/test-status/test-status.component.ts b/src/app/test-controller/test-status/test-status.component.ts new file mode 100644 index 0000000000000000000000000000000000000000..e1294ce8888d8bc982934439ab75f02b9c793dec --- /dev/null +++ b/src/app/test-controller/test-status/test-status.component.ts @@ -0,0 +1,116 @@ +import {Component, OnDestroy, OnInit} from '@angular/core'; +import {Subscription} from "rxjs"; +import {ActivatedRoute} from "@angular/router"; +import {TestControllerService} from "../test-controller.service"; +import {CustomtextService} from "iqb-components"; +import {UnitMenuButtonData} from "../test-controller.interfaces"; +import {MainDataService} from "../../maindata.service"; + +@Component({ + templateUrl: './test-status.component.html', + styleUrls: ['./test-status.component.css'] +}) + +export class TestStatusComponent implements OnInit, OnDestroy { + unitMenuButtonList: UnitMenuButtonData[] = []; + private routingSubscription: Subscription = null; + private unitMenuButtonListSubscription: Subscription = null; + flag = ''; + loginName = '??'; + + constructor( + public tcs: TestControllerService, + public cts: CustomtextService, + private route: ActivatedRoute + ) { } + + ngOnInit(): void { + setTimeout(() => { + const authData = MainDataService.getAuthData(); + if (authData) { + this.loginName = authData.displayName; + } + this.routingSubscription = this.route.params.subscribe(params => { + this.flag = params['f']; + }); + this.unitMenuButtonList = []; + let testletMarkerSwitch = true; + let prevTestletLabel = ''; + if (this.tcs.bookletConfig.unit_menu !== 'OFF' || this.tcs.testMode.showUnitMenu) { + for (let unitIndex = 0; unitIndex < this.tcs.unitListForNaviButtons.length; unitIndex++) { + if (this.tcs.unitListForNaviButtons[unitIndex].longLabel.trim() && (!this.tcs.unitListForNaviButtons[unitIndex].disabled || this.tcs.bookletConfig.unit_menu === 'FULL')) { + const testletLabel = this.tcs.unitListForNaviButtons[unitIndex].testletLabel; + let testletMarker = "testlet-marker-non"; + if (testletLabel) { + if (testletLabel !== prevTestletLabel) { + testletMarkerSwitch = !testletMarkerSwitch; + prevTestletLabel = testletLabel; + } + testletMarker = testletMarkerSwitch ? "testlet-marker-a" : "testlet-marker-b"; + } + this.unitMenuButtonList.push({ + sequenceId: this.tcs.unitListForNaviButtons[unitIndex].sequenceId, + label: this.tcs.unitListForNaviButtons[unitIndex].longLabel, + isCurrent: this.tcs.unitListForNaviButtons[unitIndex].isCurrent, + isDisabled: this.tcs.unitListForNaviButtons[unitIndex].disabled, + testletLabel: testletLabel, + testletMarker: testletMarker + }) + } + } + } + }) + } + + terminateTest() { + /* + const dialogCDRef = this.confirmDialog.open(ConfirmDialogComponent, { + width: '500px', + data: <ConfirmDialogData>{ + title: this.cts.getCustomText('booklet_warningLeaveTestTitle'), + content: this.cts.getCustomText('booklet_warningLeaveTestPrompt'), + confirmbuttonlabel: 'Trotzdem weiter', + confirmbuttonreturn: true, + showcancel: true + } + }); + return dialogCDRef.afterClosed().pipe( + switchMap(cdresult => { + if ((typeof cdresult === 'undefined') || (cdresult === false)) { + return of(false); + } else { + this.bs.addBookletLog(this.tcs.testId, Date.now(), 'BOOKLETLOCKEDbyTESTEE').pipe( + switchMap((ok) => { + if (!ok) { + console.error('failed to add log entry (locked)') + } + return this.bs.lockBooklet(this.tcs.testId).pipe( + map((ok) => { + if (!ok) { + console.error('failed to lock test') + } + return true + }) + ) + }) + ).subscribe((ok) => { + if (ok) { + localStorage.removeItem(TestControllerComponent.localStorageTestKey); + } + return of(ok) + }) + } + } + )); */ + this.tcs.terminateTest(); + } + + ngOnDestroy() { + if (this.routingSubscription !== null) { + this.routingSubscription.unsubscribe(); + } + if (this.unitMenuButtonListSubscription !== null) { + this.unitMenuButtonListSubscription.unsubscribe(); + } + } +} diff --git a/src/app/test-controller/unithost/unit-route-guards.spec.ts b/src/app/test-controller/unithost/unit-route-guards.spec.ts new file mode 100644 index 0000000000000000000000000000000000000000..2716d5eb8aca09e1565dbfb84f5a49e7da4ff6fa --- /dev/null +++ b/src/app/test-controller/unithost/unit-route-guards.spec.ts @@ -0,0 +1,38 @@ +import { TestBed, inject } from '@angular/core/testing'; + +import { UnitActivateGuard, UnitDeactivateGuard } from './unit-route-guards'; +import {HttpClientModule} from "@angular/common/http"; +import {MatDialogModule} from "@angular/material/dialog"; +import {MatSnackBarModule} from "@angular/material/snack-bar"; +import {MainDataService} from "../../maindata.service"; +import {BackendService} from "../backend.service"; +import {CustomtextService} from "iqb-components"; +import {TestControllerService} from "../test-controller.service"; +import {AppRoutingModule} from "../../app-routing.module"; + +describe('UnitActivateGuard', () => { + beforeEach(() => { + TestBed.configureTestingModule({ + providers: [UnitActivateGuard, MainDataService, TestControllerService, BackendService, CustomtextService], + imports: [HttpClientModule, AppRoutingModule, MatDialogModule, MatSnackBarModule] + }); + }); + + it('should ...', inject([UnitActivateGuard], (guard: UnitActivateGuard) => { + expect(guard).toBeTruthy(); + })); +}); + + +describe('UnitDeactivateGuard', () => { + beforeEach(() => { + TestBed.configureTestingModule({ + providers: [UnitDeactivateGuard, TestControllerService], + imports: [HttpClientModule, AppRoutingModule] + }); + }); + + it('should ...', inject([UnitDeactivateGuard], (guard: UnitDeactivateGuard) => { + expect(guard).toBeTruthy(); + })); +}); diff --git a/src/app/test-controller/unithost/unit-routing-guards.ts b/src/app/test-controller/unithost/unit-route-guards.ts similarity index 81% rename from src/app/test-controller/unithost/unit-routing-guards.ts rename to src/app/test-controller/unithost/unit-route-guards.ts index c50157cd8ae87ecf089ae3bada14418e8414c8e7..d3b041ef147a633960d406fa625f9612d1c47dae 100644 --- a/src/app/test-controller/unithost/unit-routing-guards.ts +++ b/src/app/test-controller/unithost/unit-route-guards.ts @@ -1,15 +1,21 @@ -import { StartLockInputComponent } from '../start-lock-input/start-lock-input.component'; -import { ConfirmDialogComponent, ConfirmDialogData, CustomtextService } from 'iqb-components'; -import { MatDialog, MatSnackBar } from '@angular/material'; -import { TestControllerService } from '../test-controller.service'; -import { switchMap, map, filter, take } from 'rxjs/operators'; -import { UnithostComponent } from './unithost.component'; -import { Injectable } from '@angular/core'; -import { CanActivate, CanDeactivate, ActivatedRouteSnapshot, RouterStateSnapshot } from '@angular/router'; -import { Observable, of, interval } from 'rxjs'; -import { UnitControllerData } from '../test-controller.classes'; -import { CodeInputData, LogEntryKey, StartLockData } from '../test-controller.interfaces'; -import { MainDataService } from 'src/app/maindata.service'; +import {StartLockInputComponent} from '../start-lock-input/start-lock-input.component'; +import {ConfirmDialogComponent, ConfirmDialogData, CustomtextService} from 'iqb-components'; +import {TestControllerService} from '../test-controller.service'; +import {filter, map, switchMap, take} from 'rxjs/operators'; +import {UnithostComponent} from './unithost.component'; +import {Injectable} from '@angular/core'; +import {ActivatedRouteSnapshot, CanActivate, CanDeactivate, Router, RouterStateSnapshot} from '@angular/router'; +import {interval, Observable, of} from 'rxjs'; +import {UnitControllerData} from '../test-controller.classes'; +import { + CodeInputData, + LogEntryKey, + StartLockData +} from '../test-controller.interfaces'; +import {MainDataService} from 'src/app/maindata.service'; +import {MatDialog} from "@angular/material/dialog"; +import {MatSnackBar} from '@angular/material/snack-bar'; +import {TestControllerComponent} from "../test-controller.component"; @Injectable() export class UnitActivateGuard implements CanActivate { @@ -17,6 +23,7 @@ export class UnitActivateGuard implements CanActivate { private tcs: TestControllerService, private mds: MainDataService, public startLockDialog: MatDialog, + private router: Router, public confirmDialog: MatDialog, private snackBar: MatSnackBar, private cts: CustomtextService @@ -24,7 +31,7 @@ export class UnitActivateGuard implements CanActivate { checkAndSolve_PresentationCompleteCode(newUnit: UnitControllerData): Observable<Boolean> { - if (this.tcs.navPolicyNextOnlyIfPresentationComplete && this.tcs.currentUnitSequenceId > 0) { + if ((this.tcs.bookletConfig.force_presentation_complete === 'ON') && this.tcs.currentUnitSequenceId > 0) { if (this.tcs.currentUnitSequenceId < newUnit.unitDef.sequenceId) { // go forwards =================================== let myreturn = true; @@ -45,7 +52,7 @@ export class UnitActivateGuard implements CanActivate { if (myreturn) { return of(true); } else { - if (this.tcs.mode === 'hot') { + if (this.tcs.testMode.forceNaviRestrictions) { const dialogCDRef = this.confirmDialog.open(ConfirmDialogComponent, { width: '500px', // height: '300px', @@ -77,7 +84,7 @@ export class UnitActivateGuard implements CanActivate { if (myreturn) { return of(true); } else { - if (this.tcs.mode === 'hot') { + if (this.tcs.testMode.forceNaviRestrictions) { const dialogCDRef = this.confirmDialog.open(ConfirmDialogComponent, { width: '500px', // height: '300px', @@ -112,7 +119,7 @@ export class UnitActivateGuard implements CanActivate { testletId: t.id, prompt: t.codePrompt, code: t.codeToEnter.toUpperCase().trim(), - value: this.tcs.mode === 'hot' ? '' : t.codeToEnter + value: this.tcs.testMode.presetCode ? t.codeToEnter : '' }); }); @@ -127,33 +134,38 @@ export class UnitActivateGuard implements CanActivate { }); return dialogRef.afterClosed().pipe( switchMap(result => { - if ((typeof result === 'undefined') || (result === false)) { - return of(false); - } else { - const codeData = result as CodeInputData[]; - let codesOk = true; - for (const c of codeData) { - if (c.value.toUpperCase().trim() !== c.code) { + if ((typeof result === 'undefined') || (result === false)) { + return of(false); + } else { + let codesOk = true; + for (const c of myCodes) { + const testeeInput = result[c.testletId]; + if (testeeInput) { + if (c.value.toUpperCase().trim() !== testeeInput.toUpperCase().trim()) { codesOk = false; break; } + } else { + codesOk = false; + break; } - if (codesOk) { - newUnit.codeRequiringTestlets.forEach(t => { - t.codeToEnter = ''; - }); + } + if (codesOk) { + newUnit.codeRequiringTestlets.forEach(t => { + t.codeToEnter = ''; + }); - return of(true); + return of(true); - } else { - this.snackBar.open( - 'Die Eingabe war nicht korrekt.', this.cts.getCustomText('booklet_codeToEnterTitle'), - {duration: 3000} - ); - return of(false); - } + } else { + this.snackBar.open( + 'Die Eingabe war nicht korrekt.', this.cts.getCustomText('booklet_codeToEnterTitle'), + {duration: 3000} + ); + return of(false); } } + } )); } else { return of(true); @@ -165,21 +177,21 @@ export class UnitActivateGuard implements CanActivate { // **************************************************************************************** checkAndSolve_DefLoaded(newUnit: UnitControllerData): Observable<Boolean> { - if (this.tcs.bookletLoadComplete) { + if (this.tcs.loadComplete) { return of(true); } else { if (this.tcs.currentUnitSequenceId < newUnit.unitDef.sequenceId) { // 1 going forwards - if ((newUnit.maxTimerRequiringTestlet === null) || (this.tcs.mode === 'run-review')) { + if ((newUnit.maxTimerRequiringTestlet === null) || (!this.tcs.testMode.forceNaviRestrictions)) { // 1 a) target is not in timed block or review mode --> check only target unit if (this.tcs.hasUnitDefinition(newUnit.unitDef.sequenceId)) { return of(true); } else { - this.tcs.dataLoading = true; + this.mds.setSpinnerOn(); return interval(1000) .pipe( filter(() => this.tcs.hasUnitDefinition(newUnit.unitDef.sequenceId)), @@ -206,7 +218,7 @@ export class UnitActivateGuard implements CanActivate { if (ok) { return of(true); } else { - this.tcs.dataLoading = true; + this.mds.setSpinnerOn(); return interval(1000) .pipe( filter(() => { @@ -336,22 +348,28 @@ export class UnitActivateGuard implements CanActivate { let myreturn = false; if (this.tcs.rootTestlet === null) { - console.log('unit canActivate: true (rootTestlet null)'); - myreturn = true; // ?? + console.warn('unit canActivate: true (rootTestlet null)'); + myreturn = false; + const oldTestId = localStorage.getItem(TestControllerComponent.localStorageTestKey); + if (oldTestId) { + this.router.navigate([`/t/${oldTestId}`]); + } else { + this.router.navigate(['/']); + } } else if ((targetUnitSequenceId < this.tcs.minUnitSequenceId) || (targetUnitSequenceId > this.tcs.maxUnitSequenceId)) { - console.log('unit canActivate: false (unit# out of range)'); + console.warn('unit canActivate: false (unit# out of range)'); myreturn = false; } else { const newUnit: UnitControllerData = this.tcs.rootTestlet.getUnitAt(targetUnitSequenceId); if (!newUnit) { myreturn = false; - console.log('target unit null (targetUnitSequenceId: ' + targetUnitSequenceId.toString()); + console.warn('target unit null (targetUnitSequenceId: ' + targetUnitSequenceId.toString()); } else if (newUnit.unitDef.locked) { myreturn = false; - console.log('unit canActivate: locked'); + console.warn('unit canActivate: locked'); } else if (newUnit.unitDef.canEnter === 'n') { myreturn = false; - console.log('unit canActivate: false (unit is locked)'); + console.warn('unit canActivate: false (unit is locked)'); } else { // %%%%%%%%%%%%%%%%%%%%%%%%%% @@ -367,7 +385,7 @@ export class UnitActivateGuard implements CanActivate { } else { return this.checkAndSolve_DefLoaded(newUnit).pipe( switchMap(cAsDL => { - this.tcs.dataLoading = false; + this.mds.setSpinnerOff(); if (!cAsDL) { return of(false); } else { @@ -420,4 +438,4 @@ export class UnitDeactivateGuard implements CanDeactivate<UnithostComponent> { } // 777777777777777777777777777777777777777777777777777777777777777777777777777777777 -export const unitRoutingGuards = [UnitActivateGuard, UnitDeactivateGuard]; +export const unitRouteGuards = [UnitActivateGuard, UnitDeactivateGuard]; diff --git a/src/app/test-controller/unithost/unit-routing-guards.spec.ts b/src/app/test-controller/unithost/unit-routing-guards.spec.ts deleted file mode 100644 index 3f892821882159dad21e717cbc78cc171918c2f9..0000000000000000000000000000000000000000 --- a/src/app/test-controller/unithost/unit-routing-guards.spec.ts +++ /dev/null @@ -1,28 +0,0 @@ -import { TestBed, async, inject } from '@angular/core/testing'; - -import { UnitActivateGuard, UnitDeactivateGuard } from './unit-routing-guards'; - -describe('UnitActivateGuard', () => { - beforeEach(() => { - TestBed.configureTestingModule({ - providers: [UnitActivateGuard] - }); - }); - - it('should ...', inject([UnitActivateGuard], (guard: UnitActivateGuard) => { - expect(guard).toBeTruthy(); - })); -}); - - -describe('UnitDeactivateGuard', () => { - beforeEach(() => { - TestBed.configureTestingModule({ - providers: [UnitDeactivateGuard] - }); - }); - - it('should ...', inject([UnitDeactivateGuard], (guard: UnitDeactivateGuard) => { - expect(guard).toBeTruthy(); - })); -}); diff --git a/src/app/test-controller/unithost/unithost.component.css b/src/app/test-controller/unithost/unithost.component.css index ee147b56de31bc73eba1b6a7c241c6f78e312eb1..649e164ea4c5f0b0dd5bcc85d48611ccbca18b1d 100644 --- a/src/app/test-controller/unithost/unithost.component.css +++ b/src/app/test-controller/unithost/unithost.component.css @@ -1,15 +1,15 @@ .unit-body { position: absolute; width: 100%; - top: 40px; - bottom: 45px; - padding: 0px; + top: var(--tc-unithost-topmargin); + bottom: var(--tc-unithost-bottommargin); + padding: 0; background-color: white; } #unit-title { width: 100%; - padding: 0px; + padding: 0; height: 40px; font-size: 1.5em; background-color: white; @@ -20,9 +20,9 @@ position: absolute; width: 100%; height: 45px; - bottom: 0px; + bottom: 0; /* background-color: silver; */ - padding: 0px 30px; + padding: 0 30px; font-size: 1.2em; } diff --git a/src/app/test-controller/unithost/unithost.component.html b/src/app/test-controller/unithost/unithost.component.html index b890e7636670667713215cf7141c30383c56c4b5..e8e9ebf3b08e1fe8f5049e22d72e7abae78c49dc 100644 --- a/src/app/test-controller/unithost/unithost.component.html +++ b/src/app/test-controller/unithost/unithost.component.html @@ -4,7 +4,7 @@ <div id="iFrameHost" iqbResizeIFrameChild class="unit-body"> </div> -<div id="pageNav" fxLayout="row" fxLayoutAlign="end center" fxLayoutGap="10px" *ngIf="tcs.pageNav"> + <div id="pageNav" fxLayout="row" fxLayoutAlign="end center" fxLayoutGap="10px" *ngIf="tcs.bookletConfig.page_navibuttons !== 'OFF'"> <div fxLayout="row" fxLayoutAlign="space-between center" *ngIf="showPageNav"> <div id="pageNavPrompt"> diff --git a/src/app/test-controller/unithost/unithost.component.spec.ts b/src/app/test-controller/unithost/unithost.component.spec.ts index 7c5cf61a65142dc84e3a5af4c13d689649910708..226c86d456d795c360d013233021b5738527b773 100644 --- a/src/app/test-controller/unithost/unithost.component.spec.ts +++ b/src/app/test-controller/unithost/unithost.component.spec.ts @@ -1,6 +1,8 @@ import { async, ComponentFixture, TestBed } from '@angular/core/testing'; import { UnithostComponent } from './unithost.component'; +import {HttpClientModule} from "@angular/common/http"; +import {AppRoutingModule} from "../../app-routing.module"; describe('UnithostComponent', () => { let component: UnithostComponent; @@ -8,7 +10,8 @@ describe('UnithostComponent', () => { beforeEach(async(() => { TestBed.configureTestingModule({ - declarations: [ UnithostComponent ] + declarations: [ UnithostComponent ], + imports: [HttpClientModule, AppRoutingModule] }) .compileComponents(); })); diff --git a/src/app/test-controller/unithost/unithost.component.ts b/src/app/test-controller/unithost/unithost.component.ts index 1dd0b5ca47f035791b761f9294ec325a8fa3b0fb..51ffa202261b74f165338e945cc508a5a9bbe156 100644 --- a/src/app/test-controller/unithost/unithost.component.ts +++ b/src/app/test-controller/unithost/unithost.component.ts @@ -19,8 +19,6 @@ export class UnithostComponent implements OnInit, OnDestroy { private routingSubscription: Subscription = null; public currentValidPages: string[] = []; public leaveWarning = false; - public leaveWarningText = 'Du hast den Hörtext noch nicht vollständig gehört. Nach dem ' + - 'Verlassen der Aufgabe wird der Hörtext nicht noch einmal gestartet. Trotzdem die Aufgabe verlassen?'; public unitTitle = ''; public showPageNav = false; @@ -161,57 +159,56 @@ export class UnithostComponent implements OnInit, OnDestroy { // % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % ngOnInit() { - this.iFrameHostElement = <HTMLElement>document.querySelector('#iFrameHost'); + setTimeout(() => { + this.iFrameHostElement = <HTMLElement>document.querySelector('#iFrameHost'); - this.iFrameItemplayer = null; - this.leaveWarning = false; + this.iFrameItemplayer = null; + this.leaveWarning = false; - this.routingSubscription = this.route.params.subscribe(params => { - this.myUnitSequenceId = Number(params['u']); - this.tcs.currentUnitSequenceId = this.myUnitSequenceId; + this.routingSubscription = this.route.params.subscribe(params => { + this.myUnitSequenceId = Number(params['u']); + this.tcs.currentUnitSequenceId = this.myUnitSequenceId; - while (this.iFrameHostElement.hasChildNodes()) { - this.iFrameHostElement.removeChild(this.iFrameHostElement.lastChild); - } + while (this.iFrameHostElement.hasChildNodes()) { + this.iFrameHostElement.removeChild(this.iFrameHostElement.lastChild); + } - if ((this.myUnitSequenceId >= 1) && (this.myUnitSequenceId === this.myUnitSequenceId) && (this.tcs.rootTestlet !== null)) { - this.tcs.setBookletState(LastStateKey.LASTUNIT, params['u']); + if ((this.myUnitSequenceId >= 1) && (this.myUnitSequenceId === this.myUnitSequenceId) && (this.tcs.rootTestlet !== null)) { + this.tcs.setBookletState(LastStateKey.LASTUNIT, params['u']); - const currentUnit = this.tcs.rootTestlet.getUnitAt(this.myUnitSequenceId); - this.unitTitle = currentUnit.unitDef.title; - this.myUnitDbKey = currentUnit.unitDef.alias; - this.tcs.currentUnitDbKey = this.myUnitDbKey; - this.tcs.currentUnitTitle = this.unitTitle; - this.itemplayerSessionId = Math.floor(Math.random() * 20000000 + 10000000).toString(); + const currentUnit = this.tcs.rootTestlet.getUnitAt(this.myUnitSequenceId); + this.unitTitle = currentUnit.unitDef.title; + this.myUnitDbKey = currentUnit.unitDef.alias; + this.tcs.currentUnitDbKey = this.myUnitDbKey; + this.tcs.currentUnitTitle = this.unitTitle; + this.itemplayerSessionId = Math.floor(Math.random() * 20000000 + 10000000).toString(); - this.setPageList([], ''); + this.setPageList([], ''); - this.iFrameItemplayer = <HTMLIFrameElement>document.createElement('iframe'); - // this.iFrameItemplayer.setAttribute('srcdoc', this.tcs.getPlayer(currentUnit.unitDef.playerId)); - this.iFrameItemplayer.setAttribute('sandbox', 'allow-forms allow-scripts allow-same-origin'); - this.iFrameItemplayer.setAttribute('class', 'unitHost'); - this.iFrameItemplayer.setAttribute('height', String(this.iFrameHostElement.clientHeight)); + this.iFrameItemplayer = <HTMLIFrameElement>document.createElement('iframe'); + // this.iFrameItemplayer.setAttribute('srcdoc', this.tcs.getPlayer(currentUnit.unitDef.playerId)); + this.iFrameItemplayer.setAttribute('sandbox', 'allow-forms allow-scripts allow-same-origin'); + this.iFrameItemplayer.setAttribute('class', 'unitHost'); + this.iFrameItemplayer.setAttribute('height', String(this.iFrameHostElement.clientHeight)); - if (this.tcs.hasUnitRestorePoint(this.myUnitSequenceId)) { - this.pendingUnitRestorePoint = {tag: this.itemplayerSessionId, value: this.tcs.getUnitRestorePoint(this.myUnitSequenceId)}; - } else { - this.pendingUnitRestorePoint = null; - } + if (this.tcs.hasUnitRestorePoint(this.myUnitSequenceId)) { + this.pendingUnitRestorePoint = {tag: this.itemplayerSessionId, value: this.tcs.getUnitRestorePoint(this.myUnitSequenceId)}; + } else { + this.pendingUnitRestorePoint = null; + } - this.leaveWarning = false; - if (!this.tcs.pageNav) { - this.iFrameHostElement.style.bottom = '0px'; - } + this.leaveWarning = false; - if (this.tcs.hasUnitDefinition(this.myUnitSequenceId)) { - this.pendingUnitDefinition = {tag: this.itemplayerSessionId, value: this.tcs.getUnitDefinition(this.myUnitSequenceId)}; - } else { - this.pendingUnitDefinition = null; + if (this.tcs.hasUnitDefinition(this.myUnitSequenceId)) { + this.pendingUnitDefinition = {tag: this.itemplayerSessionId, value: this.tcs.getUnitDefinition(this.myUnitSequenceId)}; + } else { + this.pendingUnitDefinition = null; + } + this.iFrameHostElement.appendChild(this.iFrameItemplayer); + srcDoc.set(this.iFrameItemplayer, this.tcs.getPlayer(currentUnit.unitDef.playerId)); } - this.iFrameHostElement.appendChild(this.iFrameItemplayer); - srcDoc.set(this.iFrameItemplayer, this.tcs.getPlayer(currentUnit.unitDef.playerId)); - } - }); + }); + }) } // ++++++++++++ page nav ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ @@ -265,11 +262,7 @@ export class UnithostComponent implements OnInit, OnDestroy { this.pageList[this.pageList.length - 1].disabled = false; } else { this.pageList[0].disabled = false; - if (currentPageIndex === this.pageList.length - 2) { - this.pageList[this.pageList.length - 1].disabled = true; - } else { - this.pageList[this.pageList.length - 1].disabled = false; - } + this.pageList[this.pageList.length - 1].disabled = currentPageIndex === this.pageList.length - 2; } } this.showPageNav = this.pageList.length > 0; diff --git a/src/app/workspace-admin/backend.service.spec.ts b/src/app/workspace-admin/backend.service.spec.ts index c31039d7e5bcc7bc70e7213ce06744a0dc6ed009..7d5789ab6b2884621c702ca26fb5d3dc8b8f9f62 100644 --- a/src/app/workspace-admin/backend.service.spec.ts +++ b/src/app/workspace-admin/backend.service.spec.ts @@ -1,14 +1,19 @@ import { TestBed, inject } from '@angular/core/testing'; import { BackendService } from './backend.service'; +import {HttpClientModule} from "@angular/common/http"; +import {WorkspaceDataService} from "./workspacedata.service"; -describe('BackendService', () => { + +describe('HttpClient testing', () => { beforeEach(() => { TestBed.configureTestingModule({ - providers: [BackendService] + imports: [HttpClientModule], + providers: [ + BackendService, + WorkspaceDataService] }); }); - it('should be created', inject([BackendService], (service: BackendService) => { expect(service).toBeTruthy(); })); diff --git a/src/app/workspace-admin/backend.service.ts b/src/app/workspace-admin/backend.service.ts index 336c92db42262c6b3305bba6d979a3c33af92597..7a151d31c6fc03878fb5d77d1508582f5f0e2c43 100644 --- a/src/app/workspace-admin/backend.service.ts +++ b/src/app/workspace-admin/backend.service.ts @@ -2,89 +2,146 @@ import { GetFileResponseData, CheckWorkspaceResponseData, SysCheckStatistics, ReviewData, LogData, UnitResponse, ResultData } from './workspace.interfaces'; import {Injectable, Inject} from '@angular/core'; import { HttpClient } from '@angular/common/http'; -import { Observable } from 'rxjs'; -import { catchError } from 'rxjs/operators'; -import { ErrorHandler, ServerError } from 'iqb-components'; - -@Injectable() +import {Observable, of} from 'rxjs'; +import { catchError, map } from 'rxjs/operators'; +import {WorkspaceDataService} from "./workspacedata.service"; +import {ApiError, WorkspaceData} from "../app.interfaces"; + +@Injectable({ + providedIn: 'root' +}) export class BackendService { - constructor( @Inject('SERVER_URL') private readonly serverUrl: string, + private wds: WorkspaceDataService, private http: HttpClient ) { } - - getFiles(workspaceId: number): Observable<GetFileResponseData[] | ServerError> { - + getWorkspaceData(workspaceId: string): Observable<WorkspaceData | number> { return this.http - .get<GetFileResponseData[]>(this.serverUrl + `workspace/${workspaceId}/files`) - .pipe(catchError(ErrorHandler.handle)); + .get<WorkspaceData>(this.serverUrl + 'workspace/' + workspaceId) + .pipe( + catchError((err: ApiError) => { + console.warn(`getWorkspaceData Api-Error: ${err.code} ${err.info} `); + return of(err.code) + }) + ); } - deleteFiles(workspaceId: number, filesToDelete: Array<string>): Observable<FileDeletionReport | ServerError> { - + getFiles(): Observable<GetFileResponseData[]> { return this.http - .request<FileDeletionReport>('delete', this.serverUrl + `workspace/${workspaceId}/files`, {body: {f: filesToDelete}}) - .pipe(catchError(ErrorHandler.handle)); + .get<GetFileResponseData[]>(this.serverUrl + `workspace/${this.wds.wsId}/files`) + .pipe( + catchError((err: ApiError) => { + console.warn(`getFiles Api-Error: ${err.code} ${err.info} `); + return [] + }) + ); } - checkWorkspace(workspaceId: number): Observable<CheckWorkspaceResponseData | ServerError> { - + deleteFiles(filesToDelete: Array<string>): Observable<FileDeletionReport> { return this.http - .get<CheckWorkspaceResponseData>(this.serverUrl + `workspace/${workspaceId}/validation`, {}) - .pipe(catchError(ErrorHandler.handle)); + .request<FileDeletionReport>('delete', this.serverUrl + `workspace/${this.wds.wsId}/files`, {body: {f: filesToDelete}}) + .pipe( + catchError((err: ApiError) => { + console.warn(`deleteFiles Api-Error: ${err.code} ${err.info} `); + return of(<FileDeletionReport> { + deleted: [], + not_allowed: [`deleteFiles Api-Error: ${err.code} ${err.info} `], + did_not_exist: [] + }) + }) + ); } - getResultData(workspaceId: number): Observable<ResultData[]> { - + checkWorkspace(): Observable<CheckWorkspaceResponseData> { return this.http - .get<ResultData[]>(this.serverUrl + `workspace/${workspaceId}/results`, {}) - .pipe(catchError(() => [])); + .get<CheckWorkspaceResponseData>(this.serverUrl + `workspace/${this.wds.wsId}/validation`, {}) + .pipe( + catchError((err: ApiError) => { + console.warn(`checkWorkspace Api-Error: ${err.code} ${err.info} `); + return of(<CheckWorkspaceResponseData>{ + errors: [`checkWorkspace Api-Error: ${err.code} ${err.info} `], + infos: [], + warnings: [] + }) + }) + ); } - getResponses(workspaceId: number, groups: string[]): Observable<UnitResponse[]> { - + getResultData(): Observable<ResultData[]> { return this.http - .get<UnitResponse[]>(this.serverUrl + `workspace/${workspaceId}/responses`, {params: {groups: groups.join(',')}}) - .pipe(catchError(() => [])); + .get<ResultData[]>(this.serverUrl + `workspace/${this.wds.wsId}/results`, {}) + .pipe( + catchError((err: ApiError) => { + console.warn(`getResultData Api-Error: ${err.code} ${err.info} `); + return [] + }) + ); } - getLogs(workspaceId: number, groups: string[]): Observable<LogData[]> { - + getResponses(groups: string[]): Observable<UnitResponse[]> { return this.http - .get<LogData[]>(this.serverUrl + `workspace/${workspaceId}/logs`, {params: {groups: groups.join(',')}}) - .pipe(catchError(() => [])); + .get<UnitResponse[]>(this.serverUrl + `workspace/${this.wds.wsId}/responses`, {params: {groups: groups.join(',')}}) + .pipe( + catchError((err: ApiError) => { + console.warn(`getResponses Api-Error: ${err.code} ${err.info} `); + return [] + }) + ); } - getReviews(workspaceId: number, groups: string[]): Observable<ReviewData[]> { - + getLogs(groups: string[]): Observable<LogData[]> { return this.http - .get<ReviewData[]>(this.serverUrl + `workspace/${workspaceId}/reviews`, {params: {groups: groups.join(',')}}) - .pipe(catchError(() => [])); + .get<LogData[]>(this.serverUrl + `workspace/${this.wds.wsId}/logs`, {params: {groups: groups.join(',')}}) + .pipe( + catchError((err: ApiError) => { + console.warn(`getLogs Api-Error: ${err.code} ${err.info} `); + return [] + }) + ); } - deleteData(workspaceId: number, groups: string[]): Observable<boolean | ServerError> { - + getReviews(groups: string[]): Observable<ReviewData[]> { return this.http - .request<boolean>('delete', this.serverUrl + `workspace/${workspaceId}/responses`, {body: {groups: groups}}) - .pipe(catchError(ErrorHandler.handle)); + .get<ReviewData[]>(this.serverUrl + `workspace/${this.wds.wsId}/reviews`, {params: {groups: groups.join(',')}}) + .pipe( + catchError((err: ApiError) => { + console.warn(`getReviews Api-Error: ${err.code} ${err.info} `); + return [] + }) + ); } - getSysCheckReportList(workspaceId: number): Observable<SysCheckStatistics[] | ServerError> { - + deleteData(groups: string[]): Observable<boolean> { return this.http - .get<ReviewData[]>(this.serverUrl + `workspace/${workspaceId}/sys-check/reports/overview`) - .pipe(catchError(() => [])); + .request('delete', this.serverUrl + `workspace/${this.wds.wsId}/responses`, {body: {groups: groups}}) + .pipe( + map(() => true), + catchError((err: ApiError) => { + console.warn(`deleteData Api-Error: ${err.code} ${err.info} `); + return of(false) + }) + ); } - getSysCheckReport(workspaceId: number, reports: string[], enclosure: string, columnDelimiter: string, lineEnding: string) - : Observable<Blob|ServerError> { + getSysCheckReportList(): Observable<SysCheckStatistics[]> { + return this.http + .get<ReviewData[]>(this.serverUrl + `workspace/${this.wds.wsId}/sys-check/reports/overview`) + .pipe( + catchError((err: ApiError) => { + console.warn(`getSysCheckReportList Api-Error: ${err.code} ${err.info} `); + return [] + }) + ); + } + getSysCheckReport(reports: string[], enclosure: string, columnDelimiter: string, lineEnding: string) + : Observable<Blob | boolean> { return this.http - .get(this.serverUrl + `workspace/${workspaceId}/sys-check/reports`, + .get(this.serverUrl + `workspace/${this.wds.wsId}/sys-check/reports`, { params: { checkIds: reports.join(','), @@ -97,21 +154,38 @@ export class BackendService { }, responseType: 'blob' }) - .pipe(catchError(ErrorHandler.handle)); + .pipe( + catchError((err: ApiError) => { + console.warn(`getSysCheckReport Api-Error: ${err.code} ${err.info} `); + return of(false) + }) + ); } - deleteSysCheckReports(workspaceId: number, checkIds: string[]): Observable <FileDeletionReport|ServerError> { - + deleteSysCheckReports(checkIds: string[]): Observable <FileDeletionReport> { return this.http - .request<FileDeletionReport>('delete', this.serverUrl + `workspace/${workspaceId}/sys-check/reports`, {body: {checkIds: checkIds}}) - .pipe(catchError(ErrorHandler.handle)); + .request<FileDeletionReport>('delete', this.serverUrl + `workspace/${this.wds.wsId}/sys-check/reports`, {body: {checkIds: checkIds}}) + .pipe( + catchError((err: ApiError) => { + console.warn(`deleteSysCheckReports Api-Error: ${err.code} ${err.info} `); + return of(<FileDeletionReport> { + deleted: [], + not_allowed: [`deleteSysCheckReports Api-Error: ${err.code} ${err.info} `], + did_not_exist: [] + }) + }) + ); } - downloadFile(workspaceId: number, fileType: string, fileName: string): Observable<Blob|ServerError> { - + downloadFile(fileType: string, fileName: string): Observable<Blob | boolean> { return this.http - .get(this.serverUrl + `workspace/${workspaceId}/file/${fileType}/${fileName}`, {responseType: 'blob'}) - .pipe(catchError(ErrorHandler.handle)); + .get(this.serverUrl + `workspace/${this.wds.wsId}/file/${fileType}/${fileName}`, {responseType: 'blob'}) + .pipe( + catchError((err: ApiError) => { + console.warn(`downloadFile Api-Error: ${err.code} ${err.info} `); + return of(false) + }) + ); } } diff --git a/src/app/workspace-admin/files/files.component.html b/src/app/workspace-admin/files/files.component.html index a23f1f4f53113716a5273b4f3e3477e528a98ef4..dc91133db8451b90ad7fbc0d8274dd22ffe90467 100644 --- a/src/app/workspace-admin/files/files.component.html +++ b/src/app/workspace-admin/files/files.component.html @@ -1,8 +1,4 @@ <div class="columnhost"> - <div class="spinner-container" *ngIf="dataLoading"> - <mat-spinner></mat-spinner> - </div> - <!-- ============================================= --> <div class="filelist"> <mat-table #table [dataSource]="serverfiles" matSort> diff --git a/src/app/workspace-admin/files/files.component.spec.ts b/src/app/workspace-admin/files/files.component.spec.ts index da941cc1423eb4e0ccee04599f7a30827265304c..be034281f27297428faacc24ed2002f39e5f4a0c 100644 --- a/src/app/workspace-admin/files/files.component.spec.ts +++ b/src/app/workspace-admin/files/files.component.spec.ts @@ -1,6 +1,12 @@ import { async, ComponentFixture, TestBed } from '@angular/core/testing'; import { FilesComponent } from './files.component'; +import {HttpClientModule} from "@angular/common/http"; +import {BackendService} from "../backend.service"; +import {WorkspaceDataService} from "../workspacedata.service"; +import {MatDialogModule} from "@angular/material/dialog"; +import {MatSnackBarModule} from "@angular/material/snack-bar"; +import {MainDataService} from "../../maindata.service"; describe('FilesComponent', () => { let component: FilesComponent; @@ -8,7 +14,17 @@ describe('FilesComponent', () => { beforeEach(async(() => { TestBed.configureTestingModule({ - declarations: [ FilesComponent ] + declarations: [ FilesComponent ], + imports: [ + HttpClientModule, + MatDialogModule, + MatSnackBarModule + ], + providers: [ + BackendService, + WorkspaceDataService, + MainDataService + ] }) .compileComponents(); })); diff --git a/src/app/workspace-admin/files/files.component.ts b/src/app/workspace-admin/files/files.component.ts index 06ced970feba139dffbcfabf5535e2b66962ad7a..a0a1821d3e77254c0e9df8ff23f9fed2530a252e 100644 --- a/src/app/workspace-admin/files/files.component.ts +++ b/src/app/workspace-admin/files/files.component.ts @@ -1,27 +1,24 @@ -import { MainDataService } from '../../maindata.service'; import { WorkspaceDataService } from '../workspacedata.service'; import { GetFileResponseData, CheckWorkspaceResponseData } from '../workspace.interfaces'; import { ConfirmDialogComponent, ConfirmDialogData, MessageDialogComponent, - MessageDialogData, MessageType, ServerError } from 'iqb-components'; -import { Subscription } from 'rxjs'; + MessageDialogData, MessageType } from 'iqb-components'; import { MatTableDataSource } from '@angular/material/table'; import { MatSnackBar } from '@angular/material/snack-bar'; import {BackendService, FileDeletionReport} from '../backend.service'; -import { Component, OnInit, Inject, OnDestroy } from '@angular/core'; +import { Component, OnInit, Inject } from '@angular/core'; import { ViewChild } from '@angular/core'; import { MatDialog } from '@angular/material/dialog'; import { MatSort } from '@angular/material/sort'; import { saveAs } from 'file-saver'; +import {MainDataService} from "../../maindata.service"; @Component({ templateUrl: './files.component.html', styleUrls: ['./files.component.css'] }) -export class FilesComponent implements OnInit, OnDestroy { +export class FilesComponent implements OnInit { public serverfiles: MatTableDataSource<GetFileResponseData>; public displayedColumns = ['checked', 'filename', 'typelabel', 'filesize', 'filedatetime']; - public dataLoading = false; - private workspaceIdSubscription: Subscription = null; // for fileupload public uploadUrl = ''; @@ -37,22 +34,19 @@ export class FilesComponent implements OnInit, OnDestroy { constructor( @Inject('SERVER_URL') private serverUrl: string, private bs: BackendService, - private mds: MainDataService, public wds: WorkspaceDataService, public confirmDialog: MatDialog, - public messsageDialog: MatDialog, + public messageDialog: MatDialog, + private mds: MainDataService, public snackBar: MatSnackBar - ) { - this.wds.workspaceId$.subscribe(workspaceId => { - this.uploadUrl = this.serverUrl + `workspace/${workspaceId}/file`; - }); - this.uploadUrl = this.serverUrl + "workspace/" + this.wds.ws + '/file'; - } + ) { } ngOnInit() { - this.workspaceIdSubscription = this.wds.workspaceId$.subscribe(() => { - this.updateFileList((this.wds.ws <= 0) || (this.mds.adminToken.length === 0)); - }); + this.uploadUrl = `${this.serverUrl}workspace/${this.wds.wsId}/file`; + setTimeout(() => { + this.mds.setSpinnerOn(); + this.updateFileList(); + }) } // *********************************************************************************** @@ -95,32 +89,23 @@ export class FilesComponent implements OnInit, OnDestroy { dialogRef.afterClosed().subscribe(result => { if (result !== false) { - // ========================================================= - this.dataLoading = true; - this.bs.deleteFiles(this.wds.ws, filesToDelete).subscribe((fileDeletionReport: FileDeletionReport|ServerError) => { - if (fileDeletionReport instanceof ServerError) { - this.wds.setNewErrorMsg(fileDeletionReport as ServerError); - } else { - - const message = []; - if (fileDeletionReport.deleted.length > 0) { - message.push(fileDeletionReport.deleted.length + ' Dateien erfolgreich gelöscht.'); - } - if (fileDeletionReport.not_allowed.length > 0) { - message.push(fileDeletionReport.not_allowed.length + ' Dateien konnten nicht gelöscht werden.'); - } - - this.snackBar.open(message.join('<br>'), message.length > 1 ? 'Achtung' : '', {duration: 1000}); - - this.updateFileList(); - this.wds.setNewErrorMsg(); + this.mds.setSpinnerOn(); + this.bs.deleteFiles(filesToDelete).subscribe((fileDeletionReport: FileDeletionReport) => { + const message = []; + if (fileDeletionReport.deleted.length > 0) { + message.push(fileDeletionReport.deleted.length + ' Dateien erfolgreich gelöscht.'); + } + if (fileDeletionReport.not_allowed.length > 0) { + message.push(fileDeletionReport.not_allowed.length + ' Dateien konnten nicht gelöscht werden.'); } + this.snackBar.open(message.join('<br>'), message.length > 1 ? 'Achtung' : '', {duration: 1000}); + this.updateFileList(); }); // ========================================================= } }); } else { - this.messsageDialog.open(MessageDialogComponent, { + this.messageDialog.open(MessageDialogComponent, { width: '400px', data: <MessageDialogData>{ title: 'Löschen von Dateien', @@ -140,67 +125,44 @@ export class FilesComponent implements OnInit, OnDestroy { if (empty || this.wds.wsRole === 'MO') { this.serverfiles = new MatTableDataSource([]); + this.mds.setSpinnerOff(); } else { - this.dataLoading = true; - this.bs.getFiles(this.wds.ws).subscribe( - (filedataresponse: GetFileResponseData[]) => { - this.serverfiles = new MatTableDataSource(filedataresponse); + this.bs.getFiles().subscribe( + (fileList: GetFileResponseData[]) => { + this.serverfiles = new MatTableDataSource(fileList); this.serverfiles.sort = this.sort; - this.dataLoading = false; - this.wds.setNewErrorMsg(); - }, (err: ServerError) => { - this.wds.setNewErrorMsg(err); - this.dataLoading = false; + this.mds.setSpinnerOff(); } ); } } - download(element: GetFileResponseData): void { - - this.dataLoading = true; - this.bs.downloadFile(this.wds.ws, element.type, element.filename) + this.mds.setSpinnerOn(); + this.bs.downloadFile(element.type, element.filename) .subscribe( - (fileData: Blob|ServerError) => { - if (fileData instanceof ServerError) { - this.wds.setNewErrorMsg(fileData); - this.dataLoading = false; - } else { - saveAs(fileData, element.filename); - this.wds.setNewErrorMsg(); - this.dataLoading = false; + (fileData: Blob|boolean) => { + this.mds.setSpinnerOff(); + if (fileData !== false) { + saveAs(fileData as Blob, element.filename); } } ); } - checkWorkspace() { this.checkErrors = []; this.checkWarnings = []; this.checkInfos = []; - this.dataLoading = true; - this.bs.checkWorkspace(this.wds.ws).subscribe( + this.mds.setSpinnerOn(); + this.bs.checkWorkspace().subscribe( (checkResponse: CheckWorkspaceResponseData) => { + this.mds.setSpinnerOff(); this.checkErrors = checkResponse.errors; this.checkWarnings = checkResponse.warnings; this.checkInfos = checkResponse.infos; - this.wds.setNewErrorMsg(); - - this.dataLoading = false; - }, (err: ServerError) => { - this.wds.setNewErrorMsg(err); - this.dataLoading = false; } ); } - - // % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % - ngOnDestroy() { - if (this.workspaceIdSubscription !== null) { - this.workspaceIdSubscription.unsubscribe(); - } - } } diff --git a/src/app/workspace-admin/files/iqb-files/iqbFilesUpload/iqbFilesUpload.component.ts b/src/app/workspace-admin/files/iqb-files/iqbFilesUpload/iqbFilesUpload.component.ts index 8f8e832caefbf2a15175958dd0826c2571418a4b..03efc74d60e60f1aa1a667ac887a6c50121af4d3 100644 --- a/src/app/workspace-admin/files/iqb-files/iqbFilesUpload/iqbFilesUpload.component.ts +++ b/src/app/workspace-admin/files/iqb-files/iqbFilesUpload/iqbFilesUpload.component.ts @@ -1,6 +1,9 @@ import {Component, EventEmitter, Input, OnInit, Output, HostBinding, OnDestroy} from '@angular/core'; -import { HttpClient, HttpEventType, HttpHeaders, HttpParams, - HttpErrorResponse, HttpEvent } from '@angular/common/http'; +import { + HttpClient, HttpEventType, HttpHeaders, HttpParams, + HttpEvent, HttpErrorResponse +} from '@angular/common/http'; +import {ApiError} from "../../../../app.interfaces"; @Component({ @@ -153,20 +156,23 @@ import { HttpClient, HttpEventType, HttpHeaders, HttpParams, this.remove(); } } - }, (errorObj: HttpErrorResponse) => { + }, (err) => { if (this.fileUploadSubscription) { this.fileUploadSubscription.unsubscribe(); } - this.status = UploadStatus.error; - if (errorObj.status === 401) { - this.requestResponseText = 'Fehler: Zugriff verweigert - bitte (neu) anmelden!'; - } else if (errorObj.status === 400) { - this.requestResponseText = 'Fehler: ' + errorObj.error; - } else if (errorObj.error instanceof ErrorEvent) { - this.requestResponseText = 'Fehler: ' + (<ErrorEvent>errorObj.error).message; + if (err instanceof HttpErrorResponse) { + this.requestResponseText = (err as HttpErrorResponse).message; + } else if (err instanceof ApiError) { + const apiError: ApiError = err; + if (apiError.code === 422) { + const slashPos = apiError.info.indexOf(' // '); + this.requestResponseText = (slashPos > 0) ? apiError.info.substr(slashPos + 4) : apiError.info; + } else { + this.requestResponseText = apiError.info; + } } else { - this.requestResponseText = 'Fehler: ' + errorObj.message; + this.requestResponseText = 'Hochladen nicht erfolgreich.' } }); } diff --git a/src/app/workspace-admin/results/results.component.html b/src/app/workspace-admin/results/results.component.html index 5ac0ebf46d395908c958eeef01f0cde816964f7d..ab74cc95766ec2979e32c87b058c627596f7b054 100644 --- a/src/app/workspace-admin/results/results.component.html +++ b/src/app/workspace-admin/results/results.component.html @@ -1,7 +1,4 @@ <div class="columnhost" fxLayout="column"> - <div class="spinner-container" *ngIf="dataLoading"> - <mat-spinner></mat-spinner> - </div> <div fxLayout="row"> <button mat-raised-button (click)="downloadResponsesCSV()" [disabled]="!tableselectionCheckbox.hasValue()" matTooltip="Download markierte Gruppen als CSV für Excel" matTooltipPosition="above"> diff --git a/src/app/workspace-admin/results/results.component.spec.ts b/src/app/workspace-admin/results/results.component.spec.ts index 23c08dfbd9069ff0c88a396817f452a838b0fd51..8459e696515a3783ae0e28c4806ab3f1f1b67b5a 100644 --- a/src/app/workspace-admin/results/results.component.spec.ts +++ b/src/app/workspace-admin/results/results.component.spec.ts @@ -1,14 +1,28 @@ import { async, ComponentFixture, TestBed } from '@angular/core/testing'; import { ResultsComponent } from './results.component'; +import {HttpClientModule} from "@angular/common/http"; +import {BackendService} from "../backend.service"; +import {WorkspaceDataService} from "../workspacedata.service"; +import {MatDialogModule} from "@angular/material/dialog"; +import {MatSnackBarModule} from "@angular/material/snack-bar"; -describe('SharedFilesComponent', () => { +describe('ResultsComponent', () => { let component: ResultsComponent; let fixture: ComponentFixture<ResultsComponent>; beforeEach(async(() => { TestBed.configureTestingModule({ - declarations: [ ResultsComponent ] + declarations: [ ResultsComponent ], + imports: [ + HttpClientModule, + MatDialogModule, + MatSnackBarModule + ], + providers: [ + BackendService, + WorkspaceDataService + ] }) .compileComponents(); })); diff --git a/src/app/workspace-admin/results/results.component.ts b/src/app/workspace-admin/results/results.component.ts index ee8e19cc464427d310f928bef24ff4d9f60f3e04..df968035f98b6a2237b909b499257547fe5f3f1d 100644 --- a/src/app/workspace-admin/results/results.component.ts +++ b/src/app/workspace-admin/results/results.component.ts @@ -1,7 +1,7 @@ import { LogData } from '../workspace.interfaces'; import { WorkspaceDataService } from '../workspacedata.service'; -import { ConfirmDialogComponent, ConfirmDialogData } from 'iqb-components'; -import { Component, OnInit, ViewChild, OnDestroy } from '@angular/core'; +import {ConfirmDialogComponent, ConfirmDialogData} from 'iqb-components'; +import { Component, OnInit, ViewChild } from '@angular/core'; import { BackendService } from '../backend.service'; import { MatDialog } from '@angular/material/dialog'; import { MatSnackBar } from '@angular/material/snack-bar'; @@ -10,20 +10,18 @@ import { MatTableDataSource } from '@angular/material/table'; import { SelectionModel } from '@angular/cdk/collections'; import { saveAs } from 'file-saver'; import { ResultData, UnitResponse, ReviewData } from '../workspace.interfaces'; -import { Subscription } from 'rxjs'; +import {MainDataService} from "../../maindata.service"; @Component({ templateUrl: './results.component.html', styleUrls: ['./results.component.css'] }) -export class ResultsComponent implements OnInit, OnDestroy { +export class ResultsComponent implements OnInit { displayedColumns: string[] = ['selectCheckbox', 'groupname', 'bookletsStarted', 'num_units_min', 'num_units_max', 'num_units_mean', 'lastchange']; public resultDataSource = new MatTableDataSource<ResultData>([]); // prepared for selection if needed sometime public tableselectionCheckbox = new SelectionModel<ResultData>(true, []); - public dataLoading = false; - private workspaceIdSubscription: Subscription = null; @ViewChild(MatSort, { static: true }) sort: MatSort; @@ -31,26 +29,28 @@ export class ResultsComponent implements OnInit, OnDestroy { private bs: BackendService, public wds: WorkspaceDataService, private deleteConfirmDialog: MatDialog, + private mds: MainDataService, public snackBar: MatSnackBar ) { } ngOnInit() { - this.workspaceIdSubscription = this.wds.workspaceId$.subscribe(() => { + setTimeout(() => { + this.mds.setSpinnerOn(); this.updateTable(); - }); + }) } updateTable() { this.tableselectionCheckbox.clear(); if (this.wds.wsRole === 'MO') { this.resultDataSource = new MatTableDataSource<ResultData>([]); + this.mds.setSpinnerOff(); } else { - this.dataLoading = true; - this.bs.getResultData(this.wds.ws).subscribe( + this.bs.getResultData().subscribe( (resultData: ResultData[]) => { - this.dataLoading = false; this.resultDataSource = new MatTableDataSource<ResultData>(resultData); this.resultDataSource.sort = this.sort; + this.mds.setSpinnerOff(); } ); } @@ -68,16 +68,16 @@ export class ResultsComponent implements OnInit, OnDestroy { this.resultDataSource.data.forEach(row => this.tableselectionCheckbox.select(row)); } - // 444444444444444444444444444444444444444444444444444444444444444444444444444444444444444 downloadResponsesCSV() { if (this.tableselectionCheckbox.selected.length > 0) { - this.dataLoading = true; const selectedGroups: string[] = []; this.tableselectionCheckbox.selected.forEach(element => { selectedGroups.push(element.groupname); }); - this.bs.getResponses(this.wds.ws, selectedGroups).subscribe( + this.mds.setSpinnerOn(); + this.bs.getResponses(selectedGroups).subscribe( (responseData: UnitResponse[]) => { + this.mds.setSpinnerOff(); if (responseData.length > 0) { const columnDelimiter = ';'; const lineDelimiter = '\n'; @@ -126,21 +126,21 @@ export class ResultsComponent implements OnInit, OnDestroy { this.snackBar.open('Keine Daten verfügbar.', 'Fehler', {duration: 3000}); } this.tableselectionCheckbox.clear(); - this.dataLoading = false; - }); + }); } } // 444444444444444444444444444444444444444444444444444444444444444444444444444444444444444 downloadReviewsCSV() { if (this.tableselectionCheckbox.selected.length > 0) { - this.dataLoading = true; const selectedGroups: string[] = []; this.tableselectionCheckbox.selected.forEach(element => { selectedGroups.push(element.groupname); }); - this.bs.getReviews(this.wds.ws, selectedGroups).subscribe( + this.mds.setSpinnerOn(); + this.bs.getReviews(selectedGroups).subscribe( (responseData: ReviewData[]) => { + this.mds.setSpinnerOff(); if (responseData.length > 0) { // collect categories const allCategories: string[] = []; @@ -188,7 +188,6 @@ export class ResultsComponent implements OnInit, OnDestroy { this.snackBar.open('Keine Daten verfügbar.', 'Fehler', {duration: 3000}); } this.tableselectionCheckbox.clear(); - this.dataLoading = false; }); } } @@ -196,13 +195,14 @@ export class ResultsComponent implements OnInit, OnDestroy { // 444444444444444444444444444444444444444444444444444444444444444444444444444444444444444 downloadLogsCSV() { if (this.tableselectionCheckbox.selected.length > 0) { - this.dataLoading = true; const selectedGroups: string[] = []; this.tableselectionCheckbox.selected.forEach(element => { selectedGroups.push(element.groupname); }); - this.bs.getLogs(this.wds.ws, selectedGroups).subscribe( + this.mds.setSpinnerOn(); + this.bs.getLogs(selectedGroups).subscribe( (responseData: LogData[]) => { + this.mds.setSpinnerOff(); if (responseData.length > 0) { const columnDelimiter = ';'; const lineDelimiter = '\n'; @@ -222,7 +222,6 @@ export class ResultsComponent implements OnInit, OnDestroy { this.snackBar.open('Keine Daten verfügbar.', 'Fehler', {duration: 3000}); } this.tableselectionCheckbox.clear(); - this.dataLoading = false; }); } } @@ -253,22 +252,18 @@ export class ResultsComponent implements OnInit, OnDestroy { dialogRef.afterClosed().subscribe(result => { if (result !== false) { - // ========================================================= - this.dataLoading = true; - this.bs.deleteData(this.wds.ws, selectedGroups).subscribe(() => { - this.tableselectionCheckbox.clear(); - this.dataLoading = false; - // TODO refresh list! - }); - } - }); - } - } - - // % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % - ngOnDestroy() { - if (this.workspaceIdSubscription !== null) { - this.workspaceIdSubscription.unsubscribe(); + this.mds.setSpinnerOn(); + this.bs.deleteData(selectedGroups).subscribe((ok: boolean) => { + if (ok) { + this.snackBar.open('Löschen erfolgreich.', 'Ok.', {duration: 3000}); + } else { + this.snackBar.open('Löschen nicht erfolgreich.', 'Fehler', {duration: 3000}); + } + this.tableselectionCheckbox.clear(); + this.updateTable() + }); + } + }); } } } diff --git a/src/app/workspace-admin/syscheck/syscheck.component.html b/src/app/workspace-admin/syscheck/syscheck.component.html index efb4ac25c50442d4650ad880236b8c53c6bc5a75..37712264c7f206a43da0861a27c3312400718163 100644 --- a/src/app/workspace-admin/syscheck/syscheck.component.html +++ b/src/app/workspace-admin/syscheck/syscheck.component.html @@ -1,7 +1,4 @@ <div class="columnhost" fxLayout="column"> - <div class="spinner-container" *ngIf="dataLoading"> - <mat-spinner></mat-spinner> - </div> <div fxLayout="row" fxLayoutGap="10px"> <button mat-raised-button (click)="downloadReportsCSV()" [disabled]="!tableselectionCheckbox.hasValue()" matTooltip="Download Berichte als CSV für Excel" matTooltipPosition="above"> diff --git a/src/app/workspace-admin/syscheck/syscheck.component.spec.ts b/src/app/workspace-admin/syscheck/syscheck.component.spec.ts index b1210159f5a75b9fd205fab50fdd402ff2e2be8f..4377c7b57c2ef0f56dd511b73df2c8cd784e5e82 100644 --- a/src/app/workspace-admin/syscheck/syscheck.component.spec.ts +++ b/src/app/workspace-admin/syscheck/syscheck.component.spec.ts @@ -1,14 +1,28 @@ import { async, ComponentFixture, TestBed } from '@angular/core/testing'; import { SyscheckComponent } from './syscheck.component'; +import {HttpClientModule} from "@angular/common/http"; +import {BackendService} from "../backend.service"; +import {MatDialogModule} from "@angular/material/dialog"; +import {MatSnackBarModule} from "@angular/material/snack-bar"; +import {WorkspaceDataService} from "../workspacedata.service"; -describe('SyscheckComponent', () => { +describe('Workspace-Admin: SyscheckComponent', () => { let component: SyscheckComponent; let fixture: ComponentFixture<SyscheckComponent>; beforeEach(async(() => { TestBed.configureTestingModule({ - declarations: [ SyscheckComponent ] + declarations: [ SyscheckComponent ], + imports: [ + HttpClientModule, + MatDialogModule, + MatSnackBarModule + ], + providers: [ + BackendService, + WorkspaceDataService + ] }) .compileComponents(); })); diff --git a/src/app/workspace-admin/syscheck/syscheck.component.ts b/src/app/workspace-admin/syscheck/syscheck.component.ts index b075f597791043cfabd84f9409064164afe5f253..0c53dd268c103e91809df632242166ea359e8b99 100644 --- a/src/app/workspace-admin/syscheck/syscheck.component.ts +++ b/src/app/workspace-admin/syscheck/syscheck.component.ts @@ -1,4 +1,4 @@ -import {ConfirmDialogComponent, ConfirmDialogData, ServerError} from 'iqb-components'; +import {ConfirmDialogComponent, ConfirmDialogData} from 'iqb-components'; import { Component, OnInit, ViewChild } from '@angular/core'; import { BackendService } from '../backend.service'; import { MatDialog } from '@angular/material/dialog'; @@ -8,7 +8,7 @@ import { MatTableDataSource } from '@angular/material/table'; import { SelectionModel } from '@angular/cdk/collections'; import { saveAs } from 'file-saver'; import { SysCheckStatistics } from '../workspace.interfaces'; -import { WorkspaceDataService } from '../workspacedata.service'; +import {MainDataService} from "../../maindata.service"; @Component({ @@ -20,30 +20,31 @@ export class SyscheckComponent implements OnInit { public resultDataSource = new MatTableDataSource<SysCheckStatistics>([]); // prepared for selection if needed sometime public tableselectionCheckbox = new SelectionModel<SysCheckStatistics>(true, []); - public dataLoading = false; @ViewChild(MatSort, { static: true }) sort: MatSort; constructor( private bs: BackendService, private deleteConfirmDialog: MatDialog, - public wds: WorkspaceDataService, + private mds: MainDataService, public snackBar: MatSnackBar ) { } ngOnInit() { - this.updateTable(); + setTimeout(() => { + this.mds.setSpinnerOn(); + this.updateTable(); + }) } updateTable() { - this.dataLoading = true; this.tableselectionCheckbox.clear(); - this.bs.getSysCheckReportList(this.wds.ws).subscribe( + this.bs.getSysCheckReportList().subscribe( (resultData: SysCheckStatistics[]) => { - this.dataLoading = false; this.resultDataSource = new MatTableDataSource<SysCheckStatistics>(resultData); this.resultDataSource.sort = this.sort; + this.mds.setSpinnerOff(); } ); } @@ -62,24 +63,28 @@ export class SyscheckComponent implements OnInit { downloadReportsCSV() { - if (this.tableselectionCheckbox.selected.length > 0) { - this.dataLoading = true; const selectedReports: string[] = []; this.tableselectionCheckbox.selected.forEach(element => { selectedReports.push(element.id); }); // TODO determine OS dependent line ending char and use this - this.bs.getSysCheckReport(this.wds.ws, selectedReports, ';', '"', '\n').subscribe( - (reportData: Blob) => { - if (reportData.size > 0) { - saveAs(reportData, 'iqb-testcenter-syscheckreports.csv'); - } else { + this.mds.setSpinnerOn(); + this.bs.getSysCheckReport(selectedReports, ';', '"', '\n').subscribe( + (response) => { + this.mds.setSpinnerOff(); + if (response === false) { this.snackBar.open('Keine Daten verfügbar.', 'Fehler', {duration: 3000}); + } else { + const reportData = response as Blob; + if (reportData.size > 0) { + saveAs(reportData, 'iqb-testcenter-syscheckreports.csv'); + } else { + this.snackBar.open('Keine Daten verfügbar.', 'Fehler', {duration: 3000}); + } + this.tableselectionCheckbox.clear(); } - this.tableselectionCheckbox.clear(); - this.dataLoading = false; - }); + }); } } @@ -108,29 +113,18 @@ export class SyscheckComponent implements OnInit { }); dialogRef.afterClosed().subscribe(result => { - if (result !== false) { - - this.dataLoading = true; - this.bs.deleteSysCheckReports(this.wds.ws, selectedReports).subscribe((fileDeletionReport) => { - - if (fileDeletionReport instanceof ServerError) { - this.wds.setNewErrorMsg(fileDeletionReport as ServerError); - } else { - - const message = []; - if (fileDeletionReport.deleted.length > 0) { - message.push(fileDeletionReport.deleted.length + ' Dateien erfolgreich gelöscht.'); - } - if (fileDeletionReport.not_allowed.length > 0) { - message.push(fileDeletionReport.not_allowed.length + ' Dateien konnten nicht gelöscht werden.'); - } - - this.snackBar.open(message.join('<br>'), message.length > 1 ? 'Achtung' : '', {duration: 1000}); - - this.updateTable(); - this.wds.setNewErrorMsg(); + this.mds.setSpinnerOn(); + this.bs.deleteSysCheckReports(selectedReports).subscribe((fileDeletionReport) => { + const message = []; + if (fileDeletionReport.deleted.length > 0) { + message.push(fileDeletionReport.deleted.length + ' Berichte erfolgreich gelöscht.'); + } + if (fileDeletionReport.not_allowed.length > 0) { + message.push(fileDeletionReport.not_allowed.length + ' Berichte konnten nicht gelöscht werden.'); } + this.snackBar.open(message.join('<br>'), message.length > 1 ? 'Achtung' : '', {duration: 1000}); + this.updateTable(); }); } }); diff --git a/src/app/workspace-admin/workspace.component.html b/src/app/workspace-admin/workspace.component.html index 6f5cf00c4d26e4735c49e8b90d0cc25c25d8e7df..8bd3f2db9d742240fff08a0fa71e2812b3b20ffe 100644 --- a/src/app/workspace-admin/workspace.component.html +++ b/src/app/workspace-admin/workspace.component.html @@ -1,17 +1,9 @@ -<div id="buttonsContainer" fxLayout="row" fxLayoutAlign="start center"> - <a [routerLink]="['/']"> - <img src="assets/IQB-LogoA.png" matTooltip="Startseite"/> - </a> - <div fxLayout="row wrap" fxLayoutAlign="space-between center" fxFlex> - <div class="error-msg">{{ (mds.globalErrorMsg$ | async)?.labelNice }}</div> - <div>IQB-Testcenter Verwaltung</div> - <div>{{ wds.wsName }} ({{ wds.wsRole }})</div> - </div> +<div class="page-header"> + <p>IQB-Testcenter Verwaltung: {{wds.wsName}} ({{ wds.wsRole }})</p> </div> + <div class="page-body"> <div class="adminbackground"> - - <nav mat-tab-nav-bar> <a mat-tab-link *ngFor="let link of wds.navLinks" diff --git a/src/app/workspace-admin/workspace.component.spec.ts b/src/app/workspace-admin/workspace.component.spec.ts index 4ea31a8f29e3256b71a7d1772483fae203751971..95bb4ab77b94a36fa24b4f5713b114913241c3e2 100644 --- a/src/app/workspace-admin/workspace.component.spec.ts +++ b/src/app/workspace-admin/workspace.component.spec.ts @@ -1,6 +1,10 @@ import { async, ComponentFixture, TestBed } from '@angular/core/testing'; import { WorkspaceComponent } from './workspace.component'; +import {AppRoutingModule} from "../app-routing.module"; +import {HttpClientModule} from "@angular/common/http"; +import {WorkspaceDataService} from "./workspacedata.service"; +import {MainDataService} from "../maindata.service"; describe('WorkspaceComponent', () => { let component: WorkspaceComponent; @@ -8,7 +12,9 @@ describe('WorkspaceComponent', () => { beforeEach(async(() => { TestBed.configureTestingModule({ - declarations: [ WorkspaceComponent ] + declarations: [ WorkspaceComponent ], + imports: [AppRoutingModule, HttpClientModule], + providers: [WorkspaceDataService, MainDataService] }) .compileComponents(); })); diff --git a/src/app/workspace-admin/workspace.component.ts b/src/app/workspace-admin/workspace.component.ts index 3958ab13f6ac91b3d8f3915e181c4d71ae02594c..0a388eb8bff501f87571e89501acb3b220363374 100644 --- a/src/app/workspace-admin/workspace.component.ts +++ b/src/app/workspace-admin/workspace.component.ts @@ -1,8 +1,8 @@ import { WorkspaceDataService } from './workspacedata.service'; -import { MainDataService } from '../maindata.service'; import { ActivatedRoute } from '@angular/router'; import { Subscription } from 'rxjs'; import { Component, OnInit, OnDestroy } from '@angular/core'; +import {BackendService} from "./backend.service"; @Component({ @@ -11,32 +11,30 @@ import { Component, OnInit, OnDestroy } from '@angular/core'; }) export class WorkspaceComponent implements OnInit, OnDestroy { private routingSubscription: Subscription = null; - private logindataSubscription: Subscription = null; constructor( private route: ActivatedRoute, - public mds: MainDataService, + private bs: BackendService, public wds: WorkspaceDataService ) { } ngOnInit() { this.routingSubscription = this.route.params.subscribe(params => { - const ws = Number(params['ws']); - this.wds.setWorkspace(ws); - }); - - this.logindataSubscription = this.mds.loginData$.subscribe(() => { - this.wds.setWorkspace(this.wds.ws); + this.wds.wsId = params['ws']; + this.bs.getWorkspaceData(this.wds.wsId).subscribe( + wsData => { + if (typeof wsData !== 'number') { + this.wds.wsName = wsData.name; + this.wds.wsRole = wsData.role; + } + } + ) }); } - ngOnDestroy() { if (this.routingSubscription !== null) { this.routingSubscription.unsubscribe(); } - if (this.logindataSubscription !== null) { - this.logindataSubscription.unsubscribe(); - } } } diff --git a/src/app/workspace-admin/workspace.interfaces.ts b/src/app/workspace-admin/workspace.interfaces.ts index b53f17d1622617ce9b17a3e4f533e1666f7ee912..75df462de5143db0af7e28afd402d74c5b8877b5 100644 --- a/src/app/workspace-admin/workspace.interfaces.ts +++ b/src/app/workspace-admin/workspace.interfaces.ts @@ -1,3 +1,9 @@ +export interface WorkspaceData { + id: string; + name: string; + role: "RW" | "RO" | "n.d."; +} + export interface GetFileResponseData { filename: string; filesize: number; @@ -9,13 +15,13 @@ export interface GetFileResponseData { isChecked: boolean; } -export interface CheckWorkspaceResponseData { +export interface CheckWorkspaceResponseData +{ errors: string[]; infos: string[]; warnings: string[]; } - export interface GroupResponse { name: string; testsTotal: number; diff --git a/src/app/workspace-admin/workspace.module.spec.ts b/src/app/workspace-admin/workspace.module.spec.ts new file mode 100644 index 0000000000000000000000000000000000000000..bc7720176082462396ff38874478b177ee3c3c15 --- /dev/null +++ b/src/app/workspace-admin/workspace.module.spec.ts @@ -0,0 +1,13 @@ +import {WorkspaceModule} from "./workspace.module"; + +describe('WorkspaceModule', () => { + let workspaceModule: WorkspaceModule; + + beforeEach(() => { + workspaceModule = new WorkspaceModule(); + }); + + it('should create an instance', () => { + expect(workspaceModule).toBeTruthy(); + }); +}); diff --git a/src/app/workspace-admin/workspacedata.service.spec.ts b/src/app/workspace-admin/workspacedata.service.spec.ts index 4efb2cb6ef585b014ba53d398f1defc114ef4ac8..95f8d42cbe66a5d26553c5b33121c299eb17c58b 100644 --- a/src/app/workspace-admin/workspacedata.service.spec.ts +++ b/src/app/workspace-admin/workspacedata.service.spec.ts @@ -1,10 +1,12 @@ import { TestBed, inject } from '@angular/core/testing'; import { WorkspaceDataService } from './workspacedata.service'; +import {HttpClientModule} from "@angular/common/http"; describe('WorkspaceDataService', () => { beforeEach(() => { TestBed.configureTestingModule({ + imports: [HttpClientModule], providers: [WorkspaceDataService] }); }); diff --git a/src/app/workspace-admin/workspacedata.service.ts b/src/app/workspace-admin/workspacedata.service.ts index 1ad6f0061db1c0b221e74806862009147d89211e..c4c7a63f676f91174ca41294a46c77de70e98901 100644 --- a/src/app/workspace-admin/workspacedata.service.ts +++ b/src/app/workspace-admin/workspacedata.service.ts @@ -1,7 +1,4 @@ -import { BehaviorSubject } from 'rxjs'; import { Injectable } from '@angular/core'; -import { ServerError } from 'iqb-components'; -import { MainDataService } from "../maindata.service"; @Injectable({ providedIn: 'root' @@ -9,50 +6,13 @@ import { MainDataService } from "../maindata.service"; @Injectable() export class WorkspaceDataService { - public workspaceId$ = new BehaviorSubject<number>(-1); - public globalErrorMsg$ = new BehaviorSubject<ServerError>(null); + public wsId: string; + public wsRole = 'RW'; + public wsName = ''; - public get ws(): number { - return this.workspaceId$.getValue(); - } - private _wsRole = ''; - public get wsRole(): string { - return this._wsRole; - } - private _wsName = ''; - public get wsName(): string { - return this._wsName; - } public navLinks = [ {path: 'files', label: 'Dateien'}, {path: 'syscheck', label: 'System-Check Berichte'}, {path: 'results', label: 'Ergebnisse/Antworten'} ]; - - constructor( - private mds: MainDataService - ) {} - - setNewErrorMsg(err: ServerError = null) { - this.globalErrorMsg$.next(err); - } - - setWorkspace(newId: number) { - this._wsName = ''; - this._wsRole = ''; - if (newId > 0) { - const myLoginData = this.mds.loginData$.getValue(); - if ((myLoginData !== null) && (myLoginData.workspaces.length > 0)) { - for (let i = 0; i < myLoginData.workspaces.length; i++) { - if (myLoginData.workspaces[i].id == newId) { - this._wsName = myLoginData.workspaces[i].name; - this._wsRole = myLoginData.workspaces[i].role; - break; - } - } - } - } - - this.workspaceId$.next(newId); - } } diff --git a/src/app/workspace-monitor/backend.service.spec.ts b/src/app/workspace-monitor/backend.service.spec.ts index c31039d7e5bcc7bc70e7213ce06744a0dc6ed009..ffdc1397ca5ced3a08516d7183bbc820c1001627 100644 --- a/src/app/workspace-monitor/backend.service.spec.ts +++ b/src/app/workspace-monitor/backend.service.spec.ts @@ -1,14 +1,16 @@ import { TestBed, inject } from '@angular/core/testing'; import { BackendService } from './backend.service'; +import {HttpClientModule} from "@angular/common/http"; -describe('BackendService', () => { + +describe('HttpClient testing', () => { beforeEach(() => { TestBed.configureTestingModule({ + imports: [HttpClientModule], providers: [BackendService] }); }); - it('should be created', inject([BackendService], (service: BackendService) => { expect(service).toBeTruthy(); })); diff --git a/src/app/workspace-monitor/backend.service.ts b/src/app/workspace-monitor/backend.service.ts index 2730e41ce6996bfc1cf9d49f7de2623441700a23..ac1d1bf6bb4c730163097990e707c3abaa5c1a2f 100644 --- a/src/app/workspace-monitor/backend.service.ts +++ b/src/app/workspace-monitor/backend.service.ts @@ -5,7 +5,9 @@ import { Observable } from 'rxjs'; import { catchError } from 'rxjs/operators'; import { ErrorHandler, ServerError } from 'iqb-components'; -@Injectable() +@Injectable({ + providedIn: 'root' +}) export class BackendService { private serverUrlSlim = ''; diff --git a/src/app/workspace-monitor/workspace-monitor-routing.module.ts b/src/app/workspace-monitor/workspace-monitor-routing.module.ts index 092b0238864595f2de4699ab163ee0c9ed2fddaa..1545e919e6c089392fcb2f4ff8ad2876d9c90827 100644 --- a/src/app/workspace-monitor/workspace-monitor-routing.module.ts +++ b/src/app/workspace-monitor/workspace-monitor-routing.module.ts @@ -4,7 +4,7 @@ import {WorkspaceMonitorComponent} from "./workspace-monitor.component"; const routes: Routes = [ { - path: ':ws', + path: '', component: WorkspaceMonitorComponent }]; diff --git a/src/app/workspace-monitor/workspace-monitor.component.html b/src/app/workspace-monitor/workspace-monitor.component.html index 046fd7e769064f524a234f74258fd7b7a0d4a511..920f5a8a60107b5bc311b3afc93d48d87b6460a5 100644 --- a/src/app/workspace-monitor/workspace-monitor.component.html +++ b/src/app/workspace-monitor/workspace-monitor.component.html @@ -3,7 +3,6 @@ <img src="assets/IQB-LogoA.png" matTooltip="Startseite"/> </a> <div fxLayout="row wrap" fxLayoutAlign="space-between center" fxFlex> - <div class="error-msg">{{ (mds.globalErrorMsg$ | async)?.labelNice }}</div> <div>IQB-Testcenter Monitor</div> <div>{{ workspaceName }}</div> </div> @@ -12,7 +11,7 @@ <div class="adminbackground"> <div class="columnhost" fxLayout="column"> - <div class="spinner-container" *ngIf="dataLoading"> + <div class="spinner" *ngIf="dataLoading"> <mat-spinner></mat-spinner> </div> <div fxLayout="row"> diff --git a/src/app/workspace-monitor/workspace-monitor.component.spec.ts b/src/app/workspace-monitor/workspace-monitor.component.spec.ts index 9af2d0a536cb1caf65f0afa15bd403bce02cd158..16b3e52b276aecaa9b063ca13e7c6f91853b7a58 100644 --- a/src/app/workspace-monitor/workspace-monitor.component.spec.ts +++ b/src/app/workspace-monitor/workspace-monitor.component.spec.ts @@ -1,6 +1,10 @@ import { async, ComponentFixture, TestBed } from '@angular/core/testing'; import { WorkspaceMonitorComponent } from './workspace-monitor.component'; +import {HttpClientModule} from "@angular/common/http"; +import {BackendService} from "./backend.service"; +import {AppRoutingModule} from "../app-routing.module"; +import {MatSnackBarModule} from "@angular/material/snack-bar"; describe('WorkspaceMonitorComponent', () => { let component: WorkspaceMonitorComponent; @@ -8,7 +12,15 @@ describe('WorkspaceMonitorComponent', () => { beforeEach(async(() => { TestBed.configureTestingModule({ - declarations: [ WorkspaceMonitorComponent ] + declarations: [ WorkspaceMonitorComponent ], + imports: [ + HttpClientModule, + AppRoutingModule, + MatSnackBarModule + ], + providers: [ + BackendService + ] }) .compileComponents(); })); diff --git a/src/app/workspace-monitor/workspace-monitor.component.ts b/src/app/workspace-monitor/workspace-monitor.component.ts index 6600d78b65e29fa9301d9b5da06d64244652fbfb..a24039f645d0d827185925daa9e72baf9e1bc422 100644 --- a/src/app/workspace-monitor/workspace-monitor.component.ts +++ b/src/app/workspace-monitor/workspace-monitor.component.ts @@ -37,8 +37,7 @@ export class WorkspaceMonitorComponent implements OnInit, OnDestroy { ngOnInit() { this.routingSubscription = this.route.params.subscribe(params => { this.workspaceId = Number(params['ws']); - const ld = this.mds.loginData$.getValue(); - this.workspaceName = ld.workspaceName; + this.workspaceName = 'xx'; // TODO where to get the workspace name from? this.updateTable(); }); } @@ -114,7 +113,6 @@ export class WorkspaceMonitorComponent implements OnInit, OnDestroy { }); this.bs.lockBooklets(this.workspaceId, selectedGroups).subscribe(success => { if (success instanceof ServerError) { - this.mds.globalErrorMsg$.next(success as ServerError); this.snackBar.open('Testhefte konnten nicht gesperrt werden.', 'Systemfehler', {duration: 3000}); } else { const ok = success as boolean; @@ -139,7 +137,6 @@ export class WorkspaceMonitorComponent implements OnInit, OnDestroy { }); this.bs.unlockBooklets(this.workspaceId, selectedGroups).subscribe(success => { if (success instanceof ServerError) { - this.mds.globalErrorMsg$.next(success as ServerError); this.snackBar.open('Testhefte konnten nicht freigegeben werden.', 'Systemfehler', {duration: 3000}); } else { const ok = success as boolean; diff --git a/src/app/workspace-monitor/workspace-monitor.module.spec.ts b/src/app/workspace-monitor/workspace-monitor.module.spec.ts new file mode 100644 index 0000000000000000000000000000000000000000..0ce77493a4775b7b0fe8d128c22a2eaa06a56a16 --- /dev/null +++ b/src/app/workspace-monitor/workspace-monitor.module.spec.ts @@ -0,0 +1,13 @@ +import {WorkspaceMonitorModule} from "./workspace-monitor.module"; + +describe('WorkspaceMonitorModule', () => { + let workspaceMonitorModule: WorkspaceMonitorModule; + + beforeEach(() => { + workspaceMonitorModule = new WorkspaceMonitorModule(); + }); + + it('should create an instance', () => { + expect(workspaceMonitorModule).toBeTruthy(); + }); +}); diff --git a/src/app/workspace-monitor/workspace-monitor.module.ts b/src/app/workspace-monitor/workspace-monitor.module.ts index fdef3e3944e6f27cd20513bf61fd437d28d47d47..0ae150d067ac01b1635ea78d7b68e58b1c8cdc3f 100644 --- a/src/app/workspace-monitor/workspace-monitor.module.ts +++ b/src/app/workspace-monitor/workspace-monitor.module.ts @@ -14,6 +14,7 @@ import {MatTooltipModule} from "@angular/material/tooltip"; import {MatCheckboxModule} from "@angular/material/checkbox"; import {ReactiveFormsModule} from "@angular/forms"; import {MatButtonModule} from "@angular/material/button"; +import {BackendService} from "./backend.service"; @NgModule({ @@ -32,6 +33,9 @@ import {MatButtonModule} from "@angular/material/button"; MatTooltipModule, MatCheckboxModule, MatButtonModule + ], + providers: [ + BackendService ] }) export class WorkspaceMonitorModule { } diff --git a/src/environments/environment.build.ts b/src/environments/environment.build.ts index f995f058d5591b1c4c20dbb6c10a9fde747feafd..4cb6d6703bb81afb7d5dfa1b899d4b55e3552069 100644 --- a/src/environments/environment.build.ts +++ b/src/environments/environment.build.ts @@ -5,5 +5,6 @@ export const environment = { testcenterUrl: '/', appName: 'IQB-Testcenter', appPublisher: 'IQB - Institut zur Qualitätsentwicklung im Bildungswesen', - appVersion: '1.5.2 - 12.2.2020' + appVersion: '1.5.2 - 12.2.2020', + apiVersionExpected: '2.2.0' }; diff --git a/src/environments/environment.prod.ts b/src/environments/environment.prod.ts index 59bddd5fde1ba9790a98f38f0a008e206215323c..837a9d16cc07240e292e522c368fb9a88442bb9f 100644 --- a/src/environments/environment.prod.ts +++ b/src/environments/environment.prod.ts @@ -2,8 +2,9 @@ export const environment = { production: true, - testcenterUrl: '/', + testcenterUrl: '/api/', appName: 'IQB-Testcenter', appPublisher: 'IQB - Institut zur Qualitätsentwicklung im Bildungswesen', - appVersion: '1.5.3 - 20.2.2020' + appVersion: '2.0.0-beta.3 - 29.4.2020', + apiVersionExpected: '2.2.0' }; diff --git a/src/environments/environment.ts b/src/environments/environment.ts index 1c41f17b6d7745b7771dae6e379e6f797772eae9..fefaeffc48e6179e2617b4fc86893c08dd248ada 100644 --- a/src/environments/environment.ts +++ b/src/environments/environment.ts @@ -4,12 +4,14 @@ export const environment = { production: false, - // testcenterUrl: 'https://ocba.iqb.hu-berlin.de/api/', + // testcenterUrl: 'http://localhost/2020/testcenter-iqb-php-postgrestest/', + testcenterUrl: 'https://ocba.iqb.hu-berlin.de/api/', // testcenterUrl: 'https://www.iqb-testcenter.de/', - testcenterUrl: 'http://localhost/api/', + // testcenterUrl: 'http://localhost/api/', appName: 'IQB-Testcenter', appPublisher: 'IQB - Institut zur Qualitätsentwicklung im Bildungswesen', - appVersion: '0 (dev)' + appVersion: '2.0.0-beta.2 - 27.4.2020', + apiVersionExpected: '3.0.0' }; /* diff --git a/src/main.ts b/src/main.ts index d7f325347b08f5e23facd85230eaa05ebce25ca0..7f12f939408d1589a1f0906c6c4bd99c7d492167 100644 --- a/src/main.ts +++ b/src/main.ts @@ -1,4 +1,4 @@ -import { enableProdMode } from '@angular/core'; +import {enableProdMode, StaticProvider} from '@angular/core'; import { platformBrowserDynamic } from '@angular/platform-browser-dynamic'; import { AppModule } from './app/app.module'; @@ -8,7 +8,7 @@ if (environment.production) { enableProdMode(); } -platformBrowserDynamic([ +platformBrowserDynamic(<StaticProvider[]>[ { provide: 'SERVER_URL', useValue: environment.testcenterUrl @@ -24,6 +24,14 @@ platformBrowserDynamic([ { provide: 'APP_VERSION', useValue: environment.appVersion + }, + { + provide: 'API_VERSION_EXPECTED', + useValue: environment.apiVersionExpected + }, + { + provide: 'IS_PRODUCTION_MODE', + useValue: environment.production } ]).bootstrapModule(AppModule) .catch(err => console.log(err)); diff --git a/src/polyfills.ts b/src/polyfills.ts index 93b907b6b190dff95cc84a5472311fc5a29a5a73..d753e51e1c80b941342624186da5befc6e937e0a 100644 --- a/src/polyfills.ts +++ b/src/polyfills.ts @@ -80,12 +80,4 @@ import 'web-animations-js'; // Run `npm install --save web-animations-js`. /*************************************************************************************************** * Zone JS is required by default for Angular itself. */ -import 'zone.js/dist/zone'; // Included with Angular CLI. - - - -/*************************************************************************************************** - * APPLICATION IMPORTS - */ - -import 'hammerjs'; +import 'zone.js/dist/zone'; diff --git a/src/scripts/findCustomTexts.js b/src/scripts/findCustomTexts.js new file mode 100644 index 0000000000000000000000000000000000000000..b6010f862b93c4e50f964ca65e8a2ceb2d8cc52b --- /dev/null +++ b/src/scripts/findCustomTexts.js @@ -0,0 +1,95 @@ +// analysis of source code (html, ts): +// listing of all used keys for customText + +const fs = require("fs"); +const definitionFilename = '../app/config/custom-texts.json'; +const startFolder = '../app'; +const mdSourceFilename = '../app/config/custom-texts.md'; +const mdTargetFilename = '../../docs/custom-texts.md'; + +let foundKeys = {}; +let foundSourceFiles = []; +let foundError = false; + +function analyse ( fileName, isHtml ) { + const fileContent = fs.readFileSync(fileName, 'utf8').toString(); + + const searchPattern = isHtml ? /\|\s*customtext:\s*'\w+'/g : /\.getCustomText\s*\(\s*'\w+'\s*\)/g; + const matches = fileContent.match(searchPattern); + if (matches) { + foundSourceFiles.push(fileName); + for (let i = 0; i < matches.length; i++) { + const posStart = matches[i].indexOf("'"); + const posEnd = matches[i].lastIndexOf("'"); + const foundKey = matches[i].substr(posStart + 1, posEnd - posStart - 1); + if (foundKeys[foundKey]) { + foundKeys[foundKey] += 1; + } else { + foundKeys[foundKey] = 1; + } + } + } +} + +function takeFolder(sourceFolder ) { + const dirEntries = fs.readdirSync(sourceFolder); + for (let i = 0; i < dirEntries.length; i++) { + const fullObjectName = sourceFolder + '/' + dirEntries[i]; + const stats = fs.statSync(fullObjectName); + if (stats.isDirectory()) { + takeFolder(fullObjectName); + } else if (stats.isFile()) { + const dotPos = fullObjectName.lastIndexOf('.'); + if (dotPos > 0) { + const fileExtension = fullObjectName.substr(dotPos + 1); + if (fileExtension.toUpperCase() === 'TS') { + analyse(fullObjectName, false); + } else if (fileExtension.toUpperCase() === 'HTML') { + analyse(fullObjectName, true); + } + } + } + } +} + +takeFolder(startFolder); + +const defaults = JSON.parse(fs.readFileSync(definitionFilename)); + +console.log(); +console.log('\x1b[33m%s\x1b[0m', 'used keys:'); +for (const k of Object.keys(foundKeys)) { + if (defaults[k]) { + console.log(` ${k}: ${foundKeys[k]}`); + } else { + foundError = true; + console.log('\x1b[31m%s\x1b[0m', ` ${k}: ${foundKeys[k]}`) + } +} + +console.log(); +console.log('\x1b[33m%s\x1b[0m', 'found in:'); +for (const f of foundSourceFiles) { + console.log(` ${f}`); +} + +console.log(); +console.log('\x1b[33m%s\x1b[0m', 'not used:'); +for (const k of Object.keys(defaults)) { + if (!foundKeys[k]) { + console.log(` ${k}`); + } +} + +if (!foundError) { + console.log(''); + console.log('writing markdown'); + let mdContent = fs.readFileSync(mdSourceFilename, 'utf8').toString(); + for (const k of Object.keys(defaults)) { + mdContent += '|`' + k + '`|' + defaults[k].label + '|' + defaults[k].defaultvalue + '|' + '\n'; + } + fs.writeFileSync(mdTargetFilename, mdContent, "utf8"); +} + +console.log(''); +console.log('done.'); diff --git a/src/scripts/generateBookletConfigClass.js b/src/scripts/generateBookletConfigClass.js new file mode 100644 index 0000000000000000000000000000000000000000..105216d5be259e2be8d2f40e42374f74ff9da2d8 --- /dev/null +++ b/src/scripts/generateBookletConfigClass.js @@ -0,0 +1,58 @@ +// generates booklet-config.ts as class with all data from JSON: + +const fs = require("fs"); +const definitionFilename = '../app/config/booklet-config.json'; +const targetTsFilename = '../app/config/booklet-config.ts'; +const mdSourceFilename = '../app/config/booklet-config.md'; +const mdTargetFilename = '../../docs/booklet-config.md'; + +console.log(''); +console.log('writing TypeScript'); + +const definition = JSON.parse(fs.readFileSync(definitionFilename)); + +let fileContent = "export class BookletConfig {\n"; +fileContent += "\t// this file is generated by 'generateBookletConfigClass' script from 'app/config/booklet-config.json'\n"; +fileContent += "\t// do not change anything here directly!\n\n"; + +for (const k of Object.keys(definition)) { + fileContent += '\t' + k + ': "' + Object.keys(definition[k].options).join('" | "') + '" = "' + definition[k].defaultvalue + '";\n'; +} + +fileContent += "\n\tpublic setFromKeyValuePairs(config) {\n"; +fileContent += "\t\tif (config) {\n"; +for (const k of Object.keys(definition)) { + fileContent += "\t\t\tif (config['" + k + "']) { this." + k + " = config['" + k + "']}\n"; +} +fileContent += "\t\t}\n\t}\n"; + +fileContent += "\n\tpublic setFromXml(bookletConfigElement: Element) {\n"; +fileContent += "\t\tif (bookletConfigElement) {\n"; +fileContent += "\t\t\tconst bookletConfigs = Array.prototype.slice.call(bookletConfigElement.childNodes).filter(function (e) { return e.nodeType === 1; });\n"; +fileContent += "\t\t\tfor (let childIndex = 0; childIndex < bookletConfigs.length; childIndex++) {\n"; +fileContent += "\t\t\t\tconst configKey = bookletConfigs[childIndex].getAttribute('key');\n"; +fileContent += "\t\t\t\tconst configValue = bookletConfigs[childIndex].textContent;\n"; +fileContent += "\t\t\t\tswitch (configKey) {\n"; +for (const k of Object.keys(definition)) { + fileContent += "\t\t\t\t\tcase '" + k + "':\n\t\t\t\t\t\tthis." + k + " = configValue;\n\t\t\t\t\t\tbreak;\n"; +} +fileContent += "\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n"; + + +fileContent += "}\n"; +fs.writeFileSync(targetTsFilename, fileContent, "utf8"); + +console.log(''); +console.log('writing markdown'); +let mdContent = fs.readFileSync(mdSourceFilename, 'utf8').toString(); +for (const k of Object.keys(definition)) { + mdContent += '\n#### `' + k + '`\n' + definition[k].label + '\n'; + for (const o of Object.keys(definition[k].options)) { + mdContent += ' * "' + o + ((o === definition[k].defaultvalue) ? '" (default): ' : '": ') + definition[k].options[o] + '\n'; + } +} + +fs.writeFileSync(mdTargetFilename, mdContent, "utf8"); + +console.log(''); +console.log('done.'); diff --git a/src/scripts/generateTestModeClass.js b/src/scripts/generateTestModeClass.js new file mode 100644 index 0000000000000000000000000000000000000000..fb8ce134a96590829d83a0c175eabda25d04e966 --- /dev/null +++ b/src/scripts/generateTestModeClass.js @@ -0,0 +1,75 @@ +// generates test-config.ts as class with all data from JSON: + +const fs = require("fs"); +const definitionOptionsFilename = '../app/config/mode-options.json'; +const definitionModesFilename = '../app/config/test-modes.json'; +const targetTsFilename = '../app/config/test-mode.ts'; +const mdSourceFilename = '../app/config/test-mode.md'; +const mdTargetFilename = '../../docs/test-mode.md'; + +console.log(''); +console.log('writing TypeScript'); + +const definitionOptions = JSON.parse(fs.readFileSync(definitionOptionsFilename)); +const definitionModes = JSON.parse(fs.readFileSync(definitionModesFilename)); + +let fileContent = "// @ts-ignore\n"; +fileContent += "import testModes from './test-modes.json';\n\n"; +fileContent += "// this file is generated by 'generateTestModeClass' script from 'app/config/test-modes.json' and 'app/config/mode-options.json'\n"; +fileContent += "// do not change anything here directly!\n\n"; +fileContent += "export class TestMode {\n"; + +const demoConfig = definitionModes.DEMO.config; + +for (const k of Object.keys(definitionOptions)) { + fileContent += '\t' + k + ': ' + (demoConfig[k] ? 'true' : 'false') + ';\n'; +} +fileContent += '\tmodeLabel: "Nur Ansicht (Demo)";\n'; + +fileContent += "\n\tpublic constructor (loginMode: string = 'DEMO') {\n"; +fileContent += "\t\tif (loginMode) {\n"; +fileContent += "\t\t\tconst regExPattern = /(" + Object.keys(definitionModes).join('|') + ")/;\n"; +fileContent += "\t\t\tif (regExPattern.test(loginMode.toUpperCase())) {\n"; +fileContent += "\t\t\t\tconst mode = loginMode.toUpperCase().match(regExPattern)[0];\n"; +fileContent += "\t\t\t\tconst modeConfig = testModes[mode];\n"; +for (const k of Object.keys(definitionOptions)) { + fileContent += "\t\t\t\tthis." + k + " = modeConfig.config." + k + ";\n"; +} +fileContent += "\t\t\t\tthis.modeLabel = modeConfig.label;\n"; + +fileContent += "\t\t\t} else {\n"; +fileContent += "\t\t\t\tconsole.error('TestConfig: invalid loginMode - take DEMO');\n"; +fileContent += "\t\t\t}\n"; +fileContent += "\t\t} else {\n"; +fileContent += "\t\t\tconsole.error('TestConfig: empty loginMode - take DEMO');\n"; +fileContent += "\t\t}\n\t}\n"; + +fileContent += "}\n"; + +fs.writeFileSync(targetTsFilename, fileContent, "utf8"); + +console.log(''); +console.log('writing markdown'); +let mdContent = fs.readFileSync(mdSourceFilename, 'utf8').toString(); + +let tableHeader1 = "| | "; +let tableHeader2 = "| :------------- |"; +for (const k of Object.keys(definitionModes)) { + mdContent += '* `' + k + (k === 'DEMO' ? '` (default): ' : '`: ') + definitionModes[k].label + '\n'; + tableHeader1 += '`' + k + '` | '; + tableHeader2 += " :-------------: |"; +} +mdContent += '\n\n'; +mdContent += tableHeader1 + '\n'; +mdContent += tableHeader2 + '\n'; +for (const ok of Object.keys(definitionOptions)) { + mdContent += '|' + definitionOptions[ok] + '|'; + for (const k of Object.keys(definitionModes)) { + mdContent += definitionModes[k].config[ok] ? 'X |' : ' |'; + } + mdContent += '\n'; +} +fs.writeFileSync(mdTargetFilename, mdContent, "utf8"); + +console.log(''); +console.log('done.'); diff --git a/src/styles.css b/src/styles.css index 8852f84e6530516d18f6f2755fb116ff131ec287..9281e1f7fd90d216ccc345bafd89816d85066fe2 100644 --- a/src/styles.css +++ b/src/styles.css @@ -1,3 +1,9 @@ +:root { + --tc-topmargin: 65px; + --tc-unithost-topmargin: 40px; + --tc-unithost-bottommargin: 45px; +} + /* orienta-regular - latin */ @font-face { font-family: 'Orienta'; @@ -17,6 +23,15 @@ bottom: 0; } +.root-body { + overflow-x: auto; + position: absolute; + width: 100%; + top: 20px; + bottom: 0; + background: linear-gradient(to bottom, #003333, #045659, #0d7b84, #1aa2b2, #2acae5); +} + .sheetofpaper { display: block; position: absolute; @@ -31,32 +46,31 @@ padding: 5px; } -.spinner-container { - position: fixed; - z-index: 999; +.spinner { + bottom: 0; height: 2em; - width: 2em; - overflow: visible; - margin: auto; - top: 0; left: 0; - bottom: 0; + margin: auto; + overflow: visible; + position: fixed; right: 0; + top: 0; + width: 2em; + z-index: 999; } -.spinner-container-local { - z-index: 999; - margin: auto; - top: 0; - left: 0; +.spinner-container-local { /* TODO remove */ + align-items: center; bottom: 0; - right: 0; - text-align: center; display: flex; - align-items: center; justify-content: center; - /*background: rgba(0, 0, 0, 0.3);*/ + left: 0; + margin: auto; position: absolute; + right: 0; + text-align: center; + top: 0; + z-index: 999; } iframe.unitHost { @@ -66,7 +80,7 @@ iframe.unitHost { margin: 0; } -p.unitMessage { +p.unitMessage { /* TODO why here? */ margin: 50px; text-align: center; } @@ -75,20 +89,55 @@ p.unitMessage { position: absolute; left: 5px; top: 5px; + z-index: 999; } div.logo img { width: 100px; } -.pagetitle { +.page-header { position: absolute; left: 140px; - top: 18px; + width: calc(100% - 140px); + top: 0; + padding: 0 10px 0 0; +} + +.page-header mat-toolbar { + position: fixed; + z-index: 100; + top: 4px; + right: 90px; +} + +.page-header mat-icon { + position: relative; + top: -8px; + font-size: 36px; + padding: 2px; +} + +.page-header p { font-size: 1.5em; color: white; } .error-msg { + position: absolute; + left: 40px; + top: 60px; + min-height: 60px; + width: calc(100% - 80px); + font-size: 1.1em; + border-width: 6px; + border-style: solid; + border-color: brown; + background-color: white; color: brown; + z-index: 999; +} + +.error-msg mat-icon { + height: 32px; } diff --git a/src/test.ts b/src/test.ts index 16317897b1c50a3a71bc775a8d6429f2b4c6cf98..09fd92542462eedb86b2b9f372484eec05d5d7f9 100644 --- a/src/test.ts +++ b/src/test.ts @@ -6,13 +6,40 @@ import { BrowserDynamicTestingModule, platformBrowserDynamicTesting } from '@angular/platform-browser-dynamic/testing'; +import {StaticProvider} from "@angular/core"; +import {environment} from "./environments/environment"; declare const require: any; // First, initialize the Angular testing environment. getTestBed().initTestEnvironment( BrowserDynamicTestingModule, - platformBrowserDynamicTesting() + platformBrowserDynamicTesting(<StaticProvider[]>[ + { + provide: 'SERVER_URL', + useValue: environment.testcenterUrl + }, + { + provide: 'APP_PUBLISHER', + useValue: environment.appPublisher + }, + { + provide: 'APP_NAME', + useValue: environment.appName + }, + { + provide: 'APP_VERSION', + useValue: environment.appVersion + }, + { + provide: 'API_VERSION_EXPECTED', + useValue: environment.apiVersionExpected + }, + { + provide: 'IS_PRODUCTION_MODE', + useValue: environment.production + } + ]) ); // Then we find all the tests. const context = require.context('./', true, /\.spec\.ts$/); diff --git a/src/tsconfig.app.json b/src/tsconfig.app.json index 722c370d58793cdaed688bd365de5cedb643e565..f3a1b80180f3b9c50766b56d1bf61b9a73d538e7 100644 --- a/src/tsconfig.app.json +++ b/src/tsconfig.app.json @@ -2,11 +2,13 @@ "extends": "../tsconfig.json", "compilerOptions": { "outDir": "../out-tsc/app", - "module": "es2015", "types": [] }, - "exclude": [ - "src/test.ts", - "**/*.spec.ts" + "files": [ + "main.ts", + "polyfills.ts" + ], + "include": [ + "src/**/*.d.ts" ] } diff --git a/src/tsconfig.spec.json b/src/tsconfig.spec.json index 8f7cedecab86d7612d16ec994e222f92f837f1c0..de7733630eb224b246854a20934f792051926e8f 100644 --- a/src/tsconfig.spec.json +++ b/src/tsconfig.spec.json @@ -2,7 +2,6 @@ "extends": "../tsconfig.json", "compilerOptions": { "outDir": "../out-tsc/spec", - "module": "commonjs", "types": [ "jasmine", "node" diff --git a/tsconfig.json b/tsconfig.json index d47546887c691397afbe24aea3e0d2fbd5ccefc1..4cc3a95745917637d71aafdf1eb610234554570f 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -10,6 +10,7 @@ "declaration": false, "moduleResolution": "node", "emitDecoratorMetadata": true, + "resolveJsonModule": true, "experimentalDecorators": true, "target": "es2015", "typeRoots": [