diff --git a/README.md b/README.md index c0d1f11d4e488ec5a3ec94b96832c5c49948d634..107ccc105144a204a307d18f88eb3a482a040022 100644 --- a/README.md +++ b/README.md @@ -47,7 +47,7 @@ and then : `npm run lint` -# Procédure d'ajout d'une calculette +# Procédure d'ajout d'un module de calcul ## JaLHyd @@ -138,7 +138,7 @@ and then : * Créer les tests unitaires correspondants -* Ajouter une valeur à l'enum _CalculatorType_ pour identifier le type de calculette (par ex _MaCalculette_). +* Ajouter une valeur à l'enum _CalculatorType_ pour identifier le type de module de calcul (par ex _MaCalculette_). * Compléter la méthode _Session.createNub()_. @@ -146,7 +146,7 @@ and then : ## ngHyd -* Créer les fichiers de configuration de la calculette +* Créer les fichiers de configuration du module de calcul - dans _src/app/calculators_ : créer un répertoire (par ex _ma-calculette_) - dans _src/app/calculators/ma-calculette_ : @@ -155,7 +155,7 @@ and then : Les ids utilisés doivent correspondre au symbole fourni à classe _ParamDefinition_ (1er paramètre du constructeur) Ne pas oublier de spécifier : - - éventuellement le type de noeud par défaut de la calculette dans les options avec le champ "_defaultNodeType_". Si ce champ est absent, sa valeur est "_ComputeNodeType.None_". Ce champ sert par ex pour les sections paramétrées à déterminer le type de section à afficher lors de la création de la calculette. + - éventuellement le type de noeud par défaut du module de calcul dans les options avec le champ "_defaultNodeType_". Si ce champ est absent, sa valeur est "_ComputeNodeType.None_". Ce champ sert par ex pour les sections paramétrées à déterminer le type de section à afficher lors de la création du module de calcul. - éventuellement le type de noeud de paramètres particuliers (objets comportant _"type":"input"_) avec le champ _"nodeType": "MaCalculetteBleue"_ (par défaut, "_ComputeNodeType.None_") @@ -178,7 +178,7 @@ and then : On peut soit composer la classe concrète directement avec ces classes, soient dériver ces dernières et composer avec. * _src/locale/error_messages.<langue>.json_ : - Ajouter un champ pour le titre de la calculette. Par exemple : + Ajouter un champ pour le titre du module de calcul. Par exemple : _"INFO_MACALC_TITRE": "Ma calculette"_ * Dans la méthode _FormulaireService.getConfigPathPrefix()_, compléter le _switch_ pour fournir le préfixe des fichiers de configuration/internationalisation. diff --git a/angular.json b/angular.json index 4f42d530dfc095135978945761b7bf9326194387..faadd182a9c765816a2267a04aae58dd292abce5 100644 --- a/angular.json +++ b/angular.json @@ -25,12 +25,11 @@ { "glob": "**/*.png", "input": "src/", "output": "/" } ], "styles": [ - "node_modules/font-awesome/scss/font-awesome.scss", - "node_modules/angular-bootstrap-md/scss/bootstrap/bootstrap.scss", - "node_modules/angular-bootstrap-md/scss/mdb-free.scss", - "src/styles.scss" + "src/styles.scss", + "src/theme.scss" ], - "scripts": [] + "scripts": [], + "showCircularDependencies": false }, "configurations": { "production": { @@ -42,7 +41,7 @@ "aot": true, "extractLicenses": true, "vendorChunk": false, - "buildOptimizer": true, + "buildOptimizer": false, "fileReplacements": [ { "replace": "src/environments/environment.ts", @@ -55,7 +54,8 @@ "serve": { "builder": "@angular-devkit/build-angular:dev-server", "options": { - "browserTarget": "ngHyd:build" + "browserTarget": "ngHyd:build", + "aot": true }, "configurations": { "production": { @@ -78,10 +78,8 @@ "tsConfig": "src/tsconfig.spec.json", "scripts": [], "styles": [ - "node_modules/font-awesome/scss/font-awesome.scss", - "node_modules/angular-bootstrap-md/scss/bootstrap/bootstrap.scss", - "node_modules/angular-bootstrap-md/scss/mdb-free.scss", - "src/styles.scss" + "src/styles.scss", + "src/theme.scss" ], "assets": [ "src/assets", diff --git a/docs-fr/calculators/hsl/regime_uniforme.md b/docs-fr/calculators/hsl/regime_uniforme.md index 09dc8c21024e562f994ad308c1183c5b30d8e793..039e0fca76c539bd3224429479254f4a439b95ac 100644 --- a/docs-fr/calculators/hsl/regime_uniforme.md +++ b/docs-fr/calculators/hsl/regime_uniforme.md @@ -34,4 +34,4 @@ $$h_{k+1} = h_k - \frac{f(h_k)}{f'(h_k)}$$ - \(f(h_k) = Q-KR^{2/3}S\sqrt{I_f}\) - \(f'(h_k) = -K \sqrt{I_f}(\frac{2}{3}R'R^{-1/3}S+R^{2/3}S')\) -Pour calculer les paramètres géométriques de la section, la calculette utilise l'équation de calcul du débit et résout le problème par dichotomie. +Pour calculer les paramètres géométriques de la section, le module de calcul utilise l'équation de calcul du débit et résout le problème par dichotomie. diff --git a/docs-fr/calculators/pam/macrorugo.md b/docs-fr/calculators/pam/macrorugo.md index 6b4014b03e016a98e79878f67356ba4a731d7d77..0ad40bbb53e9ba02cc37a99108d5f57e0bb77a7a 100644 --- a/docs-fr/calculators/pam/macrorugo.md +++ b/docs-fr/calculators/pam/macrorugo.md @@ -1,6 +1,6 @@ -# Passe à macro-rugosité +# Passe à macro-rugosités -Le module de calcul passe à macro rugosité permet de calculer les caractéristiques d'une passe à macro-rugosité constituée de blocs uniformément répartis avec des espacements transversaux \(ay\) et longitudinaux \(ay\) égaux. +Le module de calcul passe à macro-rugosités permet de calculer les caractéristiques d'une passe à macro-rugosités constituée de blocs uniformément répartis avec des espacements transversaux \(ay\) et longitudinaux \(ay\) égaux.  diff --git a/docs-fr/calculators/structures/kivi.md b/docs-fr/calculators/structures/kivi.md index fd2f16ef91c16e1abf74951946d735f4468e9756..3d28e01f8cbb9e9e0c24c38f8b1eac8150ab2842 100644 --- a/docs-fr/calculators/structures/kivi.md +++ b/docs-fr/calculators/structures/kivi.md @@ -1,7 +1,7 @@ # Formule de Kindsvater-Carter et Villemonte -La calculette permet d'effectuer des calculs hydrauliques pour plusieurs ouvrages en parallèle. +Le module de calcul permet d'effectuer des calculs hydrauliques pour plusieurs ouvrages en parallèle. ## Formule de Kindsvater-Carter (1957) diff --git a/docs-fr/calculators/structures/orifice_noye.md b/docs-fr/calculators/structures/orifice_noye.md index e8c11452e057a1a45e577d7144d385ce2afa6329..f33fa101f621634a4f885441241f612e62d289f9 100644 --- a/docs-fr/calculators/structures/orifice_noye.md +++ b/docs-fr/calculators/structures/orifice_noye.md @@ -4,7 +4,7 @@ *Extrait de Larinier, M., Travade, F., Porcher, J.-P., Gosset, C., 1992. Passes à poissons : expertise et conception des ouvrages de franchissement. CSP. (page 94)* -L'équation correspond à peu de chose près à celle de la calculette de la vanne rectangulaire noyée à la différence près que la surface de l'orifice est donnée directement plutôt que par le rapport de la largeur avec la hauteur : +L'équation correspond à peu de chose près à celle du module de calcul de la vanne rectangulaire noyée à la différence près que la surface de l'orifice est donnée directement plutôt que par le rapport de la largeur avec la hauteur : $$Q = \mu S \sqrt{2g \Delta H}$$ diff --git a/e2e/calculator.e2e-spec.ts b/e2e/calculator.e2e-spec.ts index 58beabb11e1a15b082f9554744d028d9d8ce9a77..f7e986344c299fcb0117e168b4feeb81f0eea51a 100644 --- a/e2e/calculator.e2e-spec.ts +++ b/e2e/calculator.e2e-spec.ts @@ -17,7 +17,7 @@ describe("ngHyd − calculator page", () => { expect(text.length).toBeGreaterThan(0); }); - it("when a calculator is open, no label should be empty", async () => { + it("when a calculator is open, no active label should be empty", async () => { const labels = page.getInputLabels(); await labels.each(async (l) => { const label = await l.getText(); diff --git a/e2e/calculator.po.ts b/e2e/calculator.po.ts index 31a21411827e0f847484859bb5163d455ea97185..d4b7a51d5adc0649cc0a73b1fdb2a04ce2ff1a7b 100644 --- a/e2e/calculator.po.ts +++ b/e2e/calculator.po.ts @@ -1,13 +1,9 @@ import { browser, by, element } from "protractor"; export class CalculatorPage { - navigateTo() { - // @TODO won't work - return browser.get("/#/calculator/0"); - } getInputLabels() { - return element.all(by.css("ngparam-input label")); + return element.all(by.css("ngparam-input input:not([disabled]) label")); } getHeader1() { diff --git a/e2e/list.e2e-spec.ts b/e2e/list.e2e-spec.ts index 027322c634866a0ba3e80eaac8f57bc16cba143e..775a2735ff0c673b32a7f677ed115e7548116097 100644 --- a/e2e/list.e2e-spec.ts +++ b/e2e/list.e2e-spec.ts @@ -9,6 +9,7 @@ describe("ngHyd − list page", () => { it("when list is open, user should see the list of available compute nodes", async () => { await page.navigateTo(); + expect(page.getThemesCardsLength()).toBeGreaterThan(4); expect(page.getCalculatorsMenuLength()).toBeGreaterThan(8); }); }); diff --git a/e2e/list.po.ts b/e2e/list.po.ts index 8b21d46d14e7c398dda682b1b061711f774e07b8..2f06248a15933ff12b610e0870991d8d4cfe39dc 100644 --- a/e2e/list.po.ts +++ b/e2e/list.po.ts @@ -5,12 +5,20 @@ export class ListPage { return browser.get("/#/list"); } + getThemesCards() { + return element.all(by.css("mat-card.compute-nodes-theme")); + } + + async getThemesCardsLength() { + return await this.getThemesCards().count(); + } + getCalculatorsMenuEntries() { - return element.all(by.css("ul.list-group")); + return element.all(by.css("mat-card.compute-nodes-theme button.theme-calculator")); } - getCalculatorsMenuLength() { - return this.getCalculatorsMenuEntries().count(); + async getCalculatorsMenuLength() { + return await this.getCalculatorsMenuEntries().count(); } async clickRandomCalculatorMenuEntry() { diff --git a/e2e/load-sesssion.e2e-spec.ts b/e2e/load-sesssion.e2e-spec.ts index 6b11ef387f0c8ce4f20d0439b38781ecc00a1d54..39f919a41a020378ddc0b05f33fc0d179d3c6cbd 100644 --- a/e2e/load-sesssion.e2e-spec.ts +++ b/e2e/load-sesssion.e2e-spec.ts @@ -1,6 +1,7 @@ import { AppPage } from "./app.po"; import { Navbar } from "./navbar.po"; import { SideNav } from "./sidenav.po"; +import { browser } from "protractor"; describe("ngHyd − start page", () => { let page: AppPage; @@ -15,9 +16,16 @@ describe("ngHyd − start page", () => { it("when loading session-6-calc.test.json file from home page, 6 calculators should be loaded", async () => { await page.navigateTo(); + await navbar.clickMenuButton(); + await browser.sleep(200); + await sidenav.clickLoadSessionButton(); + await browser.sleep(200); + await sidenav.loadSessionFile("./session-6-calc.test.json"); + await browser.sleep(200); + expect(await navbar.getAllCalculatorTabs().count()).toBe(6); }); diff --git a/e2e/navbar.po.ts b/e2e/navbar.po.ts index 4b7bc3715a7c9a5514178489f7323e1e7efeae06..2112ceecf8ae3666311cee6fe7627b09dc433b9a 100644 --- a/e2e/navbar.po.ts +++ b/e2e/navbar.po.ts @@ -2,7 +2,7 @@ import { by, element } from "protractor"; export class Navbar { getAllCalculatorTabs() { - return element.all(by.css("ul#navbar > li.calculator-tab")); + return element.all(by.css("#tabs-container > button.calculator-button")); } getNewCalculatorButton() { diff --git a/e2e/navigate-through-calculators.e2e-spec.ts b/e2e/navigate-through-calculators.e2e-spec.ts index e33480fa8d4d439069ee173f1e5bf9d0cd664f50..f2f91340e01c80d132312f9d96bfab31a9268eb6 100644 --- a/e2e/navigate-through-calculators.e2e-spec.ts +++ b/e2e/navigate-through-calculators.e2e-spec.ts @@ -1,6 +1,7 @@ import { ListPage } from "./list.po"; import { Navbar } from "./navbar.po"; import { CalculatorPage } from "./calculator.po"; +import { browser } from "protractor"; describe("ngHyd − create calculators and navigate among them", () => { let listPage: ListPage; @@ -13,14 +14,16 @@ describe("ngHyd − create calculators and navigate among them", () => { navbar = new Navbar(); }); - it("when many calculators are open, navigating among them should not fail (all labels should be visible)", async () => { + it("when many calculators are open, navigating among them should not fail (all active labels should be visible)", async () => { + await listPage.navigateTo(); // open 8 calculators - for (let i = 0; i < 8; i++) { + for (let i = 0; i < 6; i++) { await navbar.clickNewCalculatorButton(); + await browser.sleep(200); await listPage.clickRandomCalculatorMenuEntry(); } // navigate among them - for (let i = 0; i < 16; i++) { + for (let i = 0; i < 10; i++) { await navbar.clickRandomCalculatorTab(i); // test all form labels const labels = calculatorPage.getInputLabels(); diff --git a/e2e/preferences.e2e-spec.ts b/e2e/preferences.e2e-spec.ts index 5516cb68387f36a175f4e4ff547f2a52572a3ca3..42d4dc61172797b981bdf909383289bc347dbc18 100644 --- a/e2e/preferences.e2e-spec.ts +++ b/e2e/preferences.e2e-spec.ts @@ -1,4 +1,5 @@ import { PreferencesPage } from "./preferences.po"; +import { browser } from "protractor"; describe("ngHyd − preferences page", () => { let page: PreferencesPage; @@ -14,11 +15,53 @@ describe("ngHyd − preferences page", () => { }); it("when preferences are open, no label should be empty", async () => { - // page.navigateTo(); const labels = page.getInputLabels(); await labels.each(async (l) => { const label = await l.getText(); expect(label.length).toBeGreaterThan(0); }); }); + + it("when preferences are open, no input field should be empty", async () => { + const numericFields = page.getNumericFormFields(); + await numericFields.each(async (nf) => { + const input = page.getInputForField(nf); + const val = await input.getAttribute("value"); + expect(val).toBeTruthy(); + }); + }); + + it("when erroneous values are input, errors should appear", async () => { + const numericFields = page.getNumericFormFields(); + await numericFields.each(async (nf) => { + // add a letter after the numerical value + await page.getInputForField(nf).sendKeys("d"); + expect(page.getErrorsForField(nf).isPresent()).toBe(true); + // empty input + await page.getInputForField(nf).clear(); + expect(page.getErrorsForField(nf).isPresent()).toBe(true); + // send bad value + await page.getInputForField(nf).sendKeys("0"); + expect(page.getErrorsForField(nf).isPresent()).toBe(true); + }); + }); + + it("when correct values are input, errors should disappear", async () => { + const numericFields = page.getNumericFormFields(); + await numericFields.each(async (nf) => { + // send correct value + await page.getInputForField(nf).sendKeys("123"); + expect(page.getErrorsForField(nf).isPresent()).toBe(false); + }); + }); + + it("when language is changed, language should change", async () => { + await page.changeLanguage(0); + await browser.sleep(200); + const val1 = await page.getHeader1().getText(); + await page.changeLanguage(1); + await browser.sleep(200); + const val2 = await page.getHeader1().getText(); + expect(val1).not.toEqual(val2); + }); }); diff --git a/e2e/preferences.po.ts b/e2e/preferences.po.ts index 96ea80f42cde862b53c26b64b7b7b3f9728fcf3f..dc5aceb2bbec1595d77df593e16f1ea5b32ce405 100644 --- a/e2e/preferences.po.ts +++ b/e2e/preferences.po.ts @@ -1,4 +1,4 @@ -import { browser, by, element } from "protractor"; +import { browser, by, element, ElementFinder } from "protractor"; export class PreferencesPage { navigateTo() { @@ -9,7 +9,34 @@ export class PreferencesPage { return element(by.css("h1")); } + getLanguageSelect() { + // tslint:disable-next-line:quotemark + return element(by.css('mat-select[data-testid="language-select"]')); + } + getInputLabels() { - return element.all(by.css("base-param-input label")); + return element.all(by.css("label.mat-form-field-label")); + } + + getNumericFormFields() { + // tslint:disable-next-line:quotemark + return element.all(by.css('mat-form-field[data-testclass="numeric-input"]')); + } + + getInputForField(ff: ElementFinder) { + return ff.element(by.css("input")); + } + + getErrorsForField(ff: ElementFinder) { + return ff.element(by.css("mat-error")); + } + + async changeLanguage(index: number) { + const select = this.getLanguageSelect(); + await select.click(); + const options = (await select.getAttribute("aria-owns")).split(" "); + const optId = options[index]; + const option = element(by.id(optId)); + await option.click(); } } diff --git a/e2e/sidenav.po.ts b/e2e/sidenav.po.ts index 07dd1cea1fffe9fe8d3171cb108883fe764e6efb..2b3f469d4954b72021585ae86f22df0f33f0e57f 100644 --- a/e2e/sidenav.po.ts +++ b/e2e/sidenav.po.ts @@ -8,11 +8,12 @@ export class SideNav { getFileInput() { // tslint:disable-next-line:quotemark - return element(by.css('load-calc input[type="file"]')); + return element(by.css('dialog-load-session input[type="file"]')); } getFileLoadButton() { - return element(by.css("load-calc .modal-footer button.btn-success")); + // tslint:disable-next-line:quotemark + return element(by.css('dialog-load-session button[type="submit"]')); } async clickLoadSessionButton() { diff --git a/jalhyd_branch b/jalhyd_branch index bd388944e1091e13962974ce434774f09d31464e..1f7391f92b6a3792204e07e99f71f643cc35e7e1 100644 --- a/jalhyd_branch +++ b/jalhyd_branch @@ -1 +1 @@ -58-nettoyage-et-simplification-du-code +master diff --git a/package-lock.json b/package-lock.json index 83568879fd764796c9823a20cf4064aecda2f88e..9f12af07c5303924deb581b2cf12855cc20ee42a 100644 --- a/package-lock.json +++ b/package-lock.json @@ -5,26 +5,37 @@ "requires": true, "dependencies": { "@angular-devkit/architect": { - "version": "0.12.1", - "resolved": "https://registry.npmjs.org/@angular-devkit/architect/-/architect-0.12.1.tgz", - "integrity": "sha512-1ozBP0ZAApkSfuPpZ7b9vShU8smNxb98jW+65S12cPOxv1bVVxCj5sTmC3sSfXapgq/pMzblbaVSKOG7Ajz0vQ==", + "version": "0.12.4", + "resolved": "https://registry.npmjs.org/@angular-devkit/architect/-/architect-0.12.4.tgz", + "integrity": "sha512-19f3jbGyP+GzTSBgrHR4SWGK81SUgtTxhkAcyhmsIEDuXrMJM8kPu0HB9WivJ5p08+jzwz6xdF9mpNYSeD9uqw==", "dev": true, "requires": { - "@angular-devkit/core": "7.2.1", + "@angular-devkit/core": "7.2.4", "rxjs": "6.3.3" + }, + "dependencies": { + "rxjs": { + "version": "6.3.3", + "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.3.3.tgz", + "integrity": "sha512-JTWmoY9tWCs7zvIk/CvRjhjGaOd+OVBM987mxFo+OW66cGpdKjZcpmc74ES1sB//7Kl/PAe8+wEakuhG4pcgOw==", + "dev": true, + "requires": { + "tslib": "^1.9.0" + } + } } }, "@angular-devkit/build-angular": { - "version": "0.12.1", - "resolved": "https://registry.npmjs.org/@angular-devkit/build-angular/-/build-angular-0.12.1.tgz", - "integrity": "sha512-TpaMgKECEm1Tta4jkvZVzWdbq2OakIwVyYSzZ/7ARVe0FXhEjVLgWB1pYAdhRx+Hv4/E2ZSPJW1J3N3DTE4W4Q==", + "version": "0.12.4", + "resolved": "https://registry.npmjs.org/@angular-devkit/build-angular/-/build-angular-0.12.4.tgz", + "integrity": "sha512-zzjpM9GpCGEUtTPv/T04CALzFXkTgAAiNt1whY1Vmtu2YYUksXOm1ysA2RBLEhb81RodTEwVV2zFUj5v2xHYEw==", "dev": true, "requires": { - "@angular-devkit/architect": "0.12.1", - "@angular-devkit/build-optimizer": "0.12.1", - "@angular-devkit/build-webpack": "0.12.1", - "@angular-devkit/core": "7.2.1", - "@ngtools/webpack": "7.2.1", + "@angular-devkit/architect": "0.12.4", + "@angular-devkit/build-optimizer": "0.12.4", + "@angular-devkit/build-webpack": "0.12.4", + "@angular-devkit/core": "7.2.4", + "@ngtools/webpack": "7.2.4", "ajv": "6.6.2", "autoprefixer": "9.4.3", "circular-dependency-plugin": "5.0.2", @@ -42,11 +53,11 @@ "mini-css-extract-plugin": "0.4.4", "minimatch": "3.0.4", "node-sass": "4.10.0", - "opn": "5.3.0", + "opn": "5.4.0", "parse5": "4.0.0", "portfinder": "1.0.17", - "postcss": "7.0.5", - "postcss-import": "12.0.0", + "postcss": "7.0.13", + "postcss-import": "12.0.1", "postcss-loader": "3.0.0", "raw-loader": "0.5.1", "rxjs": "6.3.3", @@ -54,14 +65,14 @@ "semver": "5.5.1", "source-map-loader": "0.2.4", "source-map-support": "0.5.9", - "speed-measure-webpack-plugin": "1.2.3", + "speed-measure-webpack-plugin": "1.2.5", "stats-webpack-plugin": "0.7.0", "style-loader": "0.23.1", "stylus": "0.54.5", "stylus-loader": "3.0.2", - "terser-webpack-plugin": "1.1.0", + "terser-webpack-plugin": "1.2.1", "tree-kill": "1.2.0", - "webpack": "4.23.1", + "webpack": "4.28.4", "webpack-dev-middleware": "3.4.0", "webpack-dev-server": "3.1.14", "webpack-merge": "4.1.4", @@ -69,78 +80,45 @@ "webpack-subresource-integrity": "1.1.0-rc.6" }, "dependencies": { - "ajv": { - "version": "6.6.2", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.6.2.tgz", - "integrity": "sha512-FBHEW6Jf5TB9MGBgUUA9XHkTbjXYfAUjY43ACMfmdMRHniyoMHjHjzD50OK8LGDWQwp4rWEsIq5kEqq7rvIM1g==", - "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" - } - }, - "glob": { - "version": "7.1.3", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.3.tgz", - "integrity": "sha512-vcfuiIxogLV4DlGBHIUOwI0IbrJ8HWPc4MU7HzviGeNho/UJDfi6B5p3sHeWIQ0KGIU0Jpxi5ZHxemQfLkkAwQ==", - "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" - } - }, - "semver": { - "version": "5.5.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.5.1.tgz", - "integrity": "sha512-PqpAxfrEhlSUWge8dwIp4tZnQ25DIOthpiaHNIthsjEFQD6EvqUKUDM7L8O2rShkFccYo1VjJR0coWfNkCubRw==", - "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==", + "parse5": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/parse5/-/parse5-4.0.0.tgz", + "integrity": "sha512-VrZ7eOd3T1Fk4XWNXMgiGBK/z0MG48BWG2uQNU4I72fkQuKUTZpl+u9k+CxEG0twMVzSmXEEz12z5Fnw1jIQFA==", "dev": true }, - "source-map-support": { - "version": "0.5.9", - "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.9.tgz", - "integrity": "sha512-gR6Rw4MvUlYy83vP0vxoVNzM6t8MUXqNuRsuBmBHQDu1Fh6X015FrLdgoDKcNdkwGubozq0P4N0Q37UyFVr1EA==", + "rxjs": { + "version": "6.3.3", + "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.3.3.tgz", + "integrity": "sha512-JTWmoY9tWCs7zvIk/CvRjhjGaOd+OVBM987mxFo+OW66cGpdKjZcpmc74ES1sB//7Kl/PAe8+wEakuhG4pcgOw==", "dev": true, "requires": { - "buffer-from": "^1.0.0", - "source-map": "^0.6.0" + "tslib": "^1.9.0" } } } }, "@angular-devkit/build-optimizer": { - "version": "0.12.1", - "resolved": "https://registry.npmjs.org/@angular-devkit/build-optimizer/-/build-optimizer-0.12.1.tgz", - "integrity": "sha512-zYea22pJ5kvMud8UBrdzIcR9F1FDYWJ3vwj5WRUFM0sF7mbbrmTC+OsIvNI7qDJuXWNZGySwNlHw0e+rhv30gg==", + "version": "0.12.4", + "resolved": "https://registry.npmjs.org/@angular-devkit/build-optimizer/-/build-optimizer-0.12.4.tgz", + "integrity": "sha512-KraU+ZARX7JMtttPjOku9wVF+dnjMsIbiIVsQrNXhpFiGT1fSJhQTPxc98ONgEmUiGROFXXq2mHLilvMr2WdwQ==", "dev": true, "requires": { "loader-utils": "1.1.0", "source-map": "0.5.6", - "typescript": "3.2.2", + "typescript": "3.2.4", "webpack-sources": "1.2.0" }, "dependencies": { "source-map": { "version": "0.5.6", - "resolved": "http://registry.npmjs.org/source-map/-/source-map-0.5.6.tgz", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.6.tgz", "integrity": "sha1-dc449SvwczxafwwRjYEzSiu19BI=", "dev": true }, "typescript": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-3.2.2.tgz", - "integrity": "sha512-VCj5UiSyHBjwfYacmDuc/NOk4QQixbE+Wn7MFJuS0nRuPQbof132Pw4u53dm264O8LPc2MVsc7RJNml5szurkg==", + "version": "3.2.4", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-3.2.4.tgz", + "integrity": "sha512-0RNDbSdEokBeEAkgNbxJ+BLwSManFy9TeXz8uW+48j/xhEXv1ePME60olyzw2XzUqUBNAYFeJadIqAgNqIACwg==", "dev": true }, "webpack-sources": { @@ -164,20 +142,31 @@ } }, "@angular-devkit/build-webpack": { - "version": "0.12.1", - "resolved": "https://registry.npmjs.org/@angular-devkit/build-webpack/-/build-webpack-0.12.1.tgz", - "integrity": "sha512-eDNgR2EV9/l4xYTkvS3861TthUv8ERBroWpMkkniX3HhpyjgaLyI5P1OB7fVMcF3RvJsxIlqYGRZ6zx7PjCbcA==", + "version": "0.12.4", + "resolved": "https://registry.npmjs.org/@angular-devkit/build-webpack/-/build-webpack-0.12.4.tgz", + "integrity": "sha512-1+t2MUB+dq+1LbfTnvzZwj2QTWiugyMywXqYjsyt0rrh7VcriD1lQ+P5yN8kgFz/R7Ut4LgvS05yDX1JHi20qw==", "dev": true, "requires": { - "@angular-devkit/architect": "0.12.1", - "@angular-devkit/core": "7.2.1", + "@angular-devkit/architect": "0.12.4", + "@angular-devkit/core": "7.2.4", "rxjs": "6.3.3" + }, + "dependencies": { + "rxjs": { + "version": "6.3.3", + "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.3.3.tgz", + "integrity": "sha512-JTWmoY9tWCs7zvIk/CvRjhjGaOd+OVBM987mxFo+OW66cGpdKjZcpmc74ES1sB//7Kl/PAe8+wEakuhG4pcgOw==", + "dev": true, + "requires": { + "tslib": "^1.9.0" + } + } } }, "@angular-devkit/core": { - "version": "7.2.1", - "resolved": "https://registry.npmjs.org/@angular-devkit/core/-/core-7.2.1.tgz", - "integrity": "sha512-zOozPswSM1cTkltw5LeSPoZ/fJ2d3vN304IVgKgrM5/Fs54bd7nTaBcAK+HvjKS+5KmykYrXW47Q4CdFJikluQ==", + "version": "7.2.4", + "resolved": "https://registry.npmjs.org/@angular-devkit/core/-/core-7.2.4.tgz", + "integrity": "sha512-XHF59tIHg2qEM1Wd415xhykBLjjfOK6yMB7CjNk1bToUMX2QDT87izJF4y1Vwa0lIw9G0jdgP/4/M/OqXcbYmA==", "dev": true, "requires": { "ajv": "6.6.2", @@ -187,43 +176,34 @@ "source-map": "0.7.3" }, "dependencies": { - "ajv": { - "version": "6.6.2", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.6.2.tgz", - "integrity": "sha512-FBHEW6Jf5TB9MGBgUUA9XHkTbjXYfAUjY43ACMfmdMRHniyoMHjHjzD50OK8LGDWQwp4rWEsIq5kEqq7rvIM1g==", + "rxjs": { + "version": "6.3.3", + "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.3.3.tgz", + "integrity": "sha512-JTWmoY9tWCs7zvIk/CvRjhjGaOd+OVBM987mxFo+OW66cGpdKjZcpmc74ES1sB//7Kl/PAe8+wEakuhG4pcgOw==", "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" + "tslib": "^1.9.0" } - }, - "source-map": { - "version": "0.7.3", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.3.tgz", - "integrity": "sha512-CkCj6giN3S+n9qrYiBTX5gystlENnRW5jZeNLHpe6aue+SrHcG5VYwujhW9s4dY31mEGsxBDrHR6oI69fTXsaQ==", - "dev": true } } }, "@angular-devkit/schematics": { - "version": "7.1.4", - "resolved": "https://registry.npmjs.org/@angular-devkit/schematics/-/schematics-7.1.4.tgz", - "integrity": "sha512-+rn3ppcC3grsi9vV2uUIYh/5mUBEJ+JRCKW11BJoUqLMeu8W7h+vbVonyfwJXsk3FSTf9ZY0C7F7UqggRS3cWw==", + "version": "7.3.1", + "resolved": "https://registry.npmjs.org/@angular-devkit/schematics/-/schematics-7.3.1.tgz", + "integrity": "sha512-cd7usiasfSgw75INz72/VssrLr9tiVRYfo1TEdvr9ww0GuQbuQpB33xbV8W135eAV8+wzQ3Ce8ohaDHibvj6Yg==", "dev": true, "requires": { - "@angular-devkit/core": "7.1.4", + "@angular-devkit/core": "7.3.1", "rxjs": "6.3.3" }, "dependencies": { "@angular-devkit/core": { - "version": "7.1.4", - "resolved": "https://registry.npmjs.org/@angular-devkit/core/-/core-7.1.4.tgz", - "integrity": "sha512-3cBVHjSQjMyE/mIyOX82ekdybNRQlN+kUfmdZS6oVW9aV48vdxcVbEGdl8t1H4enMf89u8kXiAAET9jFaqWopg==", + "version": "7.3.1", + "resolved": "https://registry.npmjs.org/@angular-devkit/core/-/core-7.3.1.tgz", + "integrity": "sha512-56XDWWfIzOAkEk69lBLgmCYybPUA4yjunhmMlCk7vVdb7gbQUyzNjFD04Uj0GjlejatAQ5F76tRwygD9C+3RXQ==", "dev": true, "requires": { - "ajv": "6.5.3", + "ajv": "6.7.0", "chokidar": "2.0.4", "fast-json-stable-stringify": "2.0.0", "rxjs": "6.3.3", @@ -231,9 +211,9 @@ } }, "ajv": { - "version": "6.5.3", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.5.3.tgz", - "integrity": "sha512-LqZ9wY+fx3UMiiPd741yB2pj3hhil+hQc8taf4o2QGRFpWgZ2V5C8HA165DY9sS3fJwsk7uT7ZlFEyC3Ig3lLg==", + "version": "6.7.0", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.7.0.tgz", + "integrity": "sha512-RZXPviBTtfmtka9n9sy1N5M5b82CbxWIR6HIis4s3WQTXDJamc/0gpCWNGz6EWdWp4DOfjzJfhz/AS9zVPjjWg==", "dev": true, "requires": { "fast-deep-equal": "^2.0.1", @@ -242,62 +222,72 @@ "uri-js": "^4.2.2" } }, - "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 - }, - "source-map": { - "version": "0.7.3", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.3.tgz", - "integrity": "sha512-CkCj6giN3S+n9qrYiBTX5gystlENnRW5jZeNLHpe6aue+SrHcG5VYwujhW9s4dY31mEGsxBDrHR6oI69fTXsaQ==", - "dev": true + "rxjs": { + "version": "6.3.3", + "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.3.3.tgz", + "integrity": "sha512-JTWmoY9tWCs7zvIk/CvRjhjGaOd+OVBM987mxFo+OW66cGpdKjZcpmc74ES1sB//7Kl/PAe8+wEakuhG4pcgOw==", + "dev": true, + "requires": { + "tslib": "^1.9.0" + } } } }, "@angular/animations": { - "version": "7.1.4", - "resolved": "https://registry.npmjs.org/@angular/animations/-/animations-7.1.4.tgz", - "integrity": "sha512-877LZ83scksJtflVz97CUWlSsZnxduBxPD+ls5OTrTT/bq3muzHCm8rgTO7S8fBwwrEVXLorvMAlhDPpMg5Swg==", + "version": "7.2.4", + "resolved": "https://registry.npmjs.org/@angular/animations/-/animations-7.2.4.tgz", + "integrity": "sha512-Wx6cqU6koFOASlyl4aCygtbtROoehU6OKwV2EZTkfzHx6Eu/QyTiSa5kyoApVM5LMmCNeb8SxJMSAnKXztNl0A==", "requires": { "tslib": "^1.9.0" } }, + "@angular/cdk": { + "version": "7.3.2", + "resolved": "https://registry.npmjs.org/@angular/cdk/-/cdk-7.3.2.tgz", + "integrity": "sha512-jnthvY1Kt+DpJTrkgyKTiVuYgBdp4iG7QDeZJPBQm0e8mL2K0Pi9AqFbo01E4CGPqZpvtEggvqM0OJpR8J+amw==", + "requires": { + "parse5": "^5.0.0", + "tslib": "^1.7.1" + } + }, "@angular/cli": { - "version": "7.1.4", - "resolved": "https://registry.npmjs.org/@angular/cli/-/cli-7.1.4.tgz", - "integrity": "sha512-SruaZsmyq3+ymMPeMJSzhytvgtvzyzb1q58pUYX+vZjff2aMYOo0TVxJALwTOPIABICTqUTZmujbLG9uxVgxFA==", - "dev": true, - "requires": { - "@angular-devkit/architect": "0.11.4", - "@angular-devkit/core": "7.1.4", - "@angular-devkit/schematics": "7.1.4", - "@schematics/angular": "7.1.4", - "@schematics/update": "0.11.4", - "inquirer": "6.2.0", - "opn": "5.3.0", - "semver": "5.5.1", + "version": "7.3.1", + "resolved": "https://registry.npmjs.org/@angular/cli/-/cli-7.3.1.tgz", + "integrity": "sha512-8EvXYRhTqTaTk5PKv7VZxIWJiyG51R9RC9gtpRFx4bbnurqBHdEUxGMmaRsGT8QDbfvVsWnuakE0eeW1CrfZAQ==", + "dev": true, + "requires": { + "@angular-devkit/architect": "0.13.1", + "@angular-devkit/core": "7.3.1", + "@angular-devkit/schematics": "7.3.1", + "@schematics/angular": "7.3.1", + "@schematics/update": "0.13.1", + "@yarnpkg/lockfile": "1.1.0", + "ini": "1.3.5", + "inquirer": "6.2.1", + "npm-package-arg": "6.1.0", + "opn": "5.4.0", + "pacote": "9.4.0", + "semver": "5.6.0", "symbol-observable": "1.2.0" }, "dependencies": { "@angular-devkit/architect": { - "version": "0.11.4", - "resolved": "https://registry.npmjs.org/@angular-devkit/architect/-/architect-0.11.4.tgz", - "integrity": "sha512-2zi6S9tPlk52vyqN67IvFoeNgd0uxtrPlwl3TdvJ3wrH7sYGJnkQ+EzAE7cKUGWAV989BbNtx2YxhRDHnN21Fg==", + "version": "0.13.1", + "resolved": "https://registry.npmjs.org/@angular-devkit/architect/-/architect-0.13.1.tgz", + "integrity": "sha512-QDmIbqde75ZZSEFbw6Q6kQWq4cY6C7D67yujXw6XTyubDNAs1tyXJyxTIB8vjSlEKwRizTTDd/B0ZXVcke3Mvw==", "dev": true, "requires": { - "@angular-devkit/core": "7.1.4", + "@angular-devkit/core": "7.3.1", "rxjs": "6.3.3" } }, "@angular-devkit/core": { - "version": "7.1.4", - "resolved": "https://registry.npmjs.org/@angular-devkit/core/-/core-7.1.4.tgz", - "integrity": "sha512-3cBVHjSQjMyE/mIyOX82ekdybNRQlN+kUfmdZS6oVW9aV48vdxcVbEGdl8t1H4enMf89u8kXiAAET9jFaqWopg==", + "version": "7.3.1", + "resolved": "https://registry.npmjs.org/@angular-devkit/core/-/core-7.3.1.tgz", + "integrity": "sha512-56XDWWfIzOAkEk69lBLgmCYybPUA4yjunhmMlCk7vVdb7gbQUyzNjFD04Uj0GjlejatAQ5F76tRwygD9C+3RXQ==", "dev": true, "requires": { - "ajv": "6.5.3", + "ajv": "6.7.0", "chokidar": "2.0.4", "fast-json-stable-stringify": "2.0.0", "rxjs": "6.3.3", @@ -305,9 +295,9 @@ } }, "ajv": { - "version": "6.5.3", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.5.3.tgz", - "integrity": "sha512-LqZ9wY+fx3UMiiPd741yB2pj3hhil+hQc8taf4o2QGRFpWgZ2V5C8HA165DY9sS3fJwsk7uT7ZlFEyC3Ig3lLg==", + "version": "6.7.0", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.7.0.tgz", + "integrity": "sha512-RZXPviBTtfmtka9n9sy1N5M5b82CbxWIR6HIis4s3WQTXDJamc/0gpCWNGz6EWdWp4DOfjzJfhz/AS9zVPjjWg==", "dev": true, "requires": { "fast-deep-equal": "^2.0.1", @@ -316,55 +306,43 @@ "uri-js": "^4.2.2" } }, - "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 - }, - "opn": { - "version": "5.3.0", - "resolved": "http://registry.npmjs.org/opn/-/opn-5.3.0.tgz", - "integrity": "sha512-bYJHo/LOmoTd+pfiYhfZDnf9zekVJrY+cnS2a5F2x+w5ppvTqObojTP7WiFG+kVZs9Inw+qQ/lw7TroWwhdd2g==", + "rxjs": { + "version": "6.3.3", + "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.3.3.tgz", + "integrity": "sha512-JTWmoY9tWCs7zvIk/CvRjhjGaOd+OVBM987mxFo+OW66cGpdKjZcpmc74ES1sB//7Kl/PAe8+wEakuhG4pcgOw==", "dev": true, "requires": { - "is-wsl": "^1.1.0" + "tslib": "^1.9.0" } }, "semver": { - "version": "5.5.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.5.1.tgz", - "integrity": "sha512-PqpAxfrEhlSUWge8dwIp4tZnQ25DIOthpiaHNIthsjEFQD6EvqUKUDM7L8O2rShkFccYo1VjJR0coWfNkCubRw==", - "dev": true - }, - "source-map": { - "version": "0.7.3", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.3.tgz", - "integrity": "sha512-CkCj6giN3S+n9qrYiBTX5gystlENnRW5jZeNLHpe6aue+SrHcG5VYwujhW9s4dY31mEGsxBDrHR6oI69fTXsaQ==", + "version": "5.6.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.6.0.tgz", + "integrity": "sha512-RS9R6R35NYgQn++fkDWaOmqGoj4Ek9gGs+DPxNUZKuwE183xjJroKvyo1IzVFeXvUrvmALy6FWD5xrdJT25gMg==", "dev": true } } }, "@angular/common": { - "version": "7.1.4", - "resolved": "https://registry.npmjs.org/@angular/common/-/common-7.1.4.tgz", - "integrity": "sha512-oQPCilcf1H/OXmt4z6PfGoCSb1YPRBAXGs/KRBARm3tYan2r5CmV0BFwpWXWQrEMt8YQqqLiBQUQ64d8+VFm8Q==", + "version": "7.2.4", + "resolved": "https://registry.npmjs.org/@angular/common/-/common-7.2.4.tgz", + "integrity": "sha512-3/i8RtnLTx/90gJHk5maE8zwsSiHgHvLItaa0qVfNlWiU0eCId/PL6TgDkut5vN9SQYL0oxhxFaVd35HmwsmuQ==", "requires": { "tslib": "^1.9.0" } }, "@angular/compiler": { - "version": "7.1.4", - "resolved": "https://registry.npmjs.org/@angular/compiler/-/compiler-7.1.4.tgz", - "integrity": "sha512-AvYXtjEJ27Rhv4c27DXNEa58Lit63jdydzbz7VuyFhNU+FwDUK2DC4gZe0nWZsf7HUniJezVRFkECDCZQeSKCQ==", + "version": "7.2.4", + "resolved": "https://registry.npmjs.org/@angular/compiler/-/compiler-7.2.4.tgz", + "integrity": "sha512-+zyMzPCL45ePEV9nrnYJvhAVgp2Y19bDaq0f0YdZAqAjgDqHzXGGR6wX8GueyJWmUYWx5vwK6Apla4HwDrYA1w==", "requires": { "tslib": "^1.9.0" } }, "@angular/compiler-cli": { - "version": "7.1.4", - "resolved": "https://registry.npmjs.org/@angular/compiler-cli/-/compiler-cli-7.1.4.tgz", - "integrity": "sha512-fyEY58A53pmVEuhfyU1z1TAi1n5rOK5cCjhFnUUnnESQFEW/aQYOl0ZL6LDsMSYfa78fkDw4Nc0DytvZ1ymVMw==", + "version": "7.2.4", + "resolved": "https://registry.npmjs.org/@angular/compiler-cli/-/compiler-cli-7.2.4.tgz", + "integrity": "sha512-UhLosSeuwFIfaGqGcYOh9WSOuzEpeuhIRAOt81MeqOQEqkoreUjfxrQq8XWNkdqsPZHtiptF5ZwXlMBxlj9jJg==", "dev": true, "requires": { "canonical-path": "1.0.0", @@ -405,6 +383,12 @@ "arr-flatten": "^1.0.1" } }, + "array-unique": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.2.1.tgz", + "integrity": "sha1-odl8yvy8JiXMcPrc6zalDFiwGlM=", + "dev": true + }, "braces": { "version": "1.8.5", "resolved": "https://registry.npmjs.org/braces/-/braces-1.8.5.tgz", @@ -416,6 +400,12 @@ "repeat-element": "^1.1.2" } }, + "camelcase": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-4.1.0.tgz", + "integrity": "sha1-1UVjW+HjPFQmScaRc+Xeas+uNN0=", + "dev": true + }, "chokidar": { "version": "1.7.0", "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-1.7.0.tgz", @@ -507,9 +497,18 @@ "is-extglob": "^1.0.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" + } + }, "load-json-file": { "version": "2.0.0", - "resolved": "http://registry.npmjs.org/load-json-file/-/load-json-file-2.0.0.tgz", + "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-2.0.0.tgz", "integrity": "sha1-eUfkIUmvgNaWy/eXvKq8/h/inKg=", "dev": true, "requires": { @@ -549,6 +548,12 @@ "regex-cache": "^0.4.2" } }, + "minimist": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", + "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=", + "dev": true + }, "os-locale": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/os-locale/-/os-locale-2.1.0.tgz", @@ -569,6 +574,12 @@ "pify": "^2.0.0" } }, + "pify": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", + "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=", + "dev": true + }, "read-pkg": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-2.0.0.tgz", @@ -615,6 +626,12 @@ "ansi-regex": "^3.0.0" } }, + "strip-bom": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", + "integrity": "sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM=", + "dev": true + }, "which-module": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/which-module/-/which-module-2.0.0.tgz", @@ -660,55 +677,71 @@ } }, "@angular/core": { - "version": "7.1.4", - "resolved": "https://registry.npmjs.org/@angular/core/-/core-7.1.4.tgz", - "integrity": "sha512-36uWLrmmlzf8JKaq2A5F2tPQEHvFSsbTQWOT559Drp1tzM2uSA7PysNHv5TXUshDn5i54S2EQFm4bj2YPp4Hzg==", + "version": "7.2.4", + "resolved": "https://registry.npmjs.org/@angular/core/-/core-7.2.4.tgz", + "integrity": "sha512-kfAxhIxl89PmB7y81FR/RAv0yWRFcEYxEnTwV+o8jKGfemAXtQ0g/Vh+lJR0SD/TBgFilMxotN1mhwH4A8GShw==", "requires": { "tslib": "^1.9.0" } }, + "@angular/flex-layout": { + "version": "7.0.0-beta.23", + "resolved": "https://registry.npmjs.org/@angular/flex-layout/-/flex-layout-7.0.0-beta.23.tgz", + "integrity": "sha512-jH2i3i/M7SbK6scVlj2urVL5OhzwavbQ7KwvUjyc/UwccKnnzuOuWEGCINLja/aoaUO3I35LluCLv6a6VN0olA==", + "requires": { + "tslib": "^1.7.1" + } + }, "@angular/forms": { - "version": "7.1.4", - "resolved": "https://registry.npmjs.org/@angular/forms/-/forms-7.1.4.tgz", - "integrity": "sha512-YB2lDRe7aMsaO5ZlbeFZGH+uTQOcpotFDKCmTckpefRJ7id6TlUSBYdYRH80qOQfPJGpsnqQvLZkL24UMasKtQ==", + "version": "7.2.4", + "resolved": "https://registry.npmjs.org/@angular/forms/-/forms-7.2.4.tgz", + "integrity": "sha512-DAtOrdlTRsgvmZrsvczCAkY8dhTwZb5DXBmPuSXh0UR9lvEiCgNHGbwEiIiIkAHpw1wSeXZrq0qyy/oJRvf18g==", "requires": { "tslib": "^1.9.0" } }, "@angular/http": { - "version": "7.1.4", - "resolved": "https://registry.npmjs.org/@angular/http/-/http-7.1.4.tgz", - "integrity": "sha512-Lrjb99sHu0Cv7MBbVLev1I1Fe+DJcwG4v7juZB/5nE5opKmbQo3Lfqvt2dVrMOxHeju9ReFznEnuGNMK6+m6pQ==", + "version": "7.2.4", + "resolved": "https://registry.npmjs.org/@angular/http/-/http-7.2.4.tgz", + "integrity": "sha512-kazJREm7MtSCYbE+9zU/CcUXI5Csu53PooeQlAp80/TOHqry6fVKIMHCI892Db9ScY2ds0SzbyTmrxEQo7PP1A==", "requires": { "tslib": "^1.9.0" } }, "@angular/language-service": { - "version": "7.1.4", - "resolved": "https://registry.npmjs.org/@angular/language-service/-/language-service-7.1.4.tgz", - "integrity": "sha512-Pvrk3W3+6XfrmpCRcTumfyplv6AQJXKfDdPFSbhdpHJlpdcQRo6TckA85Yln5/CXZSAiPaZeiejQt2OogrIRLg==", + "version": "7.2.4", + "resolved": "https://registry.npmjs.org/@angular/language-service/-/language-service-7.2.4.tgz", + "integrity": "sha512-A9Rud/27hHMSUUjpgn57nVeLsoYgdvFwJhtlZA/oCuSpmlD+LqqBsEpPhivwn++u44+DSrFXsic29jlFnsBotw==", "dev": true }, + "@angular/material": { + "version": "7.3.2", + "resolved": "https://registry.npmjs.org/@angular/material/-/material-7.3.2.tgz", + "integrity": "sha512-x3it941KE8zuzDH1VLP4yfgmC3hwrqa1a2GHiekztF2KrbWPzEEGNvlyYOUV7nwiuwFw5twON73rW0HUKndwEA==", + "requires": { + "tslib": "^1.7.1" + } + }, "@angular/platform-browser": { - "version": "7.1.4", - "resolved": "https://registry.npmjs.org/@angular/platform-browser/-/platform-browser-7.1.4.tgz", - "integrity": "sha512-lIFBKo6Uqty7qYDI9T8quFCUzUpGBgpzvDe14aAHFwZCft9rMS1J7PB1F26/dy2RBQE8tUyN2zp2xZQnYAhMcA==", + "version": "7.2.4", + "resolved": "https://registry.npmjs.org/@angular/platform-browser/-/platform-browser-7.2.4.tgz", + "integrity": "sha512-Klt8aKR5SP9bqfMfpSY5vQOY7AQEs8JGuZOk5Bfc2dUtYT2IEIvK2IqO8v2rcFRVO13HOPUxl328efyHqLgI7g==", "requires": { "tslib": "^1.9.0" } }, "@angular/platform-browser-dynamic": { - "version": "7.1.4", - "resolved": "https://registry.npmjs.org/@angular/platform-browser-dynamic/-/platform-browser-dynamic-7.1.4.tgz", - "integrity": "sha512-LtFd6XIz98BKjxrCRbaz2y0XSmVQSTzrvpAyNzKnzHAMn+4XpIpnzyV3Y6DeHolIBwLjFHFzGKMBwOHOwME4RQ==", + "version": "7.2.4", + "resolved": "https://registry.npmjs.org/@angular/platform-browser-dynamic/-/platform-browser-dynamic-7.2.4.tgz", + "integrity": "sha512-J/xWlmaYOPUoCHZ5TiIRiyYa4uRMtCz3aGdBfY8k/NWtNo8SCYaS3aut7Sk4RS5rK8aAVi+aYFlY5YOrlW+Hbg==", "requires": { "tslib": "^1.9.0" } }, "@angular/router": { - "version": "7.1.4", - "resolved": "https://registry.npmjs.org/@angular/router/-/router-7.1.4.tgz", - "integrity": "sha512-5VVVcRsmuKrIWPnh5zF1ExXmIpCx2tlisJ7YTS2FFDXnqrZ9i2QgaxyJuyZE+Btg3t7LPF4tkhRQpjauNiHJYA==", + "version": "7.2.4", + "resolved": "https://registry.npmjs.org/@angular/router/-/router-7.2.4.tgz", + "integrity": "sha512-T8Uqf2H1SV1MQI38WwYJ4aa+4NNnvlp2Tp/rkfg6tKcp/cLkKqE6OOfiy9lmW+i/624v8tMgYoBMOUNBjAG23g==", "requires": { "tslib": "^1.9.0" } @@ -723,12 +756,12 @@ } }, "@babel/generator": { - "version": "7.2.2", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.2.2.tgz", - "integrity": "sha512-I4o675J/iS8k+P38dvJ3IBGqObLXyQLTxtrR4u9cSUJOURvafeEWb/pFMOTwtNrmq73mJzyF6ueTbO1BtN0Zeg==", + "version": "7.3.2", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.3.2.tgz", + "integrity": "sha512-f3QCuPppXxtZOEm5GWPra/uYUjmNQlu9pbAD8D/9jze4pTY83rTtB1igTBSwvkeNlC5gR24zFFkz+2WHLFQhqQ==", "dev": true, "requires": { - "@babel/types": "^7.2.2", + "@babel/types": "^7.3.2", "jsesc": "^2.5.1", "lodash": "^4.17.10", "source-map": "^0.5.0", @@ -740,6 +773,12 @@ "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz", "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==", "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 } } }, @@ -781,12 +820,20 @@ "chalk": "^2.0.0", "esutils": "^2.0.2", "js-tokens": "^4.0.0" + }, + "dependencies": { + "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 + } } }, "@babel/parser": { - "version": "7.2.3", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.2.3.tgz", - "integrity": "sha512-0LyEcVlfCoFmci8mXx8A5oIkpkOgyo8dRHtxBnK9RRBwxO2+JZPNsqtVEZQ7mJFPxnXF9lfmU24mHOPI0qnlkA==", + "version": "7.3.2", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.3.2.tgz", + "integrity": "sha512-QzNUC2RO1gadg+fs21fi0Uu0OuGNzRKEmgCxoLNzbCdoprLwjfmZwzUrpUNfJPaVRwBpDY47A17yYEGWyRelnQ==", "dev": true }, "@babel/template": { @@ -826,6 +873,12 @@ "ms": "^2.1.1" } }, + "globals": { + "version": "11.11.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-11.11.0.tgz", + "integrity": "sha512-WHq43gS+6ufNOEqlrDBxVEbb8ntfXrfAUU2ZOpCxrBdGKW3gyv8mCxAfIBD0DroPKGrJ2eSsXsLtY9MPntsyTw==", + "dev": true + }, "ms": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.1.tgz", @@ -835,36 +888,44 @@ } }, "@babel/types": { - "version": "7.2.2", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.2.2.tgz", - "integrity": "sha512-fKCuD6UFUMkR541eDWL+2ih/xFZBXPOg/7EQFeTluMDebfqR4jrpaCjLhkWlQS4hT6nRa2PMEgXKbRB5/H2fpg==", + "version": "7.3.2", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.3.2.tgz", + "integrity": "sha512-3Y6H8xlUlpbGR+XvawiH0UXehqydTmNmEpozWcXymqwcrwYAl5KMvKtQ+TF6f6E08V6Jur7v/ykdDSF+WDEIXQ==", "dev": true, "requires": { "esutils": "^2.0.2", "lodash": "^4.17.10", "to-fast-properties": "^2.0.0" + }, + "dependencies": { + "to-fast-properties": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz", + "integrity": "sha1-3F5pjL0HkmW8c+A3doGk5Og/YW4=", + "dev": true + } } }, "@compodoc/compodoc": { - "version": "1.1.7", - "resolved": "https://registry.npmjs.org/@compodoc/compodoc/-/compodoc-1.1.7.tgz", - "integrity": "sha512-bTqkv75T9b+3OxG517YL+5B0npAG0Q5nOMAk562Idr/fICTTHQ/xzSBsTptZ4QqYmtzRMV1OqOlk74FXfGPZWw==", + "version": "1.1.8", + "resolved": "https://registry.npmjs.org/@compodoc/compodoc/-/compodoc-1.1.8.tgz", + "integrity": "sha512-MuTE/KyNfRxJwLC3Ih2WXsMgd3YWFsViGxFbnrMigNYSq6/syUYVZgoj0E/Hir1au6k5jshKX1Vg7S61wqCaWg==", "dev": true, "requires": { "@compodoc/ngd-transformer": "^2.0.0", - "chalk": "^2.4.1", + "chalk": "^2.4.2", "cheerio": "^1.0.0-rc.2", - "chokidar": "^2.0.4", - "colors": "^1.3.2", + "chokidar": "^2.1.0", + "colors": "^1.3.3", "commander": "2.19.0", "cosmiconfig": "^5.0.7", - "fancy-log": "^1.3.2", + "fancy-log": "^1.3.3", "findit2": "^2.2.3", "fs-extra": "^7.0.1", "glob": "^7.1.3", "handlebars": "4.0.10", "html-entities": "^1.2.1", - "i18next": "^12.1.0", + "i18next": "^14.1.1", "inside": "^1.0.0", "json5": "^2.1.0", "live-server": "1.2.1", @@ -873,17 +934,12 @@ "marked": "^0.4.0", "opencollective": "^1.0.3", "os-name": "^3.0.0", + "semver": "^5.6.0", "traverse": "^0.6.6", "ts-simple-ast": "12.4.0", "uuid": "^3.3.2" }, "dependencies": { - "async": { - "version": "1.5.2", - "resolved": "https://registry.npmjs.org/async/-/async-1.5.2.tgz", - "integrity": "sha1-7GphrlZIDAw8skHJVhjiCJL5Zyo=", - "dev": true - }, "camelcase": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-1.2.1.tgz", @@ -891,6 +947,26 @@ "dev": true, "optional": true }, + "chokidar": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-2.1.1.tgz", + "integrity": "sha512-gfw3p2oQV2wEt+8VuMlNsPjCxDxvvgnm/kz+uATu805mWVF8IJN7uz9DN7iBz+RMJISmiVbCOBFs9qBGMjtPfQ==", + "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.0" + } + }, "cliui": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/cliui/-/cliui-2.1.0.tgz", @@ -903,12 +979,6 @@ "wordwrap": "0.0.2" } }, - "colors": { - "version": "1.3.3", - "resolved": "https://registry.npmjs.org/colors/-/colors-1.3.3.tgz", - "integrity": "sha512-mmGt/1pZqYRjMxB1axhTo16/snVZ5krrKkcmMeVKxzECMMXoCgnvTPp10QgHfcbQZw8Dq2jMNG6je4JlWU0gWg==", - "dev": true - }, "commander": { "version": "2.19.0", "resolved": "https://registry.npmjs.org/commander/-/commander-2.19.0.tgz", @@ -927,20 +997,6 @@ "parse-json": "^4.0.0" } }, - "glob": { - "version": "7.1.3", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.3.tgz", - "integrity": "sha512-vcfuiIxogLV4DlGBHIUOwI0IbrJ8HWPc4MU7HzviGeNho/UJDfi6B5p3sHeWIQ0KGIU0Jpxi5ZHxemQfLkkAwQ==", - "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" - } - }, "handlebars": { "version": "4.0.10", "resolved": "https://registry.npmjs.org/handlebars/-/handlebars-4.0.10.tgz", @@ -968,6 +1024,18 @@ "integrity": "sha512-tMsdNBgOsrUophCAFQl0XPe6Zqk/uy9gnue+jIIKhykO51hxyu6uNx7zBPy0+y/WKYVZZMspV9YeXLNdKk+iYw==", "dev": true }, + "minimist": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", + "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=", + "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 + }, "parse-json": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-4.0.0.tgz", @@ -978,6 +1046,12 @@ "json-parse-better-errors": "^1.0.1" } }, + "semver": { + "version": "5.6.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.6.0.tgz", + "integrity": "sha512-RS9R6R35NYgQn++fkDWaOmqGoj4Ek9gGs+DPxNUZKuwE183xjJroKvyo1IzVFeXvUrvmALy6FWD5xrdJT25gMg==", + "dev": true + }, "source-map": { "version": "0.4.4", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.4.4.tgz", @@ -1008,6 +1082,13 @@ } } }, + "wordwrap": { + "version": "0.0.2", + "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-0.0.2.tgz", + "integrity": "sha1-t5Zpu0LstAn4PVg8rVLKF+qhZD8=", + "dev": true, + "optional": true + }, "yargs": { "version": "3.10.0", "resolved": "https://registry.npmjs.org/yargs/-/yargs-3.10.0.tgz", @@ -1097,18 +1178,27 @@ } }, "@ngtools/webpack": { - "version": "7.2.1", - "resolved": "https://registry.npmjs.org/@ngtools/webpack/-/webpack-7.2.1.tgz", - "integrity": "sha512-/mpXSyaHBP+wfiEt/ZYNsnUmnDmdUkLL1rcNxDyxMxlrL246CtNUcMzYSVqYiKp7ufz6GNklY2QqUa9pcOlW6Q==", + "version": "7.2.4", + "resolved": "https://registry.npmjs.org/@ngtools/webpack/-/webpack-7.2.4.tgz", + "integrity": "sha512-mXMDODmy53kk+Kb5jgLNQOsSrDBQQMf6C6KZNuGo8AdvUGdGaQeZDze4o7bcUz1KUjuaaP1Zh7pZtho8C4/T+Q==", "dev": true, "requires": { - "@angular-devkit/core": "7.2.1", + "@angular-devkit/core": "7.2.4", "enhanced-resolve": "4.1.0", "rxjs": "6.3.3", "tree-kill": "1.2.0", "webpack-sources": "1.2.0" }, "dependencies": { + "rxjs": { + "version": "6.3.3", + "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.3.3.tgz", + "integrity": "sha512-JTWmoY9tWCs7zvIk/CvRjhjGaOd+OVBM987mxFo+OW66cGpdKjZcpmc74ES1sB//7Kl/PAe8+wEakuhG4pcgOw==", + "dev": true, + "requires": { + "tslib": "^1.9.0" + } + }, "source-map": { "version": "0.6.1", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", @@ -1134,23 +1224,23 @@ "dev": true }, "@schematics/angular": { - "version": "7.1.4", - "resolved": "https://registry.npmjs.org/@schematics/angular/-/angular-7.1.4.tgz", - "integrity": "sha512-4QVSmvQtOELek+FDq+k2ROeH9YrRrPJ6jWK179+qOruKSd4uTgEti/jy+fS0rfr52kDSGdDhz7XTh/QvQB89fg==", + "version": "7.3.1", + "resolved": "https://registry.npmjs.org/@schematics/angular/-/angular-7.3.1.tgz", + "integrity": "sha512-0Ne8APPlTAjKg5CSZqluwCuW/5yPjr3ALCWzqwPxN0suE745usThtasBmqrjw0RMIt8nRqRgtg54Z7lCPO9ZFg==", "dev": true, "requires": { - "@angular-devkit/core": "7.1.4", - "@angular-devkit/schematics": "7.1.4", - "typescript": "3.1.6" + "@angular-devkit/core": "7.3.1", + "@angular-devkit/schematics": "7.3.1", + "typescript": "3.2.4" }, "dependencies": { "@angular-devkit/core": { - "version": "7.1.4", - "resolved": "https://registry.npmjs.org/@angular-devkit/core/-/core-7.1.4.tgz", - "integrity": "sha512-3cBVHjSQjMyE/mIyOX82ekdybNRQlN+kUfmdZS6oVW9aV48vdxcVbEGdl8t1H4enMf89u8kXiAAET9jFaqWopg==", + "version": "7.3.1", + "resolved": "https://registry.npmjs.org/@angular-devkit/core/-/core-7.3.1.tgz", + "integrity": "sha512-56XDWWfIzOAkEk69lBLgmCYybPUA4yjunhmMlCk7vVdb7gbQUyzNjFD04Uj0GjlejatAQ5F76tRwygD9C+3RXQ==", "dev": true, "requires": { - "ajv": "6.5.3", + "ajv": "6.7.0", "chokidar": "2.0.4", "fast-json-stable-stringify": "2.0.0", "rxjs": "6.3.3", @@ -1158,9 +1248,9 @@ } }, "ajv": { - "version": "6.5.3", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.5.3.tgz", - "integrity": "sha512-LqZ9wY+fx3UMiiPd741yB2pj3hhil+hQc8taf4o2QGRFpWgZ2V5C8HA165DY9sS3fJwsk7uT7ZlFEyC3Ig3lLg==", + "version": "6.7.0", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.7.0.tgz", + "integrity": "sha512-RZXPviBTtfmtka9n9sy1N5M5b82CbxWIR6HIis4s3WQTXDJamc/0gpCWNGz6EWdWp4DOfjzJfhz/AS9zVPjjWg==", "dev": true, "requires": { "fast-deep-equal": "^2.0.1", @@ -1169,49 +1259,46 @@ "uri-js": "^4.2.2" } }, - "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 - }, - "source-map": { - "version": "0.7.3", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.3.tgz", - "integrity": "sha512-CkCj6giN3S+n9qrYiBTX5gystlENnRW5jZeNLHpe6aue+SrHcG5VYwujhW9s4dY31mEGsxBDrHR6oI69fTXsaQ==", - "dev": true + "rxjs": { + "version": "6.3.3", + "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.3.3.tgz", + "integrity": "sha512-JTWmoY9tWCs7zvIk/CvRjhjGaOd+OVBM987mxFo+OW66cGpdKjZcpmc74ES1sB//7Kl/PAe8+wEakuhG4pcgOw==", + "dev": true, + "requires": { + "tslib": "^1.9.0" + } }, "typescript": { - "version": "3.1.6", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-3.1.6.tgz", - "integrity": "sha512-tDMYfVtvpb96msS1lDX9MEdHrW4yOuZ4Kdc4Him9oU796XldPYF/t2+uKoX0BBa0hXXwDlqYQbXY5Rzjzc5hBA==", + "version": "3.2.4", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-3.2.4.tgz", + "integrity": "sha512-0RNDbSdEokBeEAkgNbxJ+BLwSManFy9TeXz8uW+48j/xhEXv1ePME60olyzw2XzUqUBNAYFeJadIqAgNqIACwg==", "dev": true } } }, "@schematics/update": { - "version": "0.11.4", - "resolved": "https://registry.npmjs.org/@schematics/update/-/update-0.11.4.tgz", - "integrity": "sha512-InfsMJtdWwoqCPmtlJeXBwRPPgIXUzpzIkCCcayRe9gy6PkPUIlOjfgEZ4Mqm/HR46lqsI8xwZfUK7SLV//a2g==", + "version": "0.13.1", + "resolved": "https://registry.npmjs.org/@schematics/update/-/update-0.13.1.tgz", + "integrity": "sha512-EHOqolT/d/jRGuVTCUESLpk8JNpuaPlsVHfeK7Kdp/t0wSEnmtOelZX4+leS25lGXDaDUF3138ntjrZR4n6bGw==", "dev": true, "requires": { - "@angular-devkit/core": "7.1.4", - "@angular-devkit/schematics": "7.1.4", + "@angular-devkit/core": "7.3.1", + "@angular-devkit/schematics": "7.3.1", "@yarnpkg/lockfile": "1.1.0", "ini": "1.3.5", - "pacote": "9.1.1", + "pacote": "9.4.0", "rxjs": "6.3.3", - "semver": "5.5.1", + "semver": "5.6.0", "semver-intersect": "1.4.0" }, "dependencies": { "@angular-devkit/core": { - "version": "7.1.4", - "resolved": "https://registry.npmjs.org/@angular-devkit/core/-/core-7.1.4.tgz", - "integrity": "sha512-3cBVHjSQjMyE/mIyOX82ekdybNRQlN+kUfmdZS6oVW9aV48vdxcVbEGdl8t1H4enMf89u8kXiAAET9jFaqWopg==", + "version": "7.3.1", + "resolved": "https://registry.npmjs.org/@angular-devkit/core/-/core-7.3.1.tgz", + "integrity": "sha512-56XDWWfIzOAkEk69lBLgmCYybPUA4yjunhmMlCk7vVdb7gbQUyzNjFD04Uj0GjlejatAQ5F76tRwygD9C+3RXQ==", "dev": true, "requires": { - "ajv": "6.5.3", + "ajv": "6.7.0", "chokidar": "2.0.4", "fast-json-stable-stringify": "2.0.0", "rxjs": "6.3.3", @@ -1219,9 +1306,9 @@ } }, "ajv": { - "version": "6.5.3", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.5.3.tgz", - "integrity": "sha512-LqZ9wY+fx3UMiiPd741yB2pj3hhil+hQc8taf4o2QGRFpWgZ2V5C8HA165DY9sS3fJwsk7uT7ZlFEyC3Ig3lLg==", + "version": "6.7.0", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.7.0.tgz", + "integrity": "sha512-RZXPviBTtfmtka9n9sy1N5M5b82CbxWIR6HIis4s3WQTXDJamc/0gpCWNGz6EWdWp4DOfjzJfhz/AS9zVPjjWg==", "dev": true, "requires": { "fast-deep-equal": "^2.0.1", @@ -1230,22 +1317,19 @@ "uri-js": "^4.2.2" } }, - "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 + "rxjs": { + "version": "6.3.3", + "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.3.3.tgz", + "integrity": "sha512-JTWmoY9tWCs7zvIk/CvRjhjGaOd+OVBM987mxFo+OW66cGpdKjZcpmc74ES1sB//7Kl/PAe8+wEakuhG4pcgOw==", + "dev": true, + "requires": { + "tslib": "^1.9.0" + } }, "semver": { - "version": "5.5.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.5.1.tgz", - "integrity": "sha512-PqpAxfrEhlSUWge8dwIp4tZnQ25DIOthpiaHNIthsjEFQD6EvqUKUDM7L8O2rShkFccYo1VjJR0coWfNkCubRw==", - "dev": true - }, - "source-map": { - "version": "0.7.3", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.3.tgz", - "integrity": "sha512-CkCj6giN3S+n9qrYiBTX5gystlENnRW5jZeNLHpe6aue+SrHcG5VYwujhW9s4dY31mEGsxBDrHR6oI69fTXsaQ==", + "version": "5.6.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.6.0.tgz", + "integrity": "sha512-RS9R6R35NYgQn++fkDWaOmqGoj4Ek9gGs+DPxNUZKuwE183xjJroKvyo1IzVFeXvUrvmALy6FWD5xrdJT25gMg==", "dev": true } } @@ -1257,9 +1341,9 @@ "dev": true }, "@types/jasmine": { - "version": "3.3.5", - "resolved": "https://registry.npmjs.org/@types/jasmine/-/jasmine-3.3.5.tgz", - "integrity": "sha512-LJtc52O1PNUffMvH6Q3fS0BOhQWYlkh3SVu/Jc4GoPgJkUytk5Y6YPbw+6lZK2mWWvG62BtVyOFw0ih7r8STsw==", + "version": "3.3.8", + "resolved": "https://registry.npmjs.org/@types/jasmine/-/jasmine-3.3.8.tgz", + "integrity": "sha512-BaOFpaddRVV8qykJoWHrHtamml880oh0+DIZWbtJgx0pu+KhDF1gER5hSfCIfzyMrbjMuYFnLUfyo1l0JUVU3Q==", "dev": true }, "@types/jasminewd2": { @@ -1272,9 +1356,9 @@ } }, "@types/node": { - "version": "8.10.39", - "resolved": "https://registry.npmjs.org/@types/node/-/node-8.10.39.tgz", - "integrity": "sha512-rE7fktr02J8ybFf6eysife+WF+L4sAHWzw09DgdCebEu+qDwMvv4zl6Bc+825ttGZP73kCKxa3dhJOoGJ8+5mA==", + "version": "8.10.40", + "resolved": "https://registry.npmjs.org/@types/node/-/node-8.10.40.tgz", + "integrity": "sha512-RRSjdwz63kS4u7edIwJUn8NqKLLQ6LyqF/X4+4jp38MBT3Vwetewi2N4dgJEshLbDwNgOJXNYoOwzVZUSSLhkQ==", "dev": true }, "@types/q": { @@ -1295,6 +1379,11 @@ "integrity": "sha512-K5K+yml8LTo9bWJI/rECfIPrGgxdpeNbj+d53lwN4QjW1MCwlkhUms+gtdzigTeUyBr09+u8BwOIY3MXvHdcsA==", "dev": true }, + "@types/sprintf-js": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@types/sprintf-js/-/sprintf-js-1.1.1.tgz", + "integrity": "sha512-h8jF5yPUoHH1QUIDfHgqFs7Y0UykKB5CJ1Z32PHGmHRLmW0pI+kYKAEnXVqeUZ3ygFmDkyvhD4vUZN+RZyTd1w==" + }, "@types/webpack-sources": { "version": "0.1.5", "resolved": "https://registry.npmjs.org/@types/webpack-sources/-/webpack-sources-0.1.5.tgz", @@ -1315,174 +1404,174 @@ } }, "@webassemblyjs/ast": { - "version": "1.7.10", - "resolved": "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.7.10.tgz", - "integrity": "sha512-wTUeaByYN2EA6qVqhbgavtGc7fLTOx0glG2IBsFlrFG51uXIGlYBTyIZMf4SPLo3v1bgV/7lBN3l7Z0R6Hswew==", + "version": "1.7.11", + "resolved": "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.7.11.tgz", + "integrity": "sha512-ZEzy4vjvTzScC+SH8RBssQUawpaInUdMTYwYYLh54/s8TuT0gBLuyUnppKsVyZEi876VmmStKsUs28UxPgdvrA==", "dev": true, "requires": { - "@webassemblyjs/helper-module-context": "1.7.10", - "@webassemblyjs/helper-wasm-bytecode": "1.7.10", - "@webassemblyjs/wast-parser": "1.7.10" + "@webassemblyjs/helper-module-context": "1.7.11", + "@webassemblyjs/helper-wasm-bytecode": "1.7.11", + "@webassemblyjs/wast-parser": "1.7.11" } }, "@webassemblyjs/floating-point-hex-parser": { - "version": "1.7.10", - "resolved": "https://registry.npmjs.org/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.7.10.tgz", - "integrity": "sha512-gMsGbI6I3p/P1xL2UxqhNh1ga2HCsx5VBB2i5VvJFAaqAjd2PBTRULc3BpTydabUQEGlaZCzEUQhLoLG7TvEYQ==", + "version": "1.7.11", + "resolved": "https://registry.npmjs.org/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.7.11.tgz", + "integrity": "sha512-zY8dSNyYcgzNRNT666/zOoAyImshm3ycKdoLsyDw/Bwo6+/uktb7p4xyApuef1dwEBo/U/SYQzbGBvV+nru2Xg==", "dev": true }, "@webassemblyjs/helper-api-error": { - "version": "1.7.10", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-api-error/-/helper-api-error-1.7.10.tgz", - "integrity": "sha512-DoYRlPWtuw3yd5BOr9XhtrmB6X1enYF0/54yNvQWGXZEPDF5PJVNI7zQ7gkcKfTESzp8bIBWailaFXEK/jjCsw==", + "version": "1.7.11", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-api-error/-/helper-api-error-1.7.11.tgz", + "integrity": "sha512-7r1qXLmiglC+wPNkGuXCvkmalyEstKVwcueZRP2GNC2PAvxbLYwLLPr14rcdJaE4UtHxQKfFkuDFuv91ipqvXg==", "dev": true }, "@webassemblyjs/helper-buffer": { - "version": "1.7.10", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-buffer/-/helper-buffer-1.7.10.tgz", - "integrity": "sha512-+RMU3dt/dPh4EpVX4u5jxsOlw22tp3zjqE0m3ftU2tsYxnPULb4cyHlgaNd2KoWuwasCQqn8Mhr+TTdbtj3LlA==", + "version": "1.7.11", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-buffer/-/helper-buffer-1.7.11.tgz", + "integrity": "sha512-MynuervdylPPh3ix+mKZloTcL06P8tenNH3sx6s0qE8SLR6DdwnfgA7Hc9NSYeob2jrW5Vql6GVlsQzKQCa13w==", "dev": true }, "@webassemblyjs/helper-code-frame": { - "version": "1.7.10", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-code-frame/-/helper-code-frame-1.7.10.tgz", - "integrity": "sha512-UiytbpKAULOEab2hUZK2ywXen4gWJVrgxtwY3Kn+eZaaSWaRM8z/7dAXRSoamhKFiBh1uaqxzE/XD9BLlug3gw==", + "version": "1.7.11", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-code-frame/-/helper-code-frame-1.7.11.tgz", + "integrity": "sha512-T8ESC9KMXFTXA5urJcyor5cn6qWeZ4/zLPyWeEXZ03hj/x9weSokGNkVCdnhSabKGYWxElSdgJ+sFa9G/RdHNw==", "dev": true, "requires": { - "@webassemblyjs/wast-printer": "1.7.10" + "@webassemblyjs/wast-printer": "1.7.11" } }, "@webassemblyjs/helper-fsm": { - "version": "1.7.10", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-fsm/-/helper-fsm-1.7.10.tgz", - "integrity": "sha512-w2vDtUK9xeSRtt5+RnnlRCI7wHEvLjF0XdnxJpgx+LJOvklTZPqWkuy/NhwHSLP19sm9H8dWxKeReMR7sCkGZA==", + "version": "1.7.11", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-fsm/-/helper-fsm-1.7.11.tgz", + "integrity": "sha512-nsAQWNP1+8Z6tkzdYlXT0kxfa2Z1tRTARd8wYnc/e3Zv3VydVVnaeePgqUzFrpkGUyhUUxOl5ML7f1NuT+gC0A==", "dev": true }, "@webassemblyjs/helper-module-context": { - "version": "1.7.10", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-module-context/-/helper-module-context-1.7.10.tgz", - "integrity": "sha512-yE5x/LzZ3XdPdREmJijxzfrf+BDRewvO0zl8kvORgSWmxpRrkqY39KZSq6TSgIWBxkK4SrzlS3BsMCv2s1FpsQ==", + "version": "1.7.11", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-module-context/-/helper-module-context-1.7.11.tgz", + "integrity": "sha512-JxfD5DX8Ygq4PvXDucq0M+sbUFA7BJAv/GGl9ITovqE+idGX+J3QSzJYz+LwQmL7fC3Rs+utvWoJxDb6pmC0qg==", "dev": true }, "@webassemblyjs/helper-wasm-bytecode": { - "version": "1.7.10", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.7.10.tgz", - "integrity": "sha512-u5qy4SJ/OrxKxZqJ9N3qH4ZQgHaAzsopsYwLvoWJY6Q33r8PhT3VPyNMaJ7ZFoqzBnZlCcS/0f4Sp8WBxylXfg==", + "version": "1.7.11", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.7.11.tgz", + "integrity": "sha512-cMXeVS9rhoXsI9LLL4tJxBgVD/KMOKXuFqYb5oCJ/opScWpkCMEz9EJtkonaNcnLv2R3K5jIeS4TRj/drde1JQ==", "dev": true }, "@webassemblyjs/helper-wasm-section": { - "version": "1.7.10", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.7.10.tgz", - "integrity": "sha512-Ecvww6sCkcjatcyctUrn22neSJHLN/TTzolMGG/N7S9rpbsTZ8c6Bl98GpSpV77EvzNijiNRHBG0+JO99qKz6g==", + "version": "1.7.11", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.7.11.tgz", + "integrity": "sha512-8ZRY5iZbZdtNFE5UFunB8mmBEAbSI3guwbrsCl4fWdfRiAcvqQpeqd5KHhSWLL5wuxo53zcaGZDBU64qgn4I4Q==", "dev": true, "requires": { - "@webassemblyjs/ast": "1.7.10", - "@webassemblyjs/helper-buffer": "1.7.10", - "@webassemblyjs/helper-wasm-bytecode": "1.7.10", - "@webassemblyjs/wasm-gen": "1.7.10" + "@webassemblyjs/ast": "1.7.11", + "@webassemblyjs/helper-buffer": "1.7.11", + "@webassemblyjs/helper-wasm-bytecode": "1.7.11", + "@webassemblyjs/wasm-gen": "1.7.11" } }, "@webassemblyjs/ieee754": { - "version": "1.7.10", - "resolved": "https://registry.npmjs.org/@webassemblyjs/ieee754/-/ieee754-1.7.10.tgz", - "integrity": "sha512-HRcWcY+YWt4+s/CvQn+vnSPfRaD4KkuzQFt5MNaELXXHSjelHlSEA8ZcqT69q0GTIuLWZ6JaoKar4yWHVpZHsQ==", + "version": "1.7.11", + "resolved": "https://registry.npmjs.org/@webassemblyjs/ieee754/-/ieee754-1.7.11.tgz", + "integrity": "sha512-Mmqx/cS68K1tSrvRLtaV/Lp3NZWzXtOHUW2IvDvl2sihAwJh4ACE0eL6A8FvMyDG9abes3saB6dMimLOs+HMoQ==", "dev": true, "requires": { "@xtuc/ieee754": "^1.2.0" } }, "@webassemblyjs/leb128": { - "version": "1.7.10", - "resolved": "https://registry.npmjs.org/@webassemblyjs/leb128/-/leb128-1.7.10.tgz", - "integrity": "sha512-og8MciYlA8hvzCLR71hCuZKPbVBfLQeHv7ImKZ4nlyxrYbG7uJHYtHiHu6OV9SqrGuD03H/HtXC4Bgdjfm9FHw==", + "version": "1.7.11", + "resolved": "https://registry.npmjs.org/@webassemblyjs/leb128/-/leb128-1.7.11.tgz", + "integrity": "sha512-vuGmgZjjp3zjcerQg+JA+tGOncOnJLWVkt8Aze5eWQLwTQGNgVLcyOTqgSCxWTR4J42ijHbBxnuRaL1Rv7XMdw==", "dev": true, "requires": { "@xtuc/long": "4.2.1" } }, "@webassemblyjs/utf8": { - "version": "1.7.10", - "resolved": "https://registry.npmjs.org/@webassemblyjs/utf8/-/utf8-1.7.10.tgz", - "integrity": "sha512-Ng6Pxv6siyZp635xCSnH3mKmIFgqWPCcGdoo0GBYgyGdxu7cUj4agV7Uu1a8REP66UYUFXJLudeGgd4RvuJAnQ==", + "version": "1.7.11", + "resolved": "https://registry.npmjs.org/@webassemblyjs/utf8/-/utf8-1.7.11.tgz", + "integrity": "sha512-C6GFkc7aErQIAH+BMrIdVSmW+6HSe20wg57HEC1uqJP8E/xpMjXqQUxkQw07MhNDSDcGpxI9G5JSNOQCqJk4sA==", "dev": true }, "@webassemblyjs/wasm-edit": { - "version": "1.7.10", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-edit/-/wasm-edit-1.7.10.tgz", - "integrity": "sha512-e9RZFQlb+ZuYcKRcW9yl+mqX/Ycj9+3/+ppDI8nEE/NCY6FoK8f3dKBcfubYV/HZn44b+ND4hjh+4BYBt+sDnA==", + "version": "1.7.11", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-edit/-/wasm-edit-1.7.11.tgz", + "integrity": "sha512-FUd97guNGsCZQgeTPKdgxJhBXkUbMTY6hFPf2Y4OedXd48H97J+sOY2Ltaq6WGVpIH8o/TGOVNiVz/SbpEMJGg==", "dev": true, "requires": { - "@webassemblyjs/ast": "1.7.10", - "@webassemblyjs/helper-buffer": "1.7.10", - "@webassemblyjs/helper-wasm-bytecode": "1.7.10", - "@webassemblyjs/helper-wasm-section": "1.7.10", - "@webassemblyjs/wasm-gen": "1.7.10", - "@webassemblyjs/wasm-opt": "1.7.10", - "@webassemblyjs/wasm-parser": "1.7.10", - "@webassemblyjs/wast-printer": "1.7.10" + "@webassemblyjs/ast": "1.7.11", + "@webassemblyjs/helper-buffer": "1.7.11", + "@webassemblyjs/helper-wasm-bytecode": "1.7.11", + "@webassemblyjs/helper-wasm-section": "1.7.11", + "@webassemblyjs/wasm-gen": "1.7.11", + "@webassemblyjs/wasm-opt": "1.7.11", + "@webassemblyjs/wasm-parser": "1.7.11", + "@webassemblyjs/wast-printer": "1.7.11" } }, "@webassemblyjs/wasm-gen": { - "version": "1.7.10", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-gen/-/wasm-gen-1.7.10.tgz", - "integrity": "sha512-M0lb6cO2Y0PzDye/L39PqwV+jvO+2YxEG5ax+7dgq7EwXdAlpOMx1jxyXJTScQoeTpzOPIb+fLgX/IkLF8h2yw==", + "version": "1.7.11", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-gen/-/wasm-gen-1.7.11.tgz", + "integrity": "sha512-U/KDYp7fgAZX5KPfq4NOupK/BmhDc5Kjy2GIqstMhvvdJRcER/kUsMThpWeRP8BMn4LXaKhSTggIJPOeYHwISA==", "dev": true, "requires": { - "@webassemblyjs/ast": "1.7.10", - "@webassemblyjs/helper-wasm-bytecode": "1.7.10", - "@webassemblyjs/ieee754": "1.7.10", - "@webassemblyjs/leb128": "1.7.10", - "@webassemblyjs/utf8": "1.7.10" + "@webassemblyjs/ast": "1.7.11", + "@webassemblyjs/helper-wasm-bytecode": "1.7.11", + "@webassemblyjs/ieee754": "1.7.11", + "@webassemblyjs/leb128": "1.7.11", + "@webassemblyjs/utf8": "1.7.11" } }, "@webassemblyjs/wasm-opt": { - "version": "1.7.10", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-opt/-/wasm-opt-1.7.10.tgz", - "integrity": "sha512-R66IHGCdicgF5ZliN10yn5HaC7vwYAqrSVJGjtJJQp5+QNPBye6heWdVH/at40uh0uoaDN/UVUfXK0gvuUqtVg==", + "version": "1.7.11", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-opt/-/wasm-opt-1.7.11.tgz", + "integrity": "sha512-XynkOwQyiRidh0GLua7SkeHvAPXQV/RxsUeERILmAInZegApOUAIJfRuPYe2F7RcjOC9tW3Cb9juPvAC/sCqvg==", "dev": true, "requires": { - "@webassemblyjs/ast": "1.7.10", - "@webassemblyjs/helper-buffer": "1.7.10", - "@webassemblyjs/wasm-gen": "1.7.10", - "@webassemblyjs/wasm-parser": "1.7.10" + "@webassemblyjs/ast": "1.7.11", + "@webassemblyjs/helper-buffer": "1.7.11", + "@webassemblyjs/wasm-gen": "1.7.11", + "@webassemblyjs/wasm-parser": "1.7.11" } }, "@webassemblyjs/wasm-parser": { - "version": "1.7.10", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-parser/-/wasm-parser-1.7.10.tgz", - "integrity": "sha512-AEv8mkXVK63n/iDR3T693EzoGPnNAwKwT3iHmKJNBrrALAhhEjuPzo/lTE4U7LquEwyvg5nneSNdTdgrBaGJcA==", + "version": "1.7.11", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-parser/-/wasm-parser-1.7.11.tgz", + "integrity": "sha512-6lmXRTrrZjYD8Ng8xRyvyXQJYUQKYSXhJqXOBLw24rdiXsHAOlvw5PhesjdcaMadU/pyPQOJ5dHreMjBxwnQKg==", "dev": true, "requires": { - "@webassemblyjs/ast": "1.7.10", - "@webassemblyjs/helper-api-error": "1.7.10", - "@webassemblyjs/helper-wasm-bytecode": "1.7.10", - "@webassemblyjs/ieee754": "1.7.10", - "@webassemblyjs/leb128": "1.7.10", - "@webassemblyjs/utf8": "1.7.10" + "@webassemblyjs/ast": "1.7.11", + "@webassemblyjs/helper-api-error": "1.7.11", + "@webassemblyjs/helper-wasm-bytecode": "1.7.11", + "@webassemblyjs/ieee754": "1.7.11", + "@webassemblyjs/leb128": "1.7.11", + "@webassemblyjs/utf8": "1.7.11" } }, "@webassemblyjs/wast-parser": { - "version": "1.7.10", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wast-parser/-/wast-parser-1.7.10.tgz", - "integrity": "sha512-YTPEtOBljkCL0VjDp4sHe22dAYSm3ZwdJ9+2NTGdtC7ayNvuip1wAhaAS8Zt9Q6SW9E5Jf5PX7YE3XWlrzR9cw==", + "version": "1.7.11", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wast-parser/-/wast-parser-1.7.11.tgz", + "integrity": "sha512-lEyVCg2np15tS+dm7+JJTNhNWq9yTZvi3qEhAIIOaofcYlUp0UR5/tVqOwa/gXYr3gjwSZqw+/lS9dscyLelbQ==", "dev": true, "requires": { - "@webassemblyjs/ast": "1.7.10", - "@webassemblyjs/floating-point-hex-parser": "1.7.10", - "@webassemblyjs/helper-api-error": "1.7.10", - "@webassemblyjs/helper-code-frame": "1.7.10", - "@webassemblyjs/helper-fsm": "1.7.10", + "@webassemblyjs/ast": "1.7.11", + "@webassemblyjs/floating-point-hex-parser": "1.7.11", + "@webassemblyjs/helper-api-error": "1.7.11", + "@webassemblyjs/helper-code-frame": "1.7.11", + "@webassemblyjs/helper-fsm": "1.7.11", "@xtuc/long": "4.2.1" } }, "@webassemblyjs/wast-printer": { - "version": "1.7.10", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wast-printer/-/wast-printer-1.7.10.tgz", - "integrity": "sha512-mJ3QKWtCchL1vhU/kZlJnLPuQZnlDOdZsyP0bbLWPGdYsQDnSBvyTLhzwBA3QAMlzEL9V4JHygEmK6/OTEyytA==", + "version": "1.7.11", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wast-printer/-/wast-printer-1.7.11.tgz", + "integrity": "sha512-m5vkAsuJ32QpkdkDOUPGSltrg8Cuk3KBx4YrmAGQwCZPRdUHXxG4phIOuuycLemHFr74sWL9Wthqss4fzdzSwg==", "dev": true, "requires": { - "@webassemblyjs/ast": "1.7.10", - "@webassemblyjs/wast-parser": "1.7.10", + "@webassemblyjs/ast": "1.7.11", + "@webassemblyjs/wast-parser": "1.7.11", "@xtuc/long": "4.2.1" } }, @@ -1576,9 +1665,9 @@ } }, "ajv": { - "version": "6.5.3", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.5.3.tgz", - "integrity": "sha512-LqZ9wY+fx3UMiiPd741yB2pj3hhil+hQc8taf4o2QGRFpWgZ2V5C8HA165DY9sS3fJwsk7uT7ZlFEyC3Ig3lLg==", + "version": "6.6.2", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.6.2.tgz", + "integrity": "sha512-FBHEW6Jf5TB9MGBgUUA9XHkTbjXYfAUjY43ACMfmdMRHniyoMHjHjzD50OK8LGDWQwp4rWEsIq5kEqq7rvIM1g==", "dev": true, "requires": { "fast-deep-equal": "^2.0.1", @@ -1594,9 +1683,9 @@ "dev": true }, "ajv-keywords": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.2.0.tgz", - "integrity": "sha1-6GuBnGAs+IIa1jdBNpjx3sAhhHo=", + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.4.0.tgz", + "integrity": "sha512-aUjdRFISbuFOl0EIZc+9e4FfZp0bDZgAdOOf30bJmw8VM9v84SHyVyxDfbWxpGYbdZD/9XoKxfHVNmxPkhwyGw==", "dev": true }, "align-text": { @@ -1604,11 +1693,21 @@ "resolved": "https://registry.npmjs.org/align-text/-/align-text-0.1.4.tgz", "integrity": "sha1-DNkKVhCT810KmSVsIrcGlDP60Rc=", "dev": true, - "optional": true, "requires": { "kind-of": "^3.0.2", "longest": "^1.0.1", "repeat-string": "^1.5.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" + } + } } }, "amdefine": { @@ -1617,11 +1716,6 @@ "integrity": "sha1-SlKCrBZHKek2Gbz9OtFR+BfOkfU=", "dev": true }, - "angular-bootstrap-md": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/angular-bootstrap-md/-/angular-bootstrap-md-7.2.0.tgz", - "integrity": "sha512-fwoedFbUXlIaRMIXxhxce5Q5n6uY64Z9dinYbWCUI9mc7YsDKzc3YmVei8LWet9QWY9acUqSs/iug/WbH9O/iA==" - }, "angular2-chartjs": { "version": "0.5.1", "resolved": "https://registry.npmjs.org/angular2-chartjs/-/angular2-chartjs-0.5.1.tgz", @@ -1637,9 +1731,9 @@ "dev": true }, "ansi-escapes": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-3.1.0.tgz", - "integrity": "sha512-UgAb8H9D41AQnu/PbWlCofQVcnV4Gs2bBJi9eZPxfU/hgglFh3SMDMENRIqdr7H6XFnXdoknctFByVsCOotTVw==", + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-3.2.0.tgz", + "integrity": "sha512-cBhpre4ma+U0T1oM5fXg7Dy1Jw7zzwv7lt/GoCpr+hDQJoYnKVPLL4dCvSEFMmQurOQvSrwT7SL/DAlhBI97RQ==", "dev": true }, "ansi-gray": { @@ -1680,6 +1774,12 @@ "requires": { "color-name": "1.1.3" } + }, + "color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", + "dev": true } } }, @@ -1740,7 +1840,6 @@ "resolved": "https://registry.npmjs.org/are-we-there-yet/-/are-we-there-yet-1.1.5.tgz", "integrity": "sha512-5hYdAkZlcG8tOLujVDTgCT+uPX0VnpAH28gWsLfzpXYm7wP6mp5Q/gYyR7YQ0cKVJcXJnl3j2kpBan13PtQf6w==", "dev": true, - "optional": true, "requires": { "delegates": "^1.0.0", "readable-stream": "^2.0.6" @@ -1814,9 +1913,9 @@ "dev": true }, "array-unique": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.2.1.tgz", - "integrity": "sha1-odl8yvy8JiXMcPrc6zalDFiwGlM=", + "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": { @@ -1875,7 +1974,7 @@ }, "util": { "version": "0.10.3", - "resolved": "http://registry.npmjs.org/util/-/util-0.10.3.tgz", + "resolved": "https://registry.npmjs.org/util/-/util-0.10.3.tgz", "integrity": "sha1-evsa/lCAUkZInj23/g7TeTNqwPk=", "dev": true, "requires": { @@ -1897,13 +1996,10 @@ "dev": true }, "async": { - "version": "2.6.1", - "resolved": "https://registry.npmjs.org/async/-/async-2.6.1.tgz", - "integrity": "sha512-fNEiL2+AZt6AlAw/29Cr0UDe4sRAHCpEHh54WMz+Bb7QfNcFw4h3loofyJpLeQs4Yx7yuqu/2dLgM5hKOs6HlQ==", - "dev": true, - "requires": { - "lodash": "^4.17.10" - } + "version": "1.5.2", + "resolved": "https://registry.npmjs.org/async/-/async-1.5.2.tgz", + "integrity": "sha1-7GphrlZIDAw8skHJVhjiCJL5Zyo=", + "dev": true }, "async-each": { "version": "1.0.1", @@ -1948,71 +2044,19 @@ "num2fraction": "^1.2.2", "postcss": "^7.0.6", "postcss-value-parser": "^3.3.1" - }, - "dependencies": { - "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" - }, - "dependencies": { - "supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", - "dev": true, - "requires": { - "has-flag": "^3.0.0" - } - } - } - }, - "postcss": { - "version": "7.0.11", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.11.tgz", - "integrity": "sha512-9AXb//5UcjeOEof9T+yPw3XTa5SL207ZOIC/lHYP4mbUTEh4M0rDAQekQpVANCZdwQwKhBtFZCk3i3h3h2hdWg==", - "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" - } - } } }, "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=", - "dev": true, - "optional": true + "dev": true }, "aws4": { "version": "1.8.0", "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.8.0.tgz", "integrity": "sha512-ReZxvNHIOv88FlT7rxcXIIC0fPt4KZqZbOlivyWtXLt8ESx84zd3kMC6iK5jVeS2qt+g7ftS7ye4fi06X5rtRQ==", - "dev": true, - "optional": true + "dev": true }, "babel-code-frame": { "version": "6.26.0", @@ -2044,15 +2088,9 @@ "supports-color": "^2.0.0" } }, - "js-tokens": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-3.0.2.tgz", - "integrity": "sha1-mGbfOVECEw449/mWvOtlRDIJwls=", - "dev": true - }, "supports-color": { "version": "2.0.0", - "resolved": "http://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=", "dev": true } @@ -2074,10 +2112,10 @@ "trim-right": "^1.0.1" }, "dependencies": { - "jsesc": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-1.3.0.tgz", - "integrity": "sha1-RsP+yMGJKxKwgz25vHYiF226s0s=", + "source-map": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", + "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", "dev": true } } @@ -2148,14 +2186,6 @@ "globals": "^9.18.0", "invariant": "^2.2.2", "lodash": "^4.17.4" - }, - "dependencies": { - "globals": { - "version": "9.18.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-9.18.0.tgz", - "integrity": "sha512-S0nG3CLEQiY/ILxqtztTWH/3iRRdyBLw6KMDxnKMchrtbj2OFmehVh0WUCfW3DUrIgx/qFrJPICrq4Z4sTR9UQ==", - "dev": true - } } }, "babel-types": { @@ -2168,14 +2198,6 @@ "esutils": "^2.0.2", "lodash": "^4.17.4", "to-fast-properties": "^1.0.3" - }, - "dependencies": { - "to-fast-properties": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-1.0.3.tgz", - "integrity": "sha1-uDVx+k2MJbguIxsG46MFXeTKGkc=", - "dev": true - } } }, "babylon": { @@ -2248,12 +2270,6 @@ "is-data-descriptor": "^1.0.0", "kind-of": "^6.0.2" } - }, - "kind-of": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.2.tgz", - "integrity": "sha512-s5kLOcnH0XqDO+FvuaLX8DDjZ18CGFk7VygH40QoKPUQhW4e2rvM0rwUq0t8IQDOwYSeLK01U90OjzBTme2QqA==", - "dev": true } } }, @@ -2282,14 +2298,6 @@ "dev": true, "requires": { "safe-buffer": "5.1.2" - }, - "dependencies": { - "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 - } } }, "batch": { @@ -2329,9 +2337,9 @@ "dev": true }, "binary-extensions": { - "version": "1.11.0", - "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-1.11.0.tgz", - "integrity": "sha1-RqoXUftqL5PuXmibsQh9SxTGwgU=", + "version": "1.13.0", + "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-1.13.0.tgz", + "integrity": "sha512-EgmjVLMn22z7eGGv3kcnHwSnJXmFHjISTY9E/S5lIcTD3Oxw05QTcBLNkJFzcb3cNueUdF/IN4U+d78V0zO8Hw==", "dev": true }, "blob": { @@ -2357,6 +2365,14 @@ "dev": true, "requires": { "minimist": "^1.2.0" + }, + "dependencies": { + "minimist": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", + "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=", + "dev": true + } } }, "bluebird": { @@ -2387,17 +2403,6 @@ "qs": "6.5.2", "raw-body": "2.3.3", "type-is": "~1.6.16" - }, - "dependencies": { - "iconv-lite": { - "version": "0.4.23", - "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.23.tgz", - "integrity": "sha512-neyTUVFtahjf0mB3dZT77u+8O0QB89jFdnBkd5P1JgYPbPaia3gXXOVL2fq8VyU2gMMD7SaN7QukTB/pmXYvDA==", - "dev": true, - "requires": { - "safer-buffer": ">= 2.1.2 < 3" - } - } } }, "bonjour": { @@ -2421,9 +2426,9 @@ "dev": true }, "brace-expansion": { - "version": "1.1.8", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.8.tgz", - "integrity": "sha1-wHshHHyVLsH479Uad+8NHTmQopI=", + "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", @@ -2448,12 +2453,6 @@ "to-regex": "^3.0.1" }, "dependencies": { - "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 - }, "extend-shallow": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", @@ -2506,14 +2505,6 @@ "des.js": "^1.0.0", "inherits": "^2.0.1", "safe-buffer": "^5.1.2" - }, - "dependencies": { - "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 - } } }, "browserify-rsa": { @@ -2551,20 +2542,20 @@ } }, "browserslist": { - "version": "4.4.0", - "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.4.0.tgz", - "integrity": "sha512-tQkHS8VVxWbrjnNDXgt7/+SuPJ7qDvD0Y2e6bLtoQluR2SPvlmPUcfcU75L1KAalhqULlIFJlJ6BDfnYyJxJsw==", + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.4.1.tgz", + "integrity": "sha512-pEBxEXg7JwaakBXjATYw/D1YZh4QUSCX/Mnd/wnqSRPPSi1U39iDhDoKGoBUcraKdxDlrYqJxSI5nNvD+dWP2A==", "dev": true, "requires": { - "caniuse-lite": "^1.0.30000928", - "electron-to-chromium": "^1.3.100", + "caniuse-lite": "^1.0.30000929", + "electron-to-chromium": "^1.3.103", "node-releases": "^1.1.3" } }, "browserstack": { - "version": "1.5.1", - "resolved": "https://registry.npmjs.org/browserstack/-/browserstack-1.5.1.tgz", - "integrity": "sha512-O8VMT64P9NOLhuIoD4YngyxBURefaSdR4QdhG8l6HZ9VxtU7jc3m6jLufFwKA5gaf7fetfB2TnRJnMxyob+heg==", + "version": "1.5.2", + "resolved": "https://registry.npmjs.org/browserstack/-/browserstack-1.5.2.tgz", + "integrity": "sha512-+6AFt9HzhKykcPF79W6yjEUJcdvZOV0lIXdkORXMJftGrDl0OKWqRF4GHqpDNkxiceDT/uB7Fb/aDwktvXX7dg==", "dev": true, "requires": { "https-proxy-agent": "^2.2.1" @@ -2720,10 +2711,11 @@ "dev": true }, "camelcase": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-4.1.0.tgz", - "integrity": "sha1-1UVjW+HjPFQmScaRc+Xeas+uNN0=", - "dev": true + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-2.1.1.tgz", + "integrity": "sha1-fB0W1nmhu+WcoCys7PsBHiAfWh8=", + "dev": true, + "optional": true }, "camelcase-keys": { "version": "2.1.0", @@ -2734,21 +2726,12 @@ "requires": { "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=", - "dev": true, - "optional": true - } } }, "caniuse-lite": { - "version": "1.0.30000928", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30000928.tgz", - "integrity": "sha512-aSpMWRXL6ZXNnzm8hgE4QDLibG5pVJ2Ujzsuj3icazlIkxXkPXtL+BWnMx6FBkWmkZgBHGUxPZQvrbRw2ZTxhg==", + "version": "1.0.30000936", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30000936.tgz", + "integrity": "sha512-orX4IdpbFhdNO7bTBhSbahp1EBpqzBc+qrvTRVUFfZgA4zta7TdM6PN5ZxkEUgDnz36m+PfWGcdX7AVfFWItJw==", "dev": true }, "canonical-path": { @@ -2775,14 +2758,25 @@ } }, "chalk": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.1.tgz", - "integrity": "sha512-ObN6h1v2fTJSmUXoS3nMQ92LbDK9be4TV+6G+omQlGJFdcUX5heKi1LZ1YnRMIgwTLEj3E24bT6tYni50rlCfQ==", + "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" + }, + "dependencies": { + "supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, + "requires": { + "has-flag": "^3.0.0" + } + } } }, "chardet": { @@ -2993,23 +2987,6 @@ "is-plain-object": "^2.0.4", "kind-of": "^6.0.0", "shallow-clone": "^1.0.0" - }, - "dependencies": { - "for-own": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/for-own/-/for-own-1.0.0.tgz", - "integrity": "sha1-xjMy9BXO3EsE2/5wz4NklMU8tEs=", - "dev": true, - "requires": { - "for-in": "^1.0.1" - } - }, - "kind-of": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.2.tgz", - "integrity": "sha512-s5kLOcnH0XqDO+FvuaLX8DDjZ18CGFk7VygH40QoKPUQhW4e2rvM0rwUq0t8IQDOwYSeLK01U90OjzBTme2QqA==", - "dev": true - } } }, "co": { @@ -3044,6 +3021,12 @@ "sprintf-js": "^1.1.1" }, "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", @@ -3068,9 +3051,9 @@ "integrity": "sha1-vbbGnOZg+t/+CwAHzER+G59ygr0=" }, "color-name": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=" + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" }, "color-support": { "version": "1.1.3", @@ -3079,9 +3062,9 @@ "dev": true }, "colors": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/colors/-/colors-1.1.2.tgz", - "integrity": "sha1-FopHAXVran9RoSzgyXv6KMCE7WM=", + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/colors/-/colors-1.3.3.tgz", + "integrity": "sha512-mmGt/1pZqYRjMxB1axhTo16/snVZ5krrKkcmMeVKxzECMMXoCgnvTPp10QgHfcbQZw8Dq2jMNG6je4JlWU0gWg==", "dev": true }, "combine-lists": { @@ -3098,7 +3081,6 @@ "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.7.tgz", "integrity": "sha512-brWl9y6vOB1xYPZcpZde3N9zDByXTosAeMDo4p1wzo6UMOX4vumB+TP1RZ76sfE6Md68Q0NJSrE/gbezd4Ul+w==", "dev": true, - "optional": true, "requires": { "delayed-stream": "~1.0.0" } @@ -3161,14 +3143,6 @@ "on-headers": "~1.0.1", "safe-buffer": "5.1.2", "vary": "~1.1.2" - }, - "dependencies": { - "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 - } } }, "concat-map": { @@ -3199,12 +3173,35 @@ "finalhandler": "1.1.0", "parseurl": "~1.3.2", "utils-merge": "1.0.1" + }, + "dependencies": { + "finalhandler": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.1.0.tgz", + "integrity": "sha1-zgtoVbRYU+eRsvzGgARtiCU91/U=", + "dev": true, + "requires": { + "debug": "2.6.9", + "encodeurl": "~1.0.1", + "escape-html": "~1.0.3", + "on-finished": "~2.3.0", + "parseurl": "~1.3.2", + "statuses": "~1.3.1", + "unpipe": "~1.0.0" + } + }, + "statuses": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.3.1.tgz", + "integrity": "sha1-+vUbnrdKrvOzrPStX2Gr8ky3uT4=", + "dev": true + } } }, "connect-history-api-fallback": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/connect-history-api-fallback/-/connect-history-api-fallback-1.5.0.tgz", - "integrity": "sha1-sGhzk0vF40T+9hGhlqb6rgruAVo=", + "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 }, "console-browserify": { @@ -3220,8 +3217,7 @@ "version": "1.1.0", "resolved": "https://registry.npmjs.org/console-control-strings/-/console-control-strings-1.1.0.tgz", "integrity": "sha1-PXz0Rk22RG6mRL9LOVB/mFEAjo4=", - "dev": true, - "optional": true + "dev": true }, "constants-browserify": { "version": "1.0.0", @@ -3299,9 +3295,9 @@ } }, "core-js": { - "version": "2.6.1", - "resolved": "https://registry.npmjs.org/core-js/-/core-js-2.6.1.tgz", - "integrity": "sha512-L72mmmEayPJBejKIWe2pYtGis5r0tQ5NaJekdhyXgeMQTpJoBsH0NL4ElY2LfSoV15xeQWKQ+XTTOZdyero5Xg==" + "version": "2.6.4", + "resolved": "https://registry.npmjs.org/core-js/-/core-js-2.6.4.tgz", + "integrity": "sha512-05qQ5hXShcqGkPZpXEFLIpxayZscVD2kuMBZewxiIPPEagukO4mqgPA9CWhUvFBJfy3ODdK2p9xyHh7FTU9/7A==" }, "core-util-is": { "version": "1.0.2", @@ -3553,6 +3549,14 @@ "dev": true, "requires": { "strip-bom": "^3.0.0" + }, + "dependencies": { + "strip-bom": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", + "integrity": "sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM=", + "dev": true + } } }, "define-property": { @@ -3593,12 +3597,6 @@ "is-data-descriptor": "^1.0.0", "kind-of": "^6.0.2" } - }, - "kind-of": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.2.tgz", - "integrity": "sha512-s5kLOcnH0XqDO+FvuaLX8DDjZ18CGFk7VygH40QoKPUQhW4e2rvM0rwUq0t8IQDOwYSeLK01U90OjzBTme2QqA==", - "dev": true } } }, @@ -3631,17 +3629,11 @@ "dependencies": { "pify": { "version": "2.3.0", - "resolved": "http://registry.npmjs.org/pify/-/pify-2.3.0.tgz", + "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=", "dev": true } } - }, - "pify": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz", - "integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=", - "dev": true } } }, @@ -3661,8 +3653,7 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/delegates/-/delegates-1.0.0.tgz", "integrity": "sha1-hMbhWbgZBP3KWaDvRM2HDTElD5o=", - "dev": true, - "optional": true + "dev": true }, "depd": { "version": "1.1.2", @@ -3731,12 +3722,11 @@ } }, "dir-glob": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-2.0.0.tgz", - "integrity": "sha512-37qirFDz8cA5fimp9feo43fSuRo2gHwaIn6dXL8Ber1dGwUosDrGZeCCXq57WnIqE4aQ+u3eQZzsk1yOzhdwag==", + "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": { - "arrify": "^1.0.1", "path-type": "^3.0.0" } }, @@ -3839,9 +3829,9 @@ "dev": true }, "duplexify": { - "version": "3.6.1", - "resolved": "https://registry.npmjs.org/duplexify/-/duplexify-3.6.1.tgz", - "integrity": "sha512-vM58DwdnKmty+FSPzT14K9JXb90H+j5emaR4KYbr2KTIz00WHGbWOe5ghQTx233ZCLZtrGDALzKwcjEtSt35mA==", + "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", @@ -3867,9 +3857,9 @@ "dev": true }, "electron-to-chromium": { - "version": "1.3.103", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.103.tgz", - "integrity": "sha512-tObPqGmY9X8MUM8i3MEimYmbnLLf05/QV5gPlkR8MQ3Uj8G8B2govE1U4cQcBYtv3ymck9Y8cIOu4waoiykMZQ==", + "version": "1.3.113", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.113.tgz", + "integrity": "sha512-De+lPAxEcpxvqPTyZAXELNpRZXABRxf+uL/rSykstQhzj/B0l1150G/ExIIxKc16lI89Hgz81J0BHAcbTqK49g==", "dev": true }, "elliptic": { @@ -4072,15 +4062,9 @@ "source-map": "~0.2.0" }, "dependencies": { - "esprima": { - "version": "2.7.3", - "resolved": "https://registry.npmjs.org/esprima/-/esprima-2.7.3.tgz", - "integrity": "sha1-luO3DVd59q1JzQMmc9HDEnZ7pYE=", - "dev": true - }, "source-map": { "version": "0.2.0", - "resolved": "http://registry.npmjs.org/source-map/-/source-map-0.2.0.tgz", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.2.0.tgz", "integrity": "sha1-2rc/vPwrqBm03gO9b26qSBZLP50=", "dev": true, "optional": true, @@ -4109,9 +4093,9 @@ } }, "esprima": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", - "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", + "version": "2.7.3", + "resolved": "https://registry.npmjs.org/esprima/-/esprima-2.7.3.tgz", + "integrity": "sha1-luO3DVd59q1JzQMmc9HDEnZ7pYE=", "dev": true }, "esrecurse": { @@ -4171,9 +4155,9 @@ "dev": true }, "events": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/events/-/events-1.1.1.tgz", - "integrity": "sha1-nr23Y1rQmccNzEwqH1AEKI6L2SQ=", + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/events/-/events-3.0.0.tgz", + "integrity": "sha512-Dc381HFWJzEOhQ+d8pkNon++bk9h6cdAoAj4iE6Q4y6xgTzySWXlKn05/TVNpjnfRqi/X0EpJEJohPjNI3zpVA==", "dev": true }, "eventsource": { @@ -4222,12 +4206,6 @@ "shebang-command": "^1.2.0", "which": "^1.2.9" } - }, - "semver": { - "version": "5.6.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.6.0.tgz", - "integrity": "sha512-RS9R6R35NYgQn++fkDWaOmqGoj4Ek9gGs+DPxNUZKuwE183xjJroKvyo1IzVFeXvUrvmALy6FWD5xrdJT25gMg==", - "dev": true } } }, @@ -4248,6 +4226,12 @@ "braces": "^0.1.2" }, "dependencies": { + "array-unique": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.2.1.tgz", + "integrity": "sha1-odl8yvy8JiXMcPrc6zalDFiwGlM=", + "dev": true + }, "braces": { "version": "0.1.5", "resolved": "https://registry.npmjs.org/braces/-/braces-0.1.5.tgz", @@ -4355,6 +4339,15 @@ "requires": { "isarray": "1.0.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" + } } } }, @@ -4401,33 +4394,6 @@ "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", "integrity": "sha1-ml9pkFGx5wczKPKgCJaLZOopVdI=", "dev": true - }, - "finalhandler": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.1.1.tgz", - "integrity": "sha512-Y1GUDo39ez4aHAw7MysnUD5JzYX+WaIj8I57kO3aEPT1fFRL4sr7mjei97FgnwhAyyzRYmQZaTHb2+9uZ1dPtg==", - "dev": true, - "requires": { - "debug": "2.6.9", - "encodeurl": "~1.0.2", - "escape-html": "~1.0.3", - "on-finished": "~2.3.0", - "parseurl": "~1.3.2", - "statuses": "~1.4.0", - "unpipe": "~1.0.0" - } - }, - "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 - }, - "statuses": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.4.0.tgz", - "integrity": "sha512-zhSCtt8v2NDrRlPQpCNtw/heZLtfUDqxBM1udqikb/Hbk52LK4nQSwr10u77iopCW5LsyHpuXS0GnEc48mLeew==", - "dev": true } } }, @@ -4467,6 +4433,17 @@ "chardet": "^0.7.0", "iconv-lite": "^0.4.24", "tmp": "^0.0.33" + }, + "dependencies": { + "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" + } + } } }, "extglob": { @@ -4485,12 +4462,6 @@ "to-regex": "^3.0.1" }, "dependencies": { - "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 - }, "define-property": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", @@ -4537,12 +4508,6 @@ "is-data-descriptor": "^1.0.0", "kind-of": "^6.0.2" } - }, - "kind-of": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.2.tgz", - "integrity": "sha512-s5kLOcnH0XqDO+FvuaLX8DDjZ18CGFk7VygH40QoKPUQhW4e2rvM0rwUq0t8IQDOwYSeLK01U90OjzBTme2QqA==", - "dev": true } } }, @@ -4571,9 +4536,9 @@ "dev": true }, "fast-glob": { - "version": "2.2.4", - "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-2.2.4.tgz", - "integrity": "sha512-FjK2nCGI/McyzgNtTESqaWP3trPvHyRyoyY70hxjc3oKPNmDe8taohLZpoVKoUjW85tbU5txaYUZCNtVzygl1g==", + "version": "2.2.6", + "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-2.2.6.tgz", + "integrity": "sha512-0BvMaZc1k9F+MeWWMe8pL6YltFzZYcJsYU7D4JyDA6PAczaXvxqQQ/z+mDF7/4Mw01DeUc+i3CTKajnkANkV4w==", "dev": true, "requires": { "@mrmlnc/readdir-enhanced": "^2.2.1", @@ -4681,26 +4646,18 @@ } }, "finalhandler": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.1.0.tgz", - "integrity": "sha1-zgtoVbRYU+eRsvzGgARtiCU91/U=", + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.1.1.tgz", + "integrity": "sha512-Y1GUDo39ez4aHAw7MysnUD5JzYX+WaIj8I57kO3aEPT1fFRL4sr7mjei97FgnwhAyyzRYmQZaTHb2+9uZ1dPtg==", "dev": true, "requires": { "debug": "2.6.9", - "encodeurl": "~1.0.1", + "encodeurl": "~1.0.2", "escape-html": "~1.0.3", "on-finished": "~2.3.0", "parseurl": "~1.3.2", - "statuses": "~1.3.1", + "statuses": "~1.4.0", "unpipe": "~1.0.0" - }, - "dependencies": { - "statuses": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.3.1.tgz", - "integrity": "sha1-+vUbnrdKrvOzrPStX2Gr8ky3uT4=", - "dev": true - } } }, "find-cache-dir": { @@ -4736,13 +4693,13 @@ "dev": true }, "flush-write-stream": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/flush-write-stream/-/flush-write-stream-1.0.3.tgz", - "integrity": "sha512-calZMC10u0FMUqoiunI2AiGIIUtUIvifNwkHhNupZH4cbNnW1Itkoh/Nf5HFYmDrwWPjrUxpkZT0KhuCq0jmGw==", + "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.1", - "readable-stream": "^2.0.4" + "inherits": "^2.0.3", + "readable-stream": "^2.3.6" } }, "follow-redirects": { @@ -4765,11 +4722,6 @@ } } }, - "font-awesome": { - "version": "4.7.0", - "resolved": "https://registry.npmjs.org/font-awesome/-/font-awesome-4.7.0.tgz", - "integrity": "sha1-j6jPBBGhoxr9B7BtKQK7n8gVoTM=" - }, "for-in": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/for-in/-/for-in-1.0.2.tgz", @@ -4777,9 +4729,9 @@ "dev": true }, "for-own": { - "version": "0.1.5", - "resolved": "https://registry.npmjs.org/for-own/-/for-own-0.1.5.tgz", - "integrity": "sha1-UmXGgaTylNq78XyVCbZ2OqhFEM4=", + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/for-own/-/for-own-1.0.0.tgz", + "integrity": "sha1-xjMy9BXO3EsE2/5wz4NklMU8tEs=", "dev": true, "requires": { "for-in": "^1.0.1" @@ -4796,7 +4748,6 @@ "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.3.3.tgz", "integrity": "sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ==", "dev": true, - "optional": true, "requires": { "asynckit": "^0.4.0", "combined-stream": "^1.0.6", @@ -4888,9 +4839,9 @@ "dev": true }, "fsevents": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-1.2.4.tgz", - "integrity": "sha512-z8H8/diyk76B7q5wg+Ud0+CqzcAF3mBBI/bA5ne5zrRUUIvNkJY//D3BqyH571KuAC4Nr7Rw7CjWX4r0y9DvNg==", + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-1.2.7.tgz", + "integrity": "sha512-Pxm6sI2MeBD7RdD12RYsqaP0nMiwx8eZBXCa6z2L+mRHm2DYrOYwihmhjpkdjUHwQhslWQjRpEgNq4XvBmaAuw==", "dev": true, "optional": true, "requires": { @@ -4900,29 +4851,24 @@ "dependencies": { "abbrev": { "version": "1.1.1", - "resolved": "", - "integrity": "sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==", + "bundled": true, "dev": true, "optional": true }, "ansi-regex": { "version": "2.1.1", - "resolved": "", - "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=", - "dev": true, - "optional": true + "bundled": true, + "dev": true }, "aproba": { "version": "1.2.0", - "resolved": "", - "integrity": "sha512-Y9J6ZjXtoYh8RnXVCMOU/ttDmk1aBjunq9vO0ta5x85WDQiQfUF9sIPBITdbiiIVcBo03Hi3jMxigBtsddlXRw==", + "bundled": true, "dev": true, "optional": true }, "are-we-there-yet": { - "version": "1.1.4", - "resolved": "", - "integrity": "sha1-u13KOCu5TwXhUZQ3PRb9O6HKEQ0=", + "version": "1.1.5", + "bundled": true, "dev": true, "optional": true, "requires": { @@ -4932,61 +4878,48 @@ }, "balanced-match": { "version": "1.0.0", - "resolved": "", - "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=", - "dev": true, - "optional": true + "bundled": true, + "dev": true }, "brace-expansion": { "version": "1.1.11", - "resolved": "", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "bundled": true, "dev": true, - "optional": true, "requires": { "balanced-match": "^1.0.0", "concat-map": "0.0.1" } }, "chownr": { - "version": "1.0.1", - "resolved": "", - "integrity": "sha1-4qdQQqlVGQi+vSW4Uj1fl2nXkYE=", + "version": "1.1.1", + "bundled": true, "dev": true, "optional": true }, "code-point-at": { "version": "1.1.0", - "resolved": "", - "integrity": "sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c=", - "dev": true, - "optional": true + "bundled": true, + "dev": true }, "concat-map": { "version": "0.0.1", - "resolved": "", - "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=", - "dev": true, - "optional": true + "bundled": true, + "dev": true }, "console-control-strings": { "version": "1.1.0", - "resolved": "", - "integrity": "sha1-PXz0Rk22RG6mRL9LOVB/mFEAjo4=", - "dev": true, - "optional": true + "bundled": true, + "dev": true }, "core-util-is": { "version": "1.0.2", - "resolved": "", - "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=", + "bundled": true, "dev": true, "optional": true }, "debug": { "version": "2.6.9", - "resolved": "", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "bundled": true, "dev": true, "optional": true, "requires": { @@ -4994,30 +4927,26 @@ } }, "deep-extend": { - "version": "0.5.1", - "resolved": "", - "integrity": "sha512-N8vBdOa+DF7zkRrDCsaOXoCs/E2fJfx9B9MrKnnSiHNh4ws7eSys6YQE4KvT1cecKmOASYQBhbKjeuDD9lT81w==", + "version": "0.6.0", + "bundled": true, "dev": true, "optional": true }, "delegates": { "version": "1.0.0", - "resolved": "", - "integrity": "sha1-hMbhWbgZBP3KWaDvRM2HDTElD5o=", + "bundled": true, "dev": true, "optional": true }, "detect-libc": { "version": "1.0.3", - "resolved": "", - "integrity": "sha1-+hN8S9aY7fVc1c0CrFWfkaTEups=", + "bundled": true, "dev": true, "optional": true }, "fs-minipass": { "version": "1.2.5", - "resolved": "", - "integrity": "sha512-JhBl0skXjUPCFH7x6x61gQxrKyXsxB5gcgePLZCwfyCGGsTISMoIeObbrvVeP6Xmyaudw4TT43qV2Gz+iyd2oQ==", + "bundled": true, "dev": true, "optional": true, "requires": { @@ -5026,15 +4955,13 @@ }, "fs.realpath": { "version": "1.0.0", - "resolved": "", - "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=", + "bundled": true, "dev": true, "optional": true }, "gauge": { "version": "2.7.4", - "resolved": "", - "integrity": "sha1-LANAXHU4w51+s3sxcCLjJfsBi/c=", + "bundled": true, "dev": true, "optional": true, "requires": { @@ -5049,9 +4976,8 @@ } }, "glob": { - "version": "7.1.2", - "resolved": "", - "integrity": "sha512-MJTUg1kjuLeQCJ+ccE4Vpa6kKVXkPYJ2mOCQyUuKLcLQsdrMCpBPUi8qVE6+YuaJkozeA9NusTAw3hLr8Xe5EQ==", + "version": "7.1.3", + "bundled": true, "dev": true, "optional": true, "requires": { @@ -5065,25 +4991,22 @@ }, "has-unicode": { "version": "2.0.1", - "resolved": "", - "integrity": "sha1-4Ob+aijPUROIVeCG0Wkedx3iqLk=", + "bundled": true, "dev": true, "optional": true }, "iconv-lite": { - "version": "0.4.21", - "resolved": "", - "integrity": "sha512-En5V9za5mBt2oUA03WGD3TwDv0MKAruqsuxstbMUZaj9W9k/m1CV/9py3l0L5kw9Bln8fdHQmzHSYtvpvTLpKw==", + "version": "0.4.24", + "bundled": true, "dev": true, "optional": true, "requires": { - "safer-buffer": "^2.1.0" + "safer-buffer": ">= 2.1.2 < 3" } }, "ignore-walk": { "version": "3.0.1", - "resolved": "", - "integrity": "sha512-DTVlMx3IYPe0/JJcYP7Gxg7ttZZu3IInhuEhbchuqneY9wWe5Ojy2mXLBaQFUQmo0AW2r3qG7m1mg86js+gnlQ==", + "bundled": true, "dev": true, "optional": true, "requires": { @@ -5092,8 +5015,7 @@ }, "inflight": { "version": "1.0.6", - "resolved": "", - "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", + "bundled": true, "dev": true, "optional": true, "requires": { @@ -5103,67 +5025,54 @@ }, "inherits": { "version": "2.0.3", - "resolved": "", - "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=", - "dev": true, - "optional": true + "bundled": true, + "dev": true }, "ini": { "version": "1.3.5", - "resolved": "", - "integrity": "sha512-RZY5huIKCMRWDUqZlEi72f/lmXKMvuszcMBduliQ3nnWbx9X/ZBQO7DijMEYS9EhHBb2qacRUMtC7svLwe0lcw==", + "bundled": true, "dev": true, "optional": true }, "is-fullwidth-code-point": { "version": "1.0.0", - "resolved": "", - "integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=", + "bundled": true, "dev": true, - "optional": true, "requires": { "number-is-nan": "^1.0.0" } }, "isarray": { "version": "1.0.0", - "resolved": "", - "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", + "bundled": true, "dev": true, "optional": true }, "minimatch": { "version": "3.0.4", - "resolved": "", - "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", + "bundled": true, "dev": true, - "optional": true, "requires": { "brace-expansion": "^1.1.7" } }, "minimist": { "version": "0.0.8", - "resolved": "", - "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=", - "dev": true, - "optional": true + "bundled": true, + "dev": true }, "minipass": { - "version": "2.2.4", - "resolved": "", - "integrity": "sha512-hzXIWWet/BzWhYs2b+u7dRHlruXhwdgvlTMDKC6Cb1U7ps6Ac6yQlR39xsbjWJE377YTCtKwIXIpJ5oP+j5y8g==", + "version": "2.3.5", + "bundled": true, "dev": true, - "optional": true, "requires": { - "safe-buffer": "^5.1.1", + "safe-buffer": "^5.1.2", "yallist": "^3.0.0" } }, "minizlib": { - "version": "1.1.0", - "resolved": "", - "integrity": "sha512-4T6Ur/GctZ27nHfpt9THOdRZNgyJ9FZchYO1ceg5S8Q3DNLCKYy44nCZzgCJgcvx2UM8czmqak5BCxJMrq37lA==", + "version": "1.2.1", + "bundled": true, "dev": true, "optional": true, "requires": { @@ -5172,25 +5081,21 @@ }, "mkdirp": { "version": "0.5.1", - "resolved": "", - "integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=", + "bundled": true, "dev": true, - "optional": true, "requires": { "minimist": "0.0.8" } }, "ms": { "version": "2.0.0", - "resolved": "", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", + "bundled": true, "dev": true, "optional": true }, "needle": { - "version": "2.2.0", - "resolved": "", - "integrity": "sha512-eFagy6c+TYayorXw/qtAdSvaUpEbBsDwDyxYFgLZ0lTojfH7K+OdBqAF7TAFwDokJaGpubpSGG0wO3iC0XPi8w==", + "version": "2.2.4", + "bundled": true, "dev": true, "optional": true, "requires": { @@ -5200,19 +5105,18 @@ } }, "node-pre-gyp": { - "version": "0.10.0", - "resolved": "", - "integrity": "sha512-G7kEonQLRbcA/mOoFoxvlMrw6Q6dPf92+t/l0DFSMuSlDoWaI9JWIyPwK0jyE1bph//CUEL65/Fz1m2vJbmjQQ==", + "version": "0.10.3", + "bundled": true, "dev": true, "optional": true, "requires": { "detect-libc": "^1.0.2", "mkdirp": "^0.5.1", - "needle": "^2.2.0", + "needle": "^2.2.1", "nopt": "^4.0.1", "npm-packlist": "^1.1.6", "npmlog": "^4.0.2", - "rc": "^1.1.7", + "rc": "^1.2.7", "rimraf": "^2.6.1", "semver": "^5.3.0", "tar": "^4" @@ -5220,8 +5124,7 @@ }, "nopt": { "version": "4.0.1", - "resolved": "", - "integrity": "sha1-0NRoWv1UFRk8jHUFYC0NF81kR00=", + "bundled": true, "dev": true, "optional": true, "requires": { @@ -5230,16 +5133,14 @@ } }, "npm-bundled": { - "version": "1.0.3", - "resolved": "", - "integrity": "sha512-ByQ3oJ/5ETLyglU2+8dBObvhfWXX8dtPZDMePCahptliFX2iIuhyEszyFk401PZUNQH20vvdW5MLjJxkwU80Ow==", + "version": "1.0.5", + "bundled": true, "dev": true, "optional": true }, "npm-packlist": { - "version": "1.1.10", - "resolved": "", - "integrity": "sha512-AQC0Dyhzn4EiYEfIUjCdMl0JJ61I2ER9ukf/sLxJUcZHfo+VyEfz2rMJgLZSS1v30OxPQe1cN0LZA1xbcaVfWA==", + "version": "1.2.0", + "bundled": true, "dev": true, "optional": true, "requires": { @@ -5249,8 +5150,7 @@ }, "npmlog": { "version": "4.1.2", - "resolved": "", - "integrity": "sha512-2uUqazuKlTaSI/dC8AzicUck7+IrEaOnN/e0jd3Xtt1KcGpwx30v50mL7oPyr/h9bL3E4aZccVwpwP+5W9Vjkg==", + "bundled": true, "dev": true, "optional": true, "requires": { @@ -5262,46 +5162,38 @@ }, "number-is-nan": { "version": "1.0.1", - "resolved": "", - "integrity": "sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0=", - "dev": true, - "optional": true + "bundled": true, + "dev": true }, "object-assign": { "version": "4.1.1", - "resolved": "", - "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=", + "bundled": true, "dev": true, "optional": true }, "once": { "version": "1.4.0", - "resolved": "", - "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", + "bundled": true, "dev": true, - "optional": true, "requires": { "wrappy": "1" } }, "os-homedir": { "version": "1.0.2", - "resolved": "", - "integrity": "sha1-/7xJiDNuDoM94MFox+8VISGqf7M=", + "bundled": true, "dev": true, "optional": true }, "os-tmpdir": { "version": "1.0.2", - "resolved": "", - "integrity": "sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ=", + "bundled": true, "dev": true, "optional": true }, "osenv": { "version": "0.1.5", - "resolved": "", - "integrity": "sha512-0CWcCECdMVc2Rw3U5w9ZjqX6ga6ubk1xDVKxtBQPK7wis/0F2r9T6k4ydGYhecl7YUBxBVxhL5oisPsNxAPe2g==", + "bundled": true, "dev": true, "optional": true, "requires": { @@ -5311,26 +5203,23 @@ }, "path-is-absolute": { "version": "1.0.1", - "resolved": "", - "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=", + "bundled": true, "dev": true, "optional": true }, "process-nextick-args": { "version": "2.0.0", - "resolved": "", - "integrity": "sha512-MtEC1TqN0EU5nephaJ4rAtThHtC86dNN9qCuEhtshvpVBkAW5ZO7BASN9REnF9eoXGcRub+pFuKEpOHE+HbEMw==", + "bundled": true, "dev": true, "optional": true }, "rc": { - "version": "1.2.7", - "resolved": "", - "integrity": "sha512-LdLD8xD4zzLsAT5xyushXDNscEjB7+2ulnl8+r1pnESlYtlJtVSoCMBGr30eDRJ3+2Gq89jK9P9e4tCEH1+ywA==", + "version": "1.2.8", + "bundled": true, "dev": true, "optional": true, "requires": { - "deep-extend": "^0.5.1", + "deep-extend": "^0.6.0", "ini": "~1.3.0", "minimist": "^1.2.0", "strip-json-comments": "~2.0.1" @@ -5338,8 +5227,7 @@ "dependencies": { "minimist": { "version": "1.2.0", - "resolved": "", - "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=", + "bundled": true, "dev": true, "optional": true } @@ -5347,8 +5235,7 @@ }, "readable-stream": { "version": "2.3.6", - "resolved": "", - "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==", + "bundled": true, "dev": true, "optional": true, "requires": { @@ -5362,63 +5249,53 @@ } }, "rimraf": { - "version": "2.6.2", - "resolved": "", - "integrity": "sha512-lreewLK/BlghmxtfH36YYVg1i8IAce4TI7oao75I1g245+6BctqTVQiBP3YUJ9C6DQOXJmkYR9X9fCLtCOJc5w==", + "version": "2.6.3", + "bundled": true, "dev": true, "optional": true, "requires": { - "glob": "^7.0.5" + "glob": "^7.1.3" } }, "safe-buffer": { - "version": "5.1.1", - "resolved": "", - "integrity": "sha512-kKvNJn6Mm93gAczWVJg7wH+wGYWNrDHdWvpUmHyEsgCtIwwo3bqPtV4tR5tuPaUhTOo/kvhVwd8XwwOllGYkbg==", - "dev": true, - "optional": true + "version": "5.1.2", + "bundled": true, + "dev": true }, "safer-buffer": { "version": "2.1.2", - "resolved": "", - "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", + "bundled": true, "dev": true, "optional": true }, "sax": { "version": "1.2.4", - "resolved": "", - "integrity": "sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw==", + "bundled": true, "dev": true, "optional": true }, "semver": { - "version": "5.5.0", - "resolved": "", - "integrity": "sha512-4SJ3dm0WAwWy/NVeioZh5AntkdJoWKxHxcmyP622fOkgHa4z3R0TdBJICINyaSDE6uNwVc8gZr+ZinwZAH4xIA==", + "version": "5.6.0", + "bundled": true, "dev": true, "optional": true }, "set-blocking": { "version": "2.0.0", - "resolved": "", - "integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc=", + "bundled": true, "dev": true, "optional": true }, "signal-exit": { "version": "3.0.2", - "resolved": "", - "integrity": "sha1-tf3AjxKH6hF4Yo5BXiUTK3NkbG0=", + "bundled": true, "dev": true, "optional": true }, "string-width": { "version": "1.0.2", - "resolved": "", - "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=", + "bundled": true, "dev": true, - "optional": true, "requires": { "code-point-at": "^1.0.0", "is-fullwidth-code-point": "^1.0.0", @@ -5427,8 +5304,7 @@ }, "string_decoder": { "version": "1.1.1", - "resolved": "", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "bundled": true, "dev": true, "optional": true, "requires": { @@ -5437,67 +5313,57 @@ }, "strip-ansi": { "version": "3.0.1", - "resolved": "", - "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", + "bundled": true, "dev": true, - "optional": true, "requires": { "ansi-regex": "^2.0.0" } }, "strip-json-comments": { "version": "2.0.1", - "resolved": "", - "integrity": "sha1-PFMZQukIwml8DsNEhYwobHygpgo=", + "bundled": true, "dev": true, "optional": true }, "tar": { - "version": "4.4.1", - "resolved": "", - "integrity": "sha512-O+v1r9yN4tOsvl90p5HAP4AEqbYhx4036AGMm075fH9F8Qwi3oJ+v4u50FkT/KkvywNGtwkk0zRI+8eYm1X/xg==", + "version": "4.4.8", + "bundled": true, "dev": true, "optional": true, "requires": { - "chownr": "^1.0.1", + "chownr": "^1.1.1", "fs-minipass": "^1.2.5", - "minipass": "^2.2.4", - "minizlib": "^1.1.0", + "minipass": "^2.3.4", + "minizlib": "^1.1.1", "mkdirp": "^0.5.0", - "safe-buffer": "^5.1.1", + "safe-buffer": "^5.1.2", "yallist": "^3.0.2" } }, "util-deprecate": { "version": "1.0.2", - "resolved": "", - "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=", + "bundled": true, "dev": true, "optional": true }, "wide-align": { - "version": "1.1.2", - "resolved": "", - "integrity": "sha512-ijDLlyQ7s6x1JgCLur53osjm/UXUYD9+0PbYKrBsYisYXzCxN+HC3mYDNy/dWdmf3AwqwU3CXwDCvsNgGK1S0w==", + "version": "1.1.3", + "bundled": true, "dev": true, "optional": true, "requires": { - "string-width": "^1.0.2" + "string-width": "^1.0.2 || 2" } }, "wrappy": { "version": "1.0.2", - "resolved": "", - "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", - "dev": true, - "optional": true + "bundled": true, + "dev": true }, "yallist": { - "version": "3.0.2", - "resolved": "", - "integrity": "sha1-hFK0u36Dx8GI2AQcGoN8dz1ti7k=", - "dev": true, - "optional": true + "version": "3.0.3", + "bundled": true, + "dev": true } } }, @@ -5506,7 +5372,6 @@ "resolved": "https://registry.npmjs.org/fstream/-/fstream-1.0.11.tgz", "integrity": "sha1-XB+x8RdHcRTwYyoOtLcbPLD9MXE=", "dev": true, - "optional": true, "requires": { "graceful-fs": "^4.1.2", "inherits": "~2.0.0", @@ -5519,7 +5384,6 @@ "resolved": "https://registry.npmjs.org/gauge/-/gauge-2.7.4.tgz", "integrity": "sha1-LANAXHU4w51+s3sxcCLjJfsBi/c=", "dev": true, - "optional": true, "requires": { "aproba": "^1.0.3", "console-control-strings": "^1.0.0", @@ -5557,8 +5421,7 @@ "version": "4.0.1", "resolved": "https://registry.npmjs.org/get-stdin/-/get-stdin-4.0.1.tgz", "integrity": "sha1-uWjGsKBDhDJJAui/Gl3zJXmkUP4=", - "dev": true, - "optional": true + "dev": true }, "get-stream": { "version": "3.0.0", @@ -5582,9 +5445,9 @@ } }, "glob": { - "version": "7.1.2", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.2.tgz", - "integrity": "sha512-MJTUg1kjuLeQCJ+ccE4Vpa6kKVXkPYJ2mOCQyUuKLcLQsdrMCpBPUi8qVE6+YuaJkozeA9NusTAw3hLr8Xe5EQ==", + "version": "7.1.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.3.tgz", + "integrity": "sha512-vcfuiIxogLV4DlGBHIUOwI0IbrJ8HWPc4MU7HzviGeNho/UJDfi6B5p3sHeWIQ0KGIU0Jpxi5ZHxemQfLkkAwQ==", "dev": true, "requires": { "fs.realpath": "^1.0.0", @@ -5659,9 +5522,9 @@ "dev": true }, "globals": { - "version": "11.9.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-11.9.0.tgz", - "integrity": "sha512-5cJVtyXWH8PiJPVLZzzoIizXx944O4OmRro5MWKx5fT4MgcN7OfaMutPeaTdJCCURwbWdhhcCWcKIffPnmTzBg==", + "version": "9.18.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-9.18.0.tgz", + "integrity": "sha512-S0nG3CLEQiY/ILxqtztTWH/3iRRdyBLw6KMDxnKMchrtbj2OFmehVh0WUCfW3DUrIgx/qFrJPICrq4Z4sTR9UQ==", "dev": true }, "globby": { @@ -5676,14 +5539,6 @@ "ignore": "^3.3.5", "pify": "^3.0.0", "slash": "^1.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 - } } }, "globule": { @@ -5708,11 +5563,16 @@ } }, "graceful-fs": { - "version": "4.1.11", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.1.11.tgz", - "integrity": "sha1-Dovf5NHduIVNZOBOp8AOKgJuVlg=", + "version": "4.1.15", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.1.15.tgz", + "integrity": "sha512-6uHUhOPEBgQ24HM+r6b/QwWfZq+yiFcipKFrOFiBEnWdy5sdzYoi+pJeQaPI5qOLRFqWmAXUPQNsielzdLoecA==", "dev": true }, + "hammerjs": { + "version": "2.0.8", + "resolved": "https://registry.npmjs.org/hammerjs/-/hammerjs-2.0.8.tgz", + "integrity": "sha1-BO93hiz/K7edMPdpIJWTAiK/YPE=" + }, "handle-thing": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/handle-thing/-/handle-thing-2.0.0.tgz", @@ -5720,9 +5580,9 @@ "dev": true }, "handlebars": { - "version": "4.0.12", - "resolved": "https://registry.npmjs.org/handlebars/-/handlebars-4.0.12.tgz", - "integrity": "sha512-RhmTekP+FZL+XNhwS1Wf+bTTZpdLougwt5pcgA1tuz6Jcx0fpH/7z0qd71RKnZHBCxIRBHfBOnio4gViPemNzA==", + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/handlebars/-/handlebars-4.1.0.tgz", + "integrity": "sha512-l2jRuU1NAWK6AW5qqcTATWQJvNPEwkM7NEKSiv/gqOsoSQbVoWyqVEY5GS+XPQ88zLNmqASRpzfdm8d79hJS+w==", "dev": true, "requires": { "async": "^2.5.0", @@ -5731,6 +5591,15 @@ "uglify-js": "^3.1.4" }, "dependencies": { + "async": { + "version": "2.6.1", + "resolved": "https://registry.npmjs.org/async/-/async-2.6.1.tgz", + "integrity": "sha512-fNEiL2+AZt6AlAw/29Cr0UDe4sRAHCpEHh54WMz+Bb7QfNcFw4h3loofyJpLeQs4Yx7yuqu/2dLgM5hKOs6HlQ==", + "dev": true, + "requires": { + "lodash": "^4.17.10" + } + }, "source-map": { "version": "0.6.1", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", @@ -5743,33 +5612,16 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/har-schema/-/har-schema-2.0.0.tgz", "integrity": "sha1-qUwiJOvKwEeCoNkDVSHyRzW37JI=", - "dev": true, - "optional": true + "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==", "dev": true, - "optional": true, "requires": { "ajv": "^6.5.5", "har-schema": "^2.0.0" - }, - "dependencies": { - "ajv": { - "version": "6.7.0", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.7.0.tgz", - "integrity": "sha512-RZXPviBTtfmtka9n9sy1N5M5b82CbxWIR6HIis4s3WQTXDJamc/0gpCWNGz6EWdWp4DOfjzJfhz/AS9zVPjjWg==", - "dev": true, - "optional": 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" - } - } } }, "has-ansi": { @@ -5814,8 +5666,7 @@ "version": "2.0.1", "resolved": "https://registry.npmjs.org/has-unicode/-/has-unicode-2.0.1.tgz", "integrity": "sha1-4Ob+aijPUROIVeCG0Wkedx3iqLk=", - "dev": true, - "optional": true + "dev": true }, "has-value": { "version": "1.0.0", @@ -5838,26 +5689,6 @@ "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": "^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" - } - } - } - }, "kind-of": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-4.0.0.tgz", @@ -5953,15 +5784,6 @@ "string_decoder": "^1.1.1", "util-deprecate": "^1.0.1" } - }, - "string_decoder": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.2.0.tgz", - "integrity": "sha512-6YqyX6ZWEYguAxgZzHGL7SsCeGx3V2TtOTqZz1xSTSWnqsbWwbptafNyvf/ACquZUXV3DANr5BDIwNYe1mN42w==", - "dev": true, - "requires": { - "safe-buffer": "~5.1.0" - } } } }, @@ -6056,7 +5878,6 @@ "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.2.0.tgz", "integrity": "sha1-muzZJRFHcvPZW2WmCruPfBj7rOE=", "dev": true, - "optional": true, "requires": { "assert-plus": "^1.0.0", "jsprim": "^1.2.2", @@ -6106,15 +5927,15 @@ } }, "i18next": { - "version": "12.1.0", - "resolved": "https://registry.npmjs.org/i18next/-/i18next-12.1.0.tgz", - "integrity": "sha512-AexmwGkKxwKfo5fGeXTWEY4xqzRPigQ1S/0InOUUVziGO54cd4fKyYK8ED1Thx9fd+WA3fRSZ+1iekvFQMbsFw==", + "version": "14.1.1", + "resolved": "https://registry.npmjs.org/i18next/-/i18next-14.1.1.tgz", + "integrity": "sha512-HItn9RHLyrDqe6pw6qXMYHGPHNc3y1FZndJfBlD6k4sRS0FAlYLvqCDVIWFc1XultBgsv348TtvL/lleG6JgBg==", "dev": true }, "iconv-lite": { - "version": "0.4.24", - "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", - "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", + "version": "0.4.23", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.23.tgz", + "integrity": "sha512-neyTUVFtahjf0mB3dZT77u+8O0QB89jFdnBkd5P1JgYPbPaia3gXXOVL2fq8VyU2gMMD7SaN7QukTB/pmXYvDA==", "dev": true, "requires": { "safer-buffer": ">= 2.1.2 < 3" @@ -6304,9 +6125,9 @@ "dev": true }, "inquirer": { - "version": "6.2.0", - "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-6.2.0.tgz", - "integrity": "sha512-QIEQG4YyQ2UYZGDC4srMZ7BjHOmNk1lR2JQj5UknBapklm6WHA+VVH7N+sUdX3A7NeCfGF8o4X1S3Ao7nAcIeg==", + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-6.2.1.tgz", + "integrity": "sha512-088kl3DRT2dLU5riVMKKr1DlImd6X7smDhpXUCkJDCKvTEJeRiXh0G132HG9u5a+6Ylw9plFRY7RuTnwohYSpg==", "dev": true, "requires": { "ansi-escapes": "^3.0.0", @@ -6320,7 +6141,7 @@ "run-async": "^2.2.0", "rxjs": "^6.1.0", "string-width": "^2.1.0", - "strip-ansi": "^4.0.0", + "strip-ansi": "^5.0.0", "through": "^2.3.6" }, "dependencies": { @@ -6344,15 +6165,34 @@ "requires": { "is-fullwidth-code-point": "^2.0.0", "strip-ansi": "^4.0.0" + }, + "dependencies": { + "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" + } + } } }, "strip-ansi": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", - "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.0.0.tgz", + "integrity": "sha512-Uu7gQyZI7J7gn5qLn1Np3G9vcYGTVqB+lFTytnDJv83dd8T22aGH451P3jueT2/QemInJDfxHB5Tde5OzgG1Ow==", "dev": true, "requires": { - "ansi-regex": "^3.0.0" + "ansi-regex": "^4.0.0" + }, + "dependencies": { + "ansi-regex": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.0.0.tgz", + "integrity": "sha512-iB5Dda8t/UqpPI/IjsejXu5jOGDrzn41wJyljwPH65VCIbk6+1BzFIMJGFwTNrYXT1CrD+B4l19U7awiQ8rk7w==", + "dev": true + } } } } @@ -6429,6 +6269,17 @@ "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-arrayish": { @@ -6452,15 +6303,6 @@ "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==", "dev": true }, - "is-builtin-module": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-builtin-module/-/is-builtin-module-1.0.0.tgz", - "integrity": "sha1-VAVy0096wxGfj3bDDLwbHgN6/74=", - "dev": true, - "requires": { - "builtin-modules": "^1.0.0" - } - }, "is-data-descriptor": { "version": "0.1.4", "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", @@ -6468,6 +6310,17 @@ "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": { @@ -6562,7 +6415,18 @@ "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-path-cwd": { "version": "1.0.0", @@ -6571,9 +6435,9 @@ "dev": true }, "is-path-in-cwd": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-path-in-cwd/-/is-path-in-cwd-1.0.0.tgz", - "integrity": "sha1-ZHdYK4IU1gI0YJRWcAO+ip6sBNw=", + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-path-in-cwd/-/is-path-in-cwd-1.0.1.tgz", + "integrity": "sha512-FjV1RTW48E7CWM7eE/J2NJvAEEVektecDBVBE5Hh3nM1Jd0kvhHtX68Pr3xsDf857xt3Y4AkwVULK1Vku62aaQ==", "dev": true, "requires": { "is-path-inside": "^1.0.0" @@ -6649,8 +6513,7 @@ "version": "0.2.1", "resolved": "https://registry.npmjs.org/is-utf8/-/is-utf8-0.2.1.tgz", "integrity": "sha1-Sw2hRCEE0bM2NA6AeX6GXPOffXI=", - "dev": true, - "optional": true + "dev": true }, "is-windows": { "version": "1.0.2", @@ -6719,18 +6582,6 @@ "wordwrap": "^1.0.0" }, "dependencies": { - "async": { - "version": "1.5.2", - "resolved": "https://registry.npmjs.org/async/-/async-1.5.2.tgz", - "integrity": "sha1-7GphrlZIDAw8skHJVhjiCJL5Zyo=", - "dev": true - }, - "esprima": { - "version": "2.7.3", - "resolved": "https://registry.npmjs.org/esprima/-/esprima-2.7.3.tgz", - "integrity": "sha1-luO3DVd59q1JzQMmc9HDEnZ7pYE=", - "dev": true - }, "glob": { "version": "5.0.15", "resolved": "https://registry.npmjs.org/glob/-/glob-5.0.15.tgz", @@ -6750,12 +6601,6 @@ "integrity": "sha1-nZ55MWXOAXoA8AQYxD+UKnsdEfo=", "dev": true }, - "resolve": { - "version": "1.1.7", - "resolved": "http://registry.npmjs.org/resolve/-/resolve-1.1.7.tgz", - "integrity": "sha1-IDEU2CrSxe2ejgQRs5ModeiJ6Xs=", - "dev": true - }, "supports-color": { "version": "3.2.3", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-3.2.3.tgz", @@ -6764,33 +6609,60 @@ "requires": { "has-flag": "^1.0.0" } - }, - "wordwrap": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-1.0.0.tgz", - "integrity": "sha1-J1hIEIkUVqQXHI0CJkQa3pDLyus=", - "dev": true } } }, "istanbul-api": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/istanbul-api/-/istanbul-api-2.0.6.tgz", - "integrity": "sha512-8W5oeAGWXhtTJjAyVfvavOLVyZCTNCKsyF6GON/INKlBdO7uJ/bv3qnPj5M6ERKzmMCJS1kntnjjGuJ86fn3rQ==", + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/istanbul-api/-/istanbul-api-2.1.0.tgz", + "integrity": "sha512-+Ygg4t1StoiNlBGc6x0f8q/Bv26FbZqP/+jegzfNpU7Q8o+4ZRoJxJPhBkgE/UonpAjtxnE4zCZIyJX+MwLRMQ==", "dev": true, "requires": { "async": "^2.6.1", "compare-versions": "^3.2.1", "fileset": "^2.0.3", - "istanbul-lib-coverage": "^2.0.1", - "istanbul-lib-hook": "^2.0.1", - "istanbul-lib-instrument": "^3.0.0", - "istanbul-lib-report": "^2.0.2", - "istanbul-lib-source-maps": "^2.0.1", - "istanbul-reports": "^2.0.1", + "istanbul-lib-coverage": "^2.0.3", + "istanbul-lib-hook": "^2.0.3", + "istanbul-lib-instrument": "^3.1.0", + "istanbul-lib-report": "^2.0.4", + "istanbul-lib-source-maps": "^3.0.2", + "istanbul-reports": "^2.1.0", "js-yaml": "^3.12.0", "make-dir": "^1.3.0", + "minimatch": "^3.0.4", "once": "^1.4.0" + }, + "dependencies": { + "async": { + "version": "2.6.1", + "resolved": "https://registry.npmjs.org/async/-/async-2.6.1.tgz", + "integrity": "sha512-fNEiL2+AZt6AlAw/29Cr0UDe4sRAHCpEHh54WMz+Bb7QfNcFw4h3loofyJpLeQs4Yx7yuqu/2dLgM5hKOs6HlQ==", + "dev": true, + "requires": { + "lodash": "^4.17.10" + } + }, + "istanbul-lib-coverage": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.3.tgz", + "integrity": "sha512-dKWuzRGCs4G+67VfW9pBFFz2Jpi4vSp/k7zBcJ888ofV5Mi1g5CUML5GvMvV6u9Cjybftu+E8Cgp+k0dI1E5lw==", + "dev": true + }, + "istanbul-lib-instrument": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-3.1.0.tgz", + "integrity": "sha512-ooVllVGT38HIk8MxDj/OIHXSYvH+1tq/Vb38s8ixt9GoJadXska4WkGY+0wkmtYCZNYtaARniH/DixUGGLZ0uA==", + "dev": true, + "requires": { + "@babel/generator": "^7.0.0", + "@babel/parser": "^7.0.0", + "@babel/template": "^7.0.0", + "@babel/traverse": "^7.0.0", + "@babel/types": "^7.0.0", + "istanbul-lib-coverage": "^2.0.3", + "semver": "^5.5.0" + } + } } }, "istanbul-instrumenter-loader": { @@ -6823,27 +6695,6 @@ "integrity": "sha1-wFNHeBfIa1HaqFPIHgWbcz0CNhQ=", "dev": true }, - "istanbul-lib-coverage": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-1.2.1.tgz", - "integrity": "sha512-PzITeunAgyGbtY1ibVIUiV679EFChHjoMNRibEIobvmrCRaIgwLxNucOSimtNWUhEib/oO7QY2imD75JVgCJWQ==", - "dev": true - }, - "istanbul-lib-instrument": { - "version": "1.10.2", - "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-1.10.2.tgz", - "integrity": "sha512-aWHxfxDqvh/ZlxR8BBaEPVSWDPUkGD63VjGQn3jcw8jCp7sHEMKcrj4xfJn/ABzdMEHiQNyvDQhqm5o8+SQg7A==", - "dev": true, - "requires": { - "babel-generator": "^6.18.0", - "babel-template": "^6.16.0", - "babel-traverse": "^6.18.0", - "babel-types": "^6.18.0", - "babylon": "^6.18.0", - "istanbul-lib-coverage": "^1.2.1", - "semver": "^5.3.0" - } - }, "json-schema-traverse": { "version": "0.3.1", "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.3.1.tgz", @@ -6862,76 +6713,82 @@ } }, "istanbul-lib-coverage": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.1.tgz", - "integrity": "sha512-nPvSZsVlbG9aLhZYaC3Oi1gT/tpyo3Yt5fNyf6NmcKIayz4VV/txxJFFKAK/gU4dcNn8ehsanBbVHVl0+amOLA==", + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-1.2.1.tgz", + "integrity": "sha512-PzITeunAgyGbtY1ibVIUiV679EFChHjoMNRibEIobvmrCRaIgwLxNucOSimtNWUhEib/oO7QY2imD75JVgCJWQ==", "dev": true }, "istanbul-lib-hook": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/istanbul-lib-hook/-/istanbul-lib-hook-2.0.1.tgz", - "integrity": "sha512-ufiZoiJ8CxY577JJWEeFuxXZoMqiKpq/RqZtOAYuQLvlkbJWscq9n3gc4xrCGH9n4pW0qnTxOz1oyMmVtk8E1w==", + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/istanbul-lib-hook/-/istanbul-lib-hook-2.0.3.tgz", + "integrity": "sha512-CLmEqwEhuCYtGcpNVJjLV1DQyVnIqavMLFHV/DP+np/g3qvdxu3gsPqYoJMXm15sN84xOlckFB3VNvRbf5yEgA==", "dev": true, "requires": { "append-transform": "^1.0.0" } }, "istanbul-lib-instrument": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-3.0.0.tgz", - "integrity": "sha512-eQY9vN9elYjdgN9Iv6NS/00bptm02EBBk70lRMaVjeA6QYocQgenVrSgC28TJurdnZa80AGO3ASdFN+w/njGiQ==", + "version": "1.10.2", + "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-1.10.2.tgz", + "integrity": "sha512-aWHxfxDqvh/ZlxR8BBaEPVSWDPUkGD63VjGQn3jcw8jCp7sHEMKcrj4xfJn/ABzdMEHiQNyvDQhqm5o8+SQg7A==", "dev": true, "requires": { - "@babel/generator": "^7.0.0", - "@babel/parser": "^7.0.0", - "@babel/template": "^7.0.0", - "@babel/traverse": "^7.0.0", - "@babel/types": "^7.0.0", - "istanbul-lib-coverage": "^2.0.1", - "semver": "^5.5.0" - }, - "dependencies": { - "semver": { - "version": "5.6.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.6.0.tgz", - "integrity": "sha512-RS9R6R35NYgQn++fkDWaOmqGoj4Ek9gGs+DPxNUZKuwE183xjJroKvyo1IzVFeXvUrvmALy6FWD5xrdJT25gMg==", - "dev": true - } + "babel-generator": "^6.18.0", + "babel-template": "^6.16.0", + "babel-traverse": "^6.18.0", + "babel-types": "^6.18.0", + "babylon": "^6.18.0", + "istanbul-lib-coverage": "^1.2.1", + "semver": "^5.3.0" } }, "istanbul-lib-report": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/istanbul-lib-report/-/istanbul-lib-report-2.0.2.tgz", - "integrity": "sha512-rJ8uR3peeIrwAxoDEbK4dJ7cqqtxBisZKCuwkMtMv0xYzaAnsAi3AHrHPAAtNXzG/bcCgZZ3OJVqm1DTi9ap2Q==", + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/istanbul-lib-report/-/istanbul-lib-report-2.0.4.tgz", + "integrity": "sha512-sOiLZLAWpA0+3b5w5/dq0cjm2rrNdAfHWaGhmn7XEFW6X++IV9Ohn+pnELAl9K3rfpaeBfbmH9JU5sejacdLeA==", "dev": true, "requires": { - "istanbul-lib-coverage": "^2.0.1", + "istanbul-lib-coverage": "^2.0.3", "make-dir": "^1.3.0", - "supports-color": "^5.4.0" + "supports-color": "^6.0.0" + }, + "dependencies": { + "istanbul-lib-coverage": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.3.tgz", + "integrity": "sha512-dKWuzRGCs4G+67VfW9pBFFz2Jpi4vSp/k7zBcJ888ofV5Mi1g5CUML5GvMvV6u9Cjybftu+E8Cgp+k0dI1E5lw==", + "dev": true + } } }, "istanbul-lib-source-maps": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/istanbul-lib-source-maps/-/istanbul-lib-source-maps-2.0.1.tgz", - "integrity": "sha512-30l40ySg+gvBLcxTrLzR4Z2XTRj3HgRCA/p2rnbs/3OiTaoj054gAbuP5DcLOtwqmy4XW8qXBHzrmP2/bQ9i3A==", + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/istanbul-lib-source-maps/-/istanbul-lib-source-maps-3.0.2.tgz", + "integrity": "sha512-JX4v0CiKTGp9fZPmoxpu9YEkPbEqCqBbO3403VabKjH+NRXo72HafD5UgnjTEqHL2SAjaZK1XDuDOkn6I5QVfQ==", "dev": true, "requires": { - "debug": "^3.1.0", - "istanbul-lib-coverage": "^2.0.1", + "debug": "^4.1.1", + "istanbul-lib-coverage": "^2.0.3", "make-dir": "^1.3.0", "rimraf": "^2.6.2", "source-map": "^0.6.1" }, "dependencies": { "debug": { - "version": "3.2.6", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.6.tgz", - "integrity": "sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ==", + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", + "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", "dev": true, "requires": { "ms": "^2.1.1" } }, + "istanbul-lib-coverage": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.3.tgz", + "integrity": "sha512-dKWuzRGCs4G+67VfW9pBFFz2Jpi4vSp/k7zBcJ888ofV5Mi1g5CUML5GvMvV6u9Cjybftu+E8Cgp+k0dI1E5lw==", + "dev": true + }, "ms": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.1.tgz", @@ -6947,9 +6804,9 @@ } }, "istanbul-reports": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-2.0.1.tgz", - "integrity": "sha512-CT0QgMBJqs6NJLF678ZHcquUAZIoBIUNzdJrRJfpkI9OnzG6MkUfHxbJC3ln981dMswC7/B1mfX3LNkhgJxsuw==", + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-2.1.0.tgz", + "integrity": "sha512-azQdSX+dtTtkQEfqq20ICxWi6eOHXyHIgMFw1VOOVi8iIPWeCWRgCyFh/CsBKIhcgskMI8ExXmU7rjXTRCIJ+A==", "dev": true, "requires": { "handlebars": "^4.0.11" @@ -7356,6 +7213,14 @@ "dev": true, "requires": { "colors": "1.1.2" + }, + "dependencies": { + "colors": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/colors/-/colors-1.1.2.tgz", + "integrity": "sha1-FopHAXVran9RoSzgyXv6KMCE7WM=", + "dev": true + } } }, "jasminewd2": { @@ -7365,26 +7230,34 @@ "dev": true }, "js-base64": { - "version": "2.5.0", - "resolved": "https://registry.npmjs.org/js-base64/-/js-base64-2.5.0.tgz", - "integrity": "sha512-wlEBIZ5LP8usDylWbDNhKPEFVFdI5hCHpnVoT/Ysvoi/PRhJENm/Rlh9TvjYB38HFfKZN7OzEbRjmjvLkFw11g==", + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/js-base64/-/js-base64-2.5.1.tgz", + "integrity": "sha512-M7kLczedRMYX4L8Mdh4MzyAMM9O5osx+4FcOQuTvr3A9F2D9S5JXheN0ewNbrvK2UatkTRhL5ejGmGSjNMiZuw==", "dev": true, "optional": true }, "js-tokens": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", - "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-3.0.2.tgz", + "integrity": "sha1-mGbfOVECEw449/mWvOtlRDIJwls=", "dev": true }, "js-yaml": { - "version": "3.12.0", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.12.0.tgz", - "integrity": "sha512-PIt2cnwmPfL4hKNwqeiuz4bKfnzHTBv6HyVgjahA6mPLwPDzjDWrplJBMjHUFxku/N3FlmrbyPclad+I+4mJ3A==", + "version": "3.12.1", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.12.1.tgz", + "integrity": "sha512-um46hB9wNOKlwkHgiuyEVAybXBjwFUV0Z/RaHJblRd9DXltue9FTYvzCr9ErQrK9Adz5MU4gHWVaNUfdmrC8qA==", "dev": true, "requires": { "argparse": "^1.0.7", "esprima": "^4.0.0" + }, + "dependencies": { + "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 + } } }, "jsbn": { @@ -7394,9 +7267,9 @@ "dev": true }, "jsesc": { - "version": "0.5.0", - "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-0.5.0.tgz", - "integrity": "sha1-597mbjXW/Bb3EP6R1c9p9w8IkR0=", + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-1.3.0.tgz", + "integrity": "sha1-RsP+yMGJKxKwgz25vHYiF226s0s=", "dev": true }, "json-parse-better-errors": { @@ -7460,14 +7333,6 @@ "extsprintf": "1.3.0", "json-schema": "0.2.3", "verror": "1.10.0" - }, - "dependencies": { - "assert-plus": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", - "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=", - "dev": true - } } }, "jszip": { @@ -7495,9 +7360,15 @@ "integrity": "sha1-AQ1YWEI6XxGJeWZfRkhqlcbuK7Y=", "dev": true }, + "process-nextick-args": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-1.0.7.tgz", + "integrity": "sha1-FQ4gt1ZZCtP5EJPyWk8q2L/zC6M=", + "dev": true + }, "readable-stream": { "version": "2.0.6", - "resolved": "http://registry.npmjs.org/readable-stream/-/readable-stream-2.0.6.tgz", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.0.6.tgz", "integrity": "sha1-j5A0HmilPMySh4jaz80Rs265t44=", "dev": true, "requires": { @@ -7511,7 +7382,7 @@ }, "string_decoder": { "version": "0.10.31", - "resolved": "http://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", "integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ=", "dev": true } @@ -7553,326 +7424,12 @@ "useragent": "2.3.0" }, "dependencies": { - "anymatch": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-2.0.0.tgz", - "integrity": "sha512-5teOsQWABXHHBFP9y3skS5P3d/WfWXpv3FUpy+LorMrNYaT9pI4oLMQX7jzQ2KklNpGpWHzdCXTDT2Y3XGlZBw==", - "dev": true, - "requires": { - "micromatch": "^3.1.4", - "normalize-path": "^2.1.1" - } - }, - "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 - }, - "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 - }, - "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" - } - } - } - }, - "chokidar": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-2.0.4.tgz", - "integrity": "sha512-z9n7yt9rOvIJrMhvDtDictKrkFHeihkNl6uWMmZlmL6tJtX9Cs+87oK+teBx+JIgzvbX3yZHT3eF8vpbDxHJXQ==", - "dev": true, - "requires": { - "anymatch": "^2.0.0", - "async-each": "^1.0.0", - "braces": "^2.3.0", - "fsevents": "^1.2.2", - "glob-parent": "^3.1.0", - "inherits": "^2.0.1", - "is-binary-path": "^1.0.0", - "is-glob": "^4.0.0", - "lodash.debounce": "^4.0.8", - "normalize-path": "^2.1.1", - "path-is-absolute": "^1.0.0", - "readdirp": "^2.0.0", - "upath": "^1.0.5" - } - }, - "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": { - "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": { - "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" - } - }, - "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": { - "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-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": { - "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": "0.1.6", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", - "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", - "dev": true, - "requires": { - "is-accessor-descriptor": "^0.1.6", - "is-data-descriptor": "^0.1.4", - "kind-of": "^5.0.0" - } - }, - "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 - } - } - }, - "extglob": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/extglob/-/extglob-2.0.4.tgz", - "integrity": "sha512-Nmb6QXkELsuBr24CJSkilo6UHHgbekK5UiZgfE6UHD3Eb27YC6oD+bhcT+tJ6cl8dmsgdQxnWlcry8ksBIBLpw==", - "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" - }, - "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" - } - } - } - }, - "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" - } - } - } - }, - "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": { - "is-glob": "^3.1.0", - "path-dirname": "^1.0.0" - }, - "dependencies": { - "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": { - "is-extglob": "^2.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==", - "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" - } - }, - "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" - } - } - } - }, - "kind-of": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.2.tgz", - "integrity": "sha512-s5kLOcnH0XqDO+FvuaLX8DDjZ18CGFk7VygH40QoKPUQhW4e2rvM0rwUq0t8IQDOwYSeLK01U90OjzBTme2QqA==", + "mime": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/mime/-/mime-2.4.0.tgz", + "integrity": "sha512-ikBcWwyqXQSHKtciCcctu9YfPbFYZ4+gbHEmE0Q8jzcTYQg5dHCr3g2wwAZjPoJfQVXZq6KXAjpXOTf5/cjT7w==", "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": { - "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" - } - }, "source-map": { "version": "0.6.1", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", @@ -7898,6 +7455,17 @@ "dev": true, "requires": { "resolve": "^1.3.3" + }, + "dependencies": { + "resolve": { + "version": "1.10.0", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.10.0.tgz", + "integrity": "sha512-3sUr9aq5OfSg2S9pNtPA9hL1FVEAjvfOC4leW0SNf/mpnaakz2a9femSd6LqAww2RaFctwyf1lCqnTHuF1rxDg==", + "dev": true, + "requires": { + "path-parse": "^1.0.6" + } + } } }, "karma-coverage-istanbul-reporter": { @@ -7932,24 +7500,6 @@ "dev": true, "requires": { "source-map-support": "^0.5.5" - }, - "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 - }, - "source-map-support": { - "version": "0.5.10", - "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.10.tgz", - "integrity": "sha512-YfQ3tQFTK/yzlGJuX8pTwa4tifQj4QS2Mj7UegOu8jAz59MqIiMGPXxQhVQiIMNzayuUSF/jEuVnfFF5JqybmQ==", - "dev": true, - "requires": { - "buffer-from": "^1.0.0", - "source-map": "^0.6.0" - } - } } }, "killable": { @@ -7959,13 +7509,10 @@ "dev": true }, "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" - } + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.2.tgz", + "integrity": "sha512-s5kLOcnH0XqDO+FvuaLX8DDjZ18CGFk7VygH40QoKPUQhW4e2rvM0rwUq0t8IQDOwYSeLK01U90OjzBTme2QqA==", + "dev": true }, "lazy-cache": { "version": "1.0.4", @@ -8000,13 +7547,6 @@ "source-map": "~0.6.0" }, "dependencies": { - "mime": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", - "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==", - "dev": true, - "optional": true - }, "source-map": { "version": "0.6.1", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", @@ -8025,14 +7565,6 @@ "clone": "^2.1.1", "loader-utils": "^1.1.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 - } } }, "levn": { @@ -8141,21 +7673,14 @@ "range-parser": "~1.2.0", "statuses": "~1.4.0" } - }, - "statuses": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.4.0.tgz", - "integrity": "sha512-zhSCtt8v2NDrRlPQpCNtw/heZLtfUDqxBM1udqikb/Hbk52LK4nQSwr10u77iopCW5LsyHpuXS0GnEc48mLeew==", - "dev": true } } }, "load-json-file": { "version": "1.1.0", - "resolved": "http://registry.npmjs.org/load-json-file/-/load-json-file-1.1.0.tgz", + "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-1.1.0.tgz", "integrity": "sha1-lWkFcI1YtLq0wiYbBPWfMcmTdMA=", "dev": true, - "optional": true, "requires": { "graceful-fs": "^4.1.2", "parse-json": "^2.2.0", @@ -8164,22 +7689,18 @@ "strip-bom": "^2.0.0" }, "dependencies": { - "strip-bom": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-2.0.0.tgz", - "integrity": "sha1-YhmoVhZSBJHzV4i9vxRHqZx+aw4=", - "dev": true, - "optional": true, - "requires": { - "is-utf8": "^0.2.0" - } + "pify": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", + "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=", + "dev": true } } }, "loader-runner": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/loader-runner/-/loader-runner-2.3.1.tgz", - "integrity": "sha512-By6ZFY7ETWOc9RFaAIb23IjJVcM4dvJC/N57nmdz9RSkMXvAXGI7SyVlAw3v8vjtDRlqThgVDVmTnr9fqMlxkw==", + "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": { @@ -8281,8 +7802,7 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/longest/-/longest-1.0.1.tgz", "integrity": "sha1-MKCy2jj3N3DoKUoNIuZiXtd9AJc=", - "dev": true, - "optional": true + "dev": true }, "loose-envify": { "version": "1.4.0", @@ -8312,14 +7832,6 @@ "requires": { "pseudomap": "^1.0.2", "yallist": "^2.1.2" - }, - "dependencies": { - "yallist": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-2.1.2.tgz", - "integrity": "sha1-HBH5IY8HYImkfdUS+TxmmaaoHVI=", - "dev": true - } } }, "lunr": { @@ -8335,12 +7847,12 @@ "dev": true }, "magic-string": { - "version": "0.25.1", - "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.25.1.tgz", - "integrity": "sha512-sCuTz6pYom8Rlt4ISPFn6wuFodbKMIHUMv4Qko9P17dpxb7s52KJTmRuZZqHdGmLCK9AOcDare039nRIcfdkEg==", + "version": "0.25.2", + "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.25.2.tgz", + "integrity": "sha512-iLs9mPjh9IuTtRsqqhNGYcZXGei0Nh/A4xirrsqW7c+QhKVFL2vm7U09ru6cHRD22azaP/wMDgI+HCqbETMTtg==", "dev": true, "requires": { - "sourcemap-codec": "^1.4.1" + "sourcemap-codec": "^1.4.4" } }, "make-dir": { @@ -8350,14 +7862,6 @@ "dev": true, "requires": { "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 - } } }, "make-error": { @@ -8418,26 +7922,6 @@ } } }, - "glob": { - "version": "7.1.3", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.3.tgz", - "integrity": "sha512-vcfuiIxogLV4DlGBHIUOwI0IbrJ8HWPc4MU7HzviGeNho/UJDfi6B5p3sHeWIQ0KGIU0Jpxi5ZHxemQfLkkAwQ==", - "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" - } - }, - "graceful-fs": { - "version": "4.1.15", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.1.15.tgz", - "integrity": "sha512-6uHUhOPEBgQ24HM+r6b/QwWfZq+yiFcipKFrOFiBEnWdy5sdzYoi+pJeQaPI5qOLRFqWmAXUPQNsielzdLoecA==", - "dev": true - }, "mississippi": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/mississippi/-/mississippi-3.0.0.tgz", @@ -8474,6 +7958,12 @@ "requires": { "figgy-pudding": "^3.5.1" } + }, + "yallist": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.0.3.tgz", + "integrity": "sha512-S+Zk8DEWE6oKpV+vI3qWkaK+jSbIK86pCwe2IF/xwIpQ8jEuxpw9NyaGjmp9+BoJv5FV2piqCDcoCtStppiq2A==", + "dev": true } } }, @@ -8496,8 +7986,7 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/map-obj/-/map-obj-1.0.1.tgz", "integrity": "sha1-2TPOuSBdgr3PSIb2dCvcK03qFG0=", - "dev": true, - "optional": true + "dev": true }, "map-stream": { "version": "0.1.0", @@ -8520,9 +8009,9 @@ "integrity": "sha512-fdZvBa7/vSQIZCi4uuwo2N3q+7jJURpMVCcbaX0S1Mg65WZ5ilXvC67MviJAsdjqqgD+CEq4RKo5AYGgINkVAA==" }, "math-random": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/math-random/-/math-random-1.0.1.tgz", - "integrity": "sha1-izqsWIuKZuSXXjzepn97sylgH6w=", + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/math-random/-/math-random-1.0.4.tgz", + "integrity": "sha512-rUxjysqif/BZQH2yhd5Aaq7vXMSx9NdEsQcyA07uEzIvxgI7zIr33gGsh+RU0/XjmQpCW7RsVof1vlkvQVCK5A==", "dev": true }, "mathjax": { @@ -8539,14 +8028,6 @@ "hash-base": "^3.0.0", "inherits": "^2.0.1", "safe-buffer": "^5.1.2" - }, - "dependencies": { - "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 - } } }, "media-typer": { @@ -8556,14 +8037,14 @@ "dev": true }, "mem": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/mem/-/mem-4.0.0.tgz", - "integrity": "sha512-WQxG/5xYc3tMbYLXoXPm81ET2WDULiU5FxbuIoNbJqLOOI8zehXFdZuiUEgfdrU2mVB1pxBZUGlYORSrpuJreA==", + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/mem/-/mem-4.1.0.tgz", + "integrity": "sha512-I5u6Q1x7wxO0kdOpYBB28xueHADYps5uty/zg936CiG8NTe5sJL8EjrCuLneuDW3PlMdZBGDIn8BirEVdovZvg==", "dev": true, "requires": { "map-age-cleaner": "^0.1.1", "mimic-fn": "^1.0.0", - "p-is-promise": "^1.1.0" + "p-is-promise": "^2.0.0" } }, "memory-fs": { @@ -8578,7 +8059,7 @@ }, "meow": { "version": "3.7.0", - "resolved": "http://registry.npmjs.org/meow/-/meow-3.7.0.tgz", + "resolved": "https://registry.npmjs.org/meow/-/meow-3.7.0.tgz", "integrity": "sha1-cstmi0JSKCkKu/qFaJJYcwioAfs=", "dev": true, "optional": true, @@ -8593,6 +8074,15 @@ "read-pkg-up": "^1.0.1", "redent": "^1.0.0", "trim-newlines": "^1.0.0" + }, + "dependencies": { + "minimist": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", + "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=", + "dev": true, + "optional": true + } } }, "merge-descriptors": { @@ -8632,20 +8122,6 @@ "regex-not": "^1.0.0", "snapdragon": "^0.8.1", "to-regex": "^3.0.2" - }, - "dependencies": { - "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 - }, - "kind-of": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.2.tgz", - "integrity": "sha512-s5kLOcnH0XqDO+FvuaLX8DDjZ18CGFk7VygH40QoKPUQhW4e2rvM0rwUq0t8IQDOwYSeLK01U90OjzBTme2QqA==", - "dev": true - } } }, "miller-rabin": { @@ -8659,10 +8135,11 @@ } }, "mime": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/mime/-/mime-2.4.0.tgz", - "integrity": "sha512-ikBcWwyqXQSHKtciCcctu9YfPbFYZ4+gbHEmE0Q8jzcTYQg5dHCr3g2wwAZjPoJfQVXZq6KXAjpXOTf5/cjT7w==", - "dev": true + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", + "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==", + "dev": true, + "optional": true }, "mime-db": { "version": "1.37.0", @@ -8718,9 +8195,9 @@ } }, "minimist": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", - "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=", + "version": "0.0.8", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz", + "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=", "dev": true }, "minipass": { @@ -8733,10 +8210,10 @@ "yallist": "^3.0.0" }, "dependencies": { - "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==", + "yallist": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.0.3.tgz", + "integrity": "sha512-S+Zk8DEWE6oKpV+vI3qWkaK+jSbIK86pCwe2IF/xwIpQ8jEuxpw9NyaGjmp9+BoJv5FV2piqCDcoCtStppiq2A==", "dev": true } } @@ -8814,20 +8291,12 @@ "dev": true, "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=", - "dev": true - } } }, "moment": { - "version": "2.23.0", - "resolved": "https://registry.npmjs.org/moment/-/moment-2.23.0.tgz", - "integrity": "sha512-3IE39bHVqFbWWaPOMHZF98Q9c3LDKGTmypMiTM2QygGXXElkFWIH7GxfmlwmY2vwa+wmNsoYZmG2iusf1ZjJoA==" + "version": "2.24.0", + "resolved": "https://registry.npmjs.org/moment/-/moment-2.24.0.tgz", + "integrity": "sha512-bV7f+6l2QigeBBZSM/6yTNq4P2fNpSWj/0e7jQcy87A8e7o2nAfP/34/2ky5Vw4B9S446EtIhodAzkFCcR4dQg==" }, "morgan": { "version": "1.9.1", @@ -8892,14 +8361,14 @@ }, "mute-stream": { "version": "0.0.7", - "resolved": "http://registry.npmjs.org/mute-stream/-/mute-stream-0.0.7.tgz", + "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.7.tgz", "integrity": "sha1-MHXOk7whuPq0PhvE2n6BFe0ee6s=", "dev": true }, "nan": { - "version": "2.10.0", - "resolved": "https://registry.npmjs.org/nan/-/nan-2.10.0.tgz", - "integrity": "sha512-bAdJv7fBLhWC+/Bls0Oza+mvTaNQtP+1RyhhhvD95pgUJz6XM5IzgmxOkItJ9tkoCiplvAnXI1tNmmUD/eScyA==", + "version": "2.12.1", + "resolved": "https://registry.npmjs.org/nan/-/nan-2.12.1.tgz", + "integrity": "sha512-JY7V6lRkStKcKTvHO5NVSQRv+RV+FIL5pvDoLiAtSL9pKlC5x9PKQcZDsq7m4FO4d57mkhC6Z+QhAh3Jdk5JFw==", "dev": true, "optional": true }, @@ -8920,26 +8389,6 @@ "regex-not": "^1.0.0", "snapdragon": "^0.8.1", "to-regex": "^3.0.1" - }, - "dependencies": { - "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 - }, - "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 - }, - "kind-of": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.2.tgz", - "integrity": "sha512-s5kLOcnH0XqDO+FvuaLX8DDjZ18CGFk7VygH40QoKPUQhW4e2rvM0rwUq0t8IQDOwYSeLK01U90OjzBTme2QqA==", - "dev": true - } } }, "negotiator": { @@ -8954,10 +8403,18 @@ "integrity": "sha512-MFh0d/Wa7vkKO3Y3LlacqAEeHK0mckVqzDieUKTT+KGxi+zIpeVsFxymkIiRpbpDziHc290Xr9A1O4Om7otoRA==", "dev": true }, + "ngx-material-file-input": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/ngx-material-file-input/-/ngx-material-file-input-1.1.0.tgz", + "integrity": "sha512-+HJOJIp6uE21QU6nHOYjT9/Hd1/JXx57CLTh8XlqDi9/HGfa5SPlvgjkn/RcrjJxTMz+lnGBMhi8RmEs6bbENA==", + "requires": { + "tslib": "^1.9.0" + } + }, "ngx-md": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/ngx-md/-/ngx-md-7.0.0.tgz", - "integrity": "sha512-IMqjkc33lS8jlQXqrLh2McuhUFXrUKBfYH5VqCAcGa3QDBkiPOakh/CuYbI5KC8KQDZMe5fngSGMKgDNVBzR7g==", + "version": "7.1.3", + "resolved": "https://registry.npmjs.org/ngx-md/-/ngx-md-7.1.3.tgz", + "integrity": "sha512-sSIr1pwg4eOO4F1xk+DkofgBWShQm4cKYTwe3oYXRZxdrhHXzN+oUief+3IMSHi2syCSi791PinmrcQ8+HYy5w==", "requires": { "marked": "^0.5.0", "prismjs": "^1.15.0", @@ -9020,7 +8477,7 @@ "dependencies": { "semver": { "version": "5.3.0", - "resolved": "http://registry.npmjs.org/semver/-/semver-5.3.0.tgz", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.3.0.tgz", "integrity": "sha1-myzl094C0XxgEq0yaqa00M9U+U8=", "dev": true, "optional": true @@ -9028,9 +8485,9 @@ } }, "node-libs-browser": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/node-libs-browser/-/node-libs-browser-2.1.0.tgz", - "integrity": "sha512-5AzFzdoIMb89hBGMZglEegffzgRg+ZFoUmisQ8HI4j1KDdpx13J0taNp2y9xPbur6W61gepGDDotGBVQ7mfUCg==", + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/node-libs-browser/-/node-libs-browser-2.2.0.tgz", + "integrity": "sha512-5MQunG/oyOaBdttrL40dA7bUfPORLRWMUJLQtMg7nluxUvk5XwnLdL9twQHFAjRx/y7mIMkLKT9++qPbbk6BZA==", "dev": true, "requires": { "assert": "^1.1.1", @@ -9040,7 +8497,7 @@ "constants-browserify": "^1.0.0", "crypto-browserify": "^3.11.0", "domain-browser": "^1.1.1", - "events": "^1.0.0", + "events": "^3.0.0", "https-browserify": "^1.0.0", "os-browserify": "^0.3.0", "path-browserify": "0.0.0", @@ -9054,14 +8511,22 @@ "timers-browserify": "^2.0.4", "tty-browserify": "0.0.0", "url": "^0.11.0", - "util": "^0.10.3", + "util": "^0.11.0", "vm-browserify": "0.0.4" + }, + "dependencies": { + "punycode": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz", + "integrity": "sha1-wNWmOycYgArY4esPpSachN1BhF4=", + "dev": true + } } }, "node-releases": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-1.1.3.tgz", - "integrity": "sha512-6VrvH7z6jqqNFY200kdB6HdzkgM96Oaj9v3dqGfgp6mF+cHmU4wyQKZ2/WPDRVoR0Jz9KqbamaBN0ZhdUaysUQ==", + "version": "1.1.7", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-1.1.7.tgz", + "integrity": "sha512-bKdrwaqJUPHqlCzDD7so/R+Nk0jGv9a11ZhLrD9f6i947qGLrGAhU3OxRENa19QQmwzGy/g6zCDEuLGDO8HPvA==", "dev": true, "requires": { "semver": "^5.3.0" @@ -9118,7 +8583,7 @@ }, "supports-color": { "version": "2.0.0", - "resolved": "http://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=", "dev": true, "optional": true @@ -9135,15 +8600,26 @@ } }, "normalize-package-data": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.4.0.tgz", - "integrity": "sha512-9jjUFbTPfEy3R/ad/2oNbKtW9Hgovl5O1FvFWKkKblNXoN/Oou6+9+KKohPK13Yc3/TyunyWhJp6gvRNR/PPAw==", + "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==", "dev": true, "requires": { "hosted-git-info": "^2.1.4", - "is-builtin-module": "^1.0.0", + "resolve": "^1.10.0", "semver": "2 || 3 || 4 || 5", "validate-npm-package-license": "^3.0.1" + }, + "dependencies": { + "resolve": { + "version": "1.10.0", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.10.0.tgz", + "integrity": "sha512-3sUr9aq5OfSg2S9pNtPA9hL1FVEAjvfOC4leW0SNf/mpnaakz2a9femSd6LqAww2RaFctwyf1lCqnTHuF1rxDg==", + "dev": true, + "requires": { + "path-parse": "^1.0.6" + } + } } }, "normalize-path": { @@ -9162,9 +8638,9 @@ "dev": true }, "npm-bundled": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/npm-bundled/-/npm-bundled-1.0.5.tgz", - "integrity": "sha512-m/e6jgWu8/v5niCUKQi9qQl8QdeEduFA96xHDDzFGqly0OOjI7c+60KM/2sppfnUU9JJagf+zs+yGhqSOFj71g==", + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/npm-bundled/-/npm-bundled-1.0.6.tgz", + "integrity": "sha512-8/JCaftHwbd//k6y2rEWp6k1wxVfpFzB6t1p825+cUb7Ym2XQfhwIC5KwhrvzZRJu+LtDE585zVaS32+CGtf0g==", "dev": true }, "npm-package-arg": { @@ -9177,20 +8653,12 @@ "osenv": "^0.1.5", "semver": "^5.5.0", "validate-npm-package-name": "^3.0.0" - }, - "dependencies": { - "semver": { - "version": "5.6.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.6.0.tgz", - "integrity": "sha512-RS9R6R35NYgQn++fkDWaOmqGoj4Ek9gGs+DPxNUZKuwE183xjJroKvyo1IzVFeXvUrvmALy6FWD5xrdJT25gMg==", - "dev": true - } } }, "npm-packlist": { - "version": "1.1.12", - "resolved": "https://registry.npmjs.org/npm-packlist/-/npm-packlist-1.1.12.tgz", - "integrity": "sha512-WJKFOVMeAlsU/pjXuqVdzU0WfgtIBCupkEVwn+1Y0ERAbUfWw8R4GjgVbaKnUjRoD2FoQbHOCbOyT5Mbs9Lw4g==", + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/npm-packlist/-/npm-packlist-1.3.0.tgz", + "integrity": "sha512-qPBc6CnxEzpOcc4bjoIBJbYdy0D/LFFPUdxvfwor4/w3vxeE0h6TiOVurCEPpQ6trjN77u/ShyfeJGsbAfB3dA==", "dev": true, "requires": { "ignore-walk": "^3.0.1", @@ -9209,9 +8677,9 @@ } }, "npm-registry-fetch": { - "version": "3.8.0", - "resolved": "https://registry.npmjs.org/npm-registry-fetch/-/npm-registry-fetch-3.8.0.tgz", - "integrity": "sha512-hrw8UMD+Nob3Kl3h8Z/YjmKamb1gf7D1ZZch2otrIXM3uFLB5vjEY6DhMlq80z/zZet6eETLbOXcuQudCB3Zpw==", + "version": "3.9.0", + "resolved": "https://registry.npmjs.org/npm-registry-fetch/-/npm-registry-fetch-3.9.0.tgz", + "integrity": "sha512-srwmt8YhNajAoSAaDWndmZgx89lJwIZ1GWxOuckH4Coek4uHv5S+o/l9FLQe/awA+JwTnj4FJHldxhlXdZEBmw==", "dev": true, "requires": { "JSONStream": "^1.3.4", @@ -9236,7 +8704,6 @@ "resolved": "https://registry.npmjs.org/npmlog/-/npmlog-4.1.2.tgz", "integrity": "sha512-2uUqazuKlTaSI/dC8AzicUck7+IrEaOnN/e0jd3Xtt1KcGpwx30v50mL7oPyr/h9bL3E4aZccVwpwP+5W9Vjkg==", "dev": true, - "optional": true, "requires": { "are-we-there-yet": "~1.1.2", "console-control-strings": "~1.1.0", @@ -9275,8 +8742,7 @@ "version": "0.9.0", "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.9.0.tgz", "integrity": "sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ==", - "dev": true, - "optional": true + "dev": true }, "object-assign": { "version": "4.1.1", @@ -9307,7 +8773,16 @@ "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", "dev": true, "requires": { - "is-descriptor": "^0.1.0" + "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" } } } @@ -9329,6 +8804,17 @@ "requires": { "for-own": "^0.1.4", "is-extendable": "^0.1.1" + }, + "dependencies": { + "for-own": { + "version": "0.1.5", + "resolved": "https://registry.npmjs.org/for-own/-/for-own-0.1.5.tgz", + "integrity": "sha1-UmXGgaTylNq78XyVCbZ2OqhFEM4=", + "dev": true, + "requires": { + "for-in": "^1.0.1" + } + } } }, "object.pick": { @@ -9468,6 +8954,12 @@ "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", "dev": true }, + "minimist": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", + "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=", + "dev": true + }, "opn": { "version": "4.0.2", "resolved": "https://registry.npmjs.org/opn/-/opn-4.0.2.tgz", @@ -9508,9 +9000,9 @@ } }, "opn": { - "version": "5.3.0", - "resolved": "http://registry.npmjs.org/opn/-/opn-5.3.0.tgz", - "integrity": "sha512-bYJHo/LOmoTd+pfiYhfZDnf9zekVJrY+cnS2a5F2x+w5ppvTqObojTP7WiFG+kVZs9Inw+qQ/lw7TroWwhdd2g==", + "version": "5.4.0", + "resolved": "https://registry.npmjs.org/opn/-/opn-5.4.0.tgz", + "integrity": "sha512-YF9MNdVy/0qvJvDtunAOzFw9iasOQHpVthTCvGzxt61Il64AYSGdK+rYwld7NAfk9qJ7dt+hymBNSc9LNYS+Sw==", "dev": true, "requires": { "is-wsl": "^1.1.0" @@ -9526,10 +9018,10 @@ "wordwrap": "~0.0.2" }, "dependencies": { - "minimist": { - "version": "0.0.10", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.10.tgz", - "integrity": "sha1-3j+YVD2/lggr5IrRoMfNqDYwHc8=", + "wordwrap": { + "version": "0.0.3", + "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-0.0.3.tgz", + "integrity": "sha1-o9XabNXAvAAI03I0u68b7WMFkQc=", "dev": true } } @@ -9546,14 +9038,6 @@ "prelude-ls": "~1.1.2", "type-check": "~0.3.2", "wordwrap": "~1.0.0" - }, - "dependencies": { - "wordwrap": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-1.0.0.tgz", - "integrity": "sha1-J1hIEIkUVqQXHI0CJkQa3pDLyus=", - "dev": true - } } }, "original": { @@ -9579,7 +9063,7 @@ }, "os-locale": { "version": "1.4.0", - "resolved": "http://registry.npmjs.org/os-locale/-/os-locale-1.4.0.tgz", + "resolved": "https://registry.npmjs.org/os-locale/-/os-locale-1.4.0.tgz", "integrity": "sha1-IPnxeuKe00XoveWDsT0gCYA8FNk=", "dev": true, "optional": true, @@ -9626,9 +9110,9 @@ "dev": true }, "p-is-promise": { - "version": "1.1.0", - "resolved": "http://registry.npmjs.org/p-is-promise/-/p-is-promise-1.1.0.tgz", - "integrity": "sha1-nJRWmJ6fZYgBewQ01WCXZ1w9oF4=", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/p-is-promise/-/p-is-promise-2.0.0.tgz", + "integrity": "sha512-pzQPhYMCAgLAKPWD2jC3Se9fEfrD9npNos0y150EeqZll7akhEgGhTW/slB6lHku8AvYGiJ+YJ5hfHKePPgFWg==", "dev": true }, "p-limit": { @@ -9662,17 +9146,17 @@ "dev": true }, "pacote": { - "version": "9.1.1", - "resolved": "https://registry.npmjs.org/pacote/-/pacote-9.1.1.tgz", - "integrity": "sha512-f28Rq5ozzKAA9YwIKw61/ipwAatUZseYmVssDbHHaexF0wRIVotapVEZPAjOT7Eu3LYVqEp0NVpNizoAnYBUaA==", + "version": "9.4.0", + "resolved": "https://registry.npmjs.org/pacote/-/pacote-9.4.0.tgz", + "integrity": "sha512-WQ1KL/phGMkedYEQx9ODsjj7xvwLSpdFJJdEXrLyw5SILMxcTNt5DTxT2Z93fXuLFYJBlZJdnwdalrQdB/rX5w==", "dev": true, "requires": { - "bluebird": "^3.5.2", - "cacache": "^11.2.0", + "bluebird": "^3.5.3", + "cacache": "^11.3.2", "figgy-pudding": "^3.5.1", "get-stream": "^4.1.0", "glob": "^7.1.3", - "lru-cache": "^4.1.3", + "lru-cache": "^5.1.1", "make-fetch-happen": "^4.0.1", "minimatch": "^3.0.4", "minipass": "^2.3.5", @@ -9681,7 +9165,7 @@ "normalize-package-data": "^2.4.0", "npm-package-arg": "^6.1.0", "npm-packlist": "^1.1.12", - "npm-pick-manifest": "^2.1.0", + "npm-pick-manifest": "^2.2.3", "npm-registry-fetch": "^3.8.0", "osenv": "^0.1.5", "promise-inflight": "^1.0.1", @@ -9691,7 +9175,7 @@ "safe-buffer": "^5.1.2", "semver": "^5.6.0", "ssri": "^6.0.1", - "tar": "^4.4.6", + "tar": "^4.4.8", "unique-filename": "^1.1.1", "which": "^1.3.1" }, @@ -9716,17 +9200,6 @@ "ssri": "^6.0.1", "unique-filename": "^1.1.1", "y18n": "^4.0.0" - }, - "dependencies": { - "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": { - "yallist": "^3.0.2" - } - } } }, "get-stream": { @@ -9738,26 +9211,15 @@ "pump": "^3.0.0" } }, - "glob": { - "version": "7.1.3", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.3.tgz", - "integrity": "sha512-vcfuiIxogLV4DlGBHIUOwI0IbrJ8HWPc4MU7HzviGeNho/UJDfi6B5p3sHeWIQ0KGIU0Jpxi5ZHxemQfLkkAwQ==", + "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": { - "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" + "yallist": "^3.0.2" } }, - "graceful-fs": { - "version": "4.1.15", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.1.15.tgz", - "integrity": "sha512-6uHUhOPEBgQ24HM+r6b/QwWfZq+yiFcipKFrOFiBEnWdy5sdzYoi+pJeQaPI5qOLRFqWmAXUPQNsielzdLoecA==", - "dev": true - }, "mississippi": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/mississippi/-/mississippi-3.0.0.tgz", @@ -9786,12 +9248,6 @@ "once": "^1.3.1" } }, - "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 - }, "semver": { "version": "5.6.0", "resolved": "https://registry.npmjs.org/semver/-/semver-5.6.0.tgz", @@ -9821,13 +9277,19 @@ "safe-buffer": "^5.1.2", "yallist": "^3.0.2" } + }, + "yallist": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.0.3.tgz", + "integrity": "sha512-S+Zk8DEWE6oKpV+vI3qWkaK+jSbIK86pCwe2IF/xwIpQ8jEuxpw9NyaGjmp9+BoJv5FV2piqCDcoCtStppiq2A==", + "dev": true } } }, "pako": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/pako/-/pako-1.0.6.tgz", - "integrity": "sha512-lQe48YPsMJAig+yngZ87Lus+NF+3mtu7DVOBu6b/gHO1YpKwIj5AWjZ/TOS7i46HD/UixzWb1zeWDZfGZ3iYcg==", + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/pako/-/pako-1.0.8.tgz", + "integrity": "sha512-6i0HVbUfcKaTv+EG8ZTr75az7GFXcLYk9UyLEg7Notv/Ma+z/UG3TCoz6GiNeOrn1E/e63I0X/Hpw18jHOTUnA==", "dev": true }, "parallel-transform": { @@ -9842,16 +9304,17 @@ } }, "parse-asn1": { - "version": "5.1.1", - "resolved": "http://registry.npmjs.org/parse-asn1/-/parse-asn1-5.1.1.tgz", - "integrity": "sha512-KPx7flKXg775zZpnp9SxJlz00gTd4BmJ2yJufSc44gMCRrRQ7NSzAcSJQfifuOLgW6bEi+ftrALtsgALeB2Adw==", + "version": "5.1.3", + "resolved": "https://registry.npmjs.org/parse-asn1/-/parse-asn1-5.1.3.tgz", + "integrity": "sha512-VrPoetlz7B/FqjBLD2f5wBVZvsZVLnRUrxVLfRYhGXCODa/NWE4p3Wp+6+aV3ZPL3KM7/OZmxDIwwijD7yuucg==", "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" + "pbkdf2": "^3.0.3", + "safe-buffer": "^5.1.1" } }, "parse-glob": { @@ -9893,16 +9356,16 @@ } }, "parse-node-version": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/parse-node-version/-/parse-node-version-1.0.0.tgz", - "integrity": "sha512-02GTVHD1u0nWc20n2G7WX/PgdhNFG04j5fi1OkaJzPWLTcf6vh6229Lta1wTmXG/7Dg42tCssgkccVt7qvd8Kg==", + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/parse-node-version/-/parse-node-version-1.0.1.tgz", + "integrity": "sha512-3YHlOa/JgH6Mnpr05jP9eDG254US9ek25LyIxZlDItp2iJtwyaXQb57lBYLdT3MowkUFYEV2XXNAYIPlESvJlA==", "dev": true }, "parse5": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/parse5/-/parse5-4.0.0.tgz", - "integrity": "sha512-VrZ7eOd3T1Fk4XWNXMgiGBK/z0MG48BWG2uQNU4I72fkQuKUTZpl+u9k+CxEG0twMVzSmXEEz12z5Fnw1jIQFA==", - "dev": true + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/parse5/-/parse5-5.1.0.tgz", + "integrity": "sha512-fxNG2sQjHvlVAYmzBZS9YlDp6PTSSDwa98vkD4QgVDDCAo84z5X1t5XyJQ62ImdLXx5NdIIfihey6xpum9/gRQ==", + "optional": true }, "parseqs": { "version": "0.0.5", @@ -9936,7 +9399,7 @@ }, "path-browserify": { "version": "0.0.0", - "resolved": "http://registry.npmjs.org/path-browserify/-/path-browserify-0.0.0.tgz", + "resolved": "https://registry.npmjs.org/path-browserify/-/path-browserify-0.0.0.tgz", "integrity": "sha1-oLhwcpquIUAFt9UDLsLLuw+0RRo=", "dev": true }, @@ -9989,14 +9452,6 @@ "dev": true, "requires": { "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 - } } }, "pause-stream": { @@ -10025,13 +9480,12 @@ "version": "2.1.0", "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz", "integrity": "sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns=", - "dev": true, - "optional": true + "dev": true }, "pify": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", - "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=", + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz", + "integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=", "dev": true }, "pinkie": { @@ -10067,14 +9521,6 @@ "async": "^1.5.2", "debug": "^2.2.0", "mkdirp": "0.5.x" - }, - "dependencies": { - "async": { - "version": "1.5.2", - "resolved": "https://registry.npmjs.org/async/-/async-1.5.2.tgz", - "integrity": "sha1-7GphrlZIDAw8skHJVhjiCJL5Zyo=", - "dev": true - } } }, "posix-character-classes": { @@ -10084,14 +9530,14 @@ "dev": true }, "postcss": { - "version": "7.0.5", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.5.tgz", - "integrity": "sha512-HBNpviAUFCKvEh7NZhw1e8MBPivRszIiUnhrJ+sBFVSYSqubrzwX3KG51mYgcRHX8j/cAgZJedONZcm5jTBdgQ==", + "version": "7.0.13", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.13.tgz", + "integrity": "sha512-h8SY6kQTd1wISHWjz+E6cswdhMuyBZRb16pSTv3W4zYZ3/YbyWeJdNUeOXB5IdZqE1U76OUEjjjqsC3z2f3hVg==", "dev": true, "requires": { - "chalk": "^2.4.1", + "chalk": "^2.4.2", "source-map": "^0.6.1", - "supports-color": "^5.5.0" + "supports-color": "^6.1.0" }, "dependencies": { "source-map": { @@ -10103,9 +9549,9 @@ } }, "postcss-import": { - "version": "12.0.0", - "resolved": "https://registry.npmjs.org/postcss-import/-/postcss-import-12.0.0.tgz", - "integrity": "sha512-3KqKRZcaZAvxbY8DVLdd81tG5uKzbUQuiWIvy0o0fzEC42bKacqPYFWbfCQyw6L4LWUaqPz/idvIdbhpgQ32eQ==", + "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": { "postcss": "^7.0.1", @@ -10169,9 +9615,9 @@ "dev": true }, "process-nextick-args": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-1.0.7.tgz", - "integrity": "sha1-FQ4gt1ZZCtP5EJPyWk8q2L/zC6M=", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.0.tgz", + "integrity": "sha512-MtEC1TqN0EU5nephaJ4rAtThHtC86dNN9qCuEhtshvpVBkAW5ZO7BASN9REnF9eoXGcRub+pFuKEpOHE+HbEMw==", "dev": true }, "promise": { @@ -10232,42 +9678,12 @@ "webdriver-manager": "^12.0.6" }, "dependencies": { - "ajv": { - "version": "6.6.2", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.6.2.tgz", - "integrity": "sha512-FBHEW6Jf5TB9MGBgUUA9XHkTbjXYfAUjY43ACMfmdMRHniyoMHjHjzD50OK8LGDWQwp4rWEsIq5kEqq7rvIM1g==", - "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" - } - }, "ansi-styles": { "version": "2.2.1", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=", "dev": true }, - "assert-plus": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", - "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=", - "dev": true - }, - "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=", - "dev": true - }, - "aws4": { - "version": "1.8.0", - "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.8.0.tgz", - "integrity": "sha512-ReZxvNHIOv88FlT7rxcXIIC0fPt4KZqZbOlivyWtXLt8ESx84zd3kMC6iK5jVeS2qt+g7ftS7ye4fi06X5rtRQ==", - "dev": true - }, "chalk": { "version": "1.1.3", "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", @@ -10281,15 +9697,6 @@ "supports-color": "^2.0.0" } }, - "combined-stream": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.7.tgz", - "integrity": "sha512-brWl9y6vOB1xYPZcpZde3N9zDByXTosAeMDo4p1wzo6UMOX4vumB+TP1RZ76sfE6Md68Q0NJSrE/gbezd4Ul+w==", - "dev": true, - "requires": { - "delayed-stream": "~1.0.0" - } - }, "del": { "version": "2.2.2", "resolved": "https://registry.npmjs.org/del/-/del-2.2.2.tgz", @@ -10305,29 +9712,6 @@ "rimraf": "^2.2.8" } }, - "extend": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", - "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==", - "dev": true - }, - "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 - }, - "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==", - "dev": true, - "requires": { - "asynckit": "^0.4.0", - "combined-stream": "^1.0.6", - "mime-types": "^2.1.12" - } - }, "globby": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/globby/-/globby-5.0.0.tgz", @@ -10342,128 +9726,39 @@ "pinkie-promise": "^2.0.0" } }, - "har-schema": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/har-schema/-/har-schema-2.0.0.tgz", - "integrity": "sha1-qUwiJOvKwEeCoNkDVSHyRzW37JI=", - "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==", - "dev": true, - "requires": { - "ajv": "^6.5.5", - "har-schema": "^2.0.0" - } - }, - "http-signature": { + "minimist": { "version": "1.2.0", - "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.2.0.tgz", - "integrity": "sha1-muzZJRFHcvPZW2WmCruPfBj7rOE=", - "dev": true, - "requires": { - "assert-plus": "^1.0.0", - "jsprim": "^1.2.2", - "sshpk": "^1.7.0" - } + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", + "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=", + "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==", + "pify": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", + "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=", "dev": true }, - "mime-db": { - "version": "1.37.0", - "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.37.0.tgz", - "integrity": "sha512-R3C4db6bgQhlIhPU48fUtdVmKnflq+hRdad7IyKhtFj06VPNVdk2RhiYL3UjQIlso8L+YxAtFkobT0VK+S/ybg==", + "source-map": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", + "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", "dev": true }, - "mime-types": { - "version": "2.1.21", - "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.21.tgz", - "integrity": "sha512-3iL6DbwpyLzjR3xHSFNFeb9Nz/M8WDkX33t1GFQnFOllWk8pOrh/LSrB5OXlnlW5P9LH73X6loW/eogc+F5lJg==", + "source-map-support": { + "version": "0.4.18", + "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.4.18.tgz", + "integrity": "sha512-try0/JqxPLF9nOjvSta7tVondkP5dwgyLDjVoyMDlmjugT2lRZ1OfsrYTkCd2hkDnJTKRbO/Rl3orm8vlsUzbA==", "dev": true, "requires": { - "mime-db": "~1.37.0" - } - }, - "oauth-sign": { - "version": "0.9.0", - "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.9.0.tgz", - "integrity": "sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ==", - "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 - }, - "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 - }, - "request": { - "version": "2.88.0", - "resolved": "https://registry.npmjs.org/request/-/request-2.88.0.tgz", - "integrity": "sha512-NAqBSrijGLZdM0WZNsInLJpkJokL72XYjUpnB0iwsRgxh7dB6COrHnTBNwN0E+lHDAJzu7kLAkDeY08z2/A0hg==", - "dev": true, - "requires": { - "aws-sign2": "~0.7.0", - "aws4": "^1.8.0", - "caseless": "~0.12.0", - "combined-stream": "~1.0.6", - "extend": "~3.0.2", - "forever-agent": "~0.6.1", - "form-data": "~2.3.2", - "har-validator": "~5.1.0", - "http-signature": "~1.2.0", - "is-typedarray": "~1.0.0", - "isstream": "~0.1.2", - "json-stringify-safe": "~5.0.1", - "mime-types": "~2.1.19", - "oauth-sign": "~0.9.0", - "performance-now": "^2.1.0", - "qs": "~6.5.2", - "safe-buffer": "^5.1.2", - "tough-cookie": "~2.4.3", - "tunnel-agent": "^0.6.0", - "uuid": "^3.3.2" + "source-map": "^0.5.6" } }, - "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 - }, "supports-color": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=", "dev": true }, - "tough-cookie": { - "version": "2.4.3", - "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.4.3.tgz", - "integrity": "sha512-Q5srk/4vDM54WJsJio3XNn6K2sCG+CQ8G5Wz6bZhRZoAe/+TxjWB/GlFAnYEbkYVlON9FMk/fE3h2RLpPXo4lQ==", - "dev": true, - "requires": { - "psl": "^1.1.24", - "punycode": "^1.4.1" - } - }, - "uuid": { - "version": "3.3.2", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.3.2.tgz", - "integrity": "sha512-yXJmeNaw3DnnKAOKJE51sL/ZaYfWJRl1pK9dr19YFCu0ObS231AB1/LbqTKRAQ5kw8A90rA6fr4riOUpTZvQZA==", - "dev": true - }, "webdriver-manager": { "version": "12.1.1", "resolved": "https://registry.npmjs.org/webdriver-manager/-/webdriver-manager-12.1.1.tgz", @@ -10531,14 +9826,6 @@ "parse-asn1": "^5.0.0", "randombytes": "^2.0.1", "safe-buffer": "^5.1.2" - }, - "dependencies": { - "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 - } } }, "pump": { @@ -10563,9 +9850,9 @@ } }, "punycode": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz", - "integrity": "sha1-wNWmOycYgArY4esPpSachN1BhF4=", + "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 }, "q": { @@ -10620,12 +9907,6 @@ "resolved": "https://registry.npmjs.org/is-number/-/is-number-4.0.0.tgz", "integrity": "sha512-rSklcAIlf1OmFdyAqbnWTLVelsQ58uvZ66S/ZyawjWqIviTWCjg2PzVGw8WUA+nNuPTqb4wgA+NszrJ+08LlgQ==", "dev": true - }, - "kind-of": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.2.tgz", - "integrity": "sha512-s5kLOcnH0XqDO+FvuaLX8DDjZ18CGFk7VygH40QoKPUQhW4e2rvM0rwUq0t8IQDOwYSeLK01U90OjzBTme2QqA==", - "dev": true } } }, @@ -10664,22 +9945,11 @@ "http-errors": "1.6.3", "iconv-lite": "0.4.23", "unpipe": "1.0.0" - }, - "dependencies": { - "iconv-lite": { - "version": "0.4.23", - "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.23.tgz", - "integrity": "sha512-neyTUVFtahjf0mB3dZT77u+8O0QB89jFdnBkd5P1JgYPbPaia3gXXOVL2fq8VyU2gMMD7SaN7QukTB/pmXYvDA==", - "dev": true, - "requires": { - "safer-buffer": ">= 2.1.2 < 3" - } - } } }, "raw-loader": { "version": "0.5.1", - "resolved": "http://registry.npmjs.org/raw-loader/-/raw-loader-0.5.1.tgz", + "resolved": "https://registry.npmjs.org/raw-loader/-/raw-loader-0.5.1.tgz", "integrity": "sha1-DD0L6u2KAclm2Xh793goElKpeao=", "dev": true }, @@ -10690,6 +9960,14 @@ "dev": true, "requires": { "pify": "^2.3.0" + }, + "dependencies": { + "pify": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", + "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=", + "dev": true + } } }, "read-pkg": { @@ -10697,7 +9975,6 @@ "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-1.1.0.tgz", "integrity": "sha1-9f+qXs0pyzHAR0vKfXVra7KePyg=", "dev": true, - "optional": true, "requires": { "load-json-file": "^1.0.0", "normalize-package-data": "^2.3.2", @@ -10709,12 +9986,17 @@ "resolved": "https://registry.npmjs.org/path-type/-/path-type-1.1.0.tgz", "integrity": "sha1-WcRPfuSR2nBNpBXaWkBwuk+P5EE=", "dev": true, - "optional": true, "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=", + "dev": true } } }, @@ -10723,7 +10005,6 @@ "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-1.0.1.tgz", "integrity": "sha1-nWPBMnbAZZGNV/ACpX9AobZD+wI=", "dev": true, - "optional": true, "requires": { "find-up": "^1.0.0", "read-pkg": "^1.0.0" @@ -10734,7 +10015,6 @@ "resolved": "https://registry.npmjs.org/find-up/-/find-up-1.1.2.tgz", "integrity": "sha1-ay6YIrGizgpgq2TWEOzK1TyyTQ8=", "dev": true, - "optional": true, "requires": { "path-exists": "^2.0.0", "pinkie-promise": "^2.0.0" @@ -10745,7 +10025,6 @@ "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-2.1.0.tgz", "integrity": "sha1-D+tsZPD8UY2adU3V77YscCJ2H0s=", "dev": true, - "optional": true, "requires": { "pinkie-promise": "^2.0.0" } @@ -10753,30 +10032,29 @@ } }, "readable-stream": { - "version": "2.3.3", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.3.tgz", - "integrity": "sha512-m+qzzcn7KUxEmd1gMbchF+Y2eIUbieUaxkWtptyHywrX0rE8QEYqPC07Vuy4Wm32/xE16NcdBctb8S0Xe/5IeQ==", + "version": "2.3.6", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz", + "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==", "dev": true, "requires": { "core-util-is": "~1.0.0", "inherits": "~2.0.3", "isarray": "~1.0.0", - "process-nextick-args": "~1.0.6", + "process-nextick-args": "~2.0.0", "safe-buffer": "~5.1.1", - "string_decoder": "~1.0.3", + "string_decoder": "~1.1.1", "util-deprecate": "~1.0.1" } }, "readdirp": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-2.1.0.tgz", - "integrity": "sha1-TtCtBg3zBzMAxIRANz9y0cxkLXg=", + "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.2", - "minimatch": "^3.0.2", - "readable-stream": "^2.0.2", - "set-immediate-shim": "^1.0.1" + "graceful-fs": "^4.1.11", + "micromatch": "^3.1.10", + "readable-stream": "^2.0.2" } }, "rechoir": { @@ -10800,9 +10078,9 @@ } }, "reflect-metadata": { - "version": "0.1.12", - "resolved": "https://registry.npmjs.org/reflect-metadata/-/reflect-metadata-0.1.12.tgz", - "integrity": "sha512-n+IyV+nGz3+0q3/Yf1ra12KpCyi001bi4XFxSjbiWWjfqb52iTTtpGXmCCAOWWIAn9KEuFZKGqBERHmrtScZ3A==", + "version": "0.1.13", + "resolved": "https://registry.npmjs.org/reflect-metadata/-/reflect-metadata-0.1.13.tgz", + "integrity": "sha512-Ts1Y/anZELhSsjMcU605fU9RE4Oi3p5ORujwbIKXfWa+0Zxs510Qrmrce5/Jowq3cHSZSJqBjypxmHarc+vEWg==", "dev": true }, "regenerate": { @@ -10860,6 +10138,14 @@ "dev": true, "requires": { "jsesc": "~0.5.0" + }, + "dependencies": { + "jsesc": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-0.5.0.tgz", + "integrity": "sha1-597mbjXW/Bb3EP6R1c9p9w8IkR0=", + "dev": true + } } }, "remove-trailing-separator": { @@ -10869,9 +10155,9 @@ "dev": true }, "repeat-element": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/repeat-element/-/repeat-element-1.1.2.tgz", - "integrity": "sha1-7wiaF40Ug7quTZPrmLT55OEdmQo=", + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/repeat-element/-/repeat-element-1.1.3.tgz", + "integrity": "sha512-ahGq0ZnV5m5XtZLMb+vP76kcAM5nkLqk0lpqAuojSKGgQtn4eRi4ZZGm2olo2zKFH+sMsWaqOCW1dqAnOru72g==", "dev": true }, "repeat-string": { @@ -10894,7 +10180,6 @@ "resolved": "https://registry.npmjs.org/request/-/request-2.88.0.tgz", "integrity": "sha512-NAqBSrijGLZdM0WZNsInLJpkJokL72XYjUpnB0iwsRgxh7dB6COrHnTBNwN0E+lHDAJzu7kLAkDeY08z2/A0hg==", "dev": true, - "optional": true, "requires": { "aws-sign2": "~0.7.0", "aws4": "^1.8.0", @@ -10916,15 +10201,6 @@ "tough-cookie": "~2.4.3", "tunnel-agent": "^0.6.0", "uuid": "^3.3.2" - }, - "dependencies": { - "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, - "optional": true - } } }, "require-directory": { @@ -10952,13 +10228,10 @@ "dev": true }, "resolve": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.9.0.tgz", - "integrity": "sha512-TZNye00tI67lwYvzxCxHGjwTNlUV70io54/Ed4j6PscB8xVfuBJpRenI/o6dVk0cY0PYTY27AgCoGGxRnYuItQ==", - "dev": true, - "requires": { - "path-parse": "^1.0.6" - } + "version": "1.1.7", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.1.7.tgz", + "integrity": "sha1-IDEU2CrSxe2ejgQRs5ModeiJ6Xs=", + "dev": true }, "resolve-cwd": { "version": "2.0.0", @@ -11020,12 +10293,12 @@ } }, "rimraf": { - "version": "2.6.2", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.2.tgz", - "integrity": "sha512-lreewLK/BlghmxtfH36YYVg1i8IAce4TI7oao75I1g245+6BctqTVQiBP3YUJ9C6DQOXJmkYR9X9fCLtCOJc5w==", + "version": "2.6.3", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.3.tgz", + "integrity": "sha512-mwqeW5XsA2qAejG46gYdENaxXjx9onRNCfn7L0duuP4hCuTIi/QO7PDK07KJfp1d+izWPrzEJDcSqBa0OZQriA==", "dev": true, "requires": { - "glob": "^7.0.5" + "glob": "^7.1.3" } }, "ripemd160": { @@ -11063,29 +10336,22 @@ "dev": true }, "rxjs": { - "version": "6.3.3", - "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.3.3.tgz", - "integrity": "sha512-JTWmoY9tWCs7zvIk/CvRjhjGaOd+OVBM987mxFo+OW66cGpdKjZcpmc74ES1sB//7Kl/PAe8+wEakuhG4pcgOw==", + "version": "6.4.0", + "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.4.0.tgz", + "integrity": "sha512-Z9Yfa11F6B9Sg/BK9MnqnQ+aQYicPLtilXBp2yUtDt2JRCE0h26d33EnfO3ZxoNxG0T92OUucP3Ct7cpfkdFfw==", "requires": { "tslib": "^1.9.0" - }, - "dependencies": { - "tslib": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.9.3.tgz", - "integrity": "sha512-4krF8scpejhaOgqzBEcGM7yDIEfi0/8+8zDRZhNZZ2kjmHJ4hv3zCbQWxoJGz1iw5U0Jl0nma13xzHXcncMavQ==" - } } }, "rxjs-compat": { - "version": "6.3.3", - "resolved": "https://registry.npmjs.org/rxjs-compat/-/rxjs-compat-6.3.3.tgz", - "integrity": "sha512-caGN7ixiabHpOofginKEquuHk7GgaCrC7UpUQ9ZqGp80tMc68msadOeP/2AKy2R4YJsT1+TX5GZCtxO82qWkyA==" + "version": "6.4.0", + "resolved": "https://registry.npmjs.org/rxjs-compat/-/rxjs-compat-6.4.0.tgz", + "integrity": "sha512-eo/O8RS83hJdJukCtA+IF6qnqa8FPOuVo+OPCzgVi+dbTle9KCdNv97IcQO0WwNVik7DJLKmf0F8uwzc0q40vw==" }, "safe-buffer": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.1.tgz", - "integrity": "sha512-kKvNJn6Mm93gAczWVJg7wH+wGYWNrDHdWvpUmHyEsgCtIwwo3bqPtV4tR5tuPaUhTOo/kvhVwd8XwwOllGYkbg==", + "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 }, "safe-regex": { @@ -11128,20 +10394,6 @@ "neo-async": "^2.5.0", "pify": "^3.0.0", "semver": "^5.5.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 - }, - "semver": { - "version": "5.6.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.6.0.tgz", - "integrity": "sha512-RS9R6R35NYgQn++fkDWaOmqGoj4Ek9gGs+DPxNUZKuwE183xjJroKvyo1IzVFeXvUrvmALy6FWD5xrdJT25gMg==", - "dev": true - } } }, "saucelabs": { @@ -11154,9 +10406,9 @@ } }, "sax": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/sax/-/sax-1.2.4.tgz", - "integrity": "sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw==", + "version": "0.5.8", + "resolved": "https://registry.npmjs.org/sax/-/sax-0.5.8.tgz", + "integrity": "sha1-1HLbIo6zMcJQaw6MFVJK25OdEsE=", "dev": true }, "schema-utils": { @@ -11183,7 +10435,7 @@ "dependencies": { "source-map": { "version": "0.4.4", - "resolved": "http://registry.npmjs.org/source-map/-/source-map-0.4.4.tgz", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.4.4.tgz", "integrity": "sha1-66T12pwNyZneaAMti092FzZSA2s=", "dev": true, "optional": true, @@ -11238,9 +10490,9 @@ } }, "semver": { - "version": "5.4.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.4.1.tgz", - "integrity": "sha512-WfG/X9+oATh81XtllIo/I8gOiY9EXRdv1cQdyykeXK17YcUW3EXUAi2To4pcH6nZtJPr7ZOpM5OMyWJZm+8Rsg==", + "version": "5.5.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.5.1.tgz", + "integrity": "sha512-PqpAxfrEhlSUWge8dwIp4tZnQ25DIOthpiaHNIthsjEFQD6EvqUKUDM7L8O2rShkFccYo1VjJR0coWfNkCubRw==", "dev": true }, "semver-dsl": { @@ -11287,12 +10539,6 @@ "resolved": "https://registry.npmjs.org/mime/-/mime-1.4.1.tgz", "integrity": "sha512-KI1+qOZu5DcW6wayYHSzR/tXKCDC5Om4s1z2QJjDULzLcmf3DvzS7oluY4HCTrc+9FiKmWUgeNLg7W3uIQvxtQ==", "dev": true - }, - "statuses": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.4.0.tgz", - "integrity": "sha512-zhSCtt8v2NDrRlPQpCNtw/heZLtfUDqxBM1udqikb/Hbk52LK4nQSwr10u77iopCW5LsyHpuXS0GnEc48mLeew==", - "dev": true } } }, @@ -11335,12 +10581,6 @@ "integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc=", "dev": true }, - "set-immediate-shim": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/set-immediate-shim/-/set-immediate-shim-1.0.1.tgz", - "integrity": "sha1-SysbJ+uAip+NzEgaWOXlb1mfP2E=", - "dev": true - }, "set-value": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/set-value/-/set-value-2.0.0.tgz", @@ -11378,7 +10618,7 @@ }, "sha.js": { "version": "2.4.11", - "resolved": "http://registry.npmjs.org/sha.js/-/sha.js-2.4.11.tgz", + "resolved": "https://registry.npmjs.org/sha.js/-/sha.js-2.4.11.tgz", "integrity": "sha512-QMEp5B7cftE7APOjk5Y6xgrbWu+WkLVQwk8JNjZ8nKRciZaByEW6MubieAiToS7+dwvrjGhH8jRXz3MVd0AYqQ==", "dev": true, "requires": { @@ -11444,9 +10684,9 @@ "dev": true }, "smart-buffer": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/smart-buffer/-/smart-buffer-4.0.1.tgz", - "integrity": "sha512-RFqinRVJVcCAL9Uh1oVqE6FZkqsyLiVOYEZ20TqIOjuX7iFVJ+zsbs4RIghnw/pTs7mZvt8ZHhvm1ZUrR4fykg==", + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/smart-buffer/-/smart-buffer-4.0.2.tgz", + "integrity": "sha512-JDhEpTKzXusOqXZ0BUIdH+CjFdO/CR3tLlf5CN34IypI+xMmXW1uB16OOY8z3cICbJlDAVJzNbwBhNO0wt9OAw==", "dev": true }, "snapdragon": { @@ -11482,6 +10722,12 @@ "requires": { "is-extendable": "^0.1.0" } + }, + "source-map": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", + "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", + "dev": true } } }, @@ -11533,12 +10779,6 @@ "is-data-descriptor": "^1.0.0", "kind-of": "^6.0.2" } - }, - "kind-of": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.2.tgz", - "integrity": "sha512-s5kLOcnH0XqDO+FvuaLX8DDjZ18CGFk7VygH40QoKPUQhW4e2rvM0rwUq0t8IQDOwYSeLK01U90OjzBTme2QqA==", - "dev": true } } }, @@ -11549,6 +10789,17 @@ "dev": true, "requires": { "kind-of": "^3.2.0" + }, + "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" + } + } } }, "socket.io": { @@ -11617,7 +10868,7 @@ }, "socket.io-parser": { "version": "3.2.0", - "resolved": "http://registry.npmjs.org/socket.io-parser/-/socket.io-parser-3.2.0.tgz", + "resolved": "https://registry.npmjs.org/socket.io-parser/-/socket.io-parser-3.2.0.tgz", "integrity": "sha512-FYiBx7rc/KORMJlgsXysflWx/RIvtqZbyGLlHZvjfmPTPeuD/I8MaW7cfFrj5tRltICJdgwflhfZ3NVVbVLFQA==", "dev": true, "requires": { @@ -11694,13 +10945,13 @@ } }, "socks": { - "version": "2.2.2", - "resolved": "https://registry.npmjs.org/socks/-/socks-2.2.2.tgz", - "integrity": "sha512-g6wjBnnMOZpE0ym6e0uHSddz9p3a+WsBaaYQaBaSCJYvrC4IXykQR9MNGjLQf38e9iIIhp3b1/Zk8YZI3KGJ0Q==", + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/socks/-/socks-2.2.3.tgz", + "integrity": "sha512-+2r83WaRT3PXYoO/1z+RDEBE7Z2f9YcdQnJ0K/ncXXbV5gJ6wYfNAebYFYiiUjM6E4JyXnPY8cimwyvFYHVUUA==", "dev": true, "requires": { "ip": "^1.1.5", - "smart-buffer": "^4.0.1" + "smart-buffer": "4.0.2" } }, "socks-proxy-agent": { @@ -11720,9 +10971,9 @@ "dev": true }, "source-map": { - "version": "0.5.7", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", - "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", + "version": "0.7.3", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.3.tgz", + "integrity": "sha512-CkCj6giN3S+n9qrYiBTX5gystlENnRW5jZeNLHpe6aue+SrHcG5VYwujhW9s4dY31mEGsxBDrHR6oI69fTXsaQ==", "dev": true }, "source-map-loader": { @@ -11733,6 +10984,17 @@ "requires": { "async": "^2.5.0", "loader-utils": "^1.1.0" + }, + "dependencies": { + "async": { + "version": "2.6.1", + "resolved": "https://registry.npmjs.org/async/-/async-2.6.1.tgz", + "integrity": "sha512-fNEiL2+AZt6AlAw/29Cr0UDe4sRAHCpEHh54WMz+Bb7QfNcFw4h3loofyJpLeQs4Yx7yuqu/2dLgM5hKOs6HlQ==", + "dev": true, + "requires": { + "lodash": "^4.17.10" + } + } } }, "source-map-resolve": { @@ -11749,12 +11011,21 @@ } }, "source-map-support": { - "version": "0.4.18", - "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.4.18.tgz", - "integrity": "sha512-try0/JqxPLF9nOjvSta7tVondkP5dwgyLDjVoyMDlmjugT2lRZ1OfsrYTkCd2hkDnJTKRbO/Rl3orm8vlsUzbA==", + "version": "0.5.9", + "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.9.tgz", + "integrity": "sha512-gR6Rw4MvUlYy83vP0vxoVNzM6t8MUXqNuRsuBmBHQDu1Fh6X015FrLdgoDKcNdkwGubozq0P4N0Q37UyFVr1EA==", "dev": true, "requires": { - "source-map": "^0.5.6" + "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 + } } }, "source-map-url": { @@ -11870,22 +11141,13 @@ "string_decoder": "^1.1.1", "util-deprecate": "^1.0.1" } - }, - "string_decoder": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.2.0.tgz", - "integrity": "sha512-6YqyX6ZWEYguAxgZzHGL7SsCeGx3V2TtOTqZz1xSTSWnqsbWwbptafNyvf/ACquZUXV3DANr5BDIwNYe1mN42w==", - "dev": true, - "requires": { - "safe-buffer": "~5.1.0" - } } } }, "speed-measure-webpack-plugin": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/speed-measure-webpack-plugin/-/speed-measure-webpack-plugin-1.2.3.tgz", - "integrity": "sha512-p+taQ69VkRUXYMoZOx2nxV/Tz8tt79ahctoZJyJDHWP7fEYvwFNf5Pd73k5kZ6auu0pTsPNLEUwWpM8mCk85Zw==", + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/speed-measure-webpack-plugin/-/speed-measure-webpack-plugin-1.2.5.tgz", + "integrity": "sha512-S/guYjC4Izn5wY2d0+M4zowED/F77Lxh9yjkTZ+XAr244pr9c1MYNcXcRe9lx2hmAj0GPbOrBXgOF2YIp/CZ8A==", "dev": true, "requires": { "chalk": "^2.0.1" @@ -11911,14 +11173,14 @@ }, "sprintf-js": { "version": "1.0.3", - "resolved": "http://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", + "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=", "dev": true }, "sshpk": { - "version": "1.16.0", - "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.16.0.tgz", - "integrity": "sha512-Zhev35/y7hRMcID/upReIvRse+I9SVhyVre/KTJSJQWMz3C3+G+HpO7m1wK/yckEtujKZ7dS4hkVxAnmHaIGVQ==", + "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", @@ -11972,9 +11234,9 @@ } }, "statuses": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz", - "integrity": "sha1-Fhx9rBd2Wf2YEfQ3cfqZOBR4Yow=", + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.4.0.tgz", + "integrity": "sha512-zhSCtt8v2NDrRlPQpCNtw/heZLtfUDqxBM1udqikb/Hbk52LK4nQSwr10u77iopCW5LsyHpuXS0GnEc48mLeew==", "dev": true }, "stdout-stream": { @@ -11988,9 +11250,9 @@ } }, "stream-browserify": { - "version": "2.0.1", - "resolved": "http://registry.npmjs.org/stream-browserify/-/stream-browserify-2.0.1.tgz", - "integrity": "sha1-ZiZu5fm9uZQKTkUUyvtDu3Hlyds=", + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/stream-browserify/-/stream-browserify-2.0.2.tgz", + "integrity": "sha512-nX6hmklHs/gr2FuxYDltq8fJA1GDlxKQCz8O/IM4atRqBH8OORmBNgfvW5gG10GT/qQ9u0CzIvr2X5Pkt6ntqg==", "dev": true, "requires": { "inherits": "~2.0.1", @@ -12027,38 +11289,6 @@ "readable-stream": "^2.3.6", "to-arraybuffer": "^1.0.0", "xtend": "^4.0.0" - }, - "dependencies": { - "process-nextick-args": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.0.tgz", - "integrity": "sha512-MtEC1TqN0EU5nephaJ4rAtThHtC86dNN9qCuEhtshvpVBkAW5ZO7BASN9REnF9eoXGcRub+pFuKEpOHE+HbEMw==", - "dev": true - }, - "readable-stream": { - "version": "2.3.6", - "resolved": "http://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz", - "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==", - "dev": 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" - } - }, - "string_decoder": { - "version": "1.1.1", - "resolved": "http://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" - } - } } }, "stream-shift": { @@ -12098,7 +11328,7 @@ }, "string-width": { "version": "1.0.2", - "resolved": "http://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz", "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=", "dev": true, "requires": { @@ -12108,9 +11338,9 @@ } }, "string_decoder": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.0.3.tgz", - "integrity": "sha512-4AH6Z5fzNNBcH+6XDMfA/BTt87skxqJlO0lAh3Dker5zThcAxG6mKz+iGu308UKoPPQ8Dcqx/4JhujzltRa+hQ==", + "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" @@ -12126,14 +11356,17 @@ } }, "strip-bom": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", - "integrity": "sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM=", - "dev": true + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-2.0.0.tgz", + "integrity": "sha1-YhmoVhZSBJHzV4i9vxRHqZx+aw4=", + "dev": true, + "requires": { + "is-utf8": "^0.2.0" + } }, "strip-eof": { "version": "1.0.0", - "resolved": "http://registry.npmjs.org/strip-eof/-/strip-eof-1.0.0.tgz", + "resolved": "https://registry.npmjs.org/strip-eof/-/strip-eof-1.0.0.tgz", "integrity": "sha1-u0P/VZim6wXYm1n80SnJgzE2Br8=", "dev": true }, @@ -12185,15 +11418,9 @@ "path-is-absolute": "^1.0.0" } }, - "sax": { - "version": "0.5.8", - "resolved": "http://registry.npmjs.org/sax/-/sax-0.5.8.tgz", - "integrity": "sha1-1HLbIo6zMcJQaw6MFVJK25OdEsE=", - "dev": true - }, "source-map": { "version": "0.1.43", - "resolved": "http://registry.npmjs.org/source-map/-/source-map-0.1.43.tgz", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.1.43.tgz", "integrity": "sha1-wkvBRspRfBRx9drL4lcbK3+eM0Y=", "dev": true, "requires": { @@ -12214,9 +11441,9 @@ } }, "supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "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" @@ -12236,7 +11463,7 @@ }, "tar": { "version": "2.2.1", - "resolved": "http://registry.npmjs.org/tar/-/tar-2.2.1.tgz", + "resolved": "https://registry.npmjs.org/tar/-/tar-2.2.1.tgz", "integrity": "sha1-jk0qJWwOIYXGsYrWlK7JaLg8sdE=", "dev": true, "optional": true, @@ -12247,14 +11474,14 @@ } }, "terser": { - "version": "3.14.1", - "resolved": "https://registry.npmjs.org/terser/-/terser-3.14.1.tgz", - "integrity": "sha512-NSo3E99QDbYSMeJaEk9YW2lTg3qS9V0aKGlb+PlOrei1X02r1wSBHCNX/O+yeTRFSWPKPIGj6MqvvdqV4rnVGw==", + "version": "3.16.1", + "resolved": "https://registry.npmjs.org/terser/-/terser-3.16.1.tgz", + "integrity": "sha512-JDJjgleBROeek2iBcSNzOHLKsB/MdDf+E/BOAJ0Tk9r7p9/fVobfv7LMJ/g/k3v9SXdmjZnIlFd5nfn/Rt0Xow==", "dev": true, "requires": { "commander": "~2.17.1", "source-map": "~0.6.1", - "source-map-support": "~0.5.6" + "source-map-support": "~0.5.9" }, "dependencies": { "source-map": { @@ -12262,23 +11489,13 @@ "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", "dev": true - }, - "source-map-support": { - "version": "0.5.10", - "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.10.tgz", - "integrity": "sha512-YfQ3tQFTK/yzlGJuX8pTwa4tifQj4QS2Mj7UegOu8jAz59MqIiMGPXxQhVQiIMNzayuUSF/jEuVnfFF5JqybmQ==", - "dev": true, - "requires": { - "buffer-from": "^1.0.0", - "source-map": "^0.6.0" - } } } }, "terser-webpack-plugin": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-1.1.0.tgz", - "integrity": "sha512-61lV0DSxMAZ8AyZG7/A4a3UPlrbOBo8NIQ4tJzLPAdGOQ+yoNC7l5ijEow27lBAL2humer01KLS6bGIMYQxKoA==", + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-1.2.1.tgz", + "integrity": "sha512-GGSt+gbT0oKcMDmPx4SRSfJPE1XaN3kQRWG4ghxKQw9cn5G9x6aCKSsgYdvyM0na9NJ4Drv0RG6jbBByZ5CMjw==", "dev": true, "requires": { "cacache": "^11.0.2", @@ -12333,26 +11550,6 @@ "locate-path": "^3.0.0" } }, - "glob": { - "version": "7.1.3", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.3.tgz", - "integrity": "sha512-vcfuiIxogLV4DlGBHIUOwI0IbrJ8HWPc4MU7HzviGeNho/UJDfi6B5p3sHeWIQ0KGIU0Jpxi5ZHxemQfLkkAwQ==", - "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" - } - }, - "graceful-fs": { - "version": "4.1.15", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.1.15.tgz", - "integrity": "sha512-6uHUhOPEBgQ24HM+r6b/QwWfZq+yiFcipKFrOFiBEnWdy5sdzYoi+pJeQaPI5qOLRFqWmAXUPQNsielzdLoecA==", - "dev": true - }, "locate-path": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz", @@ -12447,6 +11644,12 @@ "requires": { "figgy-pudding": "^3.5.1" } + }, + "yallist": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.0.3.tgz", + "integrity": "sha512-S+Zk8DEWE6oKpV+vI3qWkaK+jSbIK86pCwe2IF/xwIpQ8jEuxpw9NyaGjmp9+BoJv5FV2piqCDcoCtStppiq2A==", + "dev": true } } }, @@ -12464,38 +11667,6 @@ "requires": { "readable-stream": "~2.3.6", "xtend": "~4.0.1" - }, - "dependencies": { - "process-nextick-args": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.0.tgz", - "integrity": "sha512-MtEC1TqN0EU5nephaJ4rAtThHtC86dNN9qCuEhtshvpVBkAW5ZO7BASN9REnF9eoXGcRub+pFuKEpOHE+HbEMw==", - "dev": true - }, - "readable-stream": { - "version": "2.3.6", - "resolved": "http://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz", - "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==", - "dev": 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" - } - }, - "string_decoder": { - "version": "1.1.1", - "resolved": "http://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" - } - } } }, "thunky": { @@ -12520,9 +11691,9 @@ } }, "tiny-emitter": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/tiny-emitter/-/tiny-emitter-2.0.2.tgz", - "integrity": "sha512-2NM0auVBGft5tee/OxP4PI3d8WItkDM+fPnaRAVo6xTDI2knbz9eC5ArWGqtGlYqiH3RU5yMpdyTTO7MguC4ow==", + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/tiny-emitter/-/tiny-emitter-2.1.0.tgz", + "integrity": "sha512-NB6Dk1A9xgQPMoGqC5CVXn123gWyte215ONT5Pp5a0yt4nlEoO1ZWeCwpncaekPHXO60i47ihFnZPiRPjRMq4Q==", "optional": true }, "tmp": { @@ -12547,9 +11718,9 @@ "dev": true }, "to-fast-properties": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz", - "integrity": "sha1-3F5pjL0HkmW8c+A3doGk5Og/YW4=", + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-1.0.3.tgz", + "integrity": "sha1-uDVx+k2MJbguIxsG46MFXeTKGkc=", "dev": true }, "to-object-path": { @@ -12559,6 +11730,17 @@ "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": { @@ -12581,17 +11763,6 @@ "requires": { "is-number": "^3.0.0", "repeat-string": "^1.6.1" - }, - "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" - } - } } }, "tough-cookie": { @@ -12599,10 +11770,17 @@ "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.4.3.tgz", "integrity": "sha512-Q5srk/4vDM54WJsJio3XNn6K2sCG+CQ8G5Wz6bZhRZoAe/+TxjWB/GlFAnYEbkYVlON9FMk/fE3h2RLpPXo4lQ==", "dev": true, - "optional": true, "requires": { "psl": "^1.1.24", "punycode": "^1.4.1" + }, + "dependencies": { + "punycode": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz", + "integrity": "sha1-wNWmOycYgArY4esPpSachN1BhF4=", + "dev": true + } } }, "traverse": { @@ -12656,21 +11834,11 @@ "yn": "^2.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==", + "minimist": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", + "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=", "dev": true - }, - "source-map-support": { - "version": "0.5.9", - "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.9.tgz", - "integrity": "sha512-gR6Rw4MvUlYy83vP0vxoVNzM6t8MUXqNuRsuBmBHQDu1Fh6X015FrLdgoDKcNdkwGubozq0P4N0Q37UyFVr1EA==", - "dev": true, - "requires": { - "buffer-from": "^1.0.0", - "source-map": "^0.6.0" - } } } }, @@ -12692,6 +11860,16 @@ "typescript": "2.9.1" }, "dependencies": { + "dir-glob": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-2.0.0.tgz", + "integrity": "sha512-37qirFDz8cA5fimp9feo43fSuRo2gHwaIn6dXL8Ber1dGwUosDrGZeCCXq57WnIqE4aQ+u3eQZzsk1yOzhdwag==", + "dev": true, + "requires": { + "arrify": "^1.0.1", + "path-type": "^3.0.0" + } + }, "fs-extra": { "version": "6.0.1", "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-6.0.1.tgz", @@ -12704,13 +11882,13 @@ } }, "globby": { - "version": "8.0.1", - "resolved": "https://registry.npmjs.org/globby/-/globby-8.0.1.tgz", - "integrity": "sha512-oMrYrJERnKBLXNLVTqhm3vPEdJ/b2ZE28xN4YARiix1NOIOBPEpOUnm844K1iu/BkphCaf2WNFwMszv8Soi1pw==", + "version": "8.0.2", + "resolved": "https://registry.npmjs.org/globby/-/globby-8.0.2.tgz", + "integrity": "sha512-yTzMmKygLp8RUpG1Ymu2VXPSJQZjNAZPD4ywgYEaG7e4tBJeUQBO8OpXrf1RCNcEs5alsoJYPAMiIHP0cmeC7w==", "dev": true, "requires": { "array-union": "^1.0.1", - "dir-glob": "^2.0.0", + "dir-glob": "2.0.0", "fast-glob": "^2.0.2", "glob": "^7.1.2", "ignore": "^3.3.5", @@ -12718,12 +11896,6 @@ "slash": "^1.0.0" } }, - "pify": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz", - "integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=", - "dev": true - }, "typescript": { "version": "2.9.1", "resolved": "https://registry.npmjs.org/typescript/-/typescript-2.9.1.tgz", @@ -12738,9 +11910,9 @@ "integrity": "sha512-4krF8scpejhaOgqzBEcGM7yDIEfi0/8+8zDRZhNZZ2kjmHJ4hv3zCbQWxoJGz1iw5U0Jl0nma13xzHXcncMavQ==" }, "tslint": { - "version": "5.12.0", - "resolved": "https://registry.npmjs.org/tslint/-/tslint-5.12.0.tgz", - "integrity": "sha512-CKEcH1MHUBhoV43SA/Jmy1l24HJJgI0eyLbBNSRyFlsQvb9v6Zdq+Nz2vEOH00nC5SUx4SneJ59PZUS/ARcokQ==", + "version": "5.12.1", + "resolved": "https://registry.npmjs.org/tslint/-/tslint-5.12.1.tgz", + "integrity": "sha512-sfodBHOucFg6egff8d1BvuofoOQ/nOeYNfbp7LDlKBcLNrL3lmS5zoiDGyOMdT7YsEXAwWpTdAHwOGOc8eRZAw==", "dev": true, "requires": { "babel-code-frame": "^6.22.0", @@ -12755,6 +11927,17 @@ "semver": "^5.3.0", "tslib": "^1.8.0", "tsutils": "^2.27.2" + }, + "dependencies": { + "resolve": { + "version": "1.10.0", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.10.0.tgz", + "integrity": "sha512-3sUr9aq5OfSg2S9pNtPA9hL1FVEAjvfOC4leW0SNf/mpnaakz2a9femSd6LqAww2RaFctwyf1lCqnTHuF1rxDg==", + "dev": true, + "requires": { + "path-parse": "^1.0.6" + } + } } }, "tsutils": { @@ -12768,7 +11951,7 @@ }, "tty-browserify": { "version": "0.0.0", - "resolved": "http://registry.npmjs.org/tty-browserify/-/tty-browserify-0.0.0.tgz", + "resolved": "https://registry.npmjs.org/tty-browserify/-/tty-browserify-0.0.0.tgz", "integrity": "sha1-oVe6QC2iTpv5V/mqadUk7tQpAaY=", "dev": true }, @@ -12845,56 +12028,6 @@ "dev": true, "optional": true }, - "uglifyjs-webpack-plugin": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/uglifyjs-webpack-plugin/-/uglifyjs-webpack-plugin-1.3.0.tgz", - "integrity": "sha512-ovHIch0AMlxjD/97j9AYovZxG5wnHOPkL7T1GKochBADp/Zwc44pEWNqpKl1Loupp1WhFg7SlYmHZRUfdAacgw==", - "dev": true, - "requires": { - "cacache": "^10.0.4", - "find-cache-dir": "^1.0.0", - "schema-utils": "^0.4.5", - "serialize-javascript": "^1.4.0", - "source-map": "^0.6.1", - "uglify-es": "^3.3.4", - "webpack-sources": "^1.1.0", - "worker-farm": "^1.5.2" - }, - "dependencies": { - "commander": { - "version": "2.13.0", - "resolved": "https://registry.npmjs.org/commander/-/commander-2.13.0.tgz", - "integrity": "sha512-MVuS359B+YzaWqjCL/c+22gfryv+mCBPHAv3zyVI2GN8EY6IRP8VwtasXn8jyyhvvq84R4ImN1OKRtcbIasjYA==", - "dev": true - }, - "schema-utils": { - "version": "0.4.7", - "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-0.4.7.tgz", - "integrity": "sha512-v/iwU6wvwGK8HbU9yi3/nhGzP0yGSuhQMzL6ySiec1FSrZZDkhm4noOSWzrNFo/jEc+SJY6jRTwuwbSXJPDUnQ==", - "dev": true, - "requires": { - "ajv": "^6.1.0", - "ajv-keywords": "^3.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 - }, - "uglify-es": { - "version": "3.3.9", - "resolved": "https://registry.npmjs.org/uglify-es/-/uglify-es-3.3.9.tgz", - "integrity": "sha512-r+MU0rfv4L/0eeW3xZrd16t4NZfK8Ld4SWVglYBb7ez5uXFWHuVRs6xCTrf1yirs9a4j4Y27nn7SRfO6v67XsQ==", - "dev": true, - "requires": { - "commander": "~2.13.0", - "source-map": "~0.6.1" - } - } - } - }, "ultron": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/ultron/-/ultron-1.1.1.tgz", @@ -13031,14 +12164,6 @@ "dev": true, "requires": { "punycode": "^2.1.0" - }, - "dependencies": { - "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 - } } }, "urix": { @@ -13092,9 +12217,9 @@ } }, "util": { - "version": "0.10.4", - "resolved": "https://registry.npmjs.org/util/-/util-0.10.4.tgz", - "integrity": "sha512-0Pm9hTQ3se5ll1XihRic3FDIku70C+iHUdT/W926rSgHV5QgXsYbKZN8MSC3tJtSkhuROzvsQjAaFENRXr+19A==", + "version": "0.11.1", + "resolved": "https://registry.npmjs.org/util/-/util-0.11.1.tgz", + "integrity": "sha512-HShAsny+zS2TZfaXxD9tYj4HQGlBezXZMZuM/S5PKLLoZkShZiGk9o5CzukI1LVHZvjdvZ2Sj1aW/Ndn2NB/HQ==", "dev": true, "requires": { "inherits": "2.0.3" @@ -13152,14 +12277,6 @@ "assert-plus": "^1.0.0", "core-util-is": "1.0.2", "extsprintf": "^1.2.0" - }, - "dependencies": { - "assert-plus": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", - "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=", - "dev": true - } } }, "viz.js": { @@ -13170,7 +12287,7 @@ }, "vm-browserify": { "version": "0.0.4", - "resolved": "http://registry.npmjs.org/vm-browserify/-/vm-browserify-0.0.4.tgz", + "resolved": "https://registry.npmjs.org/vm-browserify/-/vm-browserify-0.0.4.tgz", "integrity": "sha1-XX6kW7755Kb/ZflUOOCofDV9WnM=", "dev": true, "requires": { @@ -13214,15 +12331,15 @@ } }, "webpack": { - "version": "4.23.1", - "resolved": "https://registry.npmjs.org/webpack/-/webpack-4.23.1.tgz", - "integrity": "sha512-iE5Cu4rGEDk7ONRjisTOjVHv3dDtcFfwitSxT7evtYj/rANJpt1OuC/Kozh1pBa99AUBr1L/LsaNB+D9Xz3CEg==", + "version": "4.28.4", + "resolved": "https://registry.npmjs.org/webpack/-/webpack-4.28.4.tgz", + "integrity": "sha512-NxjD61WsK/a3JIdwWjtIpimmvE6UrRi3yG54/74Hk9rwNj5FPkA4DJCf1z4ByDWLkvZhTZE+P3C/eh6UD5lDcw==", "dev": true, "requires": { - "@webassemblyjs/ast": "1.7.10", - "@webassemblyjs/helper-module-context": "1.7.10", - "@webassemblyjs/wasm-edit": "1.7.10", - "@webassemblyjs/wasm-parser": "1.7.10", + "@webassemblyjs/ast": "1.7.11", + "@webassemblyjs/helper-module-context": "1.7.11", + "@webassemblyjs/wasm-edit": "1.7.11", + "@webassemblyjs/wasm-parser": "1.7.11", "acorn": "^5.6.2", "acorn-dynamic-import": "^3.0.0", "ajv": "^6.1.0", @@ -13240,7 +12357,7 @@ "node-libs-browser": "^2.0.0", "schema-utils": "^0.4.4", "tapable": "^1.1.0", - "uglifyjs-webpack-plugin": "^1.2.4", + "terser-webpack-plugin": "^1.1.0", "watchpack": "^1.5.0", "webpack-sources": "^1.3.0" }, @@ -13275,7 +12392,7 @@ }, "source-map": { "version": "0.4.4", - "resolved": "http://registry.npmjs.org/source-map/-/source-map-0.4.4.tgz", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.4.4.tgz", "integrity": "sha1-66T12pwNyZneaAMti092FzZSA2s=", "dev": true, "requires": { @@ -13294,6 +12411,14 @@ "mime": "^2.3.1", "range-parser": "^1.0.3", "webpack-log": "^2.0.0" + }, + "dependencies": { + "mime": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/mime/-/mime-2.4.0.tgz", + "integrity": "sha512-ikBcWwyqXQSHKtciCcctu9YfPbFYZ4+gbHEmE0Q8jzcTYQg5dHCr3g2wwAZjPoJfQVXZq6KXAjpXOTf5/cjT7w==", + "dev": true + } } }, "webpack-dev-server": { @@ -13340,6 +12465,12 @@ "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=", "dev": true }, + "camelcase": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-4.1.0.tgz", + "integrity": "sha1-1UVjW+HjPFQmScaRc+Xeas+uNN0=", + "dev": true + }, "cliui": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/cliui/-/cliui-4.1.0.tgz", @@ -13535,6 +12666,15 @@ } } }, + "supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, + "requires": { + "has-flag": "^3.0.0" + } + }, "which-module": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/which-module/-/which-module-2.0.0.tgz", @@ -13661,7 +12801,6 @@ "resolved": "https://registry.npmjs.org/wide-align/-/wide-align-1.1.3.tgz", "integrity": "sha512-QGkOQc8XL6Bt5PwnsExKBPuMKBxnGxWWW3fU55Xt4feHozMUhdUMaBCk290qpm/wG5u/RSKzwdAC4i51YigihA==", "dev": true, - "optional": true, "requires": { "string-width": "^1.0.2 || 2" } @@ -13683,9 +12822,9 @@ } }, "wordwrap": { - "version": "0.0.2", - "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-0.0.2.tgz", - "integrity": "sha1-t5Zpu0LstAn4PVg8rVLKF+qhZD8=", + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-1.0.0.tgz", + "integrity": "sha1-J1hIEIkUVqQXHI0CJkQa3pDLyus=", "dev": true }, "worker-farm": { @@ -13699,7 +12838,7 @@ }, "wrap-ansi": { "version": "2.1.0", - "resolved": "http://registry.npmjs.org/wrap-ansi/-/wrap-ansi-2.1.0.tgz", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-2.1.0.tgz", "integrity": "sha1-2Pw9KE3QV5T+hJc8rs3Rz4JP3YU=", "dev": true, "requires": { @@ -13732,11 +12871,19 @@ "requires": { "sax": ">=0.6.0", "xmlbuilder": "~9.0.1" + }, + "dependencies": { + "sax": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/sax/-/sax-1.2.4.tgz", + "integrity": "sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw==", + "dev": true + } } }, "xmlbuilder": { "version": "9.0.7", - "resolved": "http://registry.npmjs.org/xmlbuilder/-/xmlbuilder-9.0.7.tgz", + "resolved": "https://registry.npmjs.org/xmlbuilder/-/xmlbuilder-9.0.7.tgz", "integrity": "sha1-Ey7mPS7FVlxVfiD0wi35rKaGsQ0=", "dev": true }, @@ -13765,9 +12912,9 @@ "dev": true }, "yallist": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.0.3.tgz", - "integrity": "sha512-S+Zk8DEWE6oKpV+vI3qWkaK+jSbIK86pCwe2IF/xwIpQ8jEuxpw9NyaGjmp9+BoJv5FV2piqCDcoCtStppiq2A==", + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-2.1.2.tgz", + "integrity": "sha1-HBH5IY8HYImkfdUS+TxmmaaoHVI=", "dev": true }, "yargs": { @@ -13840,9 +12987,9 @@ "dev": true }, "zone.js": { - "version": "0.8.26", - "resolved": "https://registry.npmjs.org/zone.js/-/zone.js-0.8.26.tgz", - "integrity": "sha512-W9Nj+UmBJG251wkCacIkETgra4QgBo/vgoEkb4a2uoLzpQG7qF9nzwoLXWU5xj3Fg2mxGvEDh47mg24vXccYjA==" + "version": "0.8.29", + "resolved": "https://registry.npmjs.org/zone.js/-/zone.js-0.8.29.tgz", + "integrity": "sha512-mla2acNCMkWXBD+c+yeUrBUrzOxYMNFdQ6FGfigGGtEVBPJx07BQeJekjt9DmH1FtZek4E9rE1eRR9qQpxACOQ==" } } } diff --git a/package.json b/package.json index c8737ad12a0b36198e40bc71cb712ef4eccd2b34..77d7b5888f7620ff738500d9d9894f80ff68abec 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "nghyd", - "version": "1.1.0", + "version": "1.2.0", "license": "MIT", "scripts": { "ng": "ng", @@ -20,37 +20,41 @@ }, "private": true, "dependencies": { - "@angular/animations": "^7.1.4", - "@angular/common": "^7.1.4", - "@angular/compiler": "^7.1.4", - "@angular/core": "^7.1.4", - "@angular/forms": "^7.1.4", - "@angular/http": "^7.1.4", - "@angular/platform-browser": "^7.1.4", - "@angular/platform-browser-dynamic": "^7.1.4", - "@angular/router": "^7.1.4", - "angular-bootstrap-md": "^7.2.0", + "@angular/animations": "^7.2.1", + "@angular/cdk": "^7.2.1", + "@angular/common": "^7.2.1", + "@angular/compiler": "^7.2.1", + "@angular/core": "^7.2.1", + "@angular/flex-layout": "^7.0.0-beta.23", + "@angular/forms": "^7.2.1", + "@angular/http": "^7.2.1", + "@angular/material": "^7.2.1", + "@angular/platform-browser": "^7.2.1", + "@angular/platform-browser-dynamic": "^7.2.1", + "@angular/router": "^7.2.1", + "@types/sprintf-js": "^1.1.1", "angular2-chartjs": "^0.5.1", - "core-js": "^2.6.1", + "core-js": "^2.6.3", "file-saver": "^2.0.0", - "font-awesome": "^4.7.0", + "hammerjs": "^2.0.8", "he": "^1.2.0", "jalhyd": "file:../jalhyd", "mathjax": "^2.7.5", + "ngx-material-file-input": "^1.1.0", "ngx-md": "^7.0.0", "rxjs": "^6.3.3", "rxjs-compat": "^6.3.3", "tslib": "^1.9.0", - "zone.js": "^0.8.26" + "zone.js": "^0.8.28" }, "devDependencies": { - "@angular-devkit/build-angular": "^0.12.1", - "@angular/cli": "^7.1.4", - "@angular/compiler-cli": "^7.1.4", - "@angular/language-service": "^7.1.4", + "@angular-devkit/build-angular": "^0.12.2", + "@angular/cli": "^7.2.2", + "@angular/compiler-cli": "^7.2.1", + "@angular/language-service": "^7.2.1", "@compodoc/compodoc": "^1.1.7", "@types/file-saver": "^2.0.0", - "@types/jasmine": "~3.3.5", + "@types/jasmine": "^3.3.7", "@types/jasminewd2": "^2.0.6", "@types/node": "^8.10.39", "codelyzer": "^4.5.0", @@ -64,7 +68,7 @@ "karma-jasmine-html-reporter": "^1.4.0", "protractor": "^5.4.2", "ts-node": "~7.0.1", - "tslint": "~5.12.0", + "tslint": "^5.12.1", "typescript": "~3.1.1", "webpack-dev-server": "^3.1.14" } diff --git a/src/app/app.component.html b/src/app/app.component.html index b1e92164976b1c922802f3cb14ebc8994a369903..fbcfa67dbeadfe99ba0a0dc88d45bc44e1eaf537 100644 --- a/src/app/app.component.html +++ b/src/app/app.component.html @@ -1,85 +1,114 @@ +<app-layout> + <header> - <!--Navbar --> - <nav class="navbar navbar-expand-sm navbar-dark indigo"> - <!-- Ouverture du sidenav --> - <span id="open-menu" style="font-size:30px;cursor:pointer;color:white" (click)="openNav()">☰</span> - - <!-- lien vide pour que le toggler des liens apparaisse à droite --> - <a class="navbar-brand"></a> - - <!-- toggler des liens --> - <button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarSupportedContent" aria-controls="navbarSupportedContent" - aria-expanded="false" aria-label="Toggle navigation"> - <!-- <span class="navbar-toggler-icon"> </span> --> - <i class="fa fa-ellipsis-v" aria-hidden="true"></i> - </button> - <!-- Collapsible content --> - <div class="collapse navbar-collapse" id="navbarSupportedContent"> - <ul id="navbar" class="navbar-nav mr-auto"> - <li class="nav-item calculator-tab" *ngFor="let c of calculators"> - <a class="nav-link waves-light {{getHighlightClass(c.uid)}}" mdbRippleRadius [routerLink]="['/calculator/',c.uid]">{{ c.title }}</a> - </li> - <li class="nav-item" id="add-calculator-tab"> - <i id="new-calculator" class="fa fa-plus-square fa-2x fa-inverse" style='vertical-align: middle' routerLink="/list" (click)='closeNav()'></i> - </li> - </ul> + <mat-toolbar #navbar id="main-toolbar" color="primary"> + + <span id="open-menu" style="font-size:30px;cursor:pointer;color:white" (click)="sidenav.toggle()"> + <mat-icon>menu</mat-icon> + </span> + + <!-- calculators list as a dropdown menu--> + <div [hidden]="tabsFitInNavbar" id="dropdown-calc-container"> + + <button *ngIf="! currentCalc" mat-button [matMenuTriggerFor]="menu" color="primary" class="calculators-menu-title"> + <mat-icon class="dropdown-icon">arrow_drop_down</mat-icon> + <span class="calc-name"> + {{ uitextSelectCalc }} + </span> + </button> + <button *ngIf="currentCalc" mat-button [matMenuTriggerFor]="menu" color="primary" class="calculators-menu-title"> + <mat-icon class="dropdown-icon">arrow_drop_down</mat-icon> + <span class="calc-name"> + {{ currentCalc.title }} + </span> + <span class="calc-type" [innerHTML]="'( ' + currentCalc ? currentCalc.type : '' + ' )'"></span> + </button> + + <mat-menu #menu="matMenu" colo="accent"> + <button mat-button *ngFor="let c of calculators" class="calculator-menu-item" [title]="c.title" + [routerLink]="['/calculator/',c.uid]" [color]="c.active ? 'primary' : ''" [class.active]="c.active" + (click)="setActiveCalc(c.uid)"> + + <span class="calc-name"> + {{ c.title }} + </span> + <span class="calc-type" [innerHTML]="'(' + getCalculatorLabel(c.type) + ')'"></span> + </button> + </mat-menu> </div> - </nav> - <!--/Navbar --> + + <!-- calculators list as a tabs bar--> + <div id="tabs-container" [hidden]="! tabsFitInNavbar"> + <button mat-raised-button color="primary" *ngFor="let c of calculators" class="calculator-button" [title]="c.title" + [routerLink]="['/calculator/',c.uid]" [color]="c.active ? '' : 'primary'" [class.active]="c.active" + (click)="setActiveCalc(c.uid)"> + + <span class="calc-name"> + {{ c.title }} + </span> + <span class="calc-type" [innerHTML]="'(' + getCalculatorLabel(c.type) + ')'"></span> + </button> + + </div> + + <button mat-icon-button id="new-calculator" routerLink="/list" (click)="sidenav.close()"> + <mat-icon>add_box</mat-icon> + </button> + + <div id="toolbar-bottom-spacer"></div> + </mat-toolbar> + </header> <main> - <!-- sidenav --> - <div class="container"> - <div class="row"> - <div id="mySidenav" class="sidenav"> - <!-- ATTENTION ! pas de href="#" sous peine de rechargement de la page et réinitialisation de l'appli --> - <a id="close-side-nav" class="closebtn" (click)="closeNav()">×</a> - <a id="side-nav-list" routerLink="/list" (click)="closeNav()">{{ uitextSidenavNewCalc }}</a> - <a id="side-nav-load-session" (click)="loadSession()">{{ uitextSidenavLoadSession }}</a> - <a id="side-nav-setup" routerLink="/setup" (click)="closeNav()">{{ uitextSidenavParams }}</a> - <a id="side-nav-help" target="_blank" href="assets/docs-fr/" (click)="closeNav()">{{ uitextSidenavHelp }}</a> - <div class="hyd_fillvertical"></div> + <mat-sidenav-container fxFlexFill class="example-container"> + + <!-- side panel --> + <mat-sidenav class="sidenav" #sidenav fxLayout="column" > + <div fxLayout="column"> + <a id="close-side-nav" class="closebtn" (click)="sidenav.close()">×</a> + + <a id="side-nav-list" routerLink="/list" (click)="sidenav.close()"> + <mat-icon>add</mat-icon> + {{ uitextSidenavNewCalc }} + </a> + <a id="side-nav-empty-session" (click)="sidenav.close(); emptySession()"> + <mat-icon>insert_drive_file</mat-icon> + {{ uitextSidenavEmptySession }} + </a> + <a id="side-nav-load-session" (click)="loadSession(); sidenav.close()"> + <mat-icon>folder_open</mat-icon> + {{ uitextSidenavLoadSession }} + </a> + <a id="side-nav-save-session" (click)="saveForm(); sidenav.close()"> + <mat-icon>save_alt</mat-icon> + {{ uitextSidenavSaveSession }} + </a> + <a id="side-nav-setup" routerLink="/setup" (click)="sidenav.close()"> + <mat-icon>settings</mat-icon> + {{ uitextSidenavParams }} + </a> + <a id="side-nav-help" target="_blank" href="assets/docs-fr/" (click)="sidenav.close()"> + <mat-icon>help</mat-icon> + {{ uitextSidenavHelp }} + </a> + <div class="hyd_version"> JaLHyd version: {{ getDateRevision()[0] }}<br/> ngHyd version: {{ getDateRevision()[1] }} </div> </div> - </div> - </div> - - <!-- chargement des calculettes --> - <div appLoadCalcDialogAnchor></div> - - <!-- sauvegarde des calculettes --> - <div appSaveCalcDialogAnchor></div> - - <!-- règle gradée des colonnes Bootstrap --> - <div *ngIf="ruler" class="container-fluid"> - <div class="row"> - <div class="col 1 red">1</div> - <div class="col 1 green">2</div> - <div class="col 1 blue">3</div> - <div class="col 1 red">4</div> - <div class="col 1 green">5</div> - <div class="col 1 blue">6</div> - <div class="col 1 red">7</div> - <div class="col 1 green">8</div> - <div class="col 1 blue">9</div> - <div class="col 1 red">10</div> - <div class="col 1 green">11</div> - <div class="col 1 blue">12</div> - </div> - </div> + </mat-sidenav> - <div class="container-fluid"> - <div class="row"> - <div class="col-12"> + <mat-sidenav-content class="sidenav-content" fxFlexFill> + <div id="app-content"> <router-outlet (activate)="onRouterOutletActivated($event)"></router-outlet> </div> - </div> - </div> + </mat-sidenav-content> + + </mat-sidenav-container> + </main> <footer> @@ -88,4 +117,6 @@ <br> <a href="http://www.irstea.fr/">Institut national de recherche en sciences et technologies pour l'environnement et l'agriculture</a> </div> --> -</footer> \ No newline at end of file +</footer> + +</app-layout> diff --git a/src/app/app.component.scss b/src/app/app.component.scss index 9a709694f5b416ba83ec193f9c35a427f232e76d..e3dee283cdb433f03f34c757032b5cd340ee8ba4 100644 --- a/src/app/app.component.scss +++ b/src/app/app.component.scss @@ -1,69 +1,209 @@ +// variables + +$navbar_height: 54px; + +// rules + .dropdown-menu > li > a:hover { background-color: rgb(172, 172, 172); background-image: none; } -// sidenav -body { - font-family: "Lato", sans-serif; +button:focus { + outline: 0; } -.sidenav { - height: 100%; - width: 0; +#main-toolbar { position: fixed; - z-index: 2000; - top: 0; - left: 0; - background-color: #111; - overflow-x: hidden; - transition: 0.5s; - padding-top: 60px; - display: flex; - flex-direction: column; + height: $navbar_height; + z-index: 200; +} + +#toolbar-bottom-spacer { + height: 3px; + background-color: white; + z-index: 200; + position: absolute; + top: 54px; + width: 100%; } -.sidenav a, .sidenav div.hyd_version { - padding: 8px 8px 8px 32px; - text-decoration: none; - font-size: 16px; - color: #aaaaaa; - display: block; - transition: 0.3s; +#open-menu { + margin-right: 16px; } -.sidenav div.hyd_version { - color: #888888; - padding: 0px 32px 0px 0px; - text-align: right; +#open-menu mat-icon, #new-calculator mat-icon { + transform: scale(1.6); } -.sidenav div.hyd_fillvertical { - flex: 1; +#new-calculator { + cursor: pointer; + position: absolute; + right: 10px; + + &:focus { + outline: 0; + } } -.sidenav a:hover { - color: #f1f1f1; +#tabs-container { + width: 100%; } -.sidenav .closebtn { - position: absolute; - top: 0; - right: 25px; - font-size: 36px; - margin-left: 50px; +#dropdown-calc-container { + width: 100%; + padding-right: 42px; +} + +.calculator-button, .calculators-menu-title, .calculator-menu-item { + + .calc-name { + display: block; + margin-top: -3px; // ark ! + text-overflow: ellipsis; + overflow: hidden; + } + + .calc-type { + display: block; + color: #bbb; + font-size: 0.7em; + line-height: 24px; + margin-top: -14px; // ark ! + text-overflow: ellipsis; + overflow: hidden; + } +} + +.calculator-button { + // @TODO remplacer par du Flex ? + width: 15.5%; // 6 larger tabs + @media screen and (max-width: 1200px) { + width: 14.5%; // 6 tabs + } + @media screen and (max-width: 800px) { + width: 21%; // 4 tabs + } + @media screen and (max-width: 640px) { + width: 27%; // 3 larger tabs + } + @media screen and (max-width: 480px) { + width: 24%; // 3 tabs + } + // tabs-looking buttons + margin-right: 3px; + margin-top: 11px; + border-bottom-left-radius: 0; + border-bottom-right-radius: 0; + border-bottom: solid #3F51B5 4px; + + &.active { + border-bottom-color: white; + box-shadow: none; + + .calc-type { + color: #777; + } + } } -.navbar-brand { - color: #fff; +.calculators-menu-title { + background-color: white; + margin-top: 8px; + width: 100%; // adapts to small screens + max-width: 400px; + + .dropdown-icon { + float: right; + transform: scale(2); + margin-top: 8px; + margin-left: 10px; + } + + .calc-type { + color: #777; + } +} + +.calculator-menu-item { + width: 100%; + border-radius: 0; + + &.active { + .calc-type { + color: #777; + } + } + + &:hover { + background-color: #ddd; + } +} + +// sidenav + +.sidenav { + position:fixed; + height: 100%; + background-color: #111; + overflow-x: hidden; + padding-top: 60px + $navbar_height; + padding-right: 4em; + z-index: 100; + + a, .div.hyd_version { + padding: 8px 8px 8px 24px; + text-decoration: none; + font-size: 16px; + color: #aaaaaa; + display: block; + transition: 0.3s; + + &:focus { + outline: 0; + } + + &:hover { + color: #f1f1f1; + } + } + + a { + cursor: pointer; + } + + div.hyd_version { + position: absolute; + bottom: 0; + right: 0; + font-size: 0.8em; + color: #888888; + padding: 0 2em 1em 0; + text-align: right; + } + + .closebtn { + position: absolute; + top: 54px; + right: 25px; + font-size: 36px; + margin-left: 50px; + } + + mat-icon { + color: #fff; + vertical-align: bottom; + margin-right: 6px; + } } -nav div.container { - display: contents; +// page contents + +.sidenav-content { + margin-top: $navbar_height; } -@media screen and (max-height: 450px) { - .sidenav {padding-top: 15px;} - .sidenav a {font-size: 18px;} +#app-content { + padding: 1em; + padding-bottom: 8em; } -// sidenav \ No newline at end of file diff --git a/src/app/app.component.ts b/src/app/app.component.ts index 811356e827b358e5e6951a1ea80686d848e3129b..542a55cdb830a07f55308c501476969b8ba3ed0c 100644 --- a/src/app/app.component.ts +++ b/src/app/app.component.ts @@ -1,23 +1,24 @@ import { Component, ApplicationRef, OnInit, OnDestroy, HostListener, ViewChild, ComponentRef } from "@angular/core"; -import { Router, ActivatedRoute } from "@angular/router"; +import { Router, Event, NavigationEnd, ActivationEnd } from "@angular/router"; -import { Observer, jalhydDateRev } from "jalhyd"; +import { Observer, jalhydDateRev, CalculatorType } from "jalhyd"; import { environment } from "../environments/environment"; -import { InternationalisationService } from "./services/internationalisation/internationalisation.service"; +import { I18nService } from "./services/internationalisation/internationalisation.service"; import { ErrorService } from "./services/error/error.service"; import { FormulaireService } from "./services/formulaire/formulaire.service"; import { FormulaireDefinition } from "./formulaire/definition/form-definition"; import { ServiceFactory } from "./services/service-factory"; import { ParamService } from "./services/param/param.service"; -import { ApplicationSetupService } from "./services/app-setup/app-setup.service"; import { HttpService } from "./services/http/http.service"; -import { LoadCalcDialogAnchorDirective } from "./components/load-calculator/load-calculator-anchor.directive"; -import { LoadCalculatorComponent } from "./components/load-calculator/load-calculator.component"; -import { SaveCalcDialogAnchorDirective } from "./components/save-calculator/save-calculator-anchor.directive"; -import { SaveCalculatorComponent } from "./components/save-calculator/save-calculator.component"; +import { ApplicationSetupService } from "./services/app-setup/app-setup.service"; import { nghydDateRev } from "../date_revision"; +import { MatSidenav, MatToolbar, MatDialog } from "@angular/material"; +import { DialogConfirmEmptySessionComponent } from "./components/dialog-confirm-empty-session/dialog-confirm-empty-session.component"; +import { DialogLoadSessionComponent } from "./components/dialog-load-session/dialog-load-session.component"; +import { DialogSaveSessionComponent } from "./components/dialog-save-session/dialog-save-session.component"; + @Component({ selector: "nghyd-app", @@ -26,24 +27,31 @@ import { nghydDateRev } from "../date_revision"; providers: [ErrorService] }) export class AppComponent implements OnInit, OnDestroy, Observer { + + @ViewChild("sidenav") + public sidenav: MatSidenav; + + @ViewChild("navbar") + public navbar: MatToolbar; + + /** current calculator, inferred from _currentFormId by setActiveCalc() (used for navbar menu) */ + public currentCalc: any; + /** - * liste des calculettes. Forme des objets : - * "title": nom de la calculette + * liste des modules de calcul. Forme des objets : + * "title": nom du module de calcul * "uid": id unique du formulaire */ private _calculators: any[] = []; /** * id du formulaire courant - * on utilise pas directement FormulaireService.currentFormId pour éviter l'erreur ExpressionChangedAfterItHasBeenCheckedError + * on utilise pas directement FormulaireService.currentFormId pour éviter l'erreur + * ExpressionChangedAfterItHasBeenCheckedError */ - private _currentFormId: number; - - @ViewChild(LoadCalcDialogAnchorDirective) - private appLoadCalcDialogAnchor: LoadCalcDialogAnchorDirective; + private _currentFormId: string; - @ViewChild(SaveCalcDialogAnchorDirective) - private appSaveCalcDialogAnchor: SaveCalcDialogAnchorDirective; + private _innerWidth: number; /** * composant actuellement affiché par l'élément <router-outlet> @@ -51,33 +59,48 @@ export class AppComponent implements OnInit, OnDestroy, Observer { private _routerCurrentComponent: Component; constructor( - private intlService: InternationalisationService, + private intlService: I18nService, private paramService: ParamService, private appSetupService: ApplicationSetupService, private appRef: ApplicationRef, private errorService: ErrorService, private router: Router, private formulaireService: FormulaireService, - private httpService: HttpService + private httpService: HttpService, + private confirmEmptySessionDialog: MatDialog, + private saveSessionDialog: MatDialog, + private loadSessionDialog: MatDialog ) { + ServiceFactory.instance.httpService = httpService; ServiceFactory.instance.applicationSetupService = appSetupService; ServiceFactory.instance.paramService = paramService; - ServiceFactory.instance.internationalisationService = intlService; + ServiceFactory.instance.i18nService = intlService; ServiceFactory.instance.formulaireService = formulaireService; - ServiceFactory.instance.httpService = httpService; - } - // process.on('unhandledRejection', (reason, p) => { - // console.log('Unhandled Rejection at: Promise', p, 'reason:', reason); - // // Stack Trace - // console.log(reason.stack); - // }); + this.router.events.subscribe((event: Event) => { + // close side navigation when clicking a calculator tab + if (event instanceof NavigationEnd) { + this.sidenav.close(); + } + // [de]activate calc tabs depending on loaded route + if (event instanceof ActivationEnd) { + const path = event.snapshot.url[0].path; + if (path === "calculator") { + const calcUid = event.snapshot.params.uid; + this.setActiveCalc(calcUid); + } else { + this.setActiveCalc(null); + } + } + }); + } ngOnInit() { this.intlService.addObserver(this); - this.intlService.setLocale("fr"); + this.intlService.setLocale(this.appSetupService.language); this.formulaireService.addObserver(this); this.subscribeErrorService(); + this._innerWidth = window.innerWidth; } ngOnDestroy() { @@ -85,6 +108,12 @@ export class AppComponent implements OnInit, OnDestroy, Observer { this.formulaireService.removeObserver(this); } + @HostListener("window:resize", ["$event"]) + onResize(event) { + // keep track of window size for navbar tabs arrangement + this._innerWidth = window.innerWidth; + } + public get uitextSidenavNewCalc() { return this.intlService.localizeText("INFO_MENU_NOUVELLE_CALC"); } @@ -97,14 +126,68 @@ export class AppComponent implements OnInit, OnDestroy, Observer { return this.intlService.localizeText("INFO_MENU_LOAD_SESSION_TITLE"); } + public get uitextSidenavSaveSession() { + return this.intlService.localizeText("INFO_MENU_SAVE_SESSION_TITLE"); + } + + public get uitextSidenavEmptySession() { + return this.intlService.localizeText("INFO_MENU_EMPTY_SESSION_TITLE"); + } + public get uitextSidenavHelp() { return this.intlService.localizeText("INFO_MENU_HELP_TITLE"); } + public get uitextSelectCalc() { + return this.intlService.localizeText("INFO_MENU_SELECT_CALC"); + } + + public getCalculatorLabel(t: CalculatorType) { + return this.formulaireService.getLocalisedTitleFromCalculatorType(t); + } + public get calculators() { return this._calculators; } + public get currentFormId() { + return this._currentFormId; + } + + public setActiveCalc(uid: string) { + this._calculators.forEach((calc) => { + calc.active = (calc.uid === uid); + }); + // mark current calc for navbar menu + const index = this.getCalculatorIndexFromId(uid); + this.currentCalc = this._calculators[index]; + } + + /** + * Returns true if sum of open calculator tabs witdh is lower than navbar + * available space (ie. if navbar is not overflowing), false otherwise + */ + public get tabsFitInNavbar() { + // manual breakpoints + // @WARNING keep in sync with .calculator-buttons sizes in app.component.scss + let tabsLimit = 0; + if (this._innerWidth > 480) { + tabsLimit = 3; + } + if (this._innerWidth > 640) { + tabsLimit = 4; + } + if (this._innerWidth > 800) { + tabsLimit = 6; + } + /*if (this._innerWidth > 1200) { + tabsLimit = 8; + }*/ + + const fits = this._calculators.length <= tabsLimit; + return fits; + } + /** * abonnement au service d'erreurs */ @@ -117,12 +200,10 @@ export class AppComponent implements OnInit, OnDestroy, Observer { } private updateLocale() { - const tag = this.intlService.currentLanguage.tag; + const tag = this.appSetupService.language; document["locale"] = tag; + this.intlService.setLocale(tag); - // location.reload(true); - // this.cdRef.markForCheck(); - // this.cdRef.detectChanges(); this.appRef.tick(); } @@ -141,11 +222,13 @@ export class AppComponent implements OnInit, OnDestroy, Observer { } else if (sender instanceof FormulaireService) { switch (data["action"]) { case "createForm": + // add newly created form to calculators list const f: FormulaireDefinition = data["form"]; this._calculators.push( { "title": f.calculatorName, - "uid": String(f.uid) + "type": f.calculatorType, + "uid": f.uid } ); @@ -158,13 +241,7 @@ export class AppComponent implements OnInit, OnDestroy, Observer { break; case "currentFormChanged": - /* - utilisation de setTimeout() pour éviter le message console ExpressionChangedAfterItHasBeenCheckedError - relatif au getter getHighlightClass() (qui change de valeur quand le formulaire courant change) - */ - setTimeout(() => { - this._currentFormId = data["formId"]; - }, 1); + this._currentFormId = data["formId"]; break; case "saveForm": @@ -176,7 +253,7 @@ export class AppComponent implements OnInit, OnDestroy, Observer { this.closeCalculator(form); break; } - } else if (sender instanceof InternationalisationService) { + } else if (sender instanceof I18nService) { this.updateLocale(); } else if (sender instanceof FormulaireDefinition) { switch (data["action"]) { @@ -203,46 +280,10 @@ export class AppComponent implements OnInit, OnDestroy, Observer { this._calculators[formIndex]["title"] = title; } - /** - * sauvegarde du/des formulaires - * @param form formulaire à sélectionner par défaut dans la liste - */ - private saveForm(form: FormulaireDefinition) { - // création du dialogue de sélection des formulaires à sauver - const compRef: ComponentRef<SaveCalculatorComponent> = this.appSaveCalcDialogAnchor.createDialog(); - - // création de la liste des formulaires - const list = []; - for (const c of this._calculators) { - const uid = c["uid"]; - list.push({ - "selected": uid === form.uid, - "title": c["title"], - "uid": uid - }); - } - - // passage de la liste, récupération d'une Promise pour traiter le résultat - const prom: Promise<any[]> = compRef.instance.run(list); - prom.then(innerList => { - let name = compRef.instance.filename; - - // ajout extension ".json" - const re = /.+\.json/; - const match = re.exec(name.toLowerCase()); - if (match === null) { - name = name + ".json"; - } - - this.saveSession(innerList, name); - }).catch(err => { }); - } - private saveSession(calcList: any[], filename) { const elems = []; for (const c of calcList) { if (c.selected) { - console.log(c.title); const form: FormulaireDefinition = this.formulaireService.getFormulaireFromId(c.uid); elems.push(form.JSONserialise()); } @@ -251,23 +292,25 @@ export class AppComponent implements OnInit, OnDestroy, Observer { this.formulaireService.saveSession(session, filename); } + /** + * Supprime un module de calcul **de l'interface** + * ATTENTION, ne supprime pas le module de calcul en mémoire ! + * Pour cela, utiliser FormulaireService.requestCloseForm(form.uid); + * @param form module de calcul à fermer + */ private closeCalculator(form: FormulaireDefinition) { const formId: string = form.uid; // désabonnement en tant qu'observateur - form.removeObserver(this); - - // recherche de la calculette correspondante à formId - + // recherche du module de calcul correspondant à formId const closedIndex = this.getCalculatorIndexFromId(formId); /* - * détermination de la nouvelle calculette à afficher : - * - celle après celle supprimée - * - ou celle avant celle supprimée si on supprime la dernière + * détermination du nouveau module de calcul à afficher : + * - celui après celui supprimé + * - ou celui avant celui supprimé si on supprime le dernier */ - let newId = null; const l = this._calculators.length; if (l > 1) { @@ -298,8 +341,9 @@ export class AppComponent implements OnInit, OnDestroy, Observer { this.router.navigate(["/list"]); } - private toCalc(id: number) { + private toCalc(id: string) { this.router.navigate(["/calculator", id]); + this.setActiveCalc(id); } /** @@ -309,38 +353,35 @@ export class AppComponent implements OnInit, OnDestroy, Observer { this._routerCurrentComponent = a; } - private getHighlightClass(uid: number) { - return uid === this._currentFormId ? "blue darken-2" : ""; - } - - // flag d'affichage des repères des colonnes Bootstrap : uniquement en mode dev - // cf. src/environments/*, ng build --env=<mode> (par ex : ng build --env=prod) - public get ruler(): boolean { - // return !environment.production; - return false; - } - - // sidenav - - public openNav() { - document.getElementById("mySidenav").style.width = "300px"; - } - - public closeNav() { - document.getElementById("mySidenav").style.width = "0"; + /** + * restarts a fresh session by closing all calculators + */ + public emptySession() { + const dialogRef = this.confirmEmptySessionDialog.open( + DialogConfirmEmptySessionComponent, + { disableClose: true } + ); + dialogRef.afterClosed().subscribe(result => { + if (result) { + for (const c of this._calculators) { + const form = this.formulaireService.getFormulaireFromId(c.uid); + this.formulaireService.requestCloseForm(form.uid); + } + } + }); } public loadSession() { - this.closeNav(); - // création du dialogue de sélection des formulaires à sauver - const compRef: ComponentRef<LoadCalculatorComponent> = this.appLoadCalcDialogAnchor.createDialog(); - - const prom: Promise<any[]> = compRef.instance.run(); - prom.then(list => { - this.formulaireService.loadSession(compRef.instance.selectedFile, compRef.instance.calculators); - compRef.destroy(); - }).catch(err => { }); + const dialogRef = this.loadSessionDialog.open( + DialogLoadSessionComponent, + { disableClose: true } + ); + dialogRef.afterClosed().subscribe(result => { + if (result) { + this.formulaireService.loadSession(result.file, result.calculators); + } + }); } public getDateRevision(): string[] { @@ -348,6 +389,47 @@ export class AppComponent implements OnInit, OnDestroy, Observer { return dr; } + /** + * sauvegarde du/des formulaires + * @param form formulaire à sélectionner par défaut dans la liste + */ + public saveForm(form?: FormulaireDefinition) { + // liste des formulaires + const list = []; + for (const c of this._calculators) { + const uid = c["uid"]; + list.push({ + "selected": form ? (uid === form.uid) : true, + "title": c["title"], + "uid": uid + }); + } + // dialogue de sélection des formulaires à sauver + const dialogRef = this.saveSessionDialog.open( + DialogSaveSessionComponent, + { + data: { + calculators: list + }, + disableClose: true + } + ); + dialogRef.afterClosed().subscribe(result => { + if (result) { + let name = result.filename; + + // ajout extension ".json" + const re = /.+\.json/; + const match = re.exec(name.toLowerCase()); + if (match === null) { + name = name + ".json"; + } + + this.saveSession(result.calculators, name); + } + }); + } + /** * détection de la fermeture de la page/navigateur et demande de confirmation */ diff --git a/src/app/app.module.ts b/src/app/app.module.ts index 0e611c9086bcec30853fd7b5ca3d525ccef61250..48eade02f7b3d44b7c105bf62c7aa985ad984597 100644 --- a/src/app/app.module.ts +++ b/src/app/app.module.ts @@ -1,28 +1,53 @@ import { BrowserModule } from "@angular/platform-browser"; import { BrowserAnimationsModule } from "@angular/platform-browser/animations"; import { NgModule, NO_ERRORS_SCHEMA } from "@angular/core"; -import { MDBBootstrapModule } from "angular-bootstrap-md"; + +import { + MatButtonModule, + MatCheckboxModule, + MatIconModule, + MatSelectModule, + MatTabsModule, + MatSidenavModule, + MatToolbarModule, + MatMenuModule, + MatDialogModule, + MatFormFieldModule, + MatInputModule, + MatListModule, + MatCardModule, + MatTableModule, + ErrorStateMatcher, + MatButtonToggleModule +} from "@angular/material"; +import { MaterialFileInputModule } from "ngx-material-file-input"; + +import { FlexLayoutModule } from "@angular/flex-layout"; +import { + CustomBreakPointsProvider, + FlexGtXxsShowHideDirective, + FlexXxsShowHideDirective, + FlexLtXsShowHideDirective +} from "./directives/flex-xxs.directive"; + import { HttpClientModule } from "@angular/common/http"; -import { FormsModule } from "@angular/forms"; // <-- NgModel lives here +import { FormsModule, ReactiveFormsModule } from "@angular/forms"; // <-- NgModel lives here import { ChartModule } from "angular2-chartjs"; import { RouterModule, Routes } from "@angular/router"; import { NgxMdModule } from "ngx-md"; import { FormulaireService } from "./services/formulaire/formulaire.service"; import { ParamService } from "./services/param/param.service"; -import { InternationalisationService } from "./services/internationalisation/internationalisation.service"; +import { I18nService } from "./services/internationalisation/internationalisation.service"; import { HttpService } from "./services/http/http.service"; import { ApplicationSetupService } from "./services/app-setup/app-setup.service"; + import { AppComponent } from "./app.component"; import { NgParamInputComponent } from "./components/ngparam-input/ngparam-input.component"; import { FieldSetComponent } from "./components/field-set/field-set.component"; import { FieldsetContainerComponent } from "./components/fieldset-container/fieldset-container.component"; import { ParamFieldLineComponent } from "./components/param-field-line/param-field-line.component"; -import { NgParamMinComponent } from "./components/param-values/ngparam-min.component"; -import { NgParamMaxComponent } from "./components/param-values/ngparam-max.component"; -import { NgParamStepComponent } from "./components/param-values/ngparam-step.component"; import { ParamValuesComponent } from "./components/param-values/param-values.component"; -import { ValueListComponent } from "./components/param-values/value-list.component"; import { SelectFieldLineComponent } from "./components/select-field-line/select-field-line.component"; import { CheckFieldLineComponent } from "./components/check-field-line/check-field-line.component"; import { CalculatorResultsComponent } from "./components/calculator-results/calculator-results.component"; @@ -41,16 +66,21 @@ import { ApplicationSetupComponent } from "./components/app-setup/app-setup.comp import { BaseParamInputComponent } from "./components/base-param-input/base-param-input.component"; import { FixedResultsComponent } from "./components/fixedvar-results/fixed-results.component"; import { VarResultsComponent } from "./components/fixedvar-results/var-results.component"; -import { ResultElementBaseComponent } from "./components/result-element/result-element-base.component"; -import { HorizontalResultElementComponent } from "./components/result-element/horizontal-result-element.component"; -import { VerticalResultElementComponent } from "./components/result-element/vertical-result-element.component"; import { LogEntryComponent } from "./components/log-entry/log-entry.component"; -import { LoadCalculatorComponent } from "./components/load-calculator/load-calculator.component"; -import { LoadCalcDialogAnchorDirective } from "./components/load-calculator/load-calculator-anchor.directive"; -import { SaveCalculatorComponent } from "./components/save-calculator/save-calculator.component"; -import { SaveCalcDialogAnchorDirective } from "./components/save-calculator/save-calculator-anchor.directive"; import { ParamLinkComponent } from "./components/param-link/param-link.component"; +import { DialogConfirmEmptySessionComponent } from "./components/dialog-confirm-empty-session/dialog-confirm-empty-session.component"; +import { DialogConfirmCloseCalcComponent } from "./components/dialog-confirm-close-calc/dialog-confirm-close-calc.component"; +import { DialogEditParamComputedComponent } from "./components/dialog-edit-param-computed/dialog-edit-param-computed.component"; +import { DialogEditParamValuesComponent } from "./components/dialog-edit-param-values/dialog-edit-param-values.component"; +import { DialogLoadSessionComponent } from "./components/dialog-load-session/dialog-load-session.component"; +import { DialogSaveSessionComponent } from "./components/dialog-save-session/dialog-save-session.component"; + +import { JalhydAsyncModelValidationDirective } from "./directives/jalhyd-async-model-validation.directive"; +import { JalhydModelValidationDirective } from "./directives/jalhyd-model-validation.directive"; +import { ImmediateErrorStateMatcher } from "./formulaire/immediate-error-state-matcher"; +import { ParamComputedComponent } from "./components/param-computed/param-computed.component"; + const appRoutes: Routes = [ { path: "list", component: CalculatorListComponent }, { path: "calculator/:uid", component: GenericCalculatorComponent }, @@ -60,51 +90,100 @@ const appRoutes: Routes = [ @NgModule({ imports: [ + FormsModule, // <-- import the FormsModule before binding with [(ngModel)] + ReactiveFormsModule, + BrowserAnimationsModule, + BrowserModule, + ChartModule, + HttpClientModule, + FlexLayoutModule, + MatButtonModule, + MatButtonToggleModule, + MatCardModule, + MatCheckboxModule, + MatDialogModule, + MaterialFileInputModule, + MatFormFieldModule, + MatIconModule, + MatInputModule, + MatListModule, + MatMenuModule, + MatSelectModule, + MatSidenavModule, + MatTableModule, + MatTabsModule, + MatToolbarModule, + NgxMdModule.forRoot(), RouterModule.forRoot( appRoutes, { useHash: true, // prevents reloading whole app when typing url in browser's navigation bar enableTracing: false // debugging purposes only } - ), - BrowserModule, - NgxMdModule.forRoot(), - BrowserAnimationsModule, - MDBBootstrapModule.forRoot(), - FormsModule, // <-- import the FormsModule before binding with [(ngModel)] - HttpClientModule, - // MdInputModule, - // MdDialogModule, - ChartModule + ) ], declarations: [ // composants, pipes et directives AppComponent, - NgParamInputComponent, - FieldSetComponent, FieldsetContainerComponent, - ParamFieldLineComponent, NgParamMinComponent, NgParamMaxComponent, NgParamStepComponent, - ParamValuesComponent, ValueListComponent, - SelectFieldLineComponent, CheckFieldLineComponent, - LogComponent, LogEntryComponent, - CalculatorListComponent, ApplicationSetupComponent, BaseParamInputComponent, - GenericCalculatorComponent, CalculatorNameComponent, - // AlertDialog, - CalculatorResultsComponent, FixedVarResultsComponent, SectionResultsComponent, RemousResultsComponent, - ResultsGraphComponent, GraphTypeSelectComponent, - CalcCanvasComponent, SectionCanvasComponent, - ResultElementBaseComponent, HorizontalResultElementComponent, VerticalResultElementComponent, - FixedResultsComponent, VarResultsComponent, - LoadCalculatorComponent, LoadCalcDialogAnchorDirective, - SaveCalculatorComponent, SaveCalcDialogAnchorDirective, - ParamLinkComponent + CalcCanvasComponent, + CalculatorListComponent, + CalculatorNameComponent, + CalculatorResultsComponent, + CheckFieldLineComponent, + DialogConfirmCloseCalcComponent, + DialogConfirmEmptySessionComponent, + DialogEditParamComputedComponent, + DialogEditParamValuesComponent, + DialogLoadSessionComponent, + DialogSaveSessionComponent, + FieldSetComponent, + FieldsetContainerComponent, + FixedResultsComponent, + FixedVarResultsComponent, + FlexGtXxsShowHideDirective, + FlexLtXsShowHideDirective, + FlexXxsShowHideDirective, + GenericCalculatorComponent, + GraphTypeSelectComponent, + JalhydAsyncModelValidationDirective, + JalhydModelValidationDirective, + LogComponent, + LogEntryComponent, + NgParamInputComponent, + ParamComputedComponent, + ParamFieldLineComponent, + ParamLinkComponent, + ParamValuesComponent, + RemousResultsComponent, + ResultsGraphComponent, + SectionCanvasComponent, + SectionResultsComponent, + SelectFieldLineComponent, + VarResultsComponent + ], + entryComponents: [ + DialogConfirmCloseCalcComponent, + DialogConfirmEmptySessionComponent, + DialogEditParamComputedComponent, + DialogEditParamValuesComponent, + DialogSaveSessionComponent, + DialogLoadSessionComponent ], - // entryComponents: [AlertDialog], - entryComponents: [LoadCalculatorComponent, SaveCalculatorComponent], providers: [ // services - ParamService, InternationalisationService, HttpService, FormulaireService, ApplicationSetupService + ApplicationSetupService, + CustomBreakPointsProvider, + FormulaireService, + HttpService, + I18nService, + ParamService, + { + provide: ErrorStateMatcher, + useClass: ImmediateErrorStateMatcher + } ], - schemas: [NO_ERRORS_SCHEMA], - bootstrap: [AppComponent] + schemas: [ NO_ERRORS_SCHEMA ], + bootstrap: [ AppComponent ] }) + export class AppModule { } diff --git a/src/app/components/alert-dialog/alert-dialog.component.ts b/src/app/components/alert-dialog/alert-dialog.component.ts deleted file mode 100644 index 82681813a99572f5c7ec02ab8cf90690bed70bae..0000000000000000000000000000000000000000 --- a/src/app/components/alert-dialog/alert-dialog.component.ts +++ /dev/null @@ -1,33 +0,0 @@ -// import { Component, Input } from '@angular/core'; -// import { MdDialog } from '@angular/material'; - -// @Component({ -// selector: 'dialog1', -// template: ` -// <h2>{{_text}}</h2> -// `, -// providers: [MdDialog] -// }) -// export class AlertDialog { -// /** -// * text input attribute -// */ -// private _text: string; - -// // constructor(private _dialog: MdDialog) { } -// // public get dialog() { -// // return this._dialog; -// // } - -// @Input() -// public set text(s: string) { -// this._text = s; -// } - -// // public run(t: string) { -// // let dialogRef = this._dialog.open(AlertDialog); -// // // let ad: AlertDialog = dialogRef.componentInstance; -// // // ad.text = "azeaze"; -// // this._text = t; -// // } -// } diff --git a/src/app/components/app-setup/app-setup.component.html b/src/app/components/app-setup/app-setup.component.html index f87d18777f7abf6238b39a1069deb4caa0b96c51..bd04a62caf6f8cb32150ac8f2472d7f5848b24c3 100644 --- a/src/app/components/app-setup/app-setup.component.html +++ b/src/app/components/app-setup/app-setup.component.html @@ -1,48 +1,76 @@ -<div class="container-fluid"> - <div class="row"> - <div class="col-4 mx-auto"> - <h1>{{ uitextTitle }}</h1> - <br/> - </div> - </div> - - <!-- précision d'affichage --> - <div class="row"> - <div class="col-4 mx-auto"> - <base-param-input #displayAccuracy title="{{uitextDisplayAccuracy}}"></base-param-input> - </div> - </div> - - <!-- précision de calcul --> - <div class="row"> - <div class="col-4 mx-auto"> - <base-param-input #computeAccuracy title="{{uitextComputeAccuracy}}"></base-param-input> - </div> - </div> - - <!-- nombre d'itérations max Newton --> - <div class="row"> - <div class="col-4 mx-auto"> - <base-param-input #newtonMaxIter title="{{uitextNewtonMaxIteration}}"></base-param-input> - </div> - </div> - - <!-- langue --> - - <div class="row"> - <div class="col-4 mx-auto"> - <div class="btn-group" dropdown> - <button dropdownToggle mdbRippleRadius type="button" class="btn btn-primary dropdown-toggle"> - Language ({{ currentLanguageLabel }}) - <span class="caret"></span> - </button> - <ul *dropdownMenu class="dropdown-menu" role="menu"> - <li role="menuitem" *ngFor="let l of intlService.languages"> - <a class="dropdown-item" (click)="selectLang(l.code)">{{ l.label }}</a> - </li> - </ul> - </div> - </div> - </div> - -</div> \ No newline at end of file + +<div class="container" fxLayout="row" fxLayoutAlign="center space-evenly"> + <mat-card id="app-setup"> + + <mat-card-header> + <mat-card-title> + <h1>{{ uitextTitle }}</h1> + </mat-card-title> + </mat-card-header> + + <mat-card-content> + <!-- template-driven form --> + <form> + + <!-- précision d'affichage --> + <mat-form-field data-testclass="numeric-input"> + <input matInput [placeholder]="uitextDisplayAccuracy" #dp="ngModel" name="dp" inputmode="numeric" + [ngModel]="displayPrec.value" (ngModelChange)="!dp.invalid ? displayPrec.setValue($event): null" + pattern="^-?([0-9]*\.)?([0-9]+[Ee]-?)?[0-9]+$" required [appJalhydModelValidation]="displayPrec"> + + <mat-error *ngIf="dp.invalid && (dp.dirty || dp.touched)"> + <div *ngIf="dp.errors.required || dp.errors.pattern"> + {{ uitextMustBeANumber }} + </div> + <div *ngIf="! dp.errors.required && dp.errors.jalhydModel"> + {{ dp.errors.jalhydModel.message }} + </div> + </mat-error> + </mat-form-field> + + <!-- précision de calcul --> + <mat-form-field data-testclass="numeric-input"> + <input matInput [placeholder]="uitextComputeAccuracy" #cp="ngModel" name="cp" inputmode="numeric" + [ngModel]="computePrec.value" (ngModelChange)="!cp.invalid ? computePrec.setValue($event): null" + pattern="^-?([0-9]*\.)?([0-9]+[Ee]-?)?[0-9]+$" required [appJalhydModelValidation]="computePrec"> + + <mat-error *ngIf="cp.invalid"> + <div *ngIf="cp.errors.required || cp.errors.pattern"> + {{ uitextMustBeANumber }} + </div> + <div *ngIf="! cp.errors.required && cp.errors.jalhydModel"> + {{ cp.errors.jalhydModel.message }} + </div> + </mat-error> + </mat-form-field> + + <!-- nombre d'itérations max Newton --> + <mat-form-field data-testclass="numeric-input"> + <input matInput [placeholder]="uitextNewtonMaxIteration" #nmi="ngModel" name="nmi" inputmode="numeric" + [ngModel]="newtonMaxIter.value" (ngModelChange)="!nmi.invalid ? newtonMaxIter.setValue($event): null" + pattern="^-?([0-9]*\.)?([0-9]+[Ee]-?)?[0-9]+$" required [appJalhydModelValidation]="newtonMaxIter"> + + <mat-error *ngIf="nmi.invalid && (nmi.dirty || nmi.touched)"> + <div *ngIf="nmi.errors.required || nmi.errors.pattern"> + {{ uitextMustBeANumber }} + </div> + <div *ngIf="! nmi.errors.required && nmi.errors.jalhydModel"> + {{ nmi.errors.jalhydModel.message }} + </div> + </mat-error> + </mat-form-field> + + <!-- langue --> + <mat-form-field> + <mat-select placeholder="Language" [(value)]="currentLanguageCode" data-testid="language-select"> + <mat-option *ngFor="let l of availableLanguages" [value]="l.code"> + {{ l.label }} + </mat-option> + </mat-select> + </mat-form-field> + + </form> + </mat-card-content> + + </mat-card> +</div> diff --git a/src/app/components/app-setup/app-setup.component.scss b/src/app/components/app-setup/app-setup.component.scss new file mode 100644 index 0000000000000000000000000000000000000000..f21f04ee05569edae10aee054c629b74b625c87c --- /dev/null +++ b/src/app/components/app-setup/app-setup.component.scss @@ -0,0 +1,50 @@ +#app-setup { + width: 360px; + padding: 3em; + + mat-card-header { + margin-bottom: 2em; + min-height: 110px; + + // @WARNING ::ng-deep est déprécié, mais y a rien d'autre pour + // l'instant (en attente de normalisation par le W3C) + ::ng-deep .mat-card-header-text { + margin: 0; + } + } + + mat-form-field { + margin-top: 1.2em; + display: block; + + ::ng-deep .mat-form-field-label { + font-size: 1.2em; + line-height: 1.4em; + margin-top: -2px; + + &.mat-form-field-empty { + font-size: 1em; + } + + .mat-form-field-required-marker { + display: none; // all fields are mandatory anyway + } + } + } + + mat-select { + + ::ng-deep .mat-select-value { + > span { + > span { + line-height: 1.3em; + } + } + } + } + + mat-error { + font-weight: 500; + font-size: 1.2em; + } +} diff --git a/src/app/components/app-setup/app-setup.component.ts b/src/app/components/app-setup/app-setup.component.ts index 79973d1dd788b3c7b86a327ca0447a6274cb8493..fc05bd484e5a30caefb9863824b51d4046f4c3fb 100644 --- a/src/app/components/app-setup/app-setup.component.ts +++ b/src/app/components/app-setup/app-setup.component.ts @@ -1,54 +1,52 @@ -import { Component, ViewChild, OnInit } from "@angular/core"; +import { Component, OnInit } from "@angular/core"; import { ParamDomainValue, Observer } from "jalhyd"; import { ApplicationSetupService } from "../../services/app-setup/app-setup.service"; -import { InternationalisationService, LanguageCode } from "../../services/internationalisation/internationalisation.service"; -import { NgBaseParam, BaseParamInputComponent } from "../base-param-input/base-param-input.component"; +import { I18nService, LanguageCode } from "../../services/internationalisation/internationalisation.service"; +import { NgBaseParam } from "../base-param-input/base-param-input.component"; import { BaseComponent } from "../base/base.component"; +import { ErrorStateMatcher } from "@angular/material"; + @Component({ selector: "setup", - templateUrl: "./app-setup.component.html" + templateUrl: "./app-setup.component.html", + styleUrls: ["./app-setup.component.scss"] }) export class ApplicationSetupComponent extends BaseComponent implements Observer, OnInit { - /** - * précision d'affichage - */ - private _displayPrec: NgBaseParam; - - /** - * précision de calcul - */ - private _computePrec: NgBaseParam; - /** - * nombre d'iterations max Newton - */ - private _newtonMaxIter: NgBaseParam; + /** précision d'affichage */ + public displayPrec: NgBaseParam; - @ViewChild("displayAccuracy") - private _displayAccuracyComponent: BaseParamInputComponent; + /** précision de calcul */ + public computePrec: NgBaseParam; - @ViewChild("computeAccuracy") - private _computeAccuracyComponent: BaseParamInputComponent; + /** nombre d'iterations max Newton */ + public newtonMaxIter: NgBaseParam; - @ViewChild("newtonMaxIter") - private _newtonMaxIterComponent: BaseParamInputComponent; + public matcher: ErrorStateMatcher; constructor( private appSetupService: ApplicationSetupService, - private intlService: InternationalisationService + private intlService: I18nService ) { super(); + this.appSetupService.addObserver(this); + } + + public get availableLanguages() { + return this.intlService.languages; } - public get currentLanguageLabel(): string { - return this.intlService.currentLanguage.label; + public get currentLanguageCode() { + return this.intlService.currentLanguage.code; } - private selectLang(lc: LanguageCode) { + public set currentLanguageCode(lc: LanguageCode) { this.intlService.setLocale(lc); + // keep language in sync in app-wide parameters service + this.appSetupService.language = this.intlService.currentLanguage.tag; } public get uitextTitle(): string { @@ -67,21 +65,22 @@ export class ApplicationSetupComponent extends BaseComponent implements Observer return this.intlService.localizeText("INFO_SETUP_NEWTON_MAX_ITER"); } + public get uitextMustBeANumber(): string { + return this.intlService.localizeText("ERROR_PARAM_MUST_BE_A_NUMBER"); + } + private init() { // modèle du composant BaseParamInputComponent de précision d'affichage - this._displayPrec = new NgBaseParam("dp", ParamDomainValue.POS, this.appSetupService.displayPrecision); - this._displayPrec.addObserver(this); - this._displayAccuracyComponent.model = this._displayPrec; + this.displayPrec = new NgBaseParam("dp", ParamDomainValue.POS, this.appSetupService.displayPrecision); + this.displayPrec.addObserver(this); // modèle du composant BaseParamInputComponent de précision de calcul - this._computePrec = new NgBaseParam("cp", ParamDomainValue.POS, this.appSetupService.computePrecision); - this._computePrec.addObserver(this); - this._computeAccuracyComponent.model = this._computePrec; + this.computePrec = new NgBaseParam("cp", ParamDomainValue.POS, this.appSetupService.computePrecision); + this.computePrec.addObserver(this); // modèle du composant BaseParamInputComponent du max d'itérations pour Newton - this._newtonMaxIter = new NgBaseParam("nmi", ParamDomainValue.POS, this.appSetupService.newtonMaxIter); - this._newtonMaxIter.addObserver(this); - this._newtonMaxIterComponent.model = this._newtonMaxIter; + this.newtonMaxIter = new NgBaseParam("nmi", ParamDomainValue.POS, this.appSetupService.newtonMaxIterations); + this.newtonMaxIter.addObserver(this); } ngOnInit() { @@ -90,19 +89,26 @@ export class ApplicationSetupComponent extends BaseComponent implements Observer // interface Observer public update(sender: any, data: any): void { - const p: NgBaseParam = sender; - switch (p.symbol) { - case "dp": - this.appSetupService.displayPrecision = +data; - break; - - case "cp": - this.appSetupService.computePrecision = +data; - break; - - case "nmi": - this.appSetupService.newtonMaxIter = +data; - break; + if (sender instanceof NgBaseParam) { + // someone typed a new value in the app-setup form + const p: NgBaseParam = sender; + switch (p.symbol) { + case "dp": + this.appSetupService.displayPrecision = +data; + break; + + case "cp": + this.appSetupService.computePrecision = +data; + break; + + case "nmi": + this.appSetupService.newtonMaxIterations = +data; + break; + } + } + if (sender instanceof ApplicationSetupService) { + // if app starts on /setup page, wait for config file to be (re)loaded by app-setup service + this.init(); } } } diff --git a/src/app/components/base-param-input/base-param-input.component.ts b/src/app/components/base-param-input/base-param-input.component.ts index 2a3588fc0a1f882b17b3d5a4579568a1ddd579de..fb65a845cc5c4c2d59a99968641c67d9e9fb5486 100644 --- a/src/app/components/base-param-input/base-param-input.component.ts +++ b/src/app/components/base-param-input/base-param-input.component.ts @@ -4,8 +4,9 @@ import { Component, ChangeDetectorRef } from "@angular/core"; import { Message, ParamDefinition, ParamDomain, ParamDomainValue, Observable, isNumeric } from "jalhyd"; -import { InternationalisationService } from "../../services/internationalisation/internationalisation.service"; +import { I18nService } from "../../services/internationalisation/internationalisation.service"; import { GenericInputComponent } from "../generic-input/generic-input.component"; +import { ServiceFactory } from "../../services/service-factory"; export class NgBaseParam extends Observable { private _param: ParamDefinition; @@ -35,6 +36,38 @@ export class NgBaseParam extends Observable { this._param.setValue(val); this.notifyObservers(val); } + + public get value() { + return this.getValue(); + } + + public set value(val: number) { + this.setValue(val); + } + + public validateModelValue(v: any): { isValid: boolean, message: string } { + let msg: string; + let valid = false; + + if (v === null || v === "") { + // NULL values are always invalid + msg = ServiceFactory.instance.i18nService.localizeText("ERROR_PARAM_NULL"); + } else { + try { + this._param.checkValue(v); + valid = true; + } catch (e) { + if (e instanceof Message) { + // @TODO ici au début le service de localisation n'a pas encore chargé ses messages… + msg = ServiceFactory.instance.i18nService.localizeMessage(e); + } else { + msg = "invalid value"; + } + } + } + + return { isValid: valid, message: msg }; + } } @Component({ @@ -42,7 +75,7 @@ export class NgBaseParam extends Observable { templateUrl: "../generic-input/generic-input.component.html", }) export class BaseParamInputComponent extends GenericInputComponent { - constructor(private intlService: InternationalisationService, cdRef: ChangeDetectorRef) { + constructor(private intlService: I18nService, cdRef: ChangeDetectorRef) { super(cdRef); } @@ -77,41 +110,6 @@ export class BaseParamInputComponent extends GenericInputComponent { } protected validateModelValue(v: any): { isValid: boolean, message: string } { - let msg; - let valid = false; - - try { - this._paramDef.checkValue(v); - valid = true; - } catch (e) { - if (e instanceof Message) { - msg = this.intlService.localizeMessage(e); - } else { - msg = "invalid value"; - } - } - - return { isValid: valid, message: msg }; - } - - protected modelToUI(v: any): string { - return String(v); - } - - protected validateUIValue(ui: string): { isValid: boolean, message: string } { - let valid = false; - let msg: string; - - if (! isNumeric(ui)) { - msg = "Veuillez entrer une valeur numérique"; - } else { - valid = true; - } - - return { isValid: valid, message: msg }; - } - - protected uiToModel(ui: string) { - return +ui; + return this._model.validateModelValue(v); } } diff --git a/src/app/components/calculator-list/calculator-list.component.css b/src/app/components/calculator-list/calculator-list.component.css deleted file mode 100644 index 61c95428bd01c0e553f853c4053569dbfaf01a98..0000000000000000000000000000000000000000 --- a/src/app/components/calculator-list/calculator-list.component.css +++ /dev/null @@ -1,12 +0,0 @@ -.full-page { - width: 100%; - height: 100%; - min-height: 100%; - background: red; - display: block; -} - -.full-height { - min-height: 100%; - height: 100%; -} diff --git a/src/app/components/calculator-list/calculator-list.component.html b/src/app/components/calculator-list/calculator-list.component.html index 7f8497ad9e951393574bbfd5ca62125eb75b7bef..925ebed1196278810f8b7be0598805d63c2730b2 100644 --- a/src/app/components/calculator-list/calculator-list.component.html +++ b/src/app/components/calculator-list/calculator-list.component.html @@ -1,10 +1,33 @@ -<div class="container-fluid"> - <div class="row"> - <div class="offset-1 col-10 mx-auto"> - <ul *ngFor="let l of items" class="list-group"> - <!-- on utilise [innerHTML] pour que les codes HTML comme soient interprétés correctement --> - <button class="list-group-item" (click)="create(l.type)" [innerHTML]="l.label"></button> - </ul> +<div class="container" fxLayout="row wrap" fxLayoutAlign="space-evenly stretch"> + + <mat-card *ngFor="let theme of items" class="compute-nodes-theme"> + + <mat-card-header> + <!-- <img mat-card-avatar src="https://s3.amazonaws.com/pix.iemoji.com/images/emoji/apple/ios-12/256/water-wave.png"> --> + <mat-card-title>{{ theme.title }}</mat-card-title> + <!-- <mat-card-subtitle>{{ theme.description }}</mat-card-subtitle> --> + </mat-card-header> + + <div class="mat-card-image-overlay-container"> + <img mat-card-image [src]="theme.image.path"> + <div class="mat-card-image-overlay"> + <div class="theme-image-credits"> + {{ theme.image.credits }} + </div> + </div> </div> - </div> -</div> \ No newline at end of file + + <mat-card-content> + <p>{{ theme.description }}</p> + </mat-card-content> + + <mat-card-actions> + <div class="container" fxLayout="column" fxLayoutAlign="left" fxLayoutGap="10px"> + <button mat-raised-button color="accent" *ngFor="let calc of theme.calculators" class="theme-calculator" + (click)="create(calc.type)" [innerHTML]="calc.label"></button> + </div> + </mat-card-actions> + + </mat-card> + +</div> diff --git a/src/app/components/calculator-list/calculator-list.component.scss b/src/app/components/calculator-list/calculator-list.component.scss new file mode 100644 index 0000000000000000000000000000000000000000..460061c0f0be33188214acbe517642f587a8193b --- /dev/null +++ b/src/app/components/calculator-list/calculator-list.component.scss @@ -0,0 +1,49 @@ +mat-card.compute-nodes-theme { + width: 300px; + margin: 1em; + + button.theme-calculator { + margin-left: 0; + margin-right: 0; + } + + .mat-card-actions:last-child { + margin-bottom: 0; // instead of -8px + } + + mat-card-header { + min-height: 80px; + } + + .mat-card-image-overlay-container { + position:relative; + + .mat-card-image { + border-radius: 5px; + } + + .mat-card-image-overlay { + position: absolute; + top: -16px; + height: 100%; + opacity: 0; + background-color: white; + // copied from mat-card-image : + width: calc(100% + 32px); + margin: 0 -16px 0 -16px; + + &:hover { + opacity: 0.7; + } + } + + .theme-image-credits { + position: absolute; + bottom: 8px; + right: 14px; + font-size: 0.9em; + font-weight: bold; + color: #444; + } + } +} diff --git a/src/app/components/calculator-list/calculator-list.component.ts b/src/app/components/calculator-list/calculator-list.component.ts index 910568f99c394980c70bc56bcafc3ebfb981664c..aef92e3e136016e8bc40b94cc47ae1f8ee66c474 100644 --- a/src/app/components/calculator-list/calculator-list.component.ts +++ b/src/app/components/calculator-list/calculator-list.component.ts @@ -5,38 +5,85 @@ import { CalculatorType, EnumEx } from "jalhyd"; import { FormulaireDefinition } from "../../formulaire/definition/form-definition"; import { ServiceFactory } from "../../services/service-factory"; -import { InternationalisationService } from "../../services/internationalisation/internationalisation.service"; +import { I18nService } from "../../services/internationalisation/internationalisation.service"; import { FormulaireParallelStructure } from "../../formulaire/definition/concrete/form-parallel-structures"; import { FieldsetContainer } from "../../formulaire/fieldset-container"; -class ListElement { - private _label: string; - - constructor(private _type: CalculatorType) { - this._label = ServiceFactory.instance.formulaireService.getLocalisedTitleFromCalculatorType(_type); - } - - public get label() { return this._label; } - public get type() { return this._type; } -} @Component({ selector: "list", templateUrl: "./calculator-list.component.html", - styleUrls: ["./calculator-list.component.css"] + styleUrls: ["./calculator-list.component.scss"] }) export class CalculatorListComponent implements OnInit { - private _items: ListElement[]; + private _items: any[]; constructor(private router: Router) { - ServiceFactory.instance.internationalisationService.addObserver(this); + ServiceFactory.instance.i18nService.addObserver(this); + ServiceFactory.instance.applicationSetupService.addObserver(this); } - private updateLocale() { + /** triggered on init */ + private loadCalculatorsThemes() { this._items = []; - for (const t of EnumEx.getValues(CalculatorType)) { - if (t !== CalculatorType.Structure) { - this._items.push(new ListElement(t)); + const unusedCalculators = EnumEx.getValues(CalculatorType); + const themes = ServiceFactory.instance.applicationSetupService.themes; + if (themes) { + // group by themes + for (const theme of themes) { + if (theme.name) { + // get theme details from config + const themeTitleKey = "INFO_THEME_" + theme.name + "_TITRE"; + const themeDescriptionKey = "INFO_THEME_" + theme.name + "_DESCRIPTION"; + const credits = ServiceFactory.instance.i18nService.localizeText("INFO_THEME_CREDITS"); + const item = { + title: ServiceFactory.instance.i18nService.localizeText(themeTitleKey), + description: ServiceFactory.instance.i18nService.localizeText(themeDescriptionKey), + image: { + path: "assets/images/themes/" + theme.image.path, + title: theme.image.title, + credits: credits + " : " + theme.image.credits + }, + calculators: [] + }; + // get calculators for this theme + for (const calcType of theme.calculators) { + item.calculators.push({ + type: calcType, + label: ServiceFactory.instance.formulaireService.getLocalisedTitleFromCalculatorType(calcType) + }); + // mark as used + const index = unusedCalculators.indexOf(calcType); + if (index > -1) { + unusedCalculators.splice(index, 1); + } + } + this._items.push(item); + } + // else special theme for unused calculators + } + // extra card for unused calculators + if (unusedCalculators.length > 0) { + const unusedThemeConfig = themes.find(i => i.name === undefined); + const unusedTheme: any = {}; + unusedTheme.calculators = []; + unusedTheme.title = ServiceFactory.instance.i18nService.localizeText("INFO_THEME_MODULES_INUTILISES_TITRE"); + unusedTheme.description = ServiceFactory.instance.i18nService.localizeText("INFO_THEME_MODULES_INUTILISES_DESCRIPTION"); + unusedTheme.image = { + path: "assets/images/themes/" + unusedThemeConfig.image.path + }; + + for (const t of unusedCalculators) { + if (t !== CalculatorType.Structure) { + unusedTheme.calculators.push({ + type: t, + label: ServiceFactory.instance.formulaireService.getLocalisedTitleFromCalculatorType(t) + }); + } + } + if (unusedTheme.calculators.length > 0) { + this._items.push(unusedTheme); + } // else the only remaining calculator was "Structure", the one we don't want } } } @@ -47,7 +94,7 @@ export class CalculatorListComponent implements OnInit { this.router.navigate(["/calculator", f.uid]); return f; }).then(f => { - // on ajoute un ouvrage après l'ouverture de la calculette "ouvrages parallèles" + // on ajoute un ouvrage après l'ouverture du module de calcul "ouvrages parallèles" if (f instanceof FormulaireParallelStructure) { for (const e of f.allFormElements) { if (e instanceof FieldsetContainer) { @@ -66,14 +113,12 @@ export class CalculatorListComponent implements OnInit { // interface Observer update(sender: any, data: any): void { - if (sender instanceof InternationalisationService) { - this.updateLocale(); + if (sender instanceof I18nService) { + this.loadCalculatorsThemes(); } } - // OnInit - ngOnInit() { - this.updateLocale(); + this.loadCalculatorsThemes(); } } diff --git a/src/app/components/calculator-results/calculator-results.component.html b/src/app/components/calculator-results/calculator-results.component.html index 21cb31f8767953bdf74bac32b4b339d931d097f0..1cf1ee86e9e06e53a464453a59f86c8d0ae54081 100644 --- a/src/app/components/calculator-results/calculator-results.component.html +++ b/src/app/components/calculator-results/calculator-results.component.html @@ -1,5 +1,5 @@ <div class="container-fluid"> - <fixedvar-results> </fixedvar-results> + <fixedvar-results></fixedvar-results> <section-results></section-results> <remous-results></remous-results> </div> diff --git a/src/app/components/dialog-confirm-close-calc/dialog-confirm-close-calc.component.html b/src/app/components/dialog-confirm-close-calc/dialog-confirm-close-calc.component.html new file mode 100644 index 0000000000000000000000000000000000000000..8018436a73c3111ceb3ee4e5888067a83e049ac4 --- /dev/null +++ b/src/app/components/dialog-confirm-close-calc/dialog-confirm-close-calc.component.html @@ -0,0 +1,12 @@ +<h1 mat-dialog-title [innerHTML]="uitextCloseCalcTitle"></h1> +<div mat-dialog-content> + <p [innerHTML]="uitextCloseCalcBody"></p> +</div> +<div mat-dialog-actions> + <button mat-raised-button color="primary" [mat-dialog-close]="false" cdkFocusInitial> + {{ uitextNo }} + </button> + <button mat-raised-button color="warn" [mat-dialog-close]="true"> + {{ uitextYes }} + </button> +</div> diff --git a/src/app/components/dialog-confirm-close-calc/dialog-confirm-close-calc.component.ts b/src/app/components/dialog-confirm-close-calc/dialog-confirm-close-calc.component.ts new file mode 100644 index 0000000000000000000000000000000000000000..e8a1f44ca145c27fef780d49aeaead3e49706aa1 --- /dev/null +++ b/src/app/components/dialog-confirm-close-calc/dialog-confirm-close-calc.component.ts @@ -0,0 +1,33 @@ +import { MatDialogRef, MAT_DIALOG_DATA } from "@angular/material"; +import { Inject, Component } from "@angular/core"; +import { I18nService } from "../../services/internationalisation/internationalisation.service"; + +@Component({ + selector: "dialog-confirm-close-calc", + templateUrl: "dialog-confirm-close-calc.component.html", +}) +export class DialogConfirmCloseCalcComponent { + + constructor( + public dialogRef: MatDialogRef<DialogConfirmCloseCalcComponent>, + private intlService: I18nService, + @Inject(MAT_DIALOG_DATA) public data: any + ) { } + + public get uitextYes() { + return this.intlService.localizeText("INFO_OPTION_YES"); + } + + public get uitextNo() { + return this.intlService.localizeText("INFO_OPTION_NO"); + } + + public get uitextCloseCalcTitle() { + return this.intlService.localizeText("INFO_CLOSE_DIALOGUE_TITRE"); + } + + public get uitextCloseCalcBody() { + return this.intlService.localizeText("INFO_CLOSE_DIALOGUE_TEXT"); + } + +} diff --git a/src/app/components/dialog-confirm-empty-session/dialog-confirm-empty-session.component.html b/src/app/components/dialog-confirm-empty-session/dialog-confirm-empty-session.component.html new file mode 100644 index 0000000000000000000000000000000000000000..699ae97867ba412c354569bf1aab09429deffc7d --- /dev/null +++ b/src/app/components/dialog-confirm-empty-session/dialog-confirm-empty-session.component.html @@ -0,0 +1,12 @@ +<h1 mat-dialog-title [innerHTML]="uitextEmptySessionTitle"></h1> +<div mat-dialog-content> + <p [innerHTML]="uitextEmptySessionBody"></p> +</div> +<div mat-dialog-actions> + <button mat-raised-button color="primary" [mat-dialog-close]="false" cdkFocusInitial> + {{ uitextNo }} + </button> + <button mat-raised-button color="warn" [mat-dialog-close]="true"> + {{ uitextYes }} + </button> +</div> diff --git a/src/app/components/dialog-confirm-empty-session/dialog-confirm-empty-session.component.ts b/src/app/components/dialog-confirm-empty-session/dialog-confirm-empty-session.component.ts new file mode 100644 index 0000000000000000000000000000000000000000..f2334de93b12bac03b00f68bac7d303a5d6914d1 --- /dev/null +++ b/src/app/components/dialog-confirm-empty-session/dialog-confirm-empty-session.component.ts @@ -0,0 +1,33 @@ +import { MatDialogRef, MAT_DIALOG_DATA } from "@angular/material"; +import { Inject, Component } from "@angular/core"; +import { I18nService } from "../../services/internationalisation/internationalisation.service"; + +@Component({ + selector: "dialog-confirm-empty-session", + templateUrl: "dialog-confirm-empty-session.component.html", +}) +export class DialogConfirmEmptySessionComponent { + + constructor( + public dialogRef: MatDialogRef<DialogConfirmEmptySessionComponent>, + private intlService: I18nService, + @Inject(MAT_DIALOG_DATA) public data: any + ) { } + + public get uitextYes() { + return this.intlService.localizeText("INFO_OPTION_YES"); + } + + public get uitextNo() { + return this.intlService.localizeText("INFO_OPTION_NO"); + } + + public get uitextEmptySessionTitle() { + return this.intlService.localizeText("INFO_EMPTY_SESSION_DIALOGUE_TITRE"); + } + + public get uitextEmptySessionBody() { + return this.intlService.localizeText("INFO_EMPTY_SESSION_DIALOGUE_TEXT"); + } + +} diff --git a/src/app/components/dialog-edit-param-computed/dialog-edit-param-computed.component.html b/src/app/components/dialog-edit-param-computed/dialog-edit-param-computed.component.html new file mode 100644 index 0000000000000000000000000000000000000000..9efaf288795c96ec273dc07655f1f13889cfad2a --- /dev/null +++ b/src/app/components/dialog-edit-param-computed/dialog-edit-param-computed.component.html @@ -0,0 +1,16 @@ +<h1 mat-dialog-title [innerHTML]="uitextEditParamComputedInitialValue"></h1> + +<form> + + <div mat-dialog-content> + <ngparam-input [title]="param.title" ></ngparam-input> + <!-- (change)="onInputChange($event)" --> + </div> + + <div mat-dialog-actions> + <button mat-raised-button [mat-dialog-close]="true" cdkFocusInitial> + {{ uitextClose }} + </button> + </div> + +</form> diff --git a/src/app/components/dialog-edit-param-computed/dialog-edit-param-computed.component.scss b/src/app/components/dialog-edit-param-computed/dialog-edit-param-computed.component.scss new file mode 100644 index 0000000000000000000000000000000000000000..bc76a27e25280cc38af4ab2f9eb032683c35e758 --- /dev/null +++ b/src/app/components/dialog-edit-param-computed/dialog-edit-param-computed.component.scss @@ -0,0 +1,3 @@ +mat-form-field { + width: 100%; +} diff --git a/src/app/components/dialog-edit-param-computed/dialog-edit-param-computed.component.ts b/src/app/components/dialog-edit-param-computed/dialog-edit-param-computed.component.ts new file mode 100644 index 0000000000000000000000000000000000000000..5321f476f84fec449f58c0fb597e4e74f4f31b92 --- /dev/null +++ b/src/app/components/dialog-edit-param-computed/dialog-edit-param-computed.component.ts @@ -0,0 +1,39 @@ +import { MatDialogRef, MAT_DIALOG_DATA } from "@angular/material"; +import { Inject, Component, ViewChild, OnInit } from "@angular/core"; +import { I18nService } from "../../services/internationalisation/internationalisation.service"; +import { NgParameter } from "../../formulaire/ngparam"; +import { NgParamInputComponent } from "../ngparam-input/ngparam-input.component"; + +@Component({ + selector: "dialog-edit-param-computed", + templateUrl: "dialog-edit-param-computed.component.html", + styleUrls: ["dialog-edit-param-computed.component.scss"] +}) +export class DialogEditParamComputedComponent implements OnInit { + + /** the related parameter to change the "fixed" value of */ + public param: NgParameter; + + @ViewChild(NgParamInputComponent) + private _ngParamInputComponent: NgParamInputComponent; + + constructor( + public dialogRef: MatDialogRef<DialogEditParamComputedComponent>, + private intlService: I18nService, + @Inject(MAT_DIALOG_DATA) public data: any + ) { + this.param = data.param; + } + + public get uitextClose() { + return this.intlService.localizeText("INFO_OPTION_CLOSE"); + } + + public get uitextEditParamComputedInitialValue() { + return this.intlService.localizeText("INFO_DIALOG_COMPUTED_VALUE_TITLE"); + } + + public ngOnInit() { + this._ngParamInputComponent.model = this.param; + } +} diff --git a/src/app/components/dialog-edit-param-values/dialog-edit-param-values.component.html b/src/app/components/dialog-edit-param-values/dialog-edit-param-values.component.html new file mode 100644 index 0000000000000000000000000000000000000000..53718ce0f5d69c711f5d0e0e2af8412932d85482 --- /dev/null +++ b/src/app/components/dialog-edit-param-values/dialog-edit-param-values.component.html @@ -0,0 +1,95 @@ +<h1 mat-dialog-title [innerHTML]="uitextEditParamVariableValues"></h1> + + <div mat-dialog-content> + + <mat-form-field> + <mat-select [placeholder]="uiTextModeSelection" [(value)]="selectedValueMode" (selectionChange)="onValueModeChange($event)" + data-testid="variable-value-mode-select"> + <mat-option *ngFor="let e of valueModes" [value]="e.value"> + {{ e.label }} + </mat-option> + </mat-select> + </mat-form-field> + + <div *ngIf="isMinMax" class="min-max-step-container"> + <form> + <mat-form-field> + <input matInput class="form-control" type="number" inputmode="numeric" name="min-value" step="0.01" + [placeholder]="uitextValeurMini" [(ngModel)]="param.minValue" required pattern="^-?([0-9]*\.)?([0-9]+[Ee]-?)?[0-9]+$"> + + <mat-error>{{ uitextMustBeANumber }}</mat-error> + </mat-form-field> + + <mat-form-field> + <input matInput class="form-control" type="number" inputmode="numeric" name="max-value" step="0.01" + [placeholder]="uitextValeurMaxi" [(ngModel)]="param.maxValue" required pattern="^-?([0-9]*\.)?([0-9]+[Ee]-?)?[0-9]+$"> + + <mat-error>{{ uitextMustBeANumber }}</mat-error> + </mat-form-field> + + <mat-form-field> + <input matInput class="form-control" type="number" inputmode="numeric" name="step-value" step="0.01" + [placeholder]="uitextPasVariation" [(ngModel)]="param.stepValue" required pattern="^-?([0-9]*\.)?([0-9]+[Ee]-?)?[0-9]+$"> + + <mat-error>{{ uitextMustBeANumber }}</mat-error> + </mat-form-field> + </form> + </div> + + <div *ngIf="isListe"> + <form [formGroup]="valuesListForm"> + <mat-form-field> + <textarea matInput matTextareaAutosize [placeholder]="uitextListeValeurs" formControlName="valuesList" + [value]="valuesList"></textarea> + <!-- (input)="valuesList = $event.target.value" --> + <mat-error> + <span *ngIf="valuesListForm.controls.valuesList.hasError('model')"> + {{ valuesListForm.controls.valuesList.errors.model }} + </span> + <span *ngIf="! valuesListForm.controls.valuesList.hasError('model')"> + {{ uitextMustBeListOfNumbers }} + </span> + </mat-error> + </mat-form-field> + + <div class="decimal-separator-and-file-container" fxLayout="row wrap" fxLayoutAlign="space-between start"> + <mat-form-field class="decimal-separator" fxFlex.gt-xs="1 0 auto" fxFlex.lt-sm="1 0 100%"> + <mat-select [placeholder]="uitextDecimalSeparator" [(value)]="decimalSeparator" + data-testid="decimal-separator-select"> + <mat-option *ngFor="let e of decimalSeparators" [value]="e.value"> + {{ e.label }} + </mat-option> + </mat-select> + </mat-form-field> + + <div fxHide.xs fxFlex.gt-xs="0 0 16px"></div> + + <mat-form-field class="values-file" fxFlex.gt-xs="1 0 auto" fxFlex.lt-sm="1 0 100%"> + <ngx-mat-file-input #valuesFile [placeholder]="uitextImportFile" + (change)="onFileSelected($event)" formControlName="file"> + </ngx-mat-file-input> + <button mat-icon-button matSuffix *ngIf="!valuesFile.empty" (click)="valuesFile.clear($event)"> + <mat-icon>clear</mat-icon> + </button> + </mat-form-field> + </div> + </form> + </div> + + </div> + + <div mat-dialog-actions> + <div *ngIf="isMinMax"> + <button mat-raised-button [mat-dialog-close]="true" cdkFocusInitial> + {{ uitextClose }} + </button> + </div> + <div *ngIf="isListe"> + <button mat-raised-button color="primary" [mat-dialog-close]="true" cdkFocusInitial> + {{ uitextCancel }} + </button> + <button mat-raised-button color="warn" (click)="onValidate()"> + {{ uitextValidate }} + </button> + </div> + </div> diff --git a/src/app/components/dialog-edit-param-values/dialog-edit-param-values.component.scss b/src/app/components/dialog-edit-param-values/dialog-edit-param-values.component.scss new file mode 100644 index 0000000000000000000000000000000000000000..c8602bba0dc8bf4b943720441741f41cb94d6183 --- /dev/null +++ b/src/app/components/dialog-edit-param-values/dialog-edit-param-values.component.scss @@ -0,0 +1,21 @@ +mat-form-field { + display: block; + margin-top: 0.5em; + + textarea { + font-size: .8em; + max-height: 100px; + } +} + +.min-max-step-container { + margin-top: -8px; +} + +.mat-dialog-content { + overflow: hidden; +} + +.decimal-separator-and-file-container { + margin-top: 1em; +} diff --git a/src/app/components/dialog-edit-param-values/dialog-edit-param-values.component.ts b/src/app/components/dialog-edit-param-values/dialog-edit-param-values.component.ts new file mode 100644 index 0000000000000000000000000000000000000000..651702a5d2ecf95e1eb03d448383234fd224565b --- /dev/null +++ b/src/app/components/dialog-edit-param-values/dialog-edit-param-values.component.ts @@ -0,0 +1,352 @@ +import { MatDialogRef, MAT_DIALOG_DATA } from "@angular/material"; +import { Inject, Component, OnInit } from "@angular/core"; +import { FormBuilder, FormGroup, Validators } from "@angular/forms"; +import { I18nService } from "../../services/internationalisation/internationalisation.service"; +import { NgParameter } from "../../formulaire/ngparam"; +import { ParamValueMode } from "jalhyd"; +import { sprintf } from "sprintf-js"; + +@Component({ + selector: "dialog-edit-param-values", + templateUrl: "dialog-edit-param-values.component.html", + styleUrls: ["dialog-edit-param-values.component.scss"] +}) +export class DialogEditParamValuesComponent implements OnInit { + + /** the related parameter to change the "variable" value of */ + public param: NgParameter; + + /** available value modes (min / max, list) */ + public valueModes: { value: ParamValueMode; label: string; }[]; + + /** available decimal separators */ + public decimalSeparators: { label: string; value: string; }[]; + + /** current decimal separator */ + public decimalSeparator: string; + + public valuesListForm: FormGroup; + + constructor( + public dialogRef: MatDialogRef<DialogEditParamValuesComponent>, + private intlService: I18nService, + private fb: FormBuilder, + @Inject(MAT_DIALOG_DATA) public data: any + ) { + this.param = data.param; + + // an explicit ReactiveForm is required for file input component + this.valuesListForm = this.fb.group({ + file: [""], + valuesList: ["", [ // not initialized with valuesList because param mode is MIN/MAX at this time + Validators.required + // Validators.pattern(new RegExp(this.valuesListPattern)) // behaves weirdly + ]] + }); + + // available options for select controls + this.valueModes = [ + { + value: ParamValueMode.MINMAX, + label: this.intlService.localizeText("INFO_PARAMMODE_MINMAX") + }, + { + value: ParamValueMode.LISTE, + label: this.intlService.localizeText("INFO_PARAMMODE_LIST") + } + ]; + this.decimalSeparators = [ + { + label: this.intlService.localizeText("INFO_PARAMFIELD_PARAMVARIER_SEPARATEUR_POINT"), + value: "." + }, + { + label: this.intlService.localizeText("INFO_PARAMFIELD_PARAMVARIER_SEPARATEUR_VIRGULE"), + value: "," + } + ]; + this.decimalSeparator = this.decimalSeparators[0].value; + } + + /** + * regular expression pattern for values list validation (depends on decimal separator) + */ + public get valuesListPattern() { + // standard pattern for decimal separator "." : ^-?([0-9]*\.)?([0-9]+[Ee]-?)?[0-9]+$ + const escapedDecimalSeparator = (this.decimalSeparator === "." ? "\\." : this.decimalSeparator); + const numberSubPattern = `-?([0-9]*${escapedDecimalSeparator})?([0-9]+[Ee]-?)?[0-9]+`; + const re = `^${numberSubPattern}(${this.separatorPattern}${numberSubPattern})*$`; + return re; + } + + /** + * accepted separator: everything but [numbers, E, +, -, decimal separator], any length + */ + public get separatorPattern() { + return "[^0-9-+Ee" + this.decimalSeparator + "]+"; + } + + public get selectedValueMode() { + return this.param.valueMode; + } + + public set selectedValueMode(v) { + this.param.valueMode = v; + } + + public get isMinMax() { + return this.param.valueMode === ParamValueMode.MINMAX; + } + + public get isListe() { + return this.param.valueMode === ParamValueMode.LISTE; + } + + /** + * renders model's numbers list as text values list (semicolon separated) + */ + public get valuesList() { + return (this.param.valueList || []).join(";"); + } + + /** + * injects text values list into model's numbers list + */ + public set valuesList(list: string) { + const vals = []; + const separatorRE = new RegExp(this.separatorPattern); + const parts = list.trim().split(separatorRE); + parts.forEach((e) => { + if (e.length > 0) { + // ensure decimal separator is "." for Number() + if (this.decimalSeparator !== ".") { + const re = new RegExp(this.decimalSeparator, "g"); // @TODO remove "g" ? + e = e.replace(re, "."); + } + vals.push(Number(e)); + } + }); + this.param.valueList = vals; + } + + public onValidate() { + const status = this.validateValuesListString(this.valuesListForm.controls.valuesList.value); + + if (status.ok) { + this.valuesListForm.controls.valuesList.setErrors(null); + this.valuesList = this.valuesListForm.controls.valuesList.value; + this.dialogRef.close(); + } else { + this.valuesListForm.controls.valuesList.setErrors({ "model": status.message }); + } + } + + /** + * Returns { ok: true } if every element of list is a valid Number, { ok: false, message: "reason" } otherwise + * @param list a string containing a list of numbers separated by this.separatorPattern + */ + private validateValuesListString(list: string) { + let message: string; + // 1. validate against general pattern + let ok = new RegExp(this.valuesListPattern).test(list); + + if (ok) { + // 2. validate each value + const separatorRE = new RegExp(this.separatorPattern); + const parts = list.trim().split(separatorRE); + for (let i = 0; i < parts.length && ok; i++) { + let e = parts[i]; + if (e.length > 0) { // should always be true as separator might be several characters long + // ensure decimal separator is "." for Number() + if (this.decimalSeparator !== ".") { + const re = new RegExp(this.decimalSeparator, "g"); // @TODO remove "g" ? + e = e.replace(re, "."); + } + // 2.1 check it is a valid Number + const n = (Number(e)); + // 2.2 validate against model + let modelIsHappy = true; + try { + this.param.checkValue(n); + } catch (e) { + modelIsHappy = false; + message = sprintf(this.intlService.localizeText("ERROR_INVALID_AT_POSITION"), i + 1) + + " " + this.intlService.localizeMessage(e); + } + // synthesis + ok = ( + ok + && !isNaN(n) + && isFinite(n) + && modelIsHappy + ); + } + } + } else { + message = this.uitextMustBeListOfNumbers; + } + + return { ok, message }; + } + + public onFileSelected(event: any) { + if (event.target.files && event.target.files.length) { + const fr = new FileReader(); + fr.onload = () => { + this.valuesListForm.controls.valuesList.setErrors(null); + // this.valuesList = String(fr.result); + this.valuesListForm.controls.valuesList.setValue(String(fr.result)); + }; + fr.onerror = () => { + fr.abort(); + throw new Error("Erreur de lecture du fichier"); + }; + fr.readAsText(event.target.files[0]); + } + } + + public onValueModeChange(event) { + this.initVariableValues(); + } + + private initVariableValues() { + // init min / max / step + if (this.isMinMax) { + if (this.param.minValue === undefined) { + this.param.minValue = this.param.getValue() / 2; + } + if (this.param.maxValue === undefined) { + this.param.maxValue = this.param.getValue() * 2; + } + let step = this.param.stepValue; + if (step === undefined) { + step = (this.param.maxValue - this.param.minValue) / 20; + } + this.param.stepValue = step; + } + // init values list + if (this.isListe) { + if (this.param.valueList === undefined) { + if (this.param.isDefined) { + this.param.valueList = [ this.param.getValue() ]; + } else { + this.param.valueList = []; + } + // set form control initial value + this.valuesListForm.controls.valuesList.setValue(this.valuesList); + } + } + } + + public get uiTextModeSelection() { + return this.intlService.localizeText("INFO_PARAMFIELD_PARAMVARIER_MODE"); + } + + public get uitextValeurMini() { + return this.intlService.localizeText("INFO_PARAMFIELD_VALEURMINI"); + } + + public get uitextValeurMaxi() { + return this.intlService.localizeText("INFO_PARAMFIELD_VALEURMAXI"); + } + + public get uitextPasVariation() { + return this.intlService.localizeText("INFO_PARAMFIELD_PASVARIATION"); + } + + public get uitextClose() { + return this.intlService.localizeText("INFO_OPTION_CLOSE"); + } + + public get uitextCancel() { + return this.intlService.localizeText("INFO_OPTION_CANCEL"); + } + + public get uitextValidate() { + return this.intlService.localizeText("INFO_OPTION_VALIDATE"); + } + + public get uitextEditParamVariableValues() { + return this.intlService.localizeText("INFO_PARAMFIELD_PARAMVARIER_TITLE"); + } + + public get uitextListeValeurs() { + return this.intlService.localizeText("INFO_PARAMFIELD_PARAMVARIER_VALUES_FORMAT"); + } + + public get uitextMustBeANumber(): string { + return this.intlService.localizeText("ERROR_PARAM_MUST_BE_A_NUMBER"); + } + + public get uitextMustBeListOfNumbers() { + return sprintf(this.intlService.localizeText("INFO_PARAMFIELD_PARAMVARIER_VALUES_FORMAT_ERROR"), this.separatorPattern); + } + + public get uitextDecimalSeparator() { + return this.intlService.localizeText("INFO_PARAMFIELD_PARAMVARIER_SEPARATEUR_DECIMAL"); + } + + public get uitextImportFile() { + return this.intlService.localizeText("INFO_PARAMFIELD_PARAMVARIER_IMPORT_FICHIER"); + } + + public ngOnInit() { + this.initVariableValues(); + } + + /* protected validateModelValue(v: any): { isValid: boolean, message: string } { + let msg: string; + let valid = false; + + if (this.param === undefined) { + msg = "internal error, model undefined"; + } else { + if (!this.param.checkMin(v)) { + msg = "La valeur n'est pas dans [" + this.param.domain.minValue + " , " + this.param.maxValue + "["; + } else { + valid = true; + } + } + + return { isValid: valid, message: msg }; + } + protected validateModelValue(v: any): { isValid: boolean, message: string } { + let msg: string; + let valid = false; + + if (this.param === undefined) { + msg = "internal error, model undefined"; + } else { + if (!this.param.checkMax(v)) { + msg = "La valeur n'est pas dans ]" + this.param.minValue + " , " + this.param.domain.maxValue + "]"; + } else { + valid = true; + } + } + + return { isValid: valid, message: msg }; + } + protected validateModelValue(v: any): { isValid: boolean, message: string } { + let msg: string; + let valid = false; + + if (! this.param) { + msg = "internal error, model undefined"; + } else { + if (this.param.isMinMaxValid) { + if (!this.param.checkStep(v)) { + msg = "La valeur n'est pas dans " + this.param.stepRefValue.toString(); + } else { + valid = v > 0; + if (!valid) { + msg = "La valeur ne peut pas être <= 0"; + } + } + } else { + msg = "Veuillez corriger le min/max"; + } + } + + return { isValid: valid, message: msg }; + } */ +} diff --git a/src/app/components/dialog-load-session/dialog-load-session.component.html b/src/app/components/dialog-load-session/dialog-load-session.component.html new file mode 100644 index 0000000000000000000000000000000000000000..b9f411fb767fdff20042560145f24d00edfef737 --- /dev/null +++ b/src/app/components/dialog-load-session/dialog-load-session.component.html @@ -0,0 +1,42 @@ +<h1 mat-dialog-title [innerHTML]="uitextLoadSessionTitle"></h1> + +<form [formGroup]="loadSessionForm"> + + <div mat-dialog-content> + + <mat-form-field> + <ngx-mat-file-input id="session-file-input" #sessionFile formControlName="file"[placeholder]="uitextLoadSessionFilename" + (change)="onFileSelected($event)"></ngx-mat-file-input> + <button mat-icon-button matSuffix *ngIf="!sessionFile.empty" (click)="sessionFile.clear($event)"> + <mat-icon>clear</mat-icon> + </button> + </mat-form-field> + + <div class="cb-container"> + <mat-checkbox [name]="c.uid" *ngFor="let c of calculators" [(ngModel)]="c.selected" [ngModelOptions]="{standalone: true}"> + {{ c.title }} + </mat-checkbox> + </div> + + <div class="btn-container"> + <button mat-raised-button (click)="selectAll()" [disabled]="calculators.length === 0"> + {{ uitextAll }} + </button> + <button mat-raised-button (click)="selectNone()" [disabled]="calculators.length === 0"> + {{ uitextNone }} + </button> + </div> + </div> + + <div mat-dialog-actions> + <button mat-raised-button color="primary" [mat-dialog-close]="false" cdkFocusInitial> + {{ uitextCancel }} + </button> + <button mat-raised-button type="submit" color="warn" (click)="loadSession()" + [disabled]="(loadSessionForm.invalid || ! atLeastOneCheckboxSelected)"> + + {{ uitextLoad }} + </button> + </div> + +</form> diff --git a/src/app/components/dialog-load-session/dialog-load-session.component.scss b/src/app/components/dialog-load-session/dialog-load-session.component.scss new file mode 100644 index 0000000000000000000000000000000000000000..e612ad2cf5490552d96d024c1122ef4cd1bbfc1f --- /dev/null +++ b/src/app/components/dialog-load-session/dialog-load-session.component.scss @@ -0,0 +1,19 @@ +mat-form-field { + width: 100%; +} + +.cb-container { + margin-bottom: 5px; + + mat-checkbox { + display: block; + } +} + +.btn-container { + margin-bottom: 20px; + + button { + margin-right: 5px; + } +} diff --git a/src/app/components/dialog-load-session/dialog-load-session.component.ts b/src/app/components/dialog-load-session/dialog-load-session.component.ts new file mode 100644 index 0000000000000000000000000000000000000000..3aa55c836a420dd0966dd5df2ae72687a382911e --- /dev/null +++ b/src/app/components/dialog-load-session/dialog-load-session.component.ts @@ -0,0 +1,97 @@ +import { MatDialogRef, MAT_DIALOG_DATA } from "@angular/material"; +import { Inject, Component } from "@angular/core"; +import { I18nService } from "../../services/internationalisation/internationalisation.service"; +import { FormGroup, FormBuilder, Validators } from "@angular/forms"; +import { ServiceFactory } from "../../services/service-factory"; + +@Component({ + selector: "dialog-load-session", + templateUrl: "dialog-load-session.component.html", + styleUrls: ["dialog-load-session.component.scss"] +}) +export class DialogLoadSessionComponent { + + public calculators: any[] = []; + + public file: any; + + public loadSessionForm: FormGroup; + + constructor( + public dialogRef: MatDialogRef<DialogLoadSessionComponent>, + private intlService: I18nService, + private fb: FormBuilder, + @Inject(MAT_DIALOG_DATA) public data: any + ) { + this.loadSessionForm = this.fb.group({ + file: [null, Validators.required] + }); + } + + public selectAll() { + for (const c of this.calculators) { + c.selected = true; + } + } + + public selectNone() { + for (const c of this.calculators) { + c.selected = false; + } + } + + public onFileSelected(event: any) { + if (event.target.files && event.target.files.length) { + this.file = event.target.files[0]; + + const formService = ServiceFactory.instance.formulaireService; + formService.calculatorInfosFromSessionFile(this.file).then( + calcInfos => { + this.calculators = calcInfos; + for (const n of this.calculators) { + n.selected = true; + } + } + ); + } + } + + public loadSession() { + this.dialogRef.close({ + calculators: this.calculators, + file: this.file + }); + } + + public get atLeastOneCheckboxSelected() { + let ok = false; + for (const c of this.calculators) { + ok = (ok || c.selected); + } + return ok; + } + + public get uitextLoad() { + return this.intlService.localizeText("INFO_OPTION_LOAD"); + } + + public get uitextCancel() { + return this.intlService.localizeText("INFO_OPTION_CANCEL"); + } + + public get uitextAll() { + return this.intlService.localizeText("INFO_OPTION_ALL"); + } + + public get uitextNone() { + return this.intlService.localizeText("INFO_OPTION_NONE"); + } + + public get uitextLoadSessionFilename() { + return this.intlService.localizeText("INFO_DIALOG_LOAD_SESSION_FILENAME"); + } + + public get uitextLoadSessionTitle() { + return this.intlService.localizeText("INFO_DIALOG_LOAD_SESSION_TITLE"); + } +} diff --git a/src/app/components/dialog-save-session/dialog-save-session.component.html b/src/app/components/dialog-save-session/dialog-save-session.component.html new file mode 100644 index 0000000000000000000000000000000000000000..5c19a5bc6c607f1367d8cc2f3a6363ddc7625bc3 --- /dev/null +++ b/src/app/components/dialog-save-session/dialog-save-session.component.html @@ -0,0 +1,34 @@ +<h1 mat-dialog-title [innerHTML]="uitextSaveSessionTitle"></h1> + +<form> + + <div mat-dialog-content> + <div class="cb-container"> + <mat-checkbox [name]="c.uid" *ngFor="let c of calculators" [(ngModel)]="c.selected"> + {{ c.title }} + </mat-checkbox> + </div> + + <div class="btn-container"> + <button mat-raised-button (click)="selectAll()">{{ uitextAll }}</button> + <button mat-raised-button (click)="selectNone()">{{ uitextNone }}</button> + </div> + + <mat-form-field> + <input matInput required [placeholder]="uitextFilenameInput" [(ngModel)]="fileName" + name="filename" #filename="ngModel"> + </mat-form-field> + </div> + + <div mat-dialog-actions> + <button mat-raised-button color="primary" [mat-dialog-close]="false" cdkFocusInitial> + {{ uitextCancel }} + </button> + <button mat-raised-button type="submit" color="warn" (click)="saveSession()" + [disabled]="(! filename.valid) || (! atLeastOneCheckboxSelected)"> + + {{ uitextSave }} + </button> + </div> + +</form> diff --git a/src/app/components/dialog-save-session/dialog-save-session.component.scss b/src/app/components/dialog-save-session/dialog-save-session.component.scss new file mode 100644 index 0000000000000000000000000000000000000000..e612ad2cf5490552d96d024c1122ef4cd1bbfc1f --- /dev/null +++ b/src/app/components/dialog-save-session/dialog-save-session.component.scss @@ -0,0 +1,19 @@ +mat-form-field { + width: 100%; +} + +.cb-container { + margin-bottom: 5px; + + mat-checkbox { + display: block; + } +} + +.btn-container { + margin-bottom: 20px; + + button { + margin-right: 5px; + } +} diff --git a/src/app/components/dialog-save-session/dialog-save-session.component.ts b/src/app/components/dialog-save-session/dialog-save-session.component.ts new file mode 100644 index 0000000000000000000000000000000000000000..032ed2c65e56e026db473bc9eaca0eea6a3349a1 --- /dev/null +++ b/src/app/components/dialog-save-session/dialog-save-session.component.ts @@ -0,0 +1,74 @@ +import { MatDialogRef, MAT_DIALOG_DATA } from "@angular/material"; +import { Inject, Component } from "@angular/core"; +import { I18nService } from "../../services/internationalisation/internationalisation.service"; + +@Component({ + selector: "dialog-save-session", + templateUrl: "dialog-save-session.component.html", + styleUrls: ["dialog-save-session.component.scss"] +}) +export class DialogSaveSessionComponent { + + public calculators: any[]; + + public fileName = "session"; + + constructor( + public dialogRef: MatDialogRef<DialogSaveSessionComponent>, + private intlService: I18nService, + @Inject(MAT_DIALOG_DATA) public data: any + ) { + this.calculators = data.calculators; + } + + public selectAll() { + for (const c of this.calculators) { + c.selected = true; + } + } + + public selectNone() { + for (const c of this.calculators) { + c.selected = false; + } + } + + public saveSession() { + this.dialogRef.close({ + calculators: this.calculators, + filename: this.fileName + }); + } + + public get atLeastOneCheckboxSelected() { + let ok = false; + for (const c of this.calculators) { + ok = (ok || c.selected); + } + return ok; + } + + public get uitextSave() { + return this.intlService.localizeText("INFO_OPTION_SAVE"); + } + + public get uitextCancel() { + return this.intlService.localizeText("INFO_OPTION_CANCEL"); + } + + public get uitextAll() { + return this.intlService.localizeText("INFO_OPTION_ALL"); + } + + public get uitextNone() { + return this.intlService.localizeText("INFO_OPTION_NONE"); + } + + public get uitextSaveSessionTitle() { + return this.intlService.localizeText("INFO_DIALOG_SAVE_SESSION_TITLE"); + } + + public get uitextFilenameInput() { + return this.intlService.localizeText("INFO_DIALOG_SAVE_SESSION_FILENAME"); + } +} diff --git a/src/app/components/field-set/field-set.component.html b/src/app/components/field-set/field-set.component.html index 9fae14a33a4d08eb39ddaa0a71d2c2a894100b8a..3217d50f0ba485c834824abf92139f58b47292d8 100644 --- a/src/app/components/field-set/field-set.component.html +++ b/src/app/components/field-set/field-set.component.html @@ -1,31 +1,31 @@ -<div class="row fieldset_backgrd"> - <div class="col fieldset_title"> +<mat-card-header class="bg-accent-light"> + <mat-card-title> {{ title }} + </mat-card-title> + <div *ngIf="showButtons" class="hyd-window-btns"> + <button mat-icon-button (click)="onAddClick()"> + <mat-icon>add_box</mat-icon> + </button> + <button mat-icon-button [disabled]="! enableRemoveButton" (click)="onRemoveClick()"> + <mat-icon>delete</mat-icon> + </button> + <button mat-icon-button [disabled]="! enableUpButton" (click)="onMoveUpClick()"> + <mat-icon>arrow_upward</mat-icon> + </button> + <button mat-icon-button [disabled]="! enableDownButton" (click)="onMoveDownClick()"> + <mat-icon>arrow_downward</mat-icon> + </button> </div> - <div *ngIf="showButtons" class="col-sm-4 fa-stack fa-2x hyd-window-btns"> - <i class="fa fa-plus" (click)='onAddClick()'></i> - <i class="fa fa-trash" [style.color]='removeButtonColor' (click)='onRemoveClick()'></i> - <i class="fa fa-arrow-up" [style.color]='upButtonColor' (click)='onMoveUpClick()'></i> - <i class="fa fa-arrow-down" [style.color]='downButtonColor' (click)='onMoveDownClick()'></i> - </div> -</div> - -<!-- - <tag *ngFor="let var of array" *ngIf="...utilisation de var..." > - </tag> - peut être transformé en - <ng-template ngFor let-var [ngForOf]="array"> - <tag *ngIf="...utilisation de var..." > - </tag> - </ng-template> ---> +</mat-card-header> -<ng-template ngFor let-p [ngForOf]="fields"> - <param-field-line *ngIf="isInputField(p)" [param]=p (radio)=onRadioClick($event) (valid)=onParamLineValid() (inputChange)=onInputChange()> - </param-field-line> +<mat-card-content> + <ng-template ngFor let-p [ngForOf]="fields"> + <param-field-line *ngIf="isInputField(p)" [param]=p (radio)=onRadioClick($event) (valid)=onParamLineValid() (inputChange)=onInputChange()> + </param-field-line> - <select-field-line *ngIf="isSelectField(p)" [_select]=p> - </select-field-line> + <select-field-line *ngIf="isSelectField(p)" [_select]=p> + </select-field-line> - <check-field-line *ngIf="isCheckField(p)" [check]=p></check-field-line> -</ng-template> \ No newline at end of file + <check-field-line *ngIf="isCheckField(p)" [check]=p></check-field-line> + </ng-template> +</mat-card-content> diff --git a/src/app/components/field-set/field-set.component.scss b/src/app/components/field-set/field-set.component.scss index dbe81a5108659a3fb67366443ca801ed88591dc0..373f5b26832ff9012eb9819ced8f1b4b23fcb914 100644 --- a/src/app/components/field-set/field-set.component.scss +++ b/src/app/components/field-set/field-set.component.scss @@ -1,12 +1,84 @@ -.fieldset_title { - font-weight: bold; +param-field-line { + // border: solid green 2px; + display: block; } -.radio_param_header { - width: 10em; + +select-field-line { + // border: solid blue 2px; + display: block; } -.fieldset_backgrd { - background-color: #eeeeee; + +mat-card-header { + margin-left: -16px; + margin-right: -16px; + padding-left: 16px; + padding-top: 8px; + color: white; + + // Pourquoi n'est-ce pas hérité de calculator.component.scss ? + // À cause de la surcharge de mat-card-header ci-dessus ? + mat-card-title { + font-size: 16px; + margin-bottom: 8px; + } + + .hyd-window-btns { + text-align: right; + + mat-icon { + cursor: pointer; + transform: scale(1.2); + margin-top: 6px; + margin-right: 5px; + } + } } -.hyd-window-btns { - text-align: right; + +mat-card-content { + margin-top: 1em; +} + +mat-card-actions { + + button { + width: 100%; + } +} + +:host { + + &.fieldset-inner { + + mat-card-header { + margin-left: 0; + margin-right: 0; + padding-left: 12px; + + mat-card-title { + font-size: 14px; + } + + .hyd-window-btns { + position: absolute; + right: 18px; + margin-top: -4px; + + button.mat-icon-button { + width: 26px; + height: 20px; + line-height: 20px; + + mat-icon { + margin-top: 0; + margin-right: 0; + transform: scale(1); + } + } + } + } + + mat-card-content { + padding: 0 1em; + } + } } diff --git a/src/app/components/field-set/field-set.component.ts b/src/app/components/field-set/field-set.component.ts index 24a031d4df575d78117d2adf4c3c1e24bb8475a2..5848aa4c1f961ab145c586232f86d6717386db71 100644 --- a/src/app/components/field-set/field-set.component.ts +++ b/src/app/components/field-set/field-set.component.ts @@ -24,26 +24,6 @@ export class FieldSetComponent implements DoCheck { return this._fieldSet.kids; } - public get showButtons() { - return this._showButtons; - } - - public set showButtons(b: boolean) { - this._showButtons = b; - } - - public set enableUpButton(b: boolean) { - this._enableUpButton = b; - } - - public set enableDownButton(b: boolean) { - this._enableDownButton = b; - } - - public set enableRemoveButton(b: boolean) { - this._enableRemoveButton = b; - } - public set fieldsetNumber(n: number) { this._fieldSet.labelNumber = n; } @@ -62,26 +42,6 @@ export class FieldSetComponent implements DoCheck { return this._isValid; } - /** - * couleur du bouton monter - */ - private get upButtonColor(): string { - return this._enableUpButton ? "black" : "lightgrey"; - } - - /** - * couleur du bouton descendre - */ - private get downButtonColor(): string { - return this._enableDownButton ? "black" : "lightgrey"; - } - - /** - * couleur du bouton supprimer - */ - private get removeButtonColor(): string { - return this._enableRemoveButton ? "black" : "lightgrey"; - } /** * field set attribute */ @@ -134,22 +94,22 @@ export class FieldSetComponent implements DoCheck { /** * flag d'affichage des boutons ajouter, supprimer, monter, descendre */ - private _showButtons = false; + public showButtons = false; /** * flag d'activation du bouton monter */ - private _enableUpButton = true; + public enableUpButton = true; /** * flag d'activation du bouton descendre */ - private _enableDownButton = true; + public enableDownButton = true; /** * flag d'activation du bouton supprimer */ - private _enableRemoveButton = true; + public enableRemoveButton = true; /** * événement de changement d'état d'un radio @@ -300,26 +260,20 @@ export class FieldSetComponent implements DoCheck { * clic sur le bouton supprimer */ private onRemoveClick() { - if (this._enableRemoveButton) { - this.removeFieldset.emit(this._fieldSet); - } + this.removeFieldset.emit(this._fieldSet); } /** * clic sur le bouton monter */ private onMoveUpClick() { - if (this._enableUpButton) { - this.moveFieldsetUp.emit(this._fieldSet); - } + this.moveFieldsetUp.emit(this._fieldSet); } /** * clic sur le bouton descendre */ private onMoveDownClick() { - if (this._enableDownButton) { - this.moveFieldsetDown.emit(this._fieldSet); - } + this.moveFieldsetDown.emit(this._fieldSet); } } diff --git a/src/app/components/fieldset-container/fieldset-container.component.html b/src/app/components/fieldset-container/fieldset-container.component.html index 84e4f78e5a5c47b81372383aafb6a8126856e52f..08e323f4465f7fad1027429de458464fbd5232c8 100644 --- a/src/app/components/fieldset-container/fieldset-container.component.html +++ b/src/app/components/fieldset-container/fieldset-container.component.html @@ -1,10 +1,13 @@ -<div class="container-fluid" style="border-style:solid; border-color: lightgray; border-radius: 10px; margin-bottom: 10px;"> - <div class="row"> - <h4 class="col">{{ title }}</h4> - </div> +<mat-card-header class="bg-accent-light"> + <mat-card-title> + {{ title }} + </mat-card-title> +</mat-card-header> - <field-set *ngFor="let fs of fieldsets" [fieldSet]=fs (radio)=onRadioClick($event) (valid)=onFieldsetValid() (inputChange)=onInputChange() - (addFieldset)=onAddFieldset($event) (removeFieldset)=onRemoveFieldset($event) (moveFieldsetUp)=onMoveFieldsetUp($event) - (moveFieldsetDown)=onMoveFieldsetDown($event)> +<mat-card-content> + <field-set *ngFor="let fs of fieldsets" class="fieldset-inner" [fieldSet]=fs + (radio)=onRadioClick($event) (valid)=onFieldsetValid() (inputChange)=onInputChange() + (addFieldset)=onAddFieldset($event) (removeFieldset)=onRemoveFieldset($event) + (moveFieldsetDown)=onMoveFieldsetDown($event) (moveFieldsetUp)=onMoveFieldsetUp($event)> </field-set> -</div> \ No newline at end of file +</mat-card-content> diff --git a/src/app/components/fieldset-container/fieldset-container.component.scss b/src/app/components/fieldset-container/fieldset-container.component.scss new file mode 100644 index 0000000000000000000000000000000000000000..bbc65715fe3bf96979687811fbac7ffc9273c3d0 --- /dev/null +++ b/src/app/components/fieldset-container/fieldset-container.component.scss @@ -0,0 +1,26 @@ +:host { + display: block; + background-color: #f0f0f0; + // reduce margins to avoid inner field-sets being too narrow on 360px display + margin-left: -8px; + margin-right: -8px; +} + +mat-card-header { + margin-left: -8px; + margin-right: -8px; + padding-left: 16px; + padding-top: 8px; + color: white; + + // Pourquoi n'est-ce pas hérité de calculator.component.scss ? + // À cause de la surcharge de mat-card-header ci-dessus ? + mat-card-title { + font-size: 16px; + margin-bottom: 8px; + } +} + +mat-card-content { + margin-top: 1em; +} diff --git a/src/app/components/fieldset-container/fieldset-container.component.ts b/src/app/components/fieldset-container/fieldset-container.component.ts index ccfedcec387e31e40bb4f141f2b30797459dbc1d..75caa880fcfb96ab8300ad8a00a09e162b39874a 100644 --- a/src/app/components/fieldset-container/fieldset-container.component.ts +++ b/src/app/components/fieldset-container/fieldset-container.component.ts @@ -7,15 +7,17 @@ import { FormulaireDefinition } from "../../formulaire/definition/form-definitio @Component({ selector: "fieldset-container", - templateUrl: "./fieldset-container.component.html" + templateUrl: "./fieldset-container.component.html", + styleUrls: [ + "./fieldset-container.component.scss" + ] }) export class FieldsetContainerComponent implements DoCheck, AfterViewInit { public get title(): string { - if (this._container === undefined) { - return undefined; + if (this._container) { + return this._container.label; } - return this._container.label; } public get fieldsets() { diff --git a/src/app/components/fixedvar-results/fixed-results.component.html b/src/app/components/fixedvar-results/fixed-results.component.html index 703075f95dc6c55653e78138b4bdf88a723a8752..b35f932d4c58789bd991bd20f33c13d0dd2ad727 100644 --- a/src/app/components/fixedvar-results/fixed-results.component.html +++ b/src/app/components/fixedvar-results/fixed-results.component.html @@ -1,30 +1,17 @@ -<div class="container-fluid"> +<div class="fixed-results-container" *ngIf="hasFixedParameters"> + <!-- table des résultats fixés --> + <table mat-table [dataSource]="dataSet"> - <!-- [style.display]="hasResults"> --> + <ng-container matColumnDef="parametre"> + <th mat-header-cell *matHeaderCellDef>{{ uitextParamFixes }}</th> + <td mat-cell *matCellDef="let element" [ngClass]="{'highlightedResult': element.isCalcResult}">{{ element.label }}</td> + </ng-container> + <ng-container matColumnDef="valeur"> + <th mat-header-cell *matHeaderCellDef>{{ uitextValeurs }}</th> + <td mat-cell *matCellDef="let element" [ngClass]="{'highlightedResult': element.isCalcResult}">{{ element.value }}</td> + </ng-container> - <div *ngIf="hasFixedParameters" class="row"> - <!-- table des résultats fixés --> - <div class="col mx-auto"> - <table class="table" style="border: 1px solid rgb(230,230,230);"> - <tr> - <th class="result_center"> - {{ uitextParamFixes }} - </th> - <th class="result_center"> - {{ uitextValeurs }} - </th> - </tr> - <tr *ngFor="let r of fixedParams; let i=index"> - <td class="result_right {{getFixedParamClass(i)}}"> - {{ formattedLabel(r) }} - </td> - <td class="result_center {{getFixedParamClass(i)}}"> - {{ formattedValue(r) }} - </td> - </tr> - <tr *ngIf="hasParameterResult" vertical-result-element [result-element]=resultElement [_label]=resultLabel> - </tr> - </table> - </div> - </div> -</div> \ No newline at end of file + <tr mat-header-row *matHeaderRowDef="tableColumns"></tr> + <tr mat-row *matRowDef="let row; columns: tableColumns;"></tr> + </table> +</div> diff --git a/src/app/components/fixedvar-results/fixed-results.component.scss b/src/app/components/fixedvar-results/fixed-results.component.scss new file mode 100644 index 0000000000000000000000000000000000000000..6884f3f370e00c829b993ac10a651536f736868c --- /dev/null +++ b/src/app/components/fixedvar-results/fixed-results.component.scss @@ -0,0 +1,33 @@ +:host { + display: block; +} + +.fixed-results-container { + margin-top: 1em; + border: solid #ccc 1px; + border-radius: 2px; +} + +table.mat-table { + + .mat-header-row { + height: 40px; + } + + .mat-row { + height: 32px; + + &:nth-child(odd) { + background-color: #f4f4f4; + } + } + + ::ng-deep .mat-header-cell { + font-size: 1em; + color: black; + } +} + +.highlightedResult { + font-weight: bold; +} diff --git a/src/app/components/fixedvar-results/fixed-results.component.ts b/src/app/components/fixedvar-results/fixed-results.component.ts index 0b7056b8f244a26aa4ef8da2dde10109002e0bbf..d9485bf0e7d14a84175d5a6c78f59869f57aab06 100644 --- a/src/app/components/fixedvar-results/fixed-results.component.ts +++ b/src/app/components/fixedvar-results/fixed-results.component.ts @@ -1,42 +1,29 @@ -import { Component } from "@angular/core"; +import { Component, ViewChild } from "@angular/core"; import { FixedResults } from "../../results/fixed-results"; import { NgParameter } from "../../formulaire/ngparam"; import { CalculatorResults } from "../../results/calculator-results"; -import { InternationalisationService } from "../../services/internationalisation/internationalisation.service"; +import { I18nService } from "../../services/internationalisation/internationalisation.service"; import { ApplicationSetupService } from "../../services/app-setup/app-setup.service"; -import { FixedVarResultsComponent } from "./fixedvar-results.component"; -import { ResultElement } from "jalhyd"; +import { MatTable } from "@angular/material"; @Component({ selector: "fixed-results", templateUrl: "./fixed-results.component.html", - styles: [` - .result_right { - text-align: right; - } - .result_center { - text-align: center; - } - .result_id_0 { - background-color: #f0f0f0; - } - .result_id_1 { - background-color: #ffffff; - } - .result_id_2 { - font-weight: bolder; - background-color: #00d0ff; - }`] + styleUrls: [ + "./fixed-results.component.scss" + ] }) export class FixedResultsComponent { - /** - * résultats non mis en forme - */ + /** résultats non mis en forme */ private _fixedResults: FixedResults; + @ViewChild(MatTable) table: MatTable<any>; + + public tableColumns = [ "parametre", "valeur" ]; + constructor( - private intlService: InternationalisationService, + private intlService: I18nService, private appSetupService: ApplicationSetupService, ) { } @@ -48,14 +35,6 @@ export class FixedResultsComponent { return this._fixedResults && this._fixedResults.hasResults; } - private get resultElement(): ResultElement { - return this._fixedResults && this._fixedResults.result && this._fixedResults.result.resultElement; - } - - private get resultLabel(): string { - return this._fixedResults && this._fixedResults.calculatedParameter && this._fixedResults.calculatedParameterHeader; - } - private get uitextParamFixes() { return this.intlService.localizeText("INFO_CALCULATOR_PARAMFIXES"); } @@ -64,13 +43,6 @@ export class FixedResultsComponent { return this.intlService.localizeText("INFO_CALCULATOR_VALEURS"); } - private getFixedParamClass(i: number) { - // if (this._results.isFixed && i === this._results.fixedResults.length - 1) - // return "font-weight-bold"; - // tslint:disable-next-line:no-bitwise - return "result_id_" + String(i & 1); - } - private get fixedParams() { return this._fixedResults && this._fixedResults.fixedParameters; } @@ -88,7 +60,37 @@ export class FixedResultsComponent { return p.getValue().toFixed(nDigits); } - private get hasResults(): boolean { - return this._fixedResults && this._fixedResults.hasResults; + /** + * Returns a combination of and results and extraResults for mat-table + */ + public get dataSet() { + const data = []; + // 1. fixed parameters + for (const fp of this.fixedParams) { + data.push({ + label: this.formattedLabel(fp), + value: this.formattedValue(fp), + isCalcResult: false // for CSS + }); + } + // 2. calculation results + if ( + this._fixedResults.result + && this._fixedResults.result.resultElement + && this._fixedResults.result.resultElement.extraResults + ) { + const extraResults = this._fixedResults.result.resultElement.extraResults; + for (const k in extraResults) { + if (extraResults.hasOwnProperty(k)) { + const er: number = extraResults[k]; + data.push({ + label: this.intlService.getExtraResLabel(k), + value: this.intlService.formatResult(k, er), + isCalcResult: true // for CSS + }); + } + } + } + return data; } } diff --git a/src/app/components/fixedvar-results/fixedvar-results.component.html b/src/app/components/fixedvar-results/fixedvar-results.component.html index a1fdb27695d8feb5ec033c2e7914fcf83ad55690..3ce5407546563ed4768f6c3990648ac5d0a341b5 100644 --- a/src/app/components/fixedvar-results/fixedvar-results.component.html +++ b/src/app/components/fixedvar-results/fixedvar-results.component.html @@ -1,23 +1,15 @@ -<div class="container-fluid"> +<div class="container"> <!-- journal --> <log></log> <results-graph *ngIf="showVarResults"></results-graph> - <!-- - classe conditionnelle : - [ngClass]="(condition) ? 'classe-si-vrai' : 'classe-si-faux'" - --> - - <div class="row"> + <div> <!-- table des résultats fixés --> - <!-- <div class="col mx-auto" *ngIf="showFixedResults"> --> - <div class="col mx-auto"> - <fixed-results [results]=fixedResults></fixed-results> - </div> + <fixed-results [results]=fixedResults></fixed-results> <!-- table des résultats variés --> - <div class="col" *ngIf="showVarResults"> + <div *ngIf="showVarResults"> <var-results [results]=varResults></var-results> </div> </div> diff --git a/src/app/components/fixedvar-results/fixedvar-results.component.ts b/src/app/components/fixedvar-results/fixedvar-results.component.ts index 8ef80d00cd31c5d87f31be25ce9ab12d22620246..d6dca7a41a47100383d7af0cc518c1190b680ad1 100644 --- a/src/app/components/fixedvar-results/fixedvar-results.component.ts +++ b/src/app/components/fixedvar-results/fixedvar-results.component.ts @@ -1,6 +1,6 @@ import { Component, ViewChild, DoCheck } from "@angular/core"; -import { InternationalisationService } from "../../services/internationalisation/internationalisation.service"; +import { I18nService } from "../../services/internationalisation/internationalisation.service"; import { LogComponent } from "../../components/log/log.component"; import { FixedResults } from "../../results/fixed-results"; import { VarResults } from "../../results/var-results"; @@ -66,7 +66,7 @@ export class FixedVarResultsComponent implements DoCheck { private resultsGraphComponent: ResultsGraphComponent; constructor( - private intlService: InternationalisationService, + private intlService: I18nService, private appSetupService: ApplicationSetupService, ) { } diff --git a/src/app/components/fixedvar-results/var-results.component.html b/src/app/components/fixedvar-results/var-results.component.html index 8ace914cfaca4b2895cb63e8bcb3aaca8b4defd5..f89799dfd48f3e55d2f516df358b3ccf908c93a3 100644 --- a/src/app/components/fixedvar-results/var-results.component.html +++ b/src/app/components/fixedvar-results/var-results.component.html @@ -1,21 +1,15 @@ -<div class="container-fluid" [style.display]="hasResults"> - <div class="row"> - <!-- table des résultats variés --> - <div class="col"> - <table class="table table-striped" style="border: 1px solid rgb(230,230,230);"> - <tr> - <th *ngFor="let h of headers">{{ h }}</th> - </tr> - <tr *ngFor="let r of rawResults; let i=index"> - <!-- paramètre varié --> - <td class="result_center"> - {{ r.param }} - </td> - <!-- résultat --> - <td horizontal-result-element [result-element]=r.result [headerKeys]=extraResultKeys> - </td> - </tr> - </table> - </div> +<div class="var-results-container"> + <!-- scrollable --> + <div class="var-results-inner-container"> + + <table mat-table [dataSource]="dataSet"> + <ng-container *ngFor="let h of headers; let i = index" [matColumnDef]="h"> + <th mat-header-cell *matHeaderCellDef>{{ h }}</th> + <td mat-cell *matCellDef="let element">{{ element[i] }}</td> + </ng-container> + + <tr mat-header-row *matHeaderRowDef="headers"></tr> + <tr mat-row *matRowDef="let row; columns: headers;"></tr> + </table> </div> -</div> \ No newline at end of file +</div> diff --git a/src/app/components/fixedvar-results/var-results.component.scss b/src/app/components/fixedvar-results/var-results.component.scss new file mode 100644 index 0000000000000000000000000000000000000000..d8b8f970ea6ea458e1f1ccf4acccb0a6839af5f1 --- /dev/null +++ b/src/app/components/fixedvar-results/var-results.component.scss @@ -0,0 +1,34 @@ +:host { + display: block; +} + +.var-results-container { + overflow-x: scroll; + margin-top: 2em; + border: solid #ccc 1px; +} + +table.mat-table { + + .mat-header-row { + height: 40px; + } + + .mat-row { + height: 32px; + + &:nth-child(odd) { + background-color: #f4f4f4; + } + } + + ::ng-deep .mat-cell { + padding: 5px; + } + + ::ng-deep .mat-header-cell { + font-size: 1em; + color: black; + padding: 5px; + } +} diff --git a/src/app/components/fixedvar-results/var-results.component.ts b/src/app/components/fixedvar-results/var-results.component.ts index a7df06053b68ab943b682b826c78fbe4f5e0ef6c..ddc5eee572aec11b83c9f2db8b9e53a8d498e73d 100644 --- a/src/app/components/fixedvar-results/var-results.component.ts +++ b/src/app/components/fixedvar-results/var-results.component.ts @@ -1,33 +1,34 @@ -import { Component, Input } from "@angular/core"; - -import { InternationalisationService } from "../../services/internationalisation/internationalisation.service"; +import { Component, ViewChild } from "@angular/core"; +import { MatTable } from "@angular/material"; import { VarResults } from "../../results/var-results"; import { ApplicationSetupService } from "../../services/app-setup/app-setup.service"; import { ResultElement } from "jalhyd"; +import { I18nService } from "../../services/internationalisation/internationalisation.service"; +import { nbind } from 'q'; @Component({ selector: "var-results", - templateUrl: "./var-results.component.html" + templateUrl: "./var-results.component.html", + styleUrls: [ + "./var-results.component.scss" + ] }) export class VarResultsComponent { - /** - * résultats non mis en forme - */ + + /** résultats non mis en forme */ private _varResults: VarResults; - /** - * résultats mis en forme - */ + /** résultats mis en forme */ private _results: any[]; - /** - * entêtes des colonnes (param à varier, à calculer + extraResults) - */ + /** entêtes des colonnes (param à varier, à calculer + extraResults) */ private _headers: string[]; + @ViewChild(MatTable) table: MatTable<any>; + constructor( - private intlService: InternationalisationService, private appSetupService: ApplicationSetupService, + private intlService: I18nService ) { } public set results(r: VarResults) { @@ -55,15 +56,43 @@ export class VarResultsComponent { return this._varResults && this._varResults.hasResults; } - private get extraResultKeys() { - return this._varResults && this._varResults.extraResultKeys; - } - public get headers() { return this._headers; } - public get rawResults() { - return this._results; + /** + * Returns a combination of and results and extraResults for mat-table + */ + public get dataSet() { + const data = []; + const nDigits = this.appSetupService.displayDigits; + if (this._results) { + for (let i = 0; i < this._results.length; i++) { + const r = this._results[i]; + const re: ResultElement = this._varResults.resultElements[i]; + + // for each computation step, build ordered list of : variable param value; result; extra results + + // 1. variable param value + const list = [ r.param ]; + + // 2. result + // list.push(re.vCalc.toFixed(nDigits)); + list.push(re.vCalc.toFixed(nDigits)); + + // 3. extra results + for (const erk of this._varResults.extraResultKeys) { + const er = re.getExtraResult(erk); + if (er !== undefined) { + list.push(this.intlService.formatResult(erk, er)); + } else { + list.push(er); // keep list ordered + } + + } + data.push(list); + } + } + return data; } } diff --git a/src/app/components/generic-calculator/calc-name.component.html b/src/app/components/generic-calculator/calc-name.component.html new file mode 100644 index 0000000000000000000000000000000000000000..3866997a9293167d49281314dc156818649c9b17 --- /dev/null +++ b/src/app/components/generic-calculator/calc-name.component.html @@ -0,0 +1,5 @@ +<mat-form-field> + <input matInput #inputControl="ngModel" class="form-control" type="text" + [id]="inputId" [(ngModel)]="uiValue" [placeholder]="title" required> + <mat-error>{{ errorMessage }}</mat-error> +</mat-form-field> diff --git a/src/app/components/generic-calculator/calc-name.component.scss b/src/app/components/generic-calculator/calc-name.component.scss new file mode 100644 index 0000000000000000000000000000000000000000..4227b604dd8b6e9ab63bdb4445e3a2292ec2077c --- /dev/null +++ b/src/app/components/generic-calculator/calc-name.component.scss @@ -0,0 +1,21 @@ +:host { + display: block; +} + +mat-form-field { + width: 100%; + + &.mat-form-field-invalid { + margin-bottom: 1em; + } + + ::ng-deep .mat-form-field-label { + font-size: 1.1em; + line-height: 1.4em; + margin-top: -2px; + + &.mat-form-field-empty { + font-size: 1em; + } + } +} diff --git a/src/app/components/generic-calculator/calc-name.component.ts b/src/app/components/generic-calculator/calc-name.component.ts index 21e9d67ac354a551f1432f3422421d273ffcce74..70c236305fa3c4f667eb8fc1b8b95fb8914d65dc 100644 --- a/src/app/components/generic-calculator/calc-name.component.ts +++ b/src/app/components/generic-calculator/calc-name.component.ts @@ -4,7 +4,10 @@ import { FormulaireDefinition } from "../../formulaire/definition/form-definitio @Component({ selector: "calc-name", - templateUrl: "../generic-input/generic-input.component.html", + templateUrl: "./calc-name.component.html", + styleUrls: [ + "./calc-name.component.scss" + ] }) export class CalculatorNameComponent extends GenericInputComponent { @@ -23,10 +26,9 @@ export class CalculatorNameComponent extends GenericInputComponent { * retourne la valeur du modèle */ protected getModelValue(): any { - if (this._form === undefined) { - return undefined; + if (this._form) { + return this._form.calculatorName; } - return this._form.calculatorName; } /** @@ -56,13 +58,6 @@ export class CalculatorNameComponent extends GenericInputComponent { return { isValid: valid, message: msg }; } - /** - * convertit le modèle en valeur affichable par l'UI - */ - protected modelToUI(v: any): string { - return v; - } - /** * valide une valeur saisie dans l'UI (forme de la saisie : est ce bien une date, un nombre, ...) * @param ui valide la valeur saisie diff --git a/src/app/components/generic-calculator/calculator.component.html b/src/app/components/generic-calculator/calculator.component.html index 1afebb5b545461c5004a1af63507d6cc11b172a3..97446a3a9ce637f766b03da297a2b9882472b0e1 100644 --- a/src/app/components/generic-calculator/calculator.component.html +++ b/src/app/components/generic-calculator/calculator.component.html @@ -1,74 +1,64 @@ -<div class="row"> - <!-- titre --> - <div class="col"> +<mat-card id="calculator-card"> + + <mat-card-header> + + <div class="hyd-window-btns"> + <!-- bouton d'aide --> + <mat-icon *ngIf="enableHelpButton" (click)="openHelp()" color="accent">help</mat-icon> + <!-- bouton de sauvegarde --> + <mat-icon (click)="saveCalculator()">save_alt</mat-icon> + <!-- bouton de fermeture --> + <mat-icon (click)="closeCalculator()">close</mat-icon> + </div> + + <!-- titre --> <!-- on utilise [innerHTML] pour que les codes HTML comme soient interprétés correctement --> - <h1 [innerHTML]="uitextTitre"></h1> - </div> + <mat-card-title> + <h1 [innerHTML]="uitextTitre"></h1> + </mat-card-title> - <div class="col-sm-3 px-0 mx-0 fa-stack fa-2x hyd-window-btns"> - <!-- bouton d'aide --> - <i *ngIf="enableHelpButton" class="fa fa-question-circle" style="color:blue" (click)="openHelp()"></i> - <!-- bouton de sauvegarde --> - <i class="fa fa-save" (click)="saveCalculator()"></i> - <!-- bouton de fermeture --> - <i class="fa fa-window-close" (click)="confirmModal.show()"></i> - </div> -</div> + </mat-card-header> -<!-- nom de la calculette --> -<div class="row"> - <div class="col-md-6"> - <calc-name title="Nom de la calculette"></calc-name> - </div> -</div> + <form> -<div class="row"> - <div [ngClass]="(hasResults) ? 'col-12 col-lg-6' : 'col-12'"> - <div class="container-fluid"> - <!-- chapitres --> - <ng-template ngFor let-fe [ngForOf]="formElements"> - <field-set *ngIf="isFieldset(fe)" [style.display]="getFieldsetStyleDisplay(fe.id)" [fieldSet]=fe (radio)=onRadioClick($event) - (validChange)=OnFieldsetValid() (inputChange)=onInputChange()></field-set> + <mat-card-content> - <fieldset-container *ngIf="isFieldsetContainer(fe)" [_container]=fe (radio)=onRadioClick($event) (validChange)=onFieldsetContainerValid()></fieldset-container> - </ng-template> - </div> + <!-- nom du module de calcul --> + <calc-name [title]="uitextCalculatorName"></calc-name> - <!-- bouton calculer --> - <div class="row"> - <div class="col-12 text-center"> - <button type="button" [ngClass]="(isCalculateDisabled) ? 'button_compute_err' : 'button_compute_ok'" name="Calculer" (click)="doCompute()" - [disabled]="isCalculateDisabled">{{ uitextCalculer }}</button> - <p></p> - <p></p> - </div> - </div> + <div id="calc-cards-container" class="container" fxLayout="row wrap" fxLayoutAlign="space-around start"> + <!-- chapitres --> + <mat-card id="calc-card-field-sets" fxFlex.gt-xs="1 0 400px" fxFlex.lt-sm="1 0 300px"> + <ng-template ngFor let-fe [ngForOf]="formElements"> + <field-set *ngIf="isFieldset(fe)" [style.display]="getFieldsetStyleDisplay(fe.id)" [fieldSet]=fe (radio)=onRadioClick($event) + (validChange)=OnFieldsetValid() (inputChange)=onInputChange()></field-set> - </div> + <fieldset-container *ngIf="isFieldsetContainer(fe)" [_container]=fe (radio)=onRadioClick($event) (validChange)=onFieldsetContainerValid()></fieldset-container> + </ng-template> - <!-- résultats --> - <div [ngClass]="(hasResults) ? 'col-12 col-lg-6' : 'col-12'"> - <calc-results id="resultsComp" (afterViewChecked)="onCalcResultsViewChecked()"></calc-results> - </div> -</div> + <mat-card-actions> + <!-- bouton calculer --> + <button mat-raised-button color="accent" name="Calculer" (click)="doCompute()"[disabled]="isCalculateDisabled"> + {{ uitextCalculer }} + </button> + </mat-card-actions> + </mat-card> + + <!-- résultats --> + <mat-card id="calc-card-results" fxFlex.gt-xs="1 0 400px" fxFlex.lt-sm="1 0 300px"> + <mat-card-header> + <mat-card-title> + <h1 [innerHTML]="uitextResultsTitle"></h1> + </mat-card-title> + </mat-card-header> + <mat-card-content> + <calc-results id="resultsComp" (afterViewChecked)="onCalcResultsViewChecked()"></calc-results> + </mat-card-content> + </mat-card> -<!-- dialogue de confirmation de fermeture --> -<div mdbModal #confirmModal="mdb-modal" class="modal fade" tabindex="-1" role="dialog" aria-hidden="true" [config]="{backdrop: false, ignoreBackdropClick: true}"> - <div class="modal-dialog" role="document"> - <div class="modal-content"> - <div class="modal-header"> - <button type="button" class="close pull-right" aria-label="Close" (click)="confirmModal.hide()"> - <span aria-hidden="true">×</span> - </button> - <h4 class="modal-title w-100" id="myModalLabel">{{ uitextCloseDialogTitle }}</h4> - </div> - <div class="modal-body"> - <h4 [innerHTML]="uitextCloseDialogText"></h4> - </div> - <div class="modal-footer"> - <button type="button" class="btn btn-danger relative waves-light" (click)="confirmModal.hide();onCloseForm()" mdbRippleRadius>{{ uitextCloseDialogYes }}</button> - <button type="button" class="btn btn-success waves-light" aria-label="Close" (click)="confirmModal.hide()" mdbRippleRadius>{{ uitextCloseDialogNo }}</button> </div> - </div> - </div> -</div> \ No newline at end of file + </mat-card-content> + + </form> + +</mat-card> diff --git a/src/app/components/generic-calculator/calculator.component.scss b/src/app/components/generic-calculator/calculator.component.scss index 161ef097e90f68ce7fc97d37d3befcbea5fdb574..b9275137bf8288272c846be0520777d73c5e211f 100644 --- a/src/app/components/generic-calculator/calculator.component.scss +++ b/src/app/components/generic-calculator/calculator.component.scss @@ -1,19 +1,66 @@ +.hyd-window-btns { + position: absolute; + right: 1em; + text-align: right; - .button_compute_ok { - height: 3em; - width: 30%; + mat-icon { + cursor: pointer; + margin-right: 5px; } +} - .button_compute_err { - height: 3em; - width: 30%; - color: red +#calc-cards-container { + margin-left: -1em; + margin-right: -1em; +} + +mat-card { + margin-bottom: 2em; + + // main card + &#calculator-card { + + > mat-card-header { + margin-bottom: .5em; + padding-right: 6em; // space for right corner buttons + } + } + + // cards inside main card + + &#calc-card-field-sets { + margin-left: 1em; + margin-right: 1em; + + mat-card-actions { + text-align: center; + + button { + padding: .5em 3em; + } + } } - .hyd-window-btns { - text-align: right; - - i.fa { - margin-right: 5px; + &#calc-card-results { + margin-left: 1em; + margin-right: 1em; + + mat-card-header { + margin-bottom: 1em; } - } \ No newline at end of file + } + + // @WARNING ::ng-deep est déprécié, mais y a rien d'autre pour + // l'instant (en attente de normalisation par le W3C) + ::ng-deep .mat-card-header-text { + margin: 0; + } + + mat-card-header { + + mat-card-title { + font-size: 16px; + margin-bottom: 8px; + } + } +} diff --git a/src/app/components/generic-calculator/calculator.component.ts b/src/app/components/generic-calculator/calculator.component.ts index c71f47b8597e18dc8d76f7aad080d6289e0eab7a..ffc2cf9d8fe41c3d9a92fa0beffdbfdd59f30eed 100644 --- a/src/app/components/generic-calculator/calculator.component.ts +++ b/src/app/components/generic-calculator/calculator.component.ts @@ -4,7 +4,7 @@ import { ActivatedRoute } from "@angular/router"; import { Observer } from "jalhyd"; import { FormulaireService } from "../../services/formulaire/formulaire.service"; -import { InternationalisationService } from "../../services/internationalisation/internationalisation.service"; +import { I18nService } from "../../services/internationalisation/internationalisation.service"; import { FieldSet } from "../../formulaire/fieldset"; import { FormulaireDefinition } from "../../formulaire/definition/form-definition"; import { CalculatorResultsComponent } from "../../components/calculator-results/calculator-results.component"; @@ -16,6 +16,8 @@ import { FormulaireElement } from "../../formulaire/formulaire-element"; import { FieldsetContainer } from "../../formulaire/fieldset-container"; import { FieldsetContainerComponent } from "../fieldset-container/fieldset-container.component"; import { ServiceFactory } from "../../services/service-factory"; +import { MatDialog } from "@angular/material"; +import { DialogConfirmCloseCalcComponent } from "../dialog-confirm-close-calc/dialog-confirm-close-calc.component"; @Component({ selector: "hydrocalc", @@ -42,7 +44,7 @@ export class GenericCalculatorComponent extends BaseComponent implements OnInit, private resultsComponent: CalculatorResultsComponent; /** - * composant "nom de la calculette" + * composant "nom du module de calcul" */ @ViewChild(CalculatorNameComponent) private _calculatorNameComponent: CalculatorNameComponent; @@ -82,12 +84,15 @@ export class GenericCalculatorComponent extends BaseComponent implements OnInit, // services - private intlService: InternationalisationService; + private intlService: I18nService; private formulaireService: FormulaireService; - constructor(private route: ActivatedRoute) { + constructor( + private route: ActivatedRoute, + private confirmCloseCalcDialog: MatDialog + ) { super(); - this.intlService = ServiceFactory.instance.internationalisationService; + this.intlService = ServiceFactory.instance.i18nService; this.formulaireService = ServiceFactory.instance.formulaireService; } @@ -127,27 +132,18 @@ export class GenericCalculatorComponent extends BaseComponent implements OnInit, if (this.hasForm) { return this.formulaireService.getLocalisedTitleFromCalculatorType(this._formulaire.calculatorType); } - return undefined; } public get uitextCalculer() { return this.intlService.localizeText("INFO_CALCULATOR_CALCULER"); } - public get uitextCloseDialogTitle() { - return this.intlService.localizeText("INFO_CLOSE_DIALOGUE_TITRE"); + public get uitextCalculatorName() { + return this.intlService.localizeText("INFO_CALCULATOR_CALC_NAME"); } - public get uitextCloseDialogText() { - return this.intlService.localizeText("INFO_CLOSE_DIALOGUE_TEXT"); - } - - public get uitextCloseDialogYes() { - return this.intlService.localizeText("INFO_OPTION_YES"); - } - - public get uitextCloseDialogNo() { - return this.intlService.localizeText("INFO_OPTION_NO"); + public get uitextResultsTitle() { + return this.intlService.localizeText("INFO_CALCULATOR_RESULTS_TITLE"); } ngOnInit() { @@ -275,7 +271,7 @@ export class GenericCalculatorComponent extends BaseComponent implements OnInit, // interface Observer update(sender: any, data: any): void { - if (sender instanceof InternationalisationService) { + if (sender instanceof I18nService) { this.formulaireService.updateLocalisation(); } else if (sender instanceof FormulaireService) { switch (data["action"]) { @@ -391,4 +387,16 @@ export class GenericCalculatorComponent extends BaseComponent implements OnInit, public saveCalculator() { this.formulaireService.saveForm(this._formulaire); } + + public closeCalculator() { + const dialogRef = this.confirmCloseCalcDialog.open( + DialogConfirmCloseCalcComponent, + { disableClose: true } + ); + dialogRef.afterClosed().subscribe(result => { + if (result) { + this.onCloseForm(); + } + }); + } } diff --git a/src/app/components/generic-input/generic-input.component.html b/src/app/components/generic-input/generic-input.component.html index 1f81ebe23535ecddd6fc1f3d1d846c80ec8be0c8..f6ca6506f4d99ffcef937546366fca94cbcf63eb 100644 --- a/src/app/components/generic-input/generic-input.component.html +++ b/src/app/components/generic-input/generic-input.component.html @@ -1,6 +1,7 @@ -<div class="md-form form-sm"> - <input mdbInputDirective [mdbValidate]="false" type="text" [id]="inputId" class="form-control" [disabled]="isDisabled" [(ngModel)]="uiValue"> - <!-- on utilise [innerHTML] pour que les codes HTML comme soient interprétés correctement --> - <label [for]="inputId" [innerHTML]="title"></label> - <small *ngIf="showError" class="text-danger" [innerHTML]="errorMessage"></small> -</div> \ No newline at end of file +<mat-form-field> + <input matInput #inputControl="ngModel" class="form-control" type="text" inputmode="numeric" + [id]="inputId" [name]="inputId" [disabled]="isDisabled" [(ngModel)]="uiValue" [placeholder]="title" + pattern="^-?([0-9]*\.)?([0-9]+[Ee]-?)?[0-9]+$" required> + + <mat-error>{{ errorMessage }}</mat-error> +</mat-form-field> diff --git a/src/app/components/generic-input/generic-input.component.ts b/src/app/components/generic-input/generic-input.component.ts index 90c2e7c034564425ab9aad6bb68fb724a5f724a2..a7cd9064ce906ff59382e4dc0382751f45fd1073 100644 --- a/src/app/components/generic-input/generic-input.component.ts +++ b/src/app/components/generic-input/generic-input.component.ts @@ -1,17 +1,7 @@ -import { Input, Output, EventEmitter, ChangeDetectorRef, OnChanges } from "@angular/core"; - +import { Input, Output, EventEmitter, ChangeDetectorRef, OnChanges, ViewChild } from "@angular/core"; +import { NgModel } from "@angular/forms"; import { BaseComponent } from "../base/base.component"; - -/* -exemple de template : - -<div class="md-form form-sm"> - <input mdbActive type="text" id="form1" class="form-control" [disabled]="isDisabled" - [ngModel]="uiValue" (ngModelChange)="setUIValue($event)"> - <label for="form1">{{title}}</label> - <small class="text-danger">{{_message}}</small> -</div> -*/ +import { isNumeric } from "jalhyd"; /** * classe de gestion générique d'un champ de saisie avec titre, validation et message d'erreur @@ -27,7 +17,7 @@ export abstract class GenericInputComponent extends BaseComponent implements OnC /** * entité mémoire gérée */ - protected _model: any; + protected _model: any; // NgBaseParam mais aussi FormDefinition parfois (!?) /** * flag de désactivation de l'input @@ -85,6 +75,8 @@ export abstract class GenericInputComponent extends BaseComponent implements OnC */ private _errorMessageModel: string; + @ViewChild("inputControl") inputField: NgModel; + constructor(private cdRef: ChangeDetectorRef) { super(); // generate "unique" input id @@ -142,6 +134,12 @@ export abstract class GenericInputComponent extends BaseComponent implements OnC if (this.isValid !== old) { this.emitValidChanged(); } + // répercussion des erreurs sur le Form angular, pour faire apparaître/disparaître les mat-error + if (b) { + this.inputField.control.setErrors(null); + } else { + this.inputField.control.setErrors({ "incorrect": true }); + } } private validateModel() { @@ -160,7 +158,7 @@ export abstract class GenericInputComponent extends BaseComponent implements OnC * getter du message d'erreur affiché. * L'erreur de forme (UI) est prioritaire */ - private get errorMessage() { + public get errorMessage() { if (this._errorMessageUI !== undefined) { return this._errorMessageUI; } @@ -268,7 +266,9 @@ export abstract class GenericInputComponent extends BaseComponent implements OnC /** * convertit le modèle en valeur affichable par l'UI */ - protected abstract modelToUI(v: any): string; + protected modelToUI(v: any): string { + return String(v); + } /** * valide une valeur saisie dans l'UI (forme de la saisie : est ce bien une date, un nombre, ...) @@ -276,12 +276,25 @@ export abstract class GenericInputComponent extends BaseComponent implements OnC * @returns isValid : true si la valeur est valide, false sinon * @returns message : message d'erreur */ - protected abstract validateUIValue(ui: string): { isValid: boolean, message: string }; + protected validateUIValue(ui: string): { isValid: boolean, message: string } { + let valid = false; + let msg: string; + + if (! isNumeric(ui)) { + msg = "Veuillez entrer une valeur numérique"; + } else { + valid = true; + } + + return { isValid: valid, message: msg }; + } /** * convertit une valeur saisie dans l'UI en valeur affectable au modèle */ - protected abstract uiToModel(ui: string): any; + protected uiToModel(ui: string): any { + return +ui; + } } /* @@ -298,7 +311,7 @@ import { isNumeric, Message } from "jalhyd"; @Component({ selector: "test-input", template: `<div class="md-form form-sm"> - <input mdbActive type="text" id="form1" class="form-control" [disabled]="isDisabled" [(ngModel)]="uiValue"> + <input type="text" id="form1" class="form-control" [disabled]="isDisabled" [(ngModel)]="uiValue"> <label for="form1">{{title}}</label> <small *ngIf="showError" class="text-danger">{{errorMessage}}</small> </div>` @@ -329,24 +342,6 @@ export class TestInputComponent extends GenericInputComponent { return { isValid: valid, message: msg }; } - protected modelToUI(v: any): string { - if (typeof (v) === "number") - return String(v); - return undefined; - } - - protected validateUIValue(ui: string): { isValid: boolean, message: string } { - let valid: boolean = false; - let msg: string = undefined; - - if (! isNumeric(ui)) - msg = "Veuillez entrer une valeur numérique"; - else - valid = true; - - return { isValid: valid, message: msg }; - } - protected uiToModel(ui: string): any { return +ui; } @@ -360,7 +355,7 @@ import { ParamDefinition } from "jalhyd"; @Component({ selector: "test2-input", template: `<div class="md-form form-sm"> - <input mdbActive type="text" id="form1" class="form-control" [disabled]="isDisabled" [(ngModel)]="uiValue"> + <input type="text" id="form1" class="form-control" [disabled]="isDisabled" [(ngModel)]="uiValue"> <label for="form1">{{title}}</label> <small *ngIf="showError" class="text-danger">{{errorMessage}}</small> </div>` @@ -394,27 +389,5 @@ export class Test2InputComponent extends GenericInputComponent { return { isValid: valid, message: msg }; } - - protected modelToUI(v: any): string { - if (typeof (v) === "number") - return String(v); - return undefined; - } - - protected validateUIValue(ui: string): { isValid: boolean, message: string } { - let valid: boolean = false; - let msg: string = undefined; - - if (! isNumeric(ui)) - msg = "Veuillez entrer une valeur numérique"; - else - valid = true; - - return { isValid: valid, message: msg }; - } - - protected uiToModel(ui: string): any { - return +ui; - } } /**/ diff --git a/src/app/components/generic-select/generic-select.component.html b/src/app/components/generic-select/generic-select.component.html index 8edaab39d123f794448d7abf0090a5cc81ad6419..da7a82515f0406dfc56beb7a36b4e61fc37ac7ac 100644 --- a/src/app/components/generic-select/generic-select.component.html +++ b/src/app/components/generic-select/generic-select.component.html @@ -1,8 +1,7 @@ -<div class="btn-group" dropdown (click)="onSelect($event)"> - <button dropdownToggle class="btn btn-primary dropdown-toggle waves-light my-1" type="button" mdbRippleRadius> - {{ currentLabel }} - </button> - <div class="dropdown-menu"> - <a class="dropdown-item" *ngFor="let e of entries" [value]=e>{{ entryLabel(e) }}</a> - </div> -</div> \ No newline at end of file +<mat-form-field> + <mat-select [placeholder]="label" [(value)]="selectedValue"> + <mat-option *ngFor="let e of entries" [value]="e"> + {{ entryLabel(e) }} + </mat-option> + </mat-select> +</mat-form-field> diff --git a/src/app/components/generic-select/generic-select.component.ts b/src/app/components/generic-select/generic-select.component.ts deleted file mode 100644 index 6614882ab63ed2f13e6b8fdcfe329dc97f7a6d80..0000000000000000000000000000000000000000 --- a/src/app/components/generic-select/generic-select.component.ts +++ /dev/null @@ -1,65 +0,0 @@ -import { Component, Output, EventEmitter } from "@angular/core"; -import { BaseComponent } from "../base/base.component"; - -/* - exemple de template : - -<div class="btn-group" dropdown (click)="onSelect($event)"> - <button dropdownToggle class="btn btn-primary dropdown-toggle waves-light my-1" type="button" mdbRippleRadius> - {{currentLabel}} - </button> - <div class="dropdown-menu"> - <a class="dropdown-item" *ngFor="let e of entries" [value]=e>{{entryLabel(e)}}</a> - </div> -</div> -*/ - -export abstract class GenericSelectComponent<T> { - - private _currentLabel: string; - - public get currentLabel(): string { - if (! this._currentLabel) { - this._currentLabel = this.selectedLabel; - } - return this._currentLabel; - } - - /** - * appelé quand la valeur courante change dans l'UI - */ - public onSelect(event: any) { - const val = event.target.value; - if (val !== undefined && val !== "") { // might be 0; opening the menu returns "" - this.selectedValue = val; - this._currentLabel = this.selectedLabel; - } - } - - private get selectedLabel(): string { - for (const e of this.entries) { - if (e === this.selectedValue) { - return this.entryLabel(e); - } - } - } - - /** - * liste des objets sélectionnables - */ - public abstract get entries(): any[]; - - /** - * calcule l'étiquette d'une entrée (ce qui est affiché dans la liste déroulante) - */ - protected abstract entryLabel(entry: any): string; - - /** - * valeur actuellement sélectionnée - * la valeur repère une entrée de la liste (cf. [value] dans le template) - */ - public abstract get selectedValue(): T; - - - public abstract set selectedValue(v: T); -} diff --git a/src/app/components/load-calculator/load-calculator-anchor.directive.ts b/src/app/components/load-calculator/load-calculator-anchor.directive.ts deleted file mode 100644 index 8d9b713edb554873a7758d464c188aef87ea5041..0000000000000000000000000000000000000000 --- a/src/app/components/load-calculator/load-calculator-anchor.directive.ts +++ /dev/null @@ -1,28 +0,0 @@ -import { Directive, ComponentFactoryResolver, ComponentFactory, ComponentRef } from "@angular/core"; - -import { ViewContainerRef } from "@angular/core"; -import { LoadCalculatorComponent } from "./load-calculator.component"; - -@Directive({ - selector: "[appLoadCalcDialogAnchor]" -}) -export class LoadCalcDialogAnchorDirective { - constructor( - private viewContainer: ViewContainerRef, - private componentFactoryResolver: ComponentFactoryResolver - ) { } - - public createDialog(): ComponentRef<LoadCalculatorComponent> { - this.viewContainer.clear(); - - const compFactory: ComponentFactory<LoadCalculatorComponent> - = this.componentFactoryResolver.resolveComponentFactory(LoadCalculatorComponent); - const compRef: ComponentRef<LoadCalculatorComponent> = this.viewContainer.createComponent(compFactory); - - // compRef.instance.confirmResult.subscribe(() => { - // compRef.destroy(); - // }); - - return compRef; - } -} diff --git a/src/app/components/load-calculator/load-calculator.component.html b/src/app/components/load-calculator/load-calculator.component.html deleted file mode 100644 index e5233cc4725179ef87203859116bdcf6596ae2d7..0000000000000000000000000000000000000000 --- a/src/app/components/load-calculator/load-calculator.component.html +++ /dev/null @@ -1,24 +0,0 @@ -<div mdbModal #loadDialog="mdb-modal" class="modal fade" tabindex="-1" role="dialog" aria-hidden="true" [config]="{backdrop: false, ignoreBackdropClick: true,show:true}"> - <div class="modal-dialog" role="document"> - <div class="modal-content"> - <div class="modal-header"> - <h4 class="modal-title w-100" id="myModalLabel">{{ uitextDialogTitle }}</h4> - </div> - <div class="modal-body"> - <div> - <input type="file" #fileSelector multiple="false" accept="*.json" (change)="onFileSelect()"> - </div> - <div *ngFor="let c of calculators"> - <input type="checkbox" value={{c.uid}} checked={{isSelected(c)}} (change)="onCheckCalc($event)">{{ c.title }} - </div> - <button *ngIf="showSelectButtons" type="button" class="btn btn-mdb-color waves-light" (click)="selectAll()" mdbRippleRadius>{{ uitextSelectAll }}</button> - <button *ngIf="showSelectButtons" type="button" class="btn btn-mdb-color waves-light" (click)="deselectAll()" mdbRippleRadius>{{ uitextDeselectAll }}</button> - </div> - <div class="modal-footer"> - <button type="button" class="btn btn-danger relative waves-light" (click)="loadDialog.hide();cancelLoad()" mdbRippleRadius>{{ uitextCancel }}</button> - <button type="button" class="btn btn-success waves-light" [disabled]="disableLoadButton" (click)="loadDialog.hide();confirmLoad()" - mdbRippleRadius>{{ uitextLoad }}</button> - </div> - </div> - </div> -</div> \ No newline at end of file diff --git a/src/app/components/load-calculator/load-calculator.component.ts b/src/app/components/load-calculator/load-calculator.component.ts deleted file mode 100644 index 655d3baf237c65fd83cb55a0b718a97623ae2c94..0000000000000000000000000000000000000000 --- a/src/app/components/load-calculator/load-calculator.component.ts +++ /dev/null @@ -1,172 +0,0 @@ -import { Component, EventEmitter, ViewChild } from "@angular/core"; - -import { ServiceFactory } from "../../services/service-factory"; -import { InternationalisationService } from "../../services/internationalisation/internationalisation.service"; - -@Component({ - selector: "load-calc", - templateUrl: "./load-calculator.component.html" -}) -export class LoadCalculatorComponent { - @ViewChild("fileSelector") fileSelector; - - private _selectFile: File; - - /** - * liste des calculettes affichées. Forme des objets : - * "title": nom de la calculette - * "selected": flag de sélection pour la sauvegarde - */ - private _calculators: any[]; - - /** - * événement émis lors du clic sur "annuler"/"charger" - * utilisé par la promise de gestion de la confirmation/annulation de la sauvegarde - */ - private _confirmResult = new EventEmitter(); - - // services - private intlService: InternationalisationService; - - constructor() { - this.intlService = ServiceFactory.instance.internationalisationService; - } - - public get uitextDialogTitle() { - return "Charger des calculettes"; - } - - public get uitextCancel() { - // return this.intlService.localizeText("INFO_OPTION_NO"); - return "Annuler"; - } - - public get uitextLoad() { - // return this.intlService.localizeText("INFO_OPTION_NO"); - return "Charger"; - } - - public get uitextSelectAll() { - return "Toutes"; - } - - public get uitextDeselectAll() { - return "Aucune"; - } - - /** - * calcule l'état du bouton charger - */ - public get disableLoadButton() { - // pas de fichier sélectionné -> bouton grisé - if (this._selectFile === undefined) { - return true; - } - - // au moins une calculette sélectionnée -> dégrisé - if (this._calculators !== undefined) { - for (const c of this._calculators) { - if (c.selected) { - return false; - } - } - } - - // grisé sinon - return true; - } - - public run(): Promise<any[]> { - // promise de gestion de la confirmation/annulation de la sauvegarde - return new Promise((resolve, reject) => { - this._confirmResult.subscribe((confirm) => { - if (confirm) { - resolve(this._calculators); - } else { - reject("canceled"); - } - }); - }); - } - - public get showSelectButtons(): boolean { - return this._calculators && this._calculators.length !== 0; - } - - private getSelectedFile(): File { - const files: { [key: string]: File } = this.fileSelector.nativeElement.files; - for (const key in files) { - if (!isNaN(Number(key))) { - return files[key]; - } - } - return undefined; - } - - public onFileSelect() { - const formService = ServiceFactory.instance.formulaireService; - this._selectFile = this.getSelectedFile(); - if (this._selectFile !== undefined) { - formService.calculatorInfosFromSessionFile(this._selectFile).then( - calcInfos => { - this._calculators = calcInfos; - for (const n of this._calculators) { - n["selected"] = true; - } - }); - } - } - - public get selectedFile(): File { - return this._selectFile; - } - - public get calculators(): any[] { - return this._calculators; - } - - private isSelected(c: any) { - return c.selected ? "checked" : undefined; - } - - private onCheckCalc(event: any) { - for (const c of this._calculators) { - if (c.uid === event.target.value) { - c.selected = event.target.checked; - break; - } - } - } - - public selectAll() { - for (const c of this._calculators) { - c.selected = true; - } - } - - public deselectAll() { - for (const c of this._calculators) { - c.selected = false; - } - } - - private set confirmed(b: boolean) { - setTimeout(() => { - this._confirmResult.next(b); - }, 0); - } - - /** - * appelé quand on clique sur annuler - */ - public cancelLoad() { - this.confirmed = false; - } - - /** - * appelé quand on clique sur charger - */ - public confirmLoad() { - this.confirmed = true; - } -} diff --git a/src/app/components/log-entry/log-entry.component.html b/src/app/components/log-entry/log-entry.component.html index b603829536bc89da7a1d9c8a52de720ade88136d..666b2665ec957279afab7bfb9b4be8f8ad413dbc 100644 --- a/src/app/components/log-entry/log-entry.component.html +++ b/src/app/components/log-entry/log-entry.component.html @@ -1,11 +1,8 @@ -<div class="row entry"> - <div class="col-1" style="text-align: center;"> - <i *ngIf="levelInfo" class="fa fa-check" style="color:green"></i> - <i *ngIf="levelWarning" class="fa fa-exclamation" style="color:orange"></i> - <i *ngIf="levelError" class="fa fa-exclamation-triangle" style="color:red"></i> - </div> - <div class="col-11"> - <!-- on utilise [innerHTML] pour que les codes HTML comme soient interprétés correctement --> - <span [innerHTML]="text"></span> - </div> -</div> \ No newline at end of file +<div class="entry"> + <mat-icon *ngIf="levelInfo" style="color:green">check_circle</mat-icon> + <mat-icon *ngIf="levelWarning" style="color:orange">error_outline</mat-icon> + <mat-icon *ngIf="levelError" style="color:red">warning</mat-icon> + + <!-- on utilise [innerHTML] pour que les codes HTML comme soient interprétés correctement --> + <div class="entry-text" [innerHTML]="text"></div> +</div> diff --git a/src/app/components/log-entry/log-entry.component.scss b/src/app/components/log-entry/log-entry.component.scss new file mode 100644 index 0000000000000000000000000000000000000000..ba2c18727d2a51835e7d5a9674d8af2ed50d8d90 --- /dev/null +++ b/src/app/components/log-entry/log-entry.component.scss @@ -0,0 +1,13 @@ +.entry { + margin-top: 0.5em; + + mat-icon { + float: left; + } + + .entry-text { + padding-top: 4px; + padding-left: 32px; + margin-bottom: 12px; + } +} diff --git a/src/app/components/log-entry/log-entry.component.ts b/src/app/components/log-entry/log-entry.component.ts index 3b53858779aff9a9eef7182fbe49a396640e6c46..5bdc15e530f0f25d6e03906fbaa3c122d8e1cd53 100644 --- a/src/app/components/log-entry/log-entry.component.ts +++ b/src/app/components/log-entry/log-entry.component.ts @@ -2,20 +2,15 @@ import { Component, Input, OnChanges } from "@angular/core"; import { Message, MessageSeverity } from "jalhyd"; -import { InternationalisationService } from "../../services/internationalisation/internationalisation.service"; +import { I18nService } from "../../services/internationalisation/internationalisation.service"; import { ApplicationSetupService } from "../../services/app-setup/app-setup.service"; @Component({ selector: "log-entry", templateUrl: "./log-entry.component.html", - styles: [` - .entry { - margin-left: 1em; - margin-right: 1em; - margin-top: 0.5em; - margin-bottom: 0.5em; - } - `] + styleUrls: [ + "./log-entry.component.scss" + ] }) export class LogEntryComponent implements OnChanges { @@ -28,7 +23,7 @@ export class LogEntryComponent implements OnChanges { private _text: string; constructor( - private intlService: InternationalisationService, + private intlService: I18nService, private appSetupService: ApplicationSetupService ) { } diff --git a/src/app/components/log/log.component.html b/src/app/components/log/log.component.html index 15d92c0f171cb2dff50912c2fd91978c5af3a986..4d3d0424a7c33bd9da1816c6f61e0c749bcacfef 100644 --- a/src/app/components/log/log.component.html +++ b/src/app/components/log/log.component.html @@ -1,13 +1,8 @@ -<div class="row" *ngIf="hasEntries"> - <div class="col-12"> - <div class="hyd_log"> - <!-- titre --> - <div class="titre">{{ uitextTitreJournal }}</div> - - <!-- entrées du journal --> - <ng-template ngFor let-m [ngForOf]="messages"> - <log-entry [_message]=m></log-entry> - </ng-template> - </div> +<div *ngIf="hasEntries"> + <div class="hyd_log"> + <!-- titre --> + <div class="titre">{{ uitextTitreJournal }}</div> + <!-- entrées du journal --> + <log-entry *ngFor="let m of messages" [_message]="m"></log-entry> </div> -</div> \ No newline at end of file +</div> diff --git a/src/app/components/log/log.component.scss b/src/app/components/log/log.component.scss new file mode 100644 index 0000000000000000000000000000000000000000..7dee1f9239623da8254eb25fedcaebd2acff4697 --- /dev/null +++ b/src/app/components/log/log.component.scss @@ -0,0 +1,22 @@ +:host { + display: block; +} + +.hyd_log { + margin-top: 1em; + border: solid #ccc 1px; + border-radius: 2px; + padding: 1em; + padding-top : 1.3em; +} + +.titre { + background-color: white; + border: 1px solid #ccc; + border-radius: 2px; + float: left; + font-weight: bold; + margin-bottom: -1em; + margin-top: -2.3em; + padding: 0.2em 0.5em; +} diff --git a/src/app/components/log/log.component.ts b/src/app/components/log/log.component.ts index 67234e62f6a8bf6b9ec639660ac59bab4069c41b..bd710cb56a43ed8a4c927fe06ef90c9ae1f94c9a 100644 --- a/src/app/components/log/log.component.ts +++ b/src/app/components/log/log.component.ts @@ -2,31 +2,14 @@ import { Component } from "@angular/core"; import { cLog, Message } from "jalhyd"; -import { InternationalisationService } from "../../services/internationalisation/internationalisation.service"; +import { I18nService } from "../../services/internationalisation/internationalisation.service"; @Component({ selector: "log", templateUrl: "./log.component.html", - styles: [` - .hyd_log { - border : 1px solid black; - margin : 1.8em 0; - padding-top : 1.3em; - border-radius: 10px; - } - .titre { - background-color: #00b0ff; - border: 1px solid black; - border-radius: 5px; - float: left; - font-size: 1.15em; - font-weight: bold; - margin-bottom: -1em; - margin-left: 0.5em; - margin-top: -2.3em; - padding: 0.2em 0.5em; - } - `] + styleUrls: [ + "./log.component.scss" + ] }) export class LogComponent { /** @@ -35,7 +18,7 @@ export class LogComponent { private _log: cLog; constructor( - private intlService: InternationalisationService, + private intlService: I18nService, ) { } private get uitextTitreJournal() { diff --git a/src/app/components/ngparam-input/ngparam-input.component.scss b/src/app/components/ngparam-input/ngparam-input.component.scss new file mode 100644 index 0000000000000000000000000000000000000000..6d5f7d7edbaa8d3cd7e36d7d4bc4298200d0ea4f --- /dev/null +++ b/src/app/components/ngparam-input/ngparam-input.component.scss @@ -0,0 +1,23 @@ +:host { + display: block; + margin-top: 14px; +} + +mat-form-field { + width: calc(100% - 16px); + margin-right: 16px; + + ::ng-deep input.mat-input-element { + line-height: 1.3em; + } + + ::ng-deep .mat-form-field-label { + font-size: 1.1em; + line-height: 1.4em; + margin-top: -2px; + + &.mat-form-field-empty { + font-size: 1em; + } + } +} diff --git a/src/app/components/ngparam-input/ngparam-input.component.ts b/src/app/components/ngparam-input/ngparam-input.component.ts index 44ba1ed15637c76ef47855b772446d73eecc82d6..7e1af55cead345ce13871671d3174e359cfbc07f 100644 --- a/src/app/components/ngparam-input/ngparam-input.component.ts +++ b/src/app/components/ngparam-input/ngparam-input.component.ts @@ -2,15 +2,18 @@ import { Component, ChangeDetectorRef, OnDestroy } from "@angular/core"; -import { isNumeric, Message, Observer } from "jalhyd"; +import { Message, Observer } from "jalhyd"; -import { InternationalisationService } from "../../services/internationalisation/internationalisation.service"; +import { I18nService } from "../../services/internationalisation/internationalisation.service"; import { NgParameter } from "../../formulaire/ngparam"; import { GenericInputComponent } from "../generic-input/generic-input.component"; @Component({ selector: "ngparam-input", - templateUrl: "../generic-input/generic-input.component.html" + templateUrl: "../generic-input/generic-input.component.html", + styleUrls: [ + "./ngparam-input.component.scss" + ] }) export class NgParamInputComponent extends GenericInputComponent implements Observer, OnDestroy { /** @@ -26,7 +29,7 @@ export class NgParamInputComponent extends GenericInputComponent implements Obse */ private _tmp: number; - constructor(private intlService: InternationalisationService, cdRef: ChangeDetectorRef) { + constructor(private intlService: I18nService, cdRef: ChangeDetectorRef) { super(cdRef); } @@ -86,27 +89,6 @@ export class NgParamInputComponent extends GenericInputComponent implements Obse return { isValid: valid, message: msg }; } - protected modelToUI(v: any): string { - return String(v); - } - - protected validateUIValue(ui: string): { isValid: boolean, message: string } { - let valid = false; - let msg: string; - - if (! isNumeric(ui)) { - msg = "Veuillez entrer une valeur numérique"; - } else { - valid = true; - } - - return { isValid: valid, message: msg }; - } - - protected uiToModel(ui: string) { - return +ui; - } - public update(sender: any, data: any): void { switch (data["action"]) { case "ngparamAfterValue": diff --git a/src/app/components/param-computed/param-computed.component.html b/src/app/components/param-computed/param-computed.component.html new file mode 100644 index 0000000000000000000000000000000000000000..0751e36bf1dc93de19a451f8aefd886085dc6130 --- /dev/null +++ b/src/app/components/param-computed/param-computed.component.html @@ -0,0 +1,7 @@ +<!-- a fake input bound to nothing, for the sake of UI consistency --> +<mat-form-field> + <input matInput disabled class="form-control" type="text" [ngModel]="infoText" [placeholder]="param.title"> + <button *ngIf="isDicho" mat-icon-button class="param-computed-more" (click)="openDialog()"> + <mat-icon>more_horiz</mat-icon> + </button> +</mat-form-field> diff --git a/src/app/components/param-computed/param-computed.component.scss b/src/app/components/param-computed/param-computed.component.scss new file mode 100644 index 0000000000000000000000000000000000000000..40469133691fccaf31a9664ceb49d99627bf7b3e --- /dev/null +++ b/src/app/components/param-computed/param-computed.component.scss @@ -0,0 +1,31 @@ +:host { + display: block; + margin-top: 14px; + + mat-form-field { + width: calc(100% - 16px); + margin-right: 16px; + + ::ng-deep input.mat-input-element { + line-height: 1.3em; + width: calc(100% - 40px); + text-overflow: ellipsis; + } + + .param-computed-more { + position: absolute; + bottom: 0; + right: 0; + } + + ::ng-deep .mat-form-field-label { + font-size: 1.1em; + line-height: 1.4em; + margin-top: -2px; + + &.mat-form-field-empty { + font-size: 1em; + } + } + } +} diff --git a/src/app/components/param-computed/param-computed.component.ts b/src/app/components/param-computed/param-computed.component.ts new file mode 100644 index 0000000000000000000000000000000000000000..6bfced00bab90372af36a4d7946a5aee44dae579 --- /dev/null +++ b/src/app/components/param-computed/param-computed.component.ts @@ -0,0 +1,53 @@ +import { Component, Input } from "@angular/core"; +import { MatDialog } from "@angular/material"; +import { NgParameter } from "../../formulaire/ngparam"; +import { ParamCalculability } from "jalhyd"; +import { DialogEditParamComputedComponent } from "../dialog-edit-param-computed/dialog-edit-param-computed.component"; +import { I18nService } from "../../services/internationalisation/internationalisation.service"; + +@Component({ + selector: "param-computed", + templateUrl: "./param-computed.component.html", + styleUrls: [ + "./param-computed.component.scss" + ] +}) +export class ParamComputedComponent { + + @Input() + public param: NgParameter; + + @Input() + public title: string; + + constructor( + private editInitialValueDialog: MatDialog, + private intlService: I18nService + ) { } + + public get isDicho() { + return this.param.paramDefinition.calculability === ParamCalculability.DICHO; + } + + public get infoText() { + let text = this.intlService.localizeText("INFO_PARAMFIELD_IN_CALCULATION"); + if (this.isDicho) { + text += " (" + this.intlService.localizeText("INFO_PARAMFIELD_IN_CALCULATION_INITIAL_VALUE") + + ": " + this.param.getValue() + ")"; + } + return text; + } + + public openDialog() { + // modification de la valeur initiale, sans avoir à remettre le mode de + // paramètre sur "fixé" + this.editInitialValueDialog.open( + DialogEditParamComputedComponent, + { + data: { + param: this.param + } + } + ); + } +} diff --git a/src/app/components/param-field-line/param-field-line.component.html b/src/app/components/param-field-line/param-field-line.component.html index 41c5d1fead0e3e3405def7577ef33328870a42f3..f1ea01b5c1bd30da5d008c0a6a00601f180d398d 100644 --- a/src/app/components/param-field-line/param-field-line.component.html +++ b/src/app/components/param-field-line/param-field-line.component.html @@ -1,43 +1,49 @@ -<div class="row"> - <!-- input de saisie de la valeur --> - <div [ngClass]="(formHasResults) ? 'col-xl-6 pt-3':'col-md-6 col-xl-8 pt-3'"> - <ngparam-input [_inputDisabled]="isInputDisabled" [title]="title" (change)="onInputChange($event)"></ngparam-input> - </div> - <div class="btn-group col" role="group"> - <!-- px-3 : padding left/right 3 --> - <!-- py-3 : padding top/bottom 3 --> - <!-- h-50 : hauteur relative de l'élément par rapport au parent à 50%--> - <!-- cf. https://getbootstrap.com/docs/4.0/utilities/spacing --> +<div class="container" fxLayout="row wrap" fxLayoutAlign="space-between start"> + + <!-- input de saisie de la valeur --> + <div fxFlex="1 0 120px"> + <!-- composant pour gérer le cas général (valeur numérique à saisir) --> + <ngparam-input [title]="param.title" [hidden]="! isRadioFixChecked" (change)="onInputChange($event)"></ngparam-input> + + <!-- composant pour gérer le cas "paramètre calculé" --> + <param-computed *ngIf="isRadioCalChecked" [title]="title" [param]="param"></param-computed> - <!-- radio "fixé" --> - <label *ngIf="hasRadioFix()" class="{{radioFixClass}} h-75 px-3 py-3" [(ngModel)]="radioModel" mdbRadio="Left" name="radio_param_{{symbol}}" - value="fix" (click)="onRadioClick('fix')" [checked]=radioFixCheck [disabled]=isDisabled id="radio_fix"> - {{ uitextParamFixe }} - </label> + <!-- composant pour gérer le cas "paramètre à varier" (min-max/liste de valeurs) --> + <param-values *ngIf="isRadioVarChecked" [title]="title" [param]="param" (valid)=onParamValuesValid($event)></param-values> + + <!-- composant pour gérer le cas "paramètre lié" --> + <param-link *ngIf="isRadioLinkChecked" [title]="title" [param]="param" (valid)=onParamValuesValid($event)></param-link> + </div> - <!-- radio "varier" --> - <label *ngIf="hasRadioVar()" class="{{radioVarClass}} h-75 px-3 py-3" [(ngModel)]="radioModel" mdbRadio="Middle" name="radio_param_{{symbol}}" - value="var" (click)="onRadioClick('var')" [checked]=radioVarCheck [disabled]=isDisabled id="radio_var"> - {{ uitextParamVarier }} - </label> + <div class="toggle-group-container" fxFlex="0 0 auto"> + <mat-button-toggle-group *ngIf="hasRadioFix() || hasRadioVar() || hasRadioCal() || hasRadioLink()"> - <!-- radio "calculer" --> - <label *ngIf="hasRadioCal()" class="{{radioCalClass}} h-75 px-3 py-3" [(ngModel)]="radioModel" mdbRadio="Right" name="radio_param_{{symbol}}" - value="cal" (click)="onRadioClick('cal')" [checked]=radioCalCheck [disabled]=isDisabled id="radio_cal"> - {{ uitextParamCalculer }} - </label> + <mat-button-toggle id="radio_fix" value="radio_fix" + (click)="onRadioClick('fix')" [checked]="isRadioFixChecked"> + <span fxHide.xxs>{{ uitextParamFixe }}</span> + <span fxHide.gt-xxs>F</span> + </mat-button-toggle> + + <mat-button-toggle id="radio_var" value="radio_var" *ngIf="hasRadioVar()" + (click)="onRadioClick('var')" [checked]="isRadioVarChecked"> + <span fxHide.xxs>{{ uitextParamVarier }}</span> + <span fxHide.gt-xxs>V</span> + </mat-button-toggle> + + <mat-button-toggle id="radio_cal" value="radio_cal" *ngIf="hasRadioCal()" + (click)="onRadioClick('cal')" [checked]="isRadioCalChecked"> + <span fxHide.xxs>{{ uitextParamCalculer }}</span> + <span fxHide.gt-xxs>C</span> + </mat-button-toggle> + + <mat-button-toggle id="radio_link" value="radio_link" *ngIf="hasRadioLink()" + (click)="onRadioClick('link')" [checked]="isRadioLinkChecked"> + <span fxHide.xxs>{{ uitextParamLie }}</span> + <span fxHide.gt-xxs>L</span> + </mat-button-toggle> - <!-- radio "lié" --> - <label *ngIf="hasRadioLink()" class="{{radioLinkClass}} h-75 px-3 py-3" [(ngModel)]="radioModel" mdbRadio="Right" name="radio_param_{{symbol}}" - value="link" (click)="onRadioClick('link')" [checked]=radioLinkCheck [disabled]=isDisabled id="radio_link"> - {{ uitextParamLie }} - </label> + </mat-button-toggle-group> </div> -</div> -<!-- composant pour gérer le cas "paramètre à varier" (min-max/liste de valeurs) --> -<param-values *ngIf="isRadioVarChecked" [param]="param" (valid)=onParamValuesValid($event)></param-values> - -<!-- composant pour gérer le cas "paramètre lié" --> -<param-link *ngIf="isRadioLinkChecked" [param]="param" (valid)=onParamValuesValid($event)></param-link> \ No newline at end of file +</div> diff --git a/src/app/components/param-field-line/param-field-line.component.scss b/src/app/components/param-field-line/param-field-line.component.scss new file mode 100644 index 0000000000000000000000000000000000000000..4cfe3dad92ebfe608a3bef8eda844f0af394d3f4 --- /dev/null +++ b/src/app/components/param-field-line/param-field-line.component.scss @@ -0,0 +1,13 @@ +.toggle-group-container { + text-align: right; +} + +mat-button-toggle-group { + margin-top: 4px; + box-shadow: 0px 3px 1px -2px rgba(0, 0, 0, 0.2), 0px 2px 2px 0px rgba(0, 0, 0, 0.14), 0px 1px 5px 0px rgba(0, 0, 0, 0.12); + + /*::ng-deep .mat-button-toggle-label-content { + line-height: 32px; + padding: 0 10px; + }*/ +} diff --git a/src/app/components/param-field-line/param-field-line.component.ts b/src/app/components/param-field-line/param-field-line.component.ts index 6282e176e28510041610c853da5c6eedc24cb1f3..435f63cfbf3c00df06a53b986e5008c731abc8d3 100644 --- a/src/app/components/param-field-line/param-field-line.component.ts +++ b/src/app/components/param-field-line/param-field-line.component.ts @@ -1,53 +1,34 @@ import { Component, ViewChild, Input, Output, EventEmitter, OnChanges } from "@angular/core"; -import { InternationalisationService } from "../../services/internationalisation/internationalisation.service"; +import { I18nService } from "../../services/internationalisation/internationalisation.service"; import { NgParameter, ParamRadioConfig } from "../../formulaire/ngparam"; import { NgParamInputComponent } from "../ngparam-input/ngparam-input.component"; import { ServiceFactory } from "../../services/service-factory"; import { ParamValueMode, CalculatorType, ParallelStructure } from "jalhyd"; import { FormulaireService } from "../../services/formulaire/formulaire.service"; import { ParamLinkComponent } from "../param-link/param-link.component"; +import { ParamComputedComponent } from "../param-computed/param-computed.component"; +import { ParamValuesComponent } from "../param-values/param-values.component"; +/** + * Sélecteur de mode pour chaque paramètre: fixé, varier, calculer, lié + */ @Component({ selector: "param-field-line", templateUrl: "./param-field-line.component.html", - styles: [ - `.btn-on { - color:#505050; - border: 3px solid #505050; - background-color:white; - text-transform: uppercase; - font-size: 0.8em; - }`, - `.btn-off { - color:white; - border: 3px solid #505050; - background-color:#505050; - text-transform: uppercase; - font-size: 0.8em; - }` + styleUrls: [ + "./param-field-line.component.scss" ] }) export class ParamFieldLineComponent implements OnChanges { constructor() { - this.intlService = ServiceFactory.instance.internationalisationService; + this.intlService = ServiceFactory.instance.i18nService; this._formService = ServiceFactory.instance.formulaireService; this.valid = new EventEmitter(); this.inputChange = new EventEmitter(); } - public get title(): string { - let t = ""; - if (this.param.label !== undefined) { - t = this.param.label; - } - if (this.param.unit !== undefined && this.param.unit !== "") { - t = t + " (" + this.param.unit + ")"; - } - return t; - } - private get uitextParamFixe() { return this.intlService.localizeText("INFO_PARAMFIELD_PARAMFIXE"); } @@ -71,112 +52,36 @@ export class ParamFieldLineComponent implements OnChanges { return this.param.symbol; } - /** - * calcule l'état du radio "paramètre fixé" - */ + // états des boutons pour l'interface + private get radioFixCheck(): string { return this.isRadioFixChecked ? "checked" : undefined; } - - /** - * calcule l'état du radio "paramètre à varier" - */ private get radioVarCheck(): string { return this.isRadioVarChecked ? "checked" : undefined; } - - /** - * calcule l'état du radio "paramètre à calculer" - */ private get radioCalCheck(): string { - if (this.param.radioState === ParamRadioConfig.CAL) { - return "checked"; - } - return undefined; + return this.isRadioCalChecked ? "checked" : undefined; } - - /** - * calcule l'état du radio "paramètre lié" - */ private get radioLinkCheck(): string { - if (this.param.radioState === ParamRadioConfig.LINK) { - return "checked"; - } - return undefined; + return this.isRadioLinkChecked ? "checked" : undefined; } - /** - * retourne l'état du radio "paramètre fixé" sous forme booléenne - */ + // états booléens des boutons + public get isRadioFixChecked(): boolean { return this.param.radioState === ParamRadioConfig.FIX; } - - /** - * retourne l'état du radio "paramètre à varier" sous forme booléenne - */ public get isRadioVarChecked(): boolean { return this.param.radioState === ParamRadioConfig.VAR; } - - /** - * retourne l'état du radio "paramètre lié" sous forme booléenne - */ + public get isRadioCalChecked(): boolean { + return this.param.radioState === ParamRadioConfig.CAL; + } public get isRadioLinkChecked(): boolean { return this.param.radioState === ParamRadioConfig.LINK; } - /** - * désactivation de tous les boutons radio si paramètre par défaut à "CAL" - */ - private get isDisabled(): boolean { - return this.param.isDefault && this.param.radioState === ParamRadioConfig.CAL; - } - - /** - * désactivation du champ de saisie - */ - public get isInputDisabled(): boolean { - return this.param.radioState !== ParamRadioConfig.FIX; - } - - private get radioFixClass(): string { - if (this.on) { - return this.radioFixCheck ? this.onClass : this.offClass; - } - return ""; - } - - /** - * classe du radio "varier" - */ - private get radioVarClass(): string { - if (this.on) { - return this.radioVarCheck ? this.onClass : this.offClass; - } - return ""; - } - - /** - * classe du radio "calculer" - */ - private get radioCalClass(): string { - if (this.on) { - return this.radioCalCheck ? this.onClass : this.offClass; - } - return ""; - } - - /** - * classe du radio "lié" - */ - private get radioLinkClass(): string { - if (this.on) { - return this.radioLinkCheck ? this.onClass : this.offClass; - } - return ""; - } - /** * validité des saisies du composant */ @@ -188,6 +93,10 @@ export class ParamFieldLineComponent implements OnChanges { case ParamRadioConfig.VAR: return this._isRangeValid; + case ParamRadioConfig.LINK: + // at first this._paramLinkComponent is undefined until view is refreshed + return this._paramLinkComponent ? this._paramLinkComponent.isValid : true; + default: return true; } @@ -198,11 +107,17 @@ export class ParamFieldLineComponent implements OnChanges { } @Input() - private param: NgParameter; + public param: NgParameter; @ViewChild(NgParamInputComponent) private _ngParamInputComponent: NgParamInputComponent; + @ViewChild(ParamComputedComponent) + private _paramComputedComponent: ParamComputedComponent; + + @ViewChild(ParamValuesComponent) + private _paramValuesComponent: ParamValuesComponent; + @ViewChild(ParamLinkComponent) private _paramLinkComponent: ParamLinkComponent; @@ -212,17 +127,13 @@ export class ParamFieldLineComponent implements OnChanges { @Output() private inputChange: EventEmitter<void>; - /** - * true si la valeur saisie est valide - */ + /** true si la valeur saisie est valide */ private _isInputValid = false; - /** - * true si le min-max/liste est valide - */ + /** true si le min-max/liste est valide */ private _isRangeValid = true; - private intlService: InternationalisationService; + private intlService: I18nService; private _formService: FormulaireService; @@ -231,7 +142,6 @@ export class ParamFieldLineComponent implements OnChanges { * envoi d'un message au composant parent * cf. https://angular.io/guide/component-interaction#parent-listens-for-child-event */ - @Output() private radio = new EventEmitter<any>(); @@ -248,7 +158,7 @@ export class ParamFieldLineComponent implements OnChanges { public hasRadioFix(): boolean { switch (this.param.radioConfig) { case ParamRadioConfig.FIX: - return this.hasRadioLink(); + return this.hasRadioLink(); // gné ? default: return true; @@ -283,16 +193,16 @@ export class ParamFieldLineComponent implements OnChanges { } /** - * calcule la présence du radio "paramètre lié" (importé d'une autre calculette) + * calcule la présence du radio "paramètre lié" (importé d'un autre module de calcul) */ public hasRadioLink(): boolean { if (this._formService.formulaires.length > 0) { - // au moins 2 calculettes ouvertes + // au moins 2 modules de calcul ouverts if (this._formService.formulaires.length > 1) { return this._formService.filterLinkableValues(this._formService.getLinkableValues(this.param)).length > 0; } - // ou une seule calculette "ouvrages parallèles" + // ou un seul module de calcul "ouvrages parallèles" if (this._formService.formulaires[0].calculatorType === CalculatorType.ParallelStructure) { const ps: ParallelStructure = this._formService.formulaires[0].currentNub as ParallelStructure; if (ps.structures.length > 1) { @@ -306,16 +216,23 @@ export class ParamFieldLineComponent implements OnChanges { private onRadioClick(option: string) { const oldValue = this.param.valueMode; - switch (option) { case "fix": - const oldValueMode = this.param.valueMode; this.param.valueMode = ParamValueMode.SINGLE; + // @WTF why do we reset the value here ? this.param.setValue(this, this.param.paramDefinition.paramValues.singleValue); break; case "var": - this.param.valueMode = ParamValueMode.MINMAX; // min/max par défaut + // prevent setting LISTE mode back to MINMAX if someone clicks "variable" again + // after setting variable mode to LISTE + if (oldValue !== ParamValueMode.MINMAX && oldValue !== ParamValueMode.LISTE) { + this.param.valueMode = ParamValueMode.MINMAX; // min/max par défaut + } + if (this._paramValuesComponent) { + // re-open modal when clicking the "var" mode button again (PoLS) + this._paramValuesComponent.openDialog(); + } break; case "cal": @@ -326,12 +243,10 @@ export class ParamFieldLineComponent implements OnChanges { this.param.valueMode = ParamValueMode.LINK; break; } - this.radio.emit({ "param": this.param, "oldValueMode": oldValue }); - // MAJ validité this.emitValidity(); } diff --git a/src/app/components/param-link/param-link.component.html b/src/app/components/param-link/param-link.component.html index f7289b7393df1263526546072753c8c72459fd87..5b198816bf96e4b7b3df1aec2f428f7e681d1ec2 100644 --- a/src/app/components/param-link/param-link.component.html +++ b/src/app/components/param-link/param-link.component.html @@ -1,13 +1,10 @@ -<div class="row"> - <div class="btn-group col-6 col-sm-3" dropdown (click)="onSelectLinkableParam($event)"> - <button dropdownToggle class="btn btn-primary dropdown-toggle waves-light my-1" type="button" mdbRippleRadius> - {{ currentLinkedParamLabel }} - </button> - <div class="dropdown-menu"> - <a class="dropdown-item" *ngFor="let e of linkableParams" [value]=e>{{ selectItemLabel(e) }}</a> - </div> - </div> - <div class="col-6 text-danger"> +<mat-form-field> + <mat-select [name]='"linked-param_" + param.uid' required [placeholder]="param.title" [(ngModel)]="currentLinkedParam"> + <mat-option *ngFor="let e of linkableParams" [value]="e"> + {{ selectItemLabel(e) }} + </mat-option> + </mat-select> + <mat-error> {{ message }} - </div> -</div> \ No newline at end of file + </mat-error> +</mat-form-field> diff --git a/src/app/components/param-link/param-link.component.scss b/src/app/components/param-link/param-link.component.scss new file mode 100644 index 0000000000000000000000000000000000000000..55d123d5ac4e3b9be8aa5a87b3d49a9ba0ec92d7 --- /dev/null +++ b/src/app/components/param-link/param-link.component.scss @@ -0,0 +1,33 @@ +:host { + display: block; + // width: 100%; + // width: 70%; min-width: 264px; // for smallest screens (360) + // get the select closer to the related param line above + margin-top: 14px; + + mat-form-field { + width: calc(100% - 16px); + margin-right: 16px; + + mat-select { + + ::ng-deep .mat-select-value { + > span { + > span { + line-height: 1.3em; + } + } + } + } + + ::ng-deep .mat-form-field-label { + font-size: 1.1em; + line-height: 1.4em; + margin-top: -2px; + + &.mat-form-field-empty { + font-size: 1em; + } + } + } +} diff --git a/src/app/components/param-link/param-link.component.ts b/src/app/components/param-link/param-link.component.ts index 256558035ff3170f49f973fea7332db36e221de4..9e28788f706eecf48a47c5836360e400ac127a98 100644 --- a/src/app/components/param-link/param-link.component.ts +++ b/src/app/components/param-link/param-link.component.ts @@ -4,15 +4,22 @@ import { NgParameter } from "../../formulaire/ngparam"; import { ServiceFactory } from "../../services/service-factory"; import { ParamValueMode, Observer } from "jalhyd"; import { FormulaireService } from "../../services/formulaire/formulaire.service"; +import { I18nService } from "../..//services/internationalisation/internationalisation.service"; @Component({ selector: "param-link", - templateUrl: "./param-link.component.html" + templateUrl: "./param-link.component.html", + styleUrls: [ + "./param-link.component.scss" + ] }) export class ParamLinkComponent implements OnChanges, Observer, OnDestroy { // paramètre géré (qui sera lié à une valeur, cad qui importe cette valeur) @Input() - private param: NgParameter; + public param: NgParameter; + + @Input() + public title: string; @Output() private valid: EventEmitter<boolean>; @@ -29,7 +36,7 @@ export class ParamLinkComponent implements OnChanges, Observer, OnDestroy { /** * liste des paramètres liables sous la forme - * {"name":<étiquette>, "value":<valeur liable>, "nub":<Nub d'origine du paramètre>, "formTitle":<nom de la calculette liée au nub>} + * {"name":<étiquette>, "value":<valeur liable>, "nub":<Nub d'origine du paramètre>, "formTitle":<nom du module de calcul lié au nub>} * * l'étiquette "name" (cf. INubReference.defineReference dans jalhyd) est de la forme <n | ouvrage[n] | N1>[.[N2]] * n : indice de de l'ouvrage dans le cas des ouvrages parallèles @@ -47,7 +54,9 @@ export class ParamLinkComponent implements OnChanges, Observer, OnDestroy { private _formService: FormulaireService; - constructor() { + constructor( + private intlService: I18nService + ) { this.valid = new EventEmitter(); this._formService = ServiceFactory.instance.formulaireService; this._formService.addObserver(this); @@ -61,27 +70,25 @@ export class ParamLinkComponent implements OnChanges, Observer, OnDestroy { return this._message; } - /** - * envoi d'un événement de validité - */ - private emitValidity() { - // this.valid.emit(this._validList); + public get label() { + return this.intlService.localizeText("INFO_PARAMFIELD_PARAMLIE_LABEL"); } - /** - * réception d'un événement du menu des paramètres liables - */ - public onSelectLinkableParam(event: any) { - const next = event.target.value; - if (next !== undefined && next !== "") { // opening the dropdown returns "" - let i = 0; - for (const e of this._linkableParams) { - if (this._linkableParams[i].value.uid === next.value.uid) { - this.linkTo(i); - break; - } else { - i++; - } + public set currentLinkedParam(p: any) { + for (let i = 0; i < this._linkableParams.length; i++) { + if (this._linkableParams[i].value.uid === p.uid) { + this.linkTo(i); + break; + } else { + i++; + } + } + } + + public get currentLinkedParam() { + if (this._linkableParams !== undefined) { + if (this._currentIndex !== -1 && this._currentIndex < this._linkableParams.length) { + return this._linkableParams[this._currentIndex]; } } } @@ -90,15 +97,14 @@ export class ParamLinkComponent implements OnChanges, Observer, OnDestroy { * valeur courante affichée dans le select des paramètres liables */ public get currentLinkedParamLabel(): string { - if (this._linkableParams !== undefined) { - if (this._currentIndex === -1 || this._currentIndex >= this._linkableParams.length) { - return undefined; - } - - return this.selectItemLabel(this._linkableParams[this._currentIndex]); + const clp = this.currentLinkedParam(); + if (clp) { + return this.selectItemLabel(clp); } + } - return undefined; + public get isValid(): boolean { + return this._currentIndex !== -1 && this.param.isValid; } /** @@ -106,7 +112,7 @@ export class ParamLinkComponent implements OnChanges, Observer, OnDestroy { */ private selectItemLabel(i: any) { const s = i.name; // nom associé au paramètre/à la valeur - const c = i.formTitle; // nom de la calculette + const c = i.formTitle; // nom du module de calcul const re5 = /(\d+)\.(.+)\.$/; // forme <nombre>.xxx. (résultat d'ouvrage) const match5 = re5.exec(s); @@ -208,6 +214,7 @@ export class ParamLinkComponent implements OnChanges, Observer, OnDestroy { public update(sender: any, data: any) { if (sender instanceof FormulaireService) { switch (data["action"]) { + // scan newly created form for available linkable params case "createForm": this.updateParamList(); break; diff --git a/src/app/components/param-values/ngparam-max.component.ts b/src/app/components/param-values/ngparam-max.component.ts deleted file mode 100644 index de13b6e24272dea9836d02097446c03b202ec1e0..0000000000000000000000000000000000000000 --- a/src/app/components/param-values/ngparam-max.component.ts +++ /dev/null @@ -1,76 +0,0 @@ -import { Component, Input, ChangeDetectorRef } from "@angular/core"; - -import { isNumeric } from "jalhyd"; - -import { GenericInputComponent } from "../generic-input/generic-input.component"; -import { InternationalisationService } from "../../services/internationalisation/internationalisation.service"; -import { NgParameter } from "../../formulaire/ngparam"; - -@Component({ - selector: "ngparam-max", - templateUrl: "../generic-input/generic-input.component.html" -}) -export class NgParamMaxComponent extends GenericInputComponent { - constructor(private intlService: InternationalisationService, cdRef: ChangeDetectorRef) { - super(cdRef); - } - - /** - * paramètre géré - */ - private get _param(): NgParameter { - return this._model; - } - - protected getModelValue(): any { - if (this._param === undefined) { - return undefined; - } - return this._param.maxValue; - } - - protected setModelValue(sender: any, v: any) { - this._param.maxValue = v; - } - - protected validateModelValue(v: any): { isValid: boolean, message: string } { - let msg; - let valid = false; - - if (this._param === undefined) { - msg = "internal error, model undefined"; - } else { - if (!this._param.checkMax(v)) { - msg = "La valeur n'est pas dans ]" + this._param.minValue + " , " + this._param.domain.maxValue + "]"; - } else { - valid = true; - } - } - - return { isValid: valid, message: msg }; - } - - protected modelToUI(v: any): string { - if (typeof (v) === "number") { - return String(v); - } - return undefined; - } - - protected validateUIValue(ui: string): { isValid: boolean, message: string } { - let valid = false; - let msg: string; - - if (! isNumeric(ui)) { - msg = "Veuillez entrer une valeur numérique"; - } else { - valid = true; - } - - return { isValid: valid, message: msg }; - } - - protected uiToModel(ui: string) { - return +ui; - } -} diff --git a/src/app/components/param-values/ngparam-min.component.ts b/src/app/components/param-values/ngparam-min.component.ts deleted file mode 100644 index 89e119f03533bf517b83940c73f6db176b192270..0000000000000000000000000000000000000000 --- a/src/app/components/param-values/ngparam-min.component.ts +++ /dev/null @@ -1,76 +0,0 @@ -import { Component, Input, ChangeDetectorRef } from "@angular/core"; - -import { isNumeric } from "jalhyd"; - -import { GenericInputComponent } from "../generic-input/generic-input.component"; -import { InternationalisationService } from "../../services/internationalisation/internationalisation.service"; -import { NgParameter } from "../../formulaire/ngparam"; - -@Component({ - selector: "ngparam-min", - templateUrl: "../generic-input/generic-input.component.html" -}) -export class NgParamMinComponent extends GenericInputComponent { - constructor(private intlService: InternationalisationService, cdRef: ChangeDetectorRef) { - super(cdRef); - } - - /** - * paramètre géré - */ - private get _param(): NgParameter { - return this._model; - } - - protected getModelValue(): any { - if (this._param === undefined) { - return undefined; - } - return this._param.minValue; - } - - protected setModelValue(sender: any, v: any) { - this._param.minValue = v; - } - - protected validateModelValue(v: any): { isValid: boolean, message: string } { - let msg: string; - let valid = false; - - if (this._param === undefined) { - msg = "internal error, model undefined"; - } else { - if (!this._param.checkMin(v)) { - msg = "La valeur n'est pas dans [" + this._param.domain.minValue + " , " + this._param.maxValue + "["; - } else { - valid = true; - } - } - - return { isValid: valid, message: msg }; - } - - protected modelToUI(v: any): string { - if (typeof (v) === "number") { - return String(v); - } - return undefined; - } - - protected validateUIValue(ui: string): { isValid: boolean, message: string } { - let valid = false; - let msg: string; - - if (! isNumeric(ui)) { - msg = "Veuillez entrer une valeur numérique"; - } else { - valid = true; - } - - return { isValid: valid, message: msg }; - } - - protected uiToModel(ui: string): any { - return +ui; - } -} diff --git a/src/app/components/param-values/ngparam-step.component.ts b/src/app/components/param-values/ngparam-step.component.ts deleted file mode 100644 index bbddcebf2f27f0a2ac55e75d3957ebf292283e2e..0000000000000000000000000000000000000000 --- a/src/app/components/param-values/ngparam-step.component.ts +++ /dev/null @@ -1,83 +0,0 @@ -import { Component, Input, ChangeDetectorRef } from "@angular/core"; - -import { isNumeric } from "jalhyd"; - -import { GenericInputComponent } from "../generic-input/generic-input.component"; -import { InternationalisationService } from "../../services/internationalisation/internationalisation.service"; -import { NgParameter } from "../../formulaire/ngparam"; - -@Component({ - selector: "ngparam-step", - templateUrl: "../generic-input/generic-input.component.html" -}) -export class NgParamStepComponent extends GenericInputComponent { - constructor(private intlService: InternationalisationService, cdRef: ChangeDetectorRef) { - super(cdRef); - } - - /** - * paramètre géré - */ - private get _param(): NgParameter { - return this._model; - } - - protected getModelValue(): any { - if (! this._param) { - return undefined; - } - return this._param.stepValue; - } - - protected setModelValue(sender: any, v: any) { - this._param.stepValue = v; - } - - protected validateModelValue(v: any): { isValid: boolean, message: string } { - let msg: string; - let valid = false; - - if (! this._param) { - msg = "internal error, model undefined"; - } else { - if (this._param.isMinMaxValid) { - if (!this._param.checkStep(v)) { - msg = "La valeur n'est pas dans " + this._param.stepRefValue.toString(); - } else { - valid = v > 0; - if (!valid) { - msg = "La valeur ne peut pas être <= 0"; - } - } - } else { - msg = "Veuillez corriger le min/max"; - } - } - - return { isValid: valid, message: msg }; - } - - protected modelToUI(v: any): string { - if (typeof (v) === "number") { - return String(v); - } - return "<invalid>"; - } - - protected validateUIValue(ui: string): { isValid: boolean, message: string } { - let valid = false; - let msg: string; - - if (! isNumeric(ui)) { - msg = "Veuillez entrer une valeur numérique"; - } else { - valid = true; - } - - return { isValid: valid, message: msg }; - } - - protected uiToModel(ui: string) { - return +ui; - } -} diff --git a/src/app/components/param-values/param-values.component.html b/src/app/components/param-values/param-values.component.html index f4dc496878e94c63d55d6e5e1b59bc277430f16d..37cda318bfbb8ac4581d6f45ab2188656e7f89fd 100644 --- a/src/app/components/param-values/param-values.component.html +++ b/src/app/components/param-values/param-values.component.html @@ -1,24 +1,7 @@ -<div class="row"> - <div class="btn-group col-12 col-sm-3" dropdown (click)="onSelectValueMode($event)"> - <button dropdownToggle class="btn btn-primary dropdown-toggle waves-light my-1" type="button" mdbRippleRadius> - {{ currentModeSelectLabel }} - </button> - <div class="dropdown-menu"> - <a class="dropdown-item" *ngFor="let e of valueModes" [value]=e.value>{{ e.label }}</a> - </div> - </div> - - <div *ngIf="isMinMax" class="col-12 col-sm-3"> - <ngparam-min [title]="uitextValeurMini" (onChange)="onMinChanged($event)"></ngparam-min> - </div> - <div *ngIf="isMinMax" class="col-12 col-sm-3"> - <ngparam-max [title]="uitextValeurMaxi" (onChange)="onMaxChanged($event)"></ngparam-max> - </div> - <div *ngIf="isMinMax" class="col-12 col-sm-3"> - <ngparam-step [title]="uitextPasVariation" [param]="param" (onChange)="onStepChanged($event)"></ngparam-step> - </div> - - <div *ngIf="isList" class="col-12 col-sm-6"> - <value-list title="valeurs séparées par ';'" (onChange)="onListChanged($event)"></value-list> - </div> -</div> \ No newline at end of file +<!-- a fake input bound to nothing, for the sake of UI consistency --> +<mat-form-field> + <input matInput disabled class="form-control" type="text" [ngModel]="infoText" [placeholder]="param.title"> + <button mat-icon-button class="param-values-more" (click)="openDialog()"> + <mat-icon>more_horiz</mat-icon> + </button> +</mat-form-field> diff --git a/src/app/components/param-values/param-values.component.scss b/src/app/components/param-values/param-values.component.scss new file mode 100644 index 0000000000000000000000000000000000000000..1edcbe0ed9b4f6fe9e3ae7c76035729ac1bc1384 --- /dev/null +++ b/src/app/components/param-values/param-values.component.scss @@ -0,0 +1,31 @@ +:host { + display: block; + margin-top: 14px; + + mat-form-field { + width: calc(100% - 16px); + margin-right: 16px; + + ::ng-deep input.mat-input-element { + line-height: 1.3em; + width: calc(100% - 40px); + text-overflow: ellipsis; + } + + .param-values-more { + position: absolute; + bottom: 0; + right: 0; + } + + ::ng-deep .mat-form-field-label { + font-size: 1.1em; + line-height: 1.4em; + margin-top: -2px; + + &.mat-form-field-empty { + font-size: 1em; + } + } + } +} diff --git a/src/app/components/param-values/param-values.component.ts b/src/app/components/param-values/param-values.component.ts index ef8c20a92bf590e6a63c3ad1d25c01ab051dd581..9a8f34c34252f0afb4bed6171d83232ba8c4c816 100644 --- a/src/app/components/param-values/param-values.component.ts +++ b/src/app/components/param-values/param-values.component.ts @@ -1,361 +1,89 @@ -import { Component, Input, Output, EventEmitter, ViewChild, AfterViewChecked, OnChanges } from "@angular/core"; - -import { ParamValueMode } from "jalhyd"; - -import { InternationalisationService } from "../../services/internationalisation/internationalisation.service"; +import { Component, Input, AfterViewInit } from "@angular/core"; import { NgParameter } from "../../formulaire/ngparam"; -import { NgParamMinComponent } from "./ngparam-min.component"; -import { NgParamMaxComponent } from "./ngparam-max.component"; -import { NgParamStepComponent } from "./ngparam-step.component"; -import { BaseComponent } from "../base/base.component"; -import { ValueListComponent } from "./value-list.component"; +import { DialogEditParamValuesComponent } from "../dialog-edit-param-values/dialog-edit-param-values.component"; +import { MatDialog } from "@angular/material"; +import { ParamValueMode } from "jalhyd"; +import { I18nService } from "../../services/internationalisation/internationalisation.service"; +import { sprintf } from "sprintf-js"; +import { ApplicationSetupService } from "../../services/app-setup/app-setup.service"; @Component({ selector: "param-values", templateUrl: "./param-values.component.html", - styles: [ - `.btn-on { - color:#505050; - border: 3px solid #505050; - background-color:white; - text-transform: uppercase; - font-size: 0.8em; - }`, - `.btn-off { - color:white; - border: 3px solid #505050; - background-color:#505050; - text-transform: uppercase; - font-size: 0.8em; - }` + styleUrls: [ + "./param-values.component.scss" ] }) -export class ParamValuesComponent extends BaseComponent implements AfterViewChecked, OnChanges { - @Input() - private param: NgParameter; - - private _valueModes = []; - - /** - * true quand les champs du composant et de ses enfants sont initialisés - */ - private _initCompleted = false; - - /** - * true si la valeur min est valide - */ - private _validMin = false; - - /** - * true si la valeur max est valide - */ - private _validMax = false; - - /** - * true si la valeur du pas est valide - */ - private _validStep = false; - - /** - * true si la liste de valeurs est valide - */ - private _validList = false; - - /** - * flag signalant qu'il faut initialiser le composant ValueListComponent (par ex quand on a sélectionné le mode "liste") - */ - private _doInitList = false; - - /** - * flag signalant qu'il faut initialiser les composants min/max/pas - */ - private _doInitMinmax = false; - - /** - * composant de saisie du minimum - */ - @ViewChild(NgParamMinComponent) - private _minComponent: NgParamMinComponent; - - /** - * composant de saisie du maximum - */ - @ViewChild(NgParamMaxComponent) - private _maxComponent: NgParamMaxComponent; - - /** - * composant de saisie du pas de variation - */ - @ViewChild(NgParamStepComponent) - private _stepComponent: NgParamStepComponent; - - /** - * composant de saisie d'une liste de valeurs - */ - @ViewChild(ValueListComponent) - private _listComponent: ValueListComponent; - - @Output() - private valid: EventEmitter<boolean>; - - constructor(private intlService: InternationalisationService) { - super(); - this._valueModes.push({ "value": ParamValueMode.MINMAX, "label": "Min/max" }); - this._valueModes.push({ "value": ParamValueMode.LISTE, "label": "Liste" }); - this.valid = new EventEmitter(); - } - - /** - * init des champs min/max/pas - */ - private initMinMaxStep() { - if (this.isMinMax && this._doInitMinmax) { - this._doInitMinmax = false; - - // valeur pour min : celle déjà définie ou celle déduite de la valeur saisie - let min: number = this.param.minValue; - if (min === undefined) { - min = this.param.getValue() / 2; - } - - // valeur pour max : celle déjà définie ou celle déduite de la valeur saisie - let max: number = this.param.maxValue; - if (max === undefined) { - max = this.param.getValue() * 2; - } +export class ParamValuesComponent implements AfterViewInit { - this.param.minValue = min; - this._minComponent.model = this.param; - - this.param.maxValue = max; - this._maxComponent.model = this.param; - - // valeur du pas - let step = this.param.stepValue; - if (step === undefined) { - step = (max - min) / 20; - } - this.param.stepValue = step; - this._stepComponent.model = this.param; - - this.validateAll(); - - this._validMin = this._minComponent.isValid; - this._validMax = this._maxComponent.isValid; - this._validStep = this._stepComponent.isValid; - this.emitValidity(); + @Input() + public param: NgParameter; - this._initCompleted = true; - } - } + @Input() + public title: string; - /** - * initialisation de la liste de valeurs avec celle du paramètre géré - */ - private initList() { - if (this._doInitList && this._listComponent !== undefined) { - this._doInitList = false; - let l = this.param.valueList; - if (l === undefined) { - if (this.param.isDefined) { - l = [this.param.getValue()]; - } else { - l = []; - } - } - this.param.valueList = l; - this._listComponent.model = this.param; - } - } + constructor( + private editValuesDialog: MatDialog, + private intlService: I18nService, + private appSetupService: ApplicationSetupService + ) { } - /** - * revalidation de tous les composants enfants - */ - private validateAll() { - if (this._minComponent !== undefined) { - this._minComponent.validate(); - } - if (this._maxComponent !== undefined) { - this._maxComponent.validate(); - } - if (this._stepComponent !== undefined) { - this._stepComponent.validate(); - } - if (this._listComponent !== undefined) { - this._listComponent.validate(); - } + public get isMinMax() { + return this.param.valueMode === ParamValueMode.MINMAX; } - /** - * envoi d'un événement de validité - */ - private emitValidity() { - switch (this.param.valueMode) { - case ParamValueMode.LISTE: - this.valid.emit(this._validList); - break; - - case ParamValueMode.MINMAX: - this.valid.emit(this._validMin && this._validMax && this._validStep); - break; - } + public get isListe() { + return this.param.valueMode === ParamValueMode.LISTE; } - /** - * réception d'un événement de NgParamMinComponent - */ - private onMinChanged(event: any) { - if (this._initCompleted) { - switch (event.action) { - case "model": - this.validateAll(); - break; - - case "valid": - this._validMin = event.value; - this.emitValidity(); - break; + public get infoText() { + let text: string; + if (this.isMinMax) { + const nDigits = this.appSetupService.displayDigits; + let min: any = this.param.minValue; + let max: any = this.param.maxValue; + let step: any = this.param.stepValue; + if (min) { + min = min.toFixed(nDigits); } - } - } - - /** - * réception d'un événement de NgParamMaxComponent - */ - private onMaxChanged(event: any) { - if (this._initCompleted) { - switch (event.action) { - case "model": - this.validateAll(); - break; - - case "valid": - this._validMax = event.value; - this.emitValidity(); - break; + if (max) { + max = max.toFixed(nDigits); } - } - } - - /** - * réception d'un événement de NgParamStepComponent - */ - private onStepChanged(event: any) { - if (this._initCompleted) { - switch (event.action) { - case "model": - this.validateAll(); - break; - - case "valid": - this._validStep = event.value; - this.emitValidity(); - break; + if (step) { + step = step.toFixed(nDigits); } + text = this.intlService.localizeText("INFO_PARAMFIELD_PARAMVARIER_MINMAXSTEP"); + text = sprintf(text, min, max, step); + } else if (this.isListe) { + text = this.intlService.localizeText("INFO_PARAMFIELD_PARAMVARIER_VALUES"); + const vals = this.param.valueList || []; + text += " " + vals.slice(0, 20).join(";"); } + return text; } - /** - * réception d'un événement de ValueListComponent - */ - private onListChanged(event: any) { - if (this._initCompleted) { - switch (event.action) { - case "model": - this.validateAll(); - break; - - case "valid": - this._validList = event.value; - this.emitValidity(); - break; + public openDialog() { + // modification des valeurs variables + this.editValuesDialog.open( + DialogEditParamValuesComponent, + { + disableClose: true, + data: { + param: this.param + } } - } - } - - private get uitextValeurMini() { - return this.intlService.localizeText("INFO_PARAMFIELD_VALEURMINI"); + ); } - private get uitextValeurMaxi() { - return this.intlService.localizeText("INFO_PARAMFIELD_VALEURMAXI"); - } - - private get uitextPasVariation() { - return this.intlService.localizeText("INFO_PARAMFIELD_PASVARIATION"); - } - - /** - * true si mode "liste de valeurs" - */ - public get isList(): boolean { - return this.param.valueMode === ParamValueMode.LISTE; - } - - /** - * true si mode "lié" - */ - public get isLink(): boolean { - return this.param.valueMode === ParamValueMode.LINK; - } - - /** - * true si mode "min/max/pas" - */ - public get isMinMax(): boolean { - return this.param.valueMode === ParamValueMode.MINMAX; - } - - /** - * valeur courante affichée dans le select min-max/list - */ - public get currentModeSelectLabel(): string { - return ParamValueMode[this.param.valueMode]; - } - - /** - * réception d'un événement du menu "min/max/liste" - */ - public onSelectValueMode(event: any) { - const next = event.target.value; - - switch (next) { - // on a sélectionné "min/max" ? - case ParamValueMode.MINMAX: - this._doInitMinmax = true; - break; - - // on a sélectionné "liste" ? - case ParamValueMode.LISTE: - this._doInitList = true; - break; - - default: - throw new Error("valeur " + next + " de ParamValueMode non prise en charge"); - } - - this.param.valueMode = next; - } - - public get valueModes() { - return this._valueModes; - } - - /** - * appelé quand les @Input changent - */ - ngOnChanges() { - if (this.isMinMax) { - this._doInitMinmax = true; - } else { - this._doInitList = true; + public ngAfterViewInit() { + // open dialog when switching to this mode, but only the first time this component is built, + // otherwise switching back from another calc tab will trigger the dialog again + if (this.param.minValue === undefined) { + // use Promise trick to introduce a pseudo-timeout and avoid ExpressionChangedAfterItHasBeenCheckedError + Promise.resolve().then(() => { + this.openDialog(); + }); } } - - ngAfterViewChecked() { - super.ngAfterViewChecked(); - this.initMinMaxStep(); - this.initList(); - } } diff --git a/src/app/components/param-values/value-list.component.ts b/src/app/components/param-values/value-list.component.ts deleted file mode 100644 index 542e770b68e351baa6601afd2604cba6a8b8bb23..0000000000000000000000000000000000000000 --- a/src/app/components/param-values/value-list.component.ts +++ /dev/null @@ -1,107 +0,0 @@ -import { Component, Input, ChangeDetectorRef } from "@angular/core"; - -import { GenericInputComponent } from "../generic-input/generic-input.component"; -import { InternationalisationService } from "../../services/internationalisation/internationalisation.service"; -import { NgParameter } from "../../formulaire/ngparam"; -import { Message } from "jalhyd"; - -@Component({ - selector: "value-list", - templateUrl: "../generic-input/generic-input.component.html" -}) -export class ValueListComponent extends GenericInputComponent { - constructor(private intlService: InternationalisationService, cdRef: ChangeDetectorRef) { - super(cdRef); - } - - /** - * paramètre géré - */ - private get _param(): NgParameter { - return this._model; - } - - protected getModelValue(): any { - if (this._param === undefined || this._param === null) { - return undefined; - } - return this._param.valueList; - } - - protected setModelValue(sender: any, l: any) { - if (typeof (l) === "number") { - this._param.valueList = []; - this._param.valueList.push(l); - } else { - this._param.valueList = l; - } - } - - protected validateModelValue(v: any): { isValid: boolean, message: string } { - let msg; - let valid = false; - - if (v instanceof Array) { - valid = true; - try { - this._param.checkList(v); - } catch (ex) { - valid = false; - if (ex instanceof Message) { - msg = this.intlService.localizeMessage(ex); - } else { - msg = "invalid value"; - } - } - } else { - msg = "Veuillez entrer une liste de nombres"; - } - - return { isValid: valid, message: msg }; - } - - protected modelToUI(v: any): string { - let res = ""; - if (v !== undefined && v !== null) { - for (const e of v) { - if (res !== "") { - res += ";"; - } - res += String(e); - } - } - return res; - } - - protected validateUIValue(ui: string): { isValid: boolean, message: string } { - let valid = false; - let msg: string; - - const tmp: string[] = ui.split(";"); - let res = true; - for (const v of tmp) { - const isnum = v !== "" && (+v === +v); - res = res && isnum; - if (!res) { - break; - } - } - - if (!res) { - msg = "Veuillez entrer une liste de nombres"; - } else { - valid = true; - } - - return { isValid: valid, message: msg }; - } - - protected uiToModel(ui: string) { - const tmp: string[] = ui.split(";"); - const res = []; - for (const v of tmp) { - res.push(+v); - } - return res; - } -} diff --git a/src/app/components/remous-results/remous-results.component.html b/src/app/components/remous-results/remous-results.component.html index 391f0ddaf6d95aa137e768f02b7ee66b5b3f1ad4..24c15f01effb82c4ca45e46839b49138fe3a8f09 100644 --- a/src/app/components/remous-results/remous-results.component.html +++ b/src/app/components/remous-results/remous-results.component.html @@ -1,19 +1,15 @@ -<div class="container-fluid" *ngIf="hasResults"> - <div class="row"> - <div class="col"> - <chart [type]="graph1_type" [data]="graph1_data" [options]="graph1_options"></chart> - </div> +<div class="container" *ngIf="hasResults"> + <div> + <chart [type]="graph1_type" [data]="graph1_data" [options]="graph1_options"></chart> </div> - <div class="row"> - <div class="col"> - <chart *ngIf="extraGraph" [type]="graph2_type" [data]="graph2_data" [options]="graph2_options"></chart> - </div> + <div> + <chart *ngIf="extraGraph" [type]="graph2_type" [data]="graph2_data" [options]="graph2_options"></chart> </div> <!-- journal --> <log></log> - <div *ngIf="hasData" class="row"> + <div *ngIf="hasData"> <!-- résultats numériques --> <var-results></var-results> </div> diff --git a/src/app/components/remous-results/remous-results.component.ts b/src/app/components/remous-results/remous-results.component.ts index 3d47a77084d5c90028e3fb5f7916593f843429ce..a64d46ce41d264b9370a6654be5d667281a374fc 100644 --- a/src/app/components/remous-results/remous-results.component.ts +++ b/src/app/components/remous-results/remous-results.component.ts @@ -2,11 +2,13 @@ import { Component, ViewChild, DoCheck } from "@angular/core"; import { ArrayReverseIterator, ResultElement, INumberIterator } from "jalhyd"; -import { InternationalisationService } from "../../services/internationalisation/internationalisation.service"; +import { I18nService } from "../../services/internationalisation/internationalisation.service"; import { LogComponent } from "../../components/log/log.component"; import { RemousResults } from "../../results/remous-results"; import { CalculatorResults } from "../../results/calculator-results"; import { VarResultsComponent } from "../fixedvar-results/var-results.component"; +import { ApplicationSetupService } from "../../services/app-setup/app-setup.service"; +import { ServiceFactory } from "../../services/service-factory"; /** * données pour une ligne dans le graphe @@ -32,6 +34,8 @@ class LineData { */ private _data = {}; + private appSetup: ApplicationSetupService; + /** * profondeur à laquelle est dessinée la ligne * les profondeurs les plus petites sont dessinées derrière les profondeurs les plus grandes @@ -44,6 +48,7 @@ class LineData { for (let i = this._tx.length - 1; i >= 0; i--) { this._ty.push(null); } + this.appSetup = ServiceFactory.instance.applicationSetupService; } public getYat(x: number) { @@ -248,8 +253,10 @@ export class RemousResultsComponent implements DoCheck { @ViewChild(LogComponent) private logComponent: LogComponent; - constructor(private intlService: InternationalisationService) { - } + constructor( + private intlService: I18nService, + private appSetup: ApplicationSetupService + ) { } private get uitextLigneFluviale() { return this.intlService.getExtraResLabel("FLU"); @@ -549,6 +556,7 @@ export class RemousResultsComponent implements DoCheck { this.graph1_data = gr1.data; + const nDigits = this.appSetup.displayDigits; this.graph1_options = { responsive: true, maintainAspectRatio: true, @@ -563,6 +571,26 @@ export class RemousResultsComponent implements DoCheck { display: true, text: this.uitextAbscisse, position: "bottom" + }, + scales: { + xAxes: [{ + gridLines: { + offsetGridLines: true + }, + ticks: { + precision: nDigits, + callback: function(value, index, values) { + return Number(value).toFixed(nDigits); + } + } + }] + }, + tooltips: { + callbacks: { + label: function(tooltipItem, data) { + return Number(tooltipItem.yLabel).toFixed(nDigits); + } + } } }; diff --git a/src/app/components/result-element/horizontal-result-element.component.html b/src/app/components/result-element/horizontal-result-element.component.html deleted file mode 100644 index 5b40239d3b81eee340e96c805916fdc6ac7f330f..0000000000000000000000000000000000000000 --- a/src/app/components/result-element/horizontal-result-element.component.html +++ /dev/null @@ -1,36 +0,0 @@ -<!-- template pour le popup --> -<ng-template #popTemplate> - <div [innerHtml]="htmlTooltip"></div> -</ng-template> - -<!-- - <ng-template #tmplxxxx let-xxx="yyy"> - {{xxx}}> - </ng-template> - - #tmplxxxx : nom utilisé pour référencer ce template - let-xxx : définition du nom d'une variable d'entrée xxx du template - yyy : clé de la valeur de xxx dans le contexte passé au template - - instancié avec : - <ng-container *ngTemplateOutlet="tmplxxxx;context:ctx"></ng-container> - ctx : contexte passé au template. Défini dans le .ts du composant : - private ctx = { yyy: 0.1 }; - - cf. https://blog.angular-university.io/angular-ng-template-ng-container-ngtemplateoutlet/ ---> - -<!-- icône en cas d'erreur --> -<i *ngIf="hasError" class="fa fa-exclamation-triangle" style="color:red" aria-hidden="true" [mdbTooltip]="popTemplate" [isDisabled]="tooltipDisabled"></i> - -<!-- valeur --> -<span *ngIf="!hasError" [mdbTooltip]="popTemplate" [isDisabled]="tooltipDisabled"> - {{ resultValue }} -</span> - -<!-- template de création de td supplémentaires pour les extraResult --> -<ng-template #extraResultTd let-v="extraResultValue"> - <td> - {{ v }} - </td> -</ng-template> \ No newline at end of file diff --git a/src/app/components/result-element/horizontal-result-element.component.ts b/src/app/components/result-element/horizontal-result-element.component.ts deleted file mode 100644 index faa0174d6a02fb277d505d55fde34d25ec4846e1..0000000000000000000000000000000000000000 --- a/src/app/components/result-element/horizontal-result-element.component.ts +++ /dev/null @@ -1,41 +0,0 @@ -import { Component, Input, ViewChild, TemplateRef, ViewContainerRef } from "@angular/core"; -import { OnChanges } from "@angular/core/src/metadata/lifecycle_hooks"; -import { ResultElementBaseComponent } from "./result-element-base.component"; - -@Component({ - selector: "[horizontal-result-element]", - templateUrl: "./horizontal-result-element.component.html" -}) -export class HorizontalResultElementComponent extends ResultElementBaseComponent implements OnChanges { - // template des td pour les extraResult - @ViewChild("extraResultTd") tdTemplate: TemplateRef<any>; - - /** - * clés des résultats complémentaires à afficher (la cellule est vide s'il n'existe pas dans le ResultElement) - */ - private _headerKeys: string[]; - - @Input() - public set headerKeys(h: string[]) { - this._headerKeys = h; - } - - constructor(private vcRef: ViewContainerRef) { - super(); - } - - ngOnChanges() { - super.ngOnChanges(); - - this.vcRef.clear(); - if (this._headerKeys && this._resultElement) { - for (const h of this._headerKeys) { - let v = this._resultElement.extraResults[h]; - if (typeof (v) === "number") { - v = this.intlService.formatResult(h, v); - } - this.vcRef.createEmbeddedView(this.tdTemplate, { extraResultValue: v }); - } - } - } -} diff --git a/src/app/components/result-element/result-element-base.component.ts b/src/app/components/result-element/result-element-base.component.ts deleted file mode 100644 index d30921bbea27adaa69cd3fec8d07b63b524a1f52..0000000000000000000000000000000000000000 --- a/src/app/components/result-element/result-element-base.component.ts +++ /dev/null @@ -1,115 +0,0 @@ -import { Component, Input } from "@angular/core"; - -import { ResultElement } from "jalhyd"; - -import { ApplicationSetupService } from "../../services/app-setup/app-setup.service"; -import { InternationalisationService } from "../../services/internationalisation/internationalisation.service"; -import { OnChanges } from "@angular/core/src/metadata/lifecycle_hooks"; -import { ServiceFactory } from "../../services/service-factory"; - -/** - * classe de base pour l'affichage d'un ResultElement - * étendue par HorizontalResultElementComponent et VerticalResultElementComponent - */ -@Component({ - selector: "[result-element-base]", - template: `<div></div>` -}) -export class ResultElementBaseComponent implements OnChanges { - /** - * ResultElement à afficher - */ - protected _resultElement: ResultElement; - - @Input("result-element") - private set resultElement(re: ResultElement) { - this._resultElement = re; - } - - /** - * valeur numérique du résultat - */ - protected _value: string; - - /** - * true si la valeur est en erreur - */ - protected _hasError: boolean; - - /** - * true si le result element a une valeur - */ - protected _hasValue: boolean; - - /** - * code HTML du tooltip - */ - protected _htmlTooltip: string; - - /** - * true si pas de texte à afficher dans le tooltip - */ - protected _emptyTooltip = false; - - protected appSetupService: ApplicationSetupService; - - protected intlService: InternationalisationService; - - constructor( - ) { - this.appSetupService = ServiceFactory.instance.applicationSetupService; - this.intlService = ServiceFactory.instance.internationalisationService; - } - - /** - * appelé quand les @Input changent - */ - ngOnChanges() { - this.updateTooltip(); - } - - private updateTooltip() { - // valeur à afficher - - const nDigits = this.appSetupService.displayDigits; - const r: ResultElement = this._resultElement; - this._hasValue = r !== undefined && r.vCalc !== undefined; - this._hasError = r === undefined || (r.vCalc === undefined && r.extraResults.length > 0); - this._value = this._hasValue ? this._value = r.vCalc.toFixed(nDigits) : " "; - - // texte du tooltip - - let res = ""; - - if (this._resultElement !== undefined) { - for (const m of this._resultElement.log.messages) { - if (res.length > 0) { - res += "<br/>"; - } - res += this.intlService.localizeMessage(m); - } - } - this._htmlTooltip = res; - this._emptyTooltip = this._htmlTooltip.length === 0; - } - - public get hasValue() { - return this._hasValue; - } - - private get resultValue(): string { - return this._value; - } - - public get hasError() { - return this._hasError && !this._emptyTooltip; - } - - private get htmlTooltip(): string { - return this._htmlTooltip; - } - - private get tooltipDisabled(): boolean { - return this._emptyTooltip; - } -} diff --git a/src/app/components/result-element/vertical-result-element.component.html b/src/app/components/result-element/vertical-result-element.component.html deleted file mode 100644 index 38226ca2658c039fda1df8ff5b4e4e6b684204bc..0000000000000000000000000000000000000000 --- a/src/app/components/result-element/vertical-result-element.component.html +++ /dev/null @@ -1,31 +0,0 @@ -<!-- template pour le popup --> -<ng-template #popTemplate> - <div [innerHtml]="htmlTooltip"></div> -</ng-template> - -<td *ngIf="hasValue" class="label2"> - {{ resultLabel }} -</td> - -<td *ngIf="hasValue||hasError" [mdbTooltip]="popTemplate" [isDisabled]="tooltipDisabled" class="value2"> - <!-- icône en cas d'erreur --> - <i *ngIf="hasError" class="fa fa-exclamation-triangle" style="color:red" aria-hidden="true"></i> - - <!-- valeur --> - <span *ngIf="hasValue"> - {{ resultValue }} - </span> -</td> - -<!-- template de création de tr supplémentaires pour les extraResult --> -<ng-template #extraResultTr let-r="extraRes" let-c="classes"> - <!-- résultats complémentaires --> - <tr> - <td class={{c.label_class}}> - {{ r.label }} - </td> - <td class={{c.value_class}}> - {{ r.value }} - </td> - </tr> -</ng-template> \ No newline at end of file diff --git a/src/app/components/result-element/vertical-result-element.component.ts b/src/app/components/result-element/vertical-result-element.component.ts deleted file mode 100644 index 8da84bab6b4f81e70a524568f8797f90f5f1cbfe..0000000000000000000000000000000000000000 --- a/src/app/components/result-element/vertical-result-element.component.ts +++ /dev/null @@ -1,107 +0,0 @@ -import { Component, Input, ViewChild, TemplateRef, ViewContainerRef } from "@angular/core"; -import { OnChanges } from "@angular/core/src/metadata/lifecycle_hooks"; -import { ResultElementBaseComponent } from "./result-element-base.component"; - -@Component({ - selector: "tr[vertical-result-element]", - templateUrl: "./vertical-result-element.component.html", - styles: [ - `.label1 { - text-align: right; background-color: #f0f0f0; font-weight: bold - }`, - `.value1 { - text-align: center; background-color: #f0f0f0; font-weight: bold - }`, - `.label2 { - text-align: right; background-color: #ffffff; font-weight: bold - }`, - `.value2 { - text-align: center; background-color: #ffffff; font-weight: bold - }` - ] -}) -export class VerticalResultElementComponent extends ResultElementBaseComponent implements OnChanges { - /** - * nom de la variable - */ - @Input() - private _label: string; - - // template des tr pour les extraResult - @ViewChild("extraResultTr") trTemplate: TemplateRef<any>; - - constructor(private vcRef: ViewContainerRef) { - super(); - } - - private get resultLabel() { - return this._label; - } - - ngOnChanges() { - super.ngOnChanges(); - - this.vcRef.clear(); - if (this._resultElement) { - let i = 0; - for (const k in this._resultElement.extraResults) { - if (this._resultElement.extraResults.hasOwnProperty(k)) { - const er: number = this._resultElement.extraResults[k]; - const lblClass = (i % 2) === 0 ? "label1" : "label2"; - const valueClass = (i % 2) === 0 ? "value1" : "value2"; - this.vcRef.createEmbeddedView(this.trTemplate, { - extraRes: { "label": this.intlService.getExtraResLabel(k), "value": this.intlService.formatResult(k, er) }, - classes: { "label_class": lblClass, "value_class": valueClass } - }); - i++; - } - } - } - } -} - -/* -exemple de composant générant plusieurs tr d'une table - -@Component({ - selector: 'tr[my-row]', - template: ` - <td>{{ firstWord }}</td> - <td>{{ secondWord }}</td> - - <ng-template #secondRow> - <tr> - <td>fooooooooooooooo</td> - <td>bar</td> - </tr> - </ng-template> - ` -}) -export class MyRowComponent { - @Input() firstWord = 'first'; - @Input() secondWord = 'second'; - @Input() secondRow = false; - - @ViewChild('secondRow') template: TemplateRef<any>; - - constructor(private vcRef: ViewContainerRef) {} - - ngOnInit() { - if(this.secondRow) { - this.vcRef.createEmbeddedView(this.template); - } - } -} - -parent.html - -<table class="table"> - <tr> - <td>column 1</td> - <td>column 2</td> - </tr> - <tr my-row firstWord="hello world" secondWord="good bye"> - <tr my-row secondRow="true"> - <tr my-row> -</table> -*/ diff --git a/src/app/components/results-graph/graph-type.component.scss b/src/app/components/results-graph/graph-type.component.scss new file mode 100644 index 0000000000000000000000000000000000000000..46070b5e341c3e12e97c41533c28c5508e6ba8a4 --- /dev/null +++ b/src/app/components/results-graph/graph-type.component.scss @@ -0,0 +1,16 @@ +:host { + display: block; + margin-top: 5px; + text-align: center; +} + +mat-select { + + ::ng-deep .mat-select-value { + > span { + > span { + line-height: 1.3em; + } + } + } +} diff --git a/src/app/components/results-graph/graph-type.component.ts b/src/app/components/results-graph/graph-type.component.ts index 5ccfbf764b89e8dec1ff38b08a42e52380908f52..c96f6c53257d276a45ee07e3a7d8f936d861af85 100644 --- a/src/app/components/results-graph/graph-type.component.ts +++ b/src/app/components/results-graph/graph-type.component.ts @@ -1,24 +1,28 @@ import { Component } from "@angular/core"; - import { Observable, IObservable, Observer } from "jalhyd"; - -import { GenericSelectComponent } from "../generic-select/generic-select.component"; import { GraphType } from "../../results/var-results"; +import { I18nService } from "../../services/internationalisation/internationalisation.service"; @Component({ selector: "graph-type", - templateUrl: "../generic-select/generic-select.component.html" + templateUrl: "../generic-select/generic-select.component.html", + styleUrls: [ + "./graph-type.component.scss" + ] }) -export class GraphTypeSelectComponent extends GenericSelectComponent<GraphType> implements IObservable { +export class GraphTypeSelectComponent implements IObservable { private _entries: GraphType[] = [GraphType.Histogram, GraphType.Scatter]; - private _entriesLabels: string[] = ["Histogramme", "XY"]; + private _entriesLabels: string[] = []; private _selected: GraphType; private _observable: Observable; - constructor() { - super(); + constructor(private intlService: I18nService) { this._observable = new Observable(); + this._entriesLabels = [ + this.intlService.localizeText("INFO_PARAMFIELD_GRAPH_TYPE_HISTOGRAM"), + "XY" + ]; } public get entries(): GraphType[] { @@ -44,6 +48,10 @@ export class GraphTypeSelectComponent extends GenericSelectComponent<GraphType> } } + public get label() { + return this.intlService.localizeText("INFO_PARAMFIELD_GRAPH_TYPE"); + } + // interface IObservable /** diff --git a/src/app/components/results-graph/results-graph.component.html b/src/app/components/results-graph/results-graph.component.html index 73ad69b83bac77af7b831eb1196232bc2248ad29..9f0dc91e235577fd23ee2138e13f465f8b40409c 100644 --- a/src/app/components/results-graph/results-graph.component.html +++ b/src/app/components/results-graph/results-graph.component.html @@ -1,12 +1,4 @@ -<div class="row"> - <div class="col-12"> - <chart [type]="graph_type" [data]="graph_data" [options]="graph_options"> - </chart> - </div> -</div> +<chart [type]="graph_type" [data]="graph_data" [options]="graph_options"> +</chart> -<div class="row"> - <div class="col-4 mx-auto"> - <graph-type></graph-type> - </div> -</div> \ No newline at end of file +<graph-type></graph-type> diff --git a/src/app/components/results-graph/results-graph.component.ts b/src/app/components/results-graph/results-graph.component.ts index 36d0ed25044c7884a4b3d4713060d039126d2399..35dbf11cda534be7b9733acd4538dec58c29c931 100644 --- a/src/app/components/results-graph/results-graph.component.ts +++ b/src/app/components/results-graph/results-graph.component.ts @@ -4,6 +4,7 @@ import { Observer } from "jalhyd"; import { VarResults, GraphType } from "../../results/var-results"; import { GraphTypeSelectComponent } from "./graph-type.component"; +import { ApplicationSetupService } from "../../services/app-setup/app-setup.service"; @Component({ selector: "results-graph", @@ -35,6 +36,13 @@ export class ResultsGraphComponent implements AfterContentInit, Observer { } }; + public constructor( + private appSetup: ApplicationSetupService + ) { + // limit display precision according to app preferences + const nDigits = this.appSetup.displayDigits; + } + public set results(r: VarResults) { this._results = r; if (this._results && this._graphTypeComponent) { @@ -73,8 +81,7 @@ export class ResultsGraphComponent implements AfterContentInit, Observer { const dat = []; let i = 0; for (const x of this._results.variatedParameter.valuesIterator) { - labs.push(String(x)); - + labs.push(x); const y = this._results.yValues[i]; dat.push(y); i++; @@ -84,12 +91,10 @@ export class ResultsGraphComponent implements AfterContentInit, Observer { this.graph_data = { labels: labs, - datasets: [ - { - label: "", - data: dat - } - ] + datasets: [{ + label: "", + data: dat + }] }; } @@ -102,30 +107,40 @@ export class ResultsGraphComponent implements AfterContentInit, Observer { let i = 0; for (const x of this._results.variatedParameter.valuesIterator) { labs.push(x); - const y = this._results.yValues[i]; dat.push(y); - i++; } this.graph_options.title.text = this._results.graphTitle; + const nDigits = this.appSetup.displayDigits; this.graph_options["scales"] = { xAxes: [{ gridLines: { offsetGridLines: true + }, + ticks: { + precision: nDigits, + callback: function(value, index, values) { + return Number(value).toFixed(nDigits); + } } }] }; + this.graph_options["tooltips"] = { + callbacks: { + label: function(tooltipItem, data) { + return Number(tooltipItem.yLabel).toFixed(nDigits); + } + } + }; this.graph_data = { labels: labs, - datasets: [ - { - label: "", - data: dat - } - ] + datasets: [{ + label: "", + data: dat + }] }; } @@ -137,32 +152,47 @@ export class ResultsGraphComponent implements AfterContentInit, Observer { let i = 0; for (const x of this._results.variatedParameter.valuesIterator) { const y = this._results.yValues[i]; - dat.push({ x: x, y: y }); + dat.push({ + x: x, + y: y + }); i++; } this.graph_options.title.text = this._results.graphTitle; + const nDigits = this.appSetup.displayDigits; this.graph_options["scales"] = { xAxes: [{ type: "linear", - position: "bottom" + position: "bottom", + ticks: { + precision: nDigits + } }], yAxes: [{ type: "linear", - position: "left" + position: "left", + ticks: { + precision: nDigits + } }] }; + this.graph_options["tooltips"] = { + callbacks: { + label: function(tooltipItem, data) { + return "(" + Number(tooltipItem.xLabel).toFixed(nDigits) + ", " + Number(tooltipItem.yLabel).toFixed(nDigits) + ")"; + } + } + }; this.graph_data = { - datasets: [ - { - label: "", - data: dat, - borderColor: "#808080", // couleur de la ligne - backgroundColor: "rgba(0,0,0,0)", // couleur de remplissage sous la courbe : transparent - showLine: "true" - } - ] + datasets: [{ + label: "", + data: dat, + borderColor: "#808080", // couleur de la ligne + backgroundColor: "rgba(0,0,0,0)", // couleur de remplissage sous la courbe : transparent + showLine: "true" + }] }; } diff --git a/src/app/components/save-calculator/save-calculator-anchor.directive.ts b/src/app/components/save-calculator/save-calculator-anchor.directive.ts deleted file mode 100644 index fa2d02f81584d9e9c2f5c32c6f0d3408f35bfa1e..0000000000000000000000000000000000000000 --- a/src/app/components/save-calculator/save-calculator-anchor.directive.ts +++ /dev/null @@ -1,28 +0,0 @@ -import { Directive, ComponentFactoryResolver, ComponentFactory, ComponentRef } from "@angular/core"; - -import { ViewContainerRef } from "@angular/core"; -import { SaveCalculatorComponent } from "./save-calculator.component"; - -@Directive({ - selector: "[appSaveCalcDialogAnchor]" -}) -export class SaveCalcDialogAnchorDirective { - constructor( - private viewContainer: ViewContainerRef, - private componentFactoryResolver: ComponentFactoryResolver - ) { } - - public createDialog(): ComponentRef<SaveCalculatorComponent> { - this.viewContainer.clear(); - - const compFactory: ComponentFactory<SaveCalculatorComponent> - = this.componentFactoryResolver.resolveComponentFactory(SaveCalculatorComponent); - const compRef: ComponentRef<SaveCalculatorComponent> = this.viewContainer.createComponent(compFactory); - - // dialogComponentRef.instance.close.subscribe(() => { - // dialogComponentRef.destroy(); - // }); - - return compRef; - } -} diff --git a/src/app/components/save-calculator/save-calculator.component.html b/src/app/components/save-calculator/save-calculator.component.html deleted file mode 100644 index 1c48d43c7dfd4aed16531596fc430da7bfb6536f..0000000000000000000000000000000000000000 --- a/src/app/components/save-calculator/save-calculator.component.html +++ /dev/null @@ -1,32 +0,0 @@ -<div mdbModal #saveDialog="mdb-modal" class="modal fade" tabindex="-1" role="dialog" aria-hidden="true" [config]="{backdrop: false, ignoreBackdropClick: true,show:true}"> - <div class="modal-dialog" role="document"> - <div class="modal-content"> - <div class="modal-header"> - <h4 class="modal-title w-100" id="myModalLabel">{{ uitextDialogTitle }}</h4> - </div> - <div class="modal-body"> - <!-- liste de calculettes avec check --> - <div *ngFor="let c of calculators"> - <input type="checkbox" value={{c.uid}} checked={{isSelected(c)}} (change)="onCheckCalc($event)">{{ c.title }} - </div> - - <!-- bouton "tout sélectionnner" --> - <button type="button" class="btn btn-mdb-color waves-light" (click)="selectAll()" mdbRippleRadius>{{ uitextSelectAll }}</button> - - <!-- bouton "tout désélectionnner" --> - <button type="button" class="btn btn-mdb-color waves-light py-10" (click)="deselectAll()" mdbRippleRadius>{{ uitextDeselectAll }}</button> - - <!-- nom du fichier --> - <div class="md-form form-sm mt-4"> - <input mdbInputDirective [mdbValidate]="false" type="text" id="form1" class="form-control" [(ngModel)]="filename"> - <!-- on utilise [innerHTML] pour que les codes HTML comme soient interprétés correctement --> - <label for="form1" [innerHTML]="filenameTitle"></label> - </div> - </div> - <div class="modal-footer"> - <button type="button" class="btn btn-danger relative waves-light" (click)="saveDialog.hide();cancelSave()" mdbRippleRadius>{{ uitextCloseDialogNo }}</button> - <button type="button" class="btn btn-success waves-light" aria-label="Close " (click)="saveDialog.hide();confirmSave()" mdbRippleRadius>{{ uitextCloseDialogYes }}</button> - </div> - </div> - </div> -</div> \ No newline at end of file diff --git a/src/app/components/save-calculator/save-calculator.component.ts b/src/app/components/save-calculator/save-calculator.component.ts deleted file mode 100644 index 653e76c4bffce16c3a14360ffa357c5ac5987810..0000000000000000000000000000000000000000 --- a/src/app/components/save-calculator/save-calculator.component.ts +++ /dev/null @@ -1,135 +0,0 @@ -import { Component, EventEmitter } from "@angular/core"; -import { ServiceFactory } from "../../services/service-factory"; -import { InternationalisationService } from "../../services/internationalisation/internationalisation.service"; - -@Component({ - selector: "save-calc", - templateUrl: "./save-calculator.component.html" -}) -export class SaveCalculatorComponent { - /** - * liste des calculettes affichées. Forme des objets : - * "title": nom de la calculette - * "selected": flag de sélection pour la sauvegarde - * "uid": id unique du formulaire - */ - private _calculators: any[]; - - /** - * nom du fichier - */ - private _filename = "session"; - - private _filenameTitle = "Nom de fichier"; - - /** - * événement émis lors du clic sur "annuler"/"enregister" - * utilisé par la promise de gestion de la confirmation/annulation de la sauvegarde - */ - private confirmResult = new EventEmitter(); - - // services - private intlService: InternationalisationService; - - constructor() { - this.intlService = ServiceFactory.instance.internationalisationService; - } - - public get uitextDialogTitle() { - return "Enregister les calculettes"; - } - - public get uitextCloseDialogYes() { - // return this.intlService.localizeText("INFO_OPTION_YES"); - return "Sauver"; - } - - public get uitextCloseDialogNo() { - // return this.intlService.localizeText("INFO_OPTION_NO"); - return "Annuler"; - } - - public get uitextSelectAll() { - return "Toutes"; - } - - public get uitextDeselectAll() { - return "Aucune"; - } - - public get filename(): string { - return this._filename; - } - - public set filename(f: string) { - this._filename = f; - } - - public get filenameTitle(): string { - return this._filenameTitle; - } - - - public run(calcList: any[]): Promise<any[]> { - this._calculators = calcList; - - // promise de gestion de la confirmation/annulation de la sauvegarde - return new Promise((resolve, reject) => { - this.confirmResult.subscribe((confirm) => { - if (confirm) { - resolve(this._calculators); - } else { - reject(); - } - }); - }); - } - - private isSelected(c: any) { - return c.selected ? "checked" : undefined; - } - - private onCheckCalc(event: any) { - for (const c of this._calculators) { - if (c.uid === event.target.value) { - c.selected = event.target.checked; - } - } - } - - public selectAll() { - for (const c of this._calculators) { - c.selected = true; - } - } - - public deselectAll() { - for (const c of this._calculators) { - c.selected = false; - } - } - - private set confirmed(b: boolean) { - setTimeout(() => { - this.confirmResult.next(b); - }, 0); - } - - public get calculators() { - return this._calculators; - } - - /** - * appelé quand on clique sur annuler - */ - public cancelSave() { - this.confirmed = false; - } - - /** - * appelé quand on clique sur sauver - */ - public confirmSave() { - this.confirmed = true; - } -} diff --git a/src/app/components/section-results/section-results.component.ts b/src/app/components/section-results/section-results.component.ts index ae3598d0fc1a560b047b9480d228f34caac61771..83ad69517fa2676d6d94324a98e2b4b52f89042f 100644 --- a/src/app/components/section-results/section-results.component.ts +++ b/src/app/components/section-results/section-results.component.ts @@ -6,7 +6,7 @@ import { SectionCanvasComponent } from "../section-canvas/section-canvas.compone import { SectionResults } from "../../results/section-results"; import { ApplicationSetupService } from "../../services/app-setup/app-setup.service"; import { CalculatorResults } from "../../results/calculator-results"; -import { InternationalisationService } from "../../services/internationalisation/internationalisation.service"; +import { I18nService } from "../../services/internationalisation/internationalisation.service"; @Component({ selector: "section-results", @@ -33,7 +33,7 @@ import { InternationalisationService } from "../../services/internationalisation }) export class SectionResultsComponent implements DoCheck { - constructor(private appSetupService: ApplicationSetupService, private intlService: InternationalisationService) { } + constructor(private appSetupService: ApplicationSetupService, private intlService: I18nService) { } public set results(rs: CalculatorResults[]) { this._resultElement = undefined; diff --git a/src/app/components/select-field-line/select-field-line.component.html b/src/app/components/select-field-line/select-field-line.component.html deleted file mode 100644 index c298402bd3203e34793e85c773167d2c1dc9aa19..0000000000000000000000000000000000000000 --- a/src/app/components/select-field-line/select-field-line.component.html +++ /dev/null @@ -1,16 +0,0 @@ -<div class="row"> - <!-- titre --> - <div class="col-12 col-sm-3"> - {{ label }} - </div> - - <!-- liste déroulante --> - <div class="btn-group col-12 col-sm-9" dropdown (click)="onSelect($event)"> - <button dropdownToggle class="btn btn-primary dropdown-toggle waves-light my-1" type="button" mdbRippleRadius> - {{ currentLabel }} - </button> - <div class="dropdown-menu"> - <a class="dropdown-item" *ngFor="let e of entries" [value]=e>{{ entryLabel(e) }}</a> - </div> - </div> -</div> \ No newline at end of file diff --git a/src/app/components/select-field-line/select-field-line.component.scss b/src/app/components/select-field-line/select-field-line.component.scss new file mode 100644 index 0000000000000000000000000000000000000000..7b16e54279684cba3f58937e588f36f560dda449 --- /dev/null +++ b/src/app/components/select-field-line/select-field-line.component.scss @@ -0,0 +1,24 @@ +mat-form-field { + width: 100%; + + mat-select { + + ::ng-deep .mat-select-value { + > span { + > span { + line-height: 1.3em; + } + } + } + + ::ng-deep .mat-form-field-label { + font-size: 1.1em; + line-height: 1.4em; + margin-top: -2px; + + &.mat-form-field-empty { + font-size: 1em; + } + } + } +} diff --git a/src/app/components/select-field-line/select-field-line.component.ts b/src/app/components/select-field-line/select-field-line.component.ts index 59f111c2364ca042154a310ad9d4809bbd74271d..a7840110a5aec8492dcacf86f4fd16775fc2c8b0 100644 --- a/src/app/components/select-field-line/select-field-line.component.ts +++ b/src/app/components/select-field-line/select-field-line.component.ts @@ -2,13 +2,16 @@ import { Component, Input } from "@angular/core"; import { SelectField } from "../../formulaire/select-field"; import { SelectEntry } from "../../formulaire/select-entry"; -import { GenericSelectComponent } from "../generic-select/generic-select.component"; @Component({ selector: "select-field-line", - templateUrl: "./select-field-line.component.html" + // templateUrl: "./select-field-line.component.html", + templateUrl: "../generic-select/generic-select.component.html", + styleUrls: [ + "./select-field-line.component.scss" + ] }) -export class SelectFieldLineComponent extends GenericSelectComponent<SelectEntry> { +export class SelectFieldLineComponent { @Input() private _select: SelectField; diff --git a/src/app/config.json b/src/app/config.json new file mode 100644 index 0000000000000000000000000000000000000000..cb7754e64b271455f1e1d128346868fd88441224 --- /dev/null +++ b/src/app/config.json @@ -0,0 +1,63 @@ +{ + "params": { + "displayPrecision": 0.001, + "computePrecision": 0.0001, + "newtonMaxIterations": 50, + "language": "fr" + }, + "themes": [ + { + "name": "PASSE_A_BASSIN", + "image": { + "path": "passe-bassin.jpg", + "title": "Passe à poisson sur le Lez, entre Bollène et Suze", + "credits": "Hervé Capra / Irstea" + }, + "calculators": [ 5, 6, 10, 9 ] + }, + { + "name": "PASSE_NATURELLE", + "image": { + "path": "passe-naturelle.jpg", + "title": "Passe à poisson sur le petit Buech, seuil de Chiala ou des Savoillons", + "credits": "Catherine Tailleux / Irstea" + }, + "calculators": [ 11 ] + }, + { + "name": "HYDRAULIQUE_A_SURFACE_LIBRE", + "image": { + "path": "surface-libre.jpg", + "title": "Jaugeage sur le canal du Congrès (Domaine du Merle, Salon de Provence)", + "credits": "David Dorchies / Irstea" + }, + "calculators": [ 2, 3, 4 ] + }, + { + "name": "HYDRAULIQUE_EN_CHARGE", + "image": { + "path": "en-charge.jpg", + "title": "Asperseurs dans la vallée de la Méouge", + "credits": "Catherine Tailleux / Irstea" + }, + "calculators": [ 1, 0 ] + }, + { + "name": "LOIS_D_OUVRAGES", + "image": { + "path": "ouvrages.jpg", + "title": "Seuil triangulaire (Halle hydraulique SupAgro Montpellier)", + "credits": "David Dorchies / Irstea" + }, + "calculators": [ 8, 9, 10 ] + }, + { + "_comment": "card for calculators not used in any theme", + "image": { + "path": "autres.jpg", + "title": "", + "credits": "" + } + } + ] +} diff --git a/src/app/directives/flex-xxs.directive.ts b/src/app/directives/flex-xxs.directive.ts new file mode 100644 index 0000000000000000000000000000000000000000..e4df90248cfa5b2c76f0b77b7d804d7e10fd217e --- /dev/null +++ b/src/app/directives/flex-xxs.directive.ts @@ -0,0 +1,65 @@ +import { Directive } from "@angular/core"; +import { BREAKPOINT, ShowHideDirective, FlexDirective } from "@angular/flex-layout"; + +const XXS_BREAKPOINTS = [ + { + alias: "xxs", + mediaQuery: "screen and (max-width: 479px)", + overlapping: false + }, + { + alias: "xs", // redéfinition + mediaQuery: "screen and (min-width: 480px) screen and (max-width: 599px)", + overlapping: false + }, + { + alias: "gt-xxs", + mediaQuery: "screen and (min-width: 480px)", + overlapping: false + }, + { + alias: "lt-xs", + mediaQuery: "screen and (max-width: 479px)", + overlapping: false + } +]; + +export const CustomBreakPointsProvider = { + provide: BREAKPOINT, + useValue: XXS_BREAKPOINTS, + multi: true +}; + +const inputsXxs = [ "fxHide.xxs" ]; +const inputsGtXxs = [ "fxHide.gt-xxs" ]; +const inputsLtXs = [ "fxHide.lt-xs" ]; + +@Directive({ + // tslint:disable-next-line:directive-selector + selector: `[fxHide.xxs]`, + // tslint:disable-next-line:use-input-property-decorator + inputs: inputsXxs +}) +export class FlexXxsShowHideDirective extends ShowHideDirective { + protected inputs = inputsXxs; +} + +@Directive({ + // tslint:disable-next-line:directive-selector + selector: `[fxHide.gt-xxs]`, + // tslint:disable-next-line:use-input-property-decorator + inputs: inputsGtXxs +}) +export class FlexGtXxsShowHideDirective extends ShowHideDirective { + protected inputs = inputsGtXxs; +} + +@Directive({ + // tslint:disable-next-line:directive-selector + selector: `[fxHide.lt-xs]`, + // tslint:disable-next-line:use-input-property-decorator + inputs: inputsLtXs +}) +export class FlexLtXsShowHideDirective extends ShowHideDirective { + protected inputs = inputsLtXs; +} diff --git a/src/app/directives/jalhyd-async-model-validation.directive.ts b/src/app/directives/jalhyd-async-model-validation.directive.ts new file mode 100644 index 0000000000000000000000000000000000000000..b8c7bebd00cc6bb8b8eafacc61b5713837442655 --- /dev/null +++ b/src/app/directives/jalhyd-async-model-validation.directive.ts @@ -0,0 +1,37 @@ +import { Validator, AbstractControl, ValidationErrors, NG_ASYNC_VALIDATORS } from "@angular/forms"; +import { Directive, Input, forwardRef } from "@angular/core"; +import { NgBaseParam } from "../components/base-param-input/base-param-input.component"; +import { Observable } from "rxjs"; + +/** + * Asynchronous validator for Ngparam, relying on JaLHyd ParamDefinition model + */ +@Directive({ + selector: "[appAsyncJalhydModelValidation]", + providers: [ { + provide: NG_ASYNC_VALIDATORS, + useExisting: forwardRef(() => JalhydAsyncModelValidationDirective), + multi: true + } ] +}) +export class JalhydAsyncModelValidationDirective implements Validator { + @Input("appAsyncJalhydModelValidation") ngBaseParam: NgBaseParam; + + validate(control: AbstractControl): Promise<ValidationErrors | null> | Observable<ValidationErrors | null> { + let errorPromiseReturn = new Promise(res => { + res(null); + }); // no error, everything OK + const result = this.ngBaseParam.validateModelValue(control.value); + if (! result.isValid) { + errorPromiseReturn = new Promise<ValidationErrors>(res => { + res({ + "jalhydModel": { + value: control.value, + message: result.message + } + }); + }); + } + return errorPromiseReturn; + } +} diff --git a/src/app/directives/jalhyd-model-validation.directive.ts b/src/app/directives/jalhyd-model-validation.directive.ts new file mode 100644 index 0000000000000000000000000000000000000000..06a9bf67363afa05e468202f6417b94247a126be --- /dev/null +++ b/src/app/directives/jalhyd-model-validation.directive.ts @@ -0,0 +1,39 @@ +import { NG_VALIDATORS, Validator, AbstractControl, ValidatorFn } from "@angular/forms"; +import { Directive, Input } from "@angular/core"; +import { NgBaseParam } from "../components/base-param-input/base-param-input.component"; + +/** + * Synchronous validator for Ngparam, relying on JaLHyd ParamDefinition model + */ +@Directive({ + selector: "[appJalhydModelValidation]", + providers: [ { + provide: NG_VALIDATORS, + useExisting: JalhydModelValidationDirective, + multi: true + } ] +}) +export class JalhydModelValidationDirective implements Validator { + @Input("appJalhydModelValidation") ngBaseParam: NgBaseParam; + + validate(control: AbstractControl): { [key: string]: any } | null { + const mv = jalhydModelValidator(this.ngBaseParam)(control); + return mv; + } +} + +export function jalhydModelValidator(ngBaseParam: NgBaseParam): ValidatorFn { + return (control: AbstractControl): { [key: string]: any } | null => { + let errorReturn = null; // no error, everything OK + const result = ngBaseParam.validateModelValue(control.value); + if (result && ! result.isValid) { + errorReturn = { + "jalhydModel": { + value: control.value, + message: result.message + } + }; + } + return errorReturn; + }; +} diff --git a/src/app/formulaire/definition/concrete/form-parallel-structures.ts b/src/app/formulaire/definition/concrete/form-parallel-structures.ts index 4d5697248f5612f0a8fa5eb16aa24ac64d12132a..8e563f732817ee5ff32917aefa00ea3a4764fb40 100644 --- a/src/app/formulaire/definition/concrete/form-parallel-structures.ts +++ b/src/app/formulaire/definition/concrete/form-parallel-structures.ts @@ -223,11 +223,9 @@ export class FormulaireParallelStructure extends FormulaireDefinition { } } - if (select === undefined) { - return undefined; + if (select !== undefined) { + return { "select": select, "entry": selectEntry }; } - - return { "select": select, "entry": selectEntry }; } /** @@ -244,8 +242,6 @@ export class FormulaireParallelStructure extends FormulaireDefinition { } } } - - return undefined; } /** diff --git a/src/app/formulaire/definition/concrete/form-regime-uniforme.ts b/src/app/formulaire/definition/concrete/form-regime-uniforme.ts index b7549d6764dfdb11b89f4b6e65f90b4871981aec..63ed5d5a8249cba95173d3ce91ed355774f7accf 100644 --- a/src/app/formulaire/definition/concrete/form-regime-uniforme.ts +++ b/src/app/formulaire/definition/concrete/form-regime-uniforme.ts @@ -1,5 +1,5 @@ import { FormDefFixedVar } from "../form-def-fixedvar"; -import { CalculatorType, ComputeNodeType, IObservable, Observer } from "jalhyd"; +import { IObservable, Observer } from "jalhyd"; import { FormResultFixedVar } from "../form-result-fixedvar"; import { FormulaireDefinition } from "../form-definition"; import { FormDefSection } from "../form-def-section"; diff --git a/src/app/formulaire/definition/concrete/form-section-parametree.ts b/src/app/formulaire/definition/concrete/form-section-parametree.ts index 5b2e2bd2d29f3564f37d141ae3f8364fc464aea9..e5d22bcf919c95bb75d229c64fe0da09be0dd916 100644 --- a/src/app/formulaire/definition/concrete/form-section-parametree.ts +++ b/src/app/formulaire/definition/concrete/form-section-parametree.ts @@ -6,7 +6,7 @@ import { NgParameter } from "../../ngparam"; import { InputField } from "../../input-field"; import { FormComputeSectionParametree } from "../form-compute-section-parametree"; import { FormulaireDefinition } from "../form-definition"; -import { InternationalisationService } from "../../../services/internationalisation/internationalisation.service"; +import { I18nService } from "../../../services/internationalisation/internationalisation.service"; import { CalculatorResults } from "../../../results/calculator-results"; import { FormDefFixedVar } from "../form-def-fixedvar"; import { FieldSet } from "../../fieldset"; diff --git a/src/app/formulaire/definition/form-compute-fixedvar.ts b/src/app/formulaire/definition/form-compute-fixedvar.ts index 873488018729347e8e215267e12933ac9a3eda7f..7b64ec15da3be9b36d88fe94169fe05562f711c0 100644 --- a/src/app/formulaire/definition/form-compute-fixedvar.ts +++ b/src/app/formulaire/definition/form-compute-fixedvar.ts @@ -26,7 +26,6 @@ export class FormComputeFixedVar extends FormCompute { return p; } } - return undefined; } private getComputedParameter(): NgParameter { diff --git a/src/app/formulaire/definition/form-def-fixedvar.ts b/src/app/formulaire/definition/form-def-fixedvar.ts index 9e72537aad47170faa27b75b90e5a6df09bd57d5..d34f67110ac5f75bf50c5fc2e78637133d63ba95 100644 --- a/src/app/formulaire/definition/form-def-fixedvar.ts +++ b/src/app/formulaire/definition/form-def-fixedvar.ts @@ -66,7 +66,7 @@ export class FormDefFixedVar { * action2 : reset (à FIX) de tous les autres paramètres que celui modifié sauf celui/ceux à VAR * action3 : reset (à FIX) de tous les autres paramètres que celui modifié * action4 : mettre le paramètre désigné par la conf comme "par défault" à CAL - * action5 : mettre le 1er paramètre de la calculette à CAL + * action5 : mettre le 1er paramètre du module de calcul à CAL */ protected processRadioStateChange(sourceParam: NgParameter, oldState: ParamValueMode) { switch (oldState) { @@ -143,6 +143,7 @@ export class FormDefFixedVar { for (const p of this._formBase.allFormElements) { if (p instanceof NgParameter) { + // change all radio button groups except the one that sent the event if (p.radioConfig === ParamRadioConfig.CAL && p.radioState === ParamRadioConfig.FIX && p !== sourceParam) { newCal = p; break; @@ -152,7 +153,8 @@ export class FormDefFixedVar { break; } } - + // if the current calculated parameter was set to another mode, set a new param + // to calculated mode (there must always be at least one) if (newCal) { newCal.valueMode = ParamValueMode.CALCUL; } @@ -173,9 +175,6 @@ export class FormDefFixedVar { public onRadioClick(info: any) { const param: NgParameter = info.param; // paramètre source de l'événement radio const old: ParamValueMode = info.oldValueMode; // ancien état (radio) - - // this.logParams(); this.resetRadiosAndResults(param, old); - // this.logParams(); } } diff --git a/src/app/formulaire/definition/form-def-section.ts b/src/app/formulaire/definition/form-def-section.ts index 734243db275a0149fe78bdf08219e4bd7df11932..f4fe312ca445de92751bd3f3db6fa3ea73b42120 100644 --- a/src/app/formulaire/definition/form-def-section.ts +++ b/src/app/formulaire/definition/form-def-section.ts @@ -53,7 +53,7 @@ export class FormDefSection { * @param fs nouveau FieldSet */ public afterParseFieldset(fs: FieldSet) { - if (this.hasSectionNodeTypeSource) { // s'il existe un menu de choix de section dans la calculette + if (this.hasSectionNodeTypeSource) { // s'il existe un menu de choix de section dans le module de calcul const sel = fs.getFormulaireNodeById(this._sectionSourceId); if (sel) { // on abonne le formulaire aux propriétés du FieldSet pour MAJ du nub, reset du formulaire, ... diff --git a/src/app/formulaire/definition/form-definition.ts b/src/app/formulaire/definition/form-definition.ts index a8a00aaa62ccf32b5f1c5bd0fddf85c8805b0439..390718dcd6c94fe67c1efa92400c9b13a1958617 100644 --- a/src/app/formulaire/definition/form-definition.ts +++ b/src/app/formulaire/definition/form-definition.ts @@ -20,7 +20,7 @@ import { CalculatorResults } from "../../results/calculator-results"; */ export abstract class FormulaireDefinition extends FormulaireNode implements Observer { /** - * nom de la calculette + * nom du module de calcul */ private _calculatorName: string; @@ -70,8 +70,7 @@ export abstract class FormulaireDefinition extends FormulaireNode implements Obs this.notifyObservers({ "action": "nameChanged", "name": name - }, - this); + }, this); } public get jsonConfig(): {} { @@ -133,8 +132,6 @@ export abstract class FormulaireDefinition extends FormulaireNode implements Obs if (json["type"] === "options") { return json[option]; } - - return undefined; } public afterParseFieldset(fs: FieldSet) { @@ -147,6 +144,14 @@ export abstract class FormulaireDefinition extends FormulaireNode implements Obs return res; } + /** + * @return true si le SessionNub attaché (ou un de ses enfants) a l'uid donné + * @param uid id à rechercher + */ + public hasNubId(uid: string): boolean { + return this._currentNub.uid === uid; + } + public moveFieldsetUp(fs: FieldSet) { } @@ -206,7 +211,7 @@ export abstract class FormulaireDefinition extends FormulaireNode implements Obs this.initParse(); // analyse des options globales - // il est utile de le faire avant le reste pour les calculettes utilisant + // il est utile de le faire avant le reste pour les modules de calcul utilisant // des sections (id des selects type de section/variable à calculer) // tslint:disable-next-line:forin @@ -224,7 +229,7 @@ export abstract class FormulaireDefinition extends FormulaireNode implements Obs /** * 2ème passe d'analyse de la configuration */ - public parseConfig(json: {}) { + public parseConfig(json?: {}) { if (json !== undefined) { this._jsonConfig = json; } @@ -255,7 +260,7 @@ export abstract class FormulaireDefinition extends FormulaireNode implements Obs break; default: - throw new Error(`type d'objet de calculette ${type} non pris en charge`); + throw new Error(`type d'objet de module de calcul ${type} non pris en charge`); } } @@ -293,7 +298,6 @@ export abstract class FormulaireDefinition extends FormulaireNode implements Obs } } } - return undefined; } public getDisplayedParamFromState(st: ParamRadioConfig): NgParameter { @@ -304,7 +308,6 @@ export abstract class FormulaireDefinition extends FormulaireNode implements Obs } } } - return undefined; } public getDisplayedParamListFromState(st: ParamRadioConfig): NgParameter[] { @@ -322,7 +325,6 @@ export abstract class FormulaireDefinition extends FormulaireNode implements Obs if (res instanceof Field) { return res; } - return undefined; } public getParameterValue(symbol: string): number { @@ -523,6 +525,44 @@ export abstract class FormulaireDefinition extends FormulaireNode implements Obs } } + /** + * MAJ des liens entre paramètres lors de la désérialisation JSON + */ + + private getNthFieldset(n: number): FieldSet { + let i = 0; + for (const e of this.topFormElements) { + if (e instanceof FieldSet) { + if (i === n) { + return e; + } + i++; + } + } + + return undefined; + } + + /** + * @param json conf du formulaire + * @param uidMap table de correspondance uid dans le fichier de conf <-> uid en mémoire + */ + public updateParamsLinks(json: {}, uidMap: {}[]) { + for (const ks in json) { + switch (ks) { + case "elements": + let n = 0; + for (const e of json[ks]) { + if (Object.keys(e)[0] === "fieldset") { + this.getNthFieldset(n).updateParamsLinks(e["fieldset"], uidMap); + n++; + } + } + break; + } + } + } + // interface Observer public update(sender: any, data: any) { diff --git a/src/app/formulaire/dependency/dependency.ts b/src/app/formulaire/dependency/dependency.ts index 368ac35a0078f35f65e8ea9b807484535e93223e..fe7426f55bed6b9e75365cce30b1a5e9c1aad49a 100644 --- a/src/app/formulaire/dependency/dependency.ts +++ b/src/app/formulaire/dependency/dependency.ts @@ -28,7 +28,6 @@ export abstract class Dependency { } parentNode = parentNode.parent; } - return undefined; } protected get masterElement(): FormulaireElement { diff --git a/src/app/formulaire/fieldset.ts b/src/app/formulaire/fieldset.ts index ed645c97bd70120813916c1d8e63e160e7d9b9bd..73740f7ecee0809098836692fa016d378084349b 100644 --- a/src/app/formulaire/fieldset.ts +++ b/src/app/formulaire/fieldset.ts @@ -76,7 +76,6 @@ export class FieldSet extends FormulaireElement implements Observer { n++; } } - return undefined; } public get isValid(): boolean { @@ -129,7 +128,7 @@ export class FieldSet extends FormulaireElement implements Observer { /** * crée un input - * @param json definition de l'input, extrait du fichier de conf de la calculette + * @param json definition de l'input, extrait du fichier de conf du module de calcul * @param node_type_filter filtre sur le type de noeud (input créé si undefined ou égal) * @param default_radio_config config du radio fixé/à varier/à calculer */ @@ -221,7 +220,7 @@ export class FieldSet extends FormulaireElement implements Observer { this.updateLocalisation(); // MAJ des selects avec les valeurs actuelles des propriétés - // spécifique à chaque calculette, à revoir + // spécifique à chaque modul de calcul, à revoir if (this._confId === "fs_ouvrage") { const sf1: SelectField = this.getFormulaireNodeById("select_ouvrage") as SelectField; @@ -314,8 +313,6 @@ export class FieldSet extends FormulaireElement implements Observer { } } } - - return undefined; } public getNodeParameterValue(symbol: string): number { @@ -346,7 +343,6 @@ export class FieldSet extends FormulaireElement implements Observer { return FormulaireElement.removePrefix(value, selectFieldId + "_"); } } - return undefined; } // interface Observer @@ -445,4 +441,46 @@ export class FieldSet extends FormulaireElement implements Observer { } } } + + /** + * MAJ des liens entre paramètres lors de la désérialisation JSON + * @param json conf du fieldset issue du fichier + * @param uidMap table de correspondance uid dans le fichier de conf <-> uid en mémoire + */ + public updateParamsLinks(json: {}, uidMap: {}[]) { + for (const ks in json) { + switch (ks) { + case "elements": + for (const e of json[ks]) { + if (Object.keys(e)[0] === "param") { + const prm = e["param"]; + if (prm["values"]["mode"] === "LINK") { + // id du formulaire cible dans le fichier + const oldFormUid = +prm["values"]["form_uid"]; + + // correspondance avec l'objet mémoire + let newFormUid; + for (const m of uidMap) { + if (m["type"] === "form" && m["old"] === oldFormUid) { + newFormUid = m["new"]; + break; + } + } + + // formulaire dont le Nub est la cible du lien + const destForm: FormulaireDefinition + = ServiceFactory.instance.formulaireService.getFormulaireFromId(newFormUid); + + // paramètre source (celui qui est lié à une valeur) + const src: NgParameter = this.getFormulaireNodeById(prm["id"]) as NgParameter; + + // création du lien + src.paramDefinition.defineReference(destForm.currentNub, prm["values"]["ref"]); + } + break; + } + } + } + } + } } diff --git a/src/app/formulaire/formulaire-element.ts b/src/app/formulaire/formulaire-element.ts index 6933766e0ac491e997304af136818297768afbc8..c2347b6ee8574b780f72c560a8e617024fd087bf 100644 --- a/src/app/formulaire/formulaire-element.ts +++ b/src/app/formulaire/formulaire-element.ts @@ -5,7 +5,7 @@ import { DependencyCondition, DependencyConditionType } from "./dependency/depen import { ValueDependencyCondition } from "./dependency/value-dependency-condition"; import { ExistenceDependency } from "./dependency/existence-dependency"; import { DeepFormulaireElementIterator } from "./form-iterator/deep-element-iterator"; -import { InternationalisationService } from "../services/internationalisation/internationalisation.service"; +import { I18nService } from "../services/internationalisation/internationalisation.service"; import { ServiceFactory } from "../services/service-factory"; /** @@ -27,7 +27,7 @@ export abstract class FormulaireElement extends FormulaireNode { */ private _labelNumber: number; - private intlService: InternationalisationService; + private intlService: I18nService; protected _dependencies: Dependency[] = []; @@ -36,13 +36,12 @@ export abstract class FormulaireElement extends FormulaireNode { const l = prefix.length; return s.substr(l, s.length - l); } - return undefined; } constructor(parent: FormulaireNode) { super(parent); this._isDisplayed = true; - this.intlService = ServiceFactory.instance.internationalisationService; + this.intlService = ServiceFactory.instance.i18nService; } get isDisplayed(): boolean { @@ -69,7 +68,7 @@ export abstract class FormulaireElement extends FormulaireNode { } public getKids(): FormulaireElement[] { - return super.kids as FormulaireElement[]; + return this.kids as FormulaireElement[]; } /** diff --git a/src/app/formulaire/formulaire-node.ts b/src/app/formulaire/formulaire-node.ts index 44245795e47a5a381c6f6382603a7d392ff6f5ac..627e38f7d9225419a966d63c0d0d96801dede6c0 100644 --- a/src/app/formulaire/formulaire-node.ts +++ b/src/app/formulaire/formulaire-node.ts @@ -70,8 +70,6 @@ export abstract class FormulaireNode implements IObservable { return res; } } - - return undefined; } /** @@ -88,8 +86,6 @@ export abstract class FormulaireNode implements IObservable { return res; } } - - return undefined; } /** diff --git a/src/app/formulaire/immediate-error-state-matcher.ts b/src/app/formulaire/immediate-error-state-matcher.ts new file mode 100644 index 0000000000000000000000000000000000000000..687edca5be1449ddc2dbe80742ba451a0eeb0269 --- /dev/null +++ b/src/app/formulaire/immediate-error-state-matcher.ts @@ -0,0 +1,16 @@ +import { ErrorStateMatcher } from "@angular/material"; +import { FormControl, FormGroupDirective, NgForm } from "@angular/forms"; + +/** + * An error state matcher for Angular Forms that displays errors immediately, + * instead of waiting for the focus to get out of the input at least once + */ +export class ImmediateErrorStateMatcher implements ErrorStateMatcher { + + constructor() { } + + isErrorState(control: FormControl | null, form: FormGroupDirective | NgForm | null): boolean { + const isSubmitted = form && form.submitted; + return !!(control && control.invalid /* && (control.dirty || control.touched || isSubmitted) */ ); + } +} diff --git a/src/app/formulaire/ngparam.ts b/src/app/formulaire/ngparam.ts index 50125790a4fd68293ae9ae70ebc2d952eb698f0b..82cca313a78d8406fadd269a9385505202866da5 100644 --- a/src/app/formulaire/ngparam.ts +++ b/src/app/formulaire/ngparam.ts @@ -54,7 +54,7 @@ export class NgParameter extends InputField implements Observer { this._confId = id; } - public get _paramValues() { // @TODO remettre en private ! (debug) + private get _paramValues() { return this._paramDef.paramValues; } @@ -148,6 +148,17 @@ export class NgParameter extends InputField implements Observer { return this._paramDef.isValid; } + public get title(): string { + let t = ""; + if (this.label !== undefined) { + t = this.label; + } + if (this.unit !== undefined && this.unit !== "") { + t = t + " (" + this.unit + ")"; + } + return t; + } + public get valuesIterator(): INumberIterator { return this._paramDef.valuesIterator; } @@ -155,7 +166,8 @@ export class NgParameter extends InputField implements Observer { public radioConfig: ParamRadioConfig; /** - * true si ce paramètre est celui par défaut dans un formulaire (cf. fichier de conf des calculettes, objet "options", champ "idCal") + * true si ce paramètre est celui par défaut dans un formulaire + * (cf. fichier de conf des modules de calcul, objet "options", champ "idCal") */ public isDefault = false; // archi bug du langage ! si on relit cette propriété sans l'avoir modifiée entre-temps, elle vaut undefined ! @@ -326,6 +338,12 @@ export class NgParameter extends InputField implements Observer { case ParamValueMode.LISTE: res["values"] = this._paramValues.valueList; break; + + case ParamValueMode.LINK: + // @TODO copié à l'arrache, vérifier que ça marche + res["form_uid"] = ServiceFactory.instance.formulaireService.getFormulaireFromNubId(this._paramDef.referencedNub["uid"]).uid; + res["ref"] = this.paramDefinition.referenceDefinition; + break; } return res; } @@ -359,6 +377,9 @@ export class NgParameter extends InputField implements Observer { this._paramValues.valueMode = ParamValueMode.CALCUL; break; + case ParamValueMode.LINK: + break; // cf FormulaireService.updateParamsLinks() + default: throw new Error(`session file : invalid value mode '${json["mode"]}' in param object`); } diff --git a/src/app/formulaire/select-field.ts b/src/app/formulaire/select-field.ts index 3e3bd899d61a39a0613b217174e73a1f540842c3..3bfadc6cf957cd3df97395df4cb7344aafd4ee75 100644 --- a/src/app/formulaire/select-field.ts +++ b/src/app/formulaire/select-field.ts @@ -35,7 +35,6 @@ export class SelectField extends Field { return se; } } - return undefined; } public getValue() { diff --git a/src/app/results/var-results.ts b/src/app/results/var-results.ts index 4776f5d8837a41013655fb42cb618e8bf34f8064..657dd44f690b3ea84912c475aa618697e1421765 100644 --- a/src/app/results/var-results.ts +++ b/src/app/results/var-results.ts @@ -140,7 +140,7 @@ export class VarResults extends CalculatedParamResults { // entêtes des résultats supplémentaires - const intlService = ServiceFactory.instance.internationalisationService; + const intlService = ServiceFactory.instance.i18nService; for (const k of this._extraResultKeys) { this._extraResultHeaders.push(intlService.getExtraResLabel(k)); } diff --git a/src/app/services/app-setup/app-setup.service.ts b/src/app/services/app-setup/app-setup.service.ts index 9c24f2d1131c05fdd11e14ad8d8e13fc199cf59d..6a6069c637bfdc6986892a5e09ac8833bbb10a21 100644 --- a/src/app/services/app-setup/app-setup.service.ts +++ b/src/app/services/app-setup/app-setup.service.ts @@ -1,14 +1,56 @@ +import { HttpService } from "../http/http.service"; +import { Injectable } from "@angular/core"; +import { Observable } from "jalhyd"; + /** * Stores app preferences - * @TODO save in cookie / localStorage ? */ -export class ApplicationSetupService { +@Injectable() +export class ApplicationSetupService extends Observable { + + private CONFIG_FILE_PATH = "app/config.json"; + // default builtin values public displayPrecision = 0.001; public computePrecision = 0.0001; - public newtonMaxIter = 50; + public newtonMaxIterations = 50; + private _language = "fr"; + /** themes to group calculators, for displaying on the front page */ + public themes: any[]; + + public constructor( + private httpService: HttpService + ) { + + super(); + this.readValuesFromConfig(); + } public get displayDigits() { return -Math.log10(this.displayPrecision); } + + public set language(lang: string) { + this._language = lang; + this.notifyObservers(null); + } + + public get language(): string { + return this._language; + } + + // @TODO save preferences in cookie / localStorage ? + + // read default values from config and notify observers + private readValuesFromConfig() { + this.httpService.httpGetRequestPromise(this.CONFIG_FILE_PATH).then((data: any) => { + this.displayPrecision = data.params.displayPrecision; + this.computePrecision = data.params.computePrecision; + this.newtonMaxIterations = data.params.newtonMaxIterations; + this.language = data.params.language; + this.themes = data.themes; + + this.notifyObservers(null); + }); + } } diff --git a/src/app/services/formulaire/formulaire.service.ts b/src/app/services/formulaire/formulaire.service.ts index e6570d34fbaf970365ac24660d389b6c70030b76..dda5ad7a3f3d766173caec498ca3309bfdd1fcc6 100644 --- a/src/app/services/formulaire/formulaire.service.ts +++ b/src/app/services/formulaire/formulaire.service.ts @@ -1,14 +1,12 @@ import { Injectable } from "@angular/core"; -import "rxjs/add/operator/toPromise"; import { decode } from "he"; import { saveAs } from "file-saver"; import { CalculatorType, EnumEx, Observable, ParamDefinition } from "jalhyd"; -import { ServiceFactory } from "../service-factory"; import { HttpService } from "../../services/http/http.service"; -import { InternationalisationService } from "../../services/internationalisation/internationalisation.service"; +import { I18nService } from "../../services/internationalisation/internationalisation.service"; import { FormulaireDefinition } from "../../formulaire/definition/form-definition"; import { FormulaireElement } from "../../formulaire/formulaire-element"; import { InputField } from "../../formulaire/input-field"; @@ -29,17 +27,20 @@ export class FormulaireService extends Observable { private _currentFormId: string = null; - constructor() { + constructor( + private i18nService: I18nService, + private httpService: HttpService) { + super(); this._formulaires = []; } - private get _intlService(): InternationalisationService { - return ServiceFactory.instance.internationalisationService; + private get _intlService(): I18nService { + return this.i18nService; } private get _httpService(): HttpService { - return ServiceFactory.instance.httpService; + return this.httpService; } public get formulaires(): FormulaireDefinition[] { @@ -48,7 +49,7 @@ export class FormulaireService extends Observable { private loadLocalisation(calc: CalculatorType): Promise<any> { const f: string = this.getConfigPathPrefix(calc) + this._intlService.currentLanguage.tag + ".json"; - const prom = this._httpService.httpGetRequestPromise(undefined, undefined, undefined, f); + const prom = this._httpService.httpGetRequestPromise(f); return prom.then((j) => { return j as StringMap; @@ -101,7 +102,7 @@ export class FormulaireService extends Observable { public loadConfig(ct: CalculatorType): Promise<any> { const f: string = this.getConfigPathPrefix(ct) + "config.json"; - return this._httpService.httpGetRequestPromise(undefined, undefined, undefined, f); + return this._httpService.httpGetRequestPromise(f); } private newFormulaire(ct: CalculatorType, jsonState?: {}): FormulaireDefinition { @@ -137,7 +138,7 @@ export class FormulaireService extends Observable { break; default: - throw new Error(`FormulaireService.newFormulaire() : type de calculette ${CalculatorType[ct]} non pris en charge`); + throw new Error(`FormulaireService.newFormulaire() : type de module de calcul ${CalculatorType[ct]} non pris en charge`); } f.defaultProperties["calcType"] = ct; @@ -157,30 +158,19 @@ export class FormulaireService extends Observable { const prom: Promise<any> = this.loadConfig(ct); return prom.then(s => { f.preparseConfig(s); - return f; - }).then(fi => { if (jsonState === undefined) { - fi.calculatorName = decode(this.getLocalisedTitleFromCalculatorType(ct) + " (" + fi.uid + ")"); + f.calculatorName = decode(this.getLocalisedTitleFromCalculatorType(ct)); } - fi.initNub(); - return fi; - }).then(fi => { - fi.parseConfig(undefined); - return fi; - }).then(fi => { + f.initNub(); + f.parseConfig(); if (jsonState !== undefined) { - fi.deserialiseJSON(jsonState); - const props = jsonState["props"]; + f.deserialiseJSON(jsonState); } - return fi; - }).then(fi => { // la méthode loadUpdateFormulaireLocalisation retourne une Promise; le fait de retourner une Promise dans un then // fait que le then suivant est exécuté juste après. - return this.loadUpdateFormulaireLocalisation(fi); + return this.loadUpdateFormulaireLocalisation(f); }).then(fi => { fi.applyDependencies(); - return fi; - }).then(fi => { this.notifyObservers( { "action": "createForm", @@ -196,8 +186,6 @@ export class FormulaireService extends Observable { return f; } } - - return undefined; } public getInputField(formId: string, elemId: string): InputField { @@ -233,7 +221,6 @@ export class FormulaireService extends Observable { } } } - return undefined; } public getParamdefParentForm(prm: ParamDefinition): FormulaireDefinition { @@ -246,7 +233,17 @@ export class FormulaireService extends Observable { } } } - return undefined; + } + + /** + * retrouve un formulaire à partir d'un uid de Nub + */ + public getFormulaireFromNubId(uid: string) { + for (const f of this._formulaires) { + if (f.hasNubId(uid)) { + return f; + } + } } public getConfigPathPrefix(ct: CalculatorType): string { @@ -360,9 +357,9 @@ export class FormulaireService extends Observable { } /** - * charge une session en tenant compte des calculettes sélectionnées + * charge une session en tenant compte des modules de calcul sélectionnées * @param f fichier session - * @param formInfos infos sur les calculettes @see LoadCalculatorComponent._calculators + * @param formInfos infos sur les modules de calcul @see DialogLoadSessionComponent.calculators */ public loadSession(f: File, formInfos: any[]) { this.readSingleFile(f).then(s => { @@ -388,7 +385,7 @@ export class FormulaireService extends Observable { } /** - * obtient des infos (nom, uid des calculettes) d'un fichier session + * obtient des infos (nom, uid des modules de calcul) d'un fichier session * @param f fichier session */ public calculatorInfosFromSessionFile(f: File): Promise<any[]> { @@ -396,7 +393,7 @@ export class FormulaireService extends Observable { const res: any[] = []; const session = JSON.parse(s); - // liste des noms de calculettes + // liste des noms de modules de calcul for (const k in session) { switch (k) { case "session": @@ -427,13 +424,13 @@ export class FormulaireService extends Observable { }); } - private deserialiseForm(elements: {}) { + private deserialiseForm(elements: {}): Promise<FormulaireDefinition> { const props = elements["props"]; const ct: CalculatorType = props["calcType"]; - this.createFormulaire(ct, elements); + return this.createFormulaire(ct, elements); } - private deserialiseSessionElement(element: {}, formInfos: any[]) { + private deserialiseSessionElement(element: {}, formInfos: any[]): Promise<FormulaireDefinition> { const keys = Object.keys(element); if (keys.length !== 1) { throw new Error(`session file : invalid session object '${element}'`); @@ -445,7 +442,7 @@ export class FormulaireService extends Observable { for (const i of formInfos) { if (i["uid"] === form["uid"] && i["selected"]) { - this.deserialiseForm(form); + return this.deserialiseForm(form); } } break; @@ -455,12 +452,85 @@ export class FormulaireService extends Observable { } } + /** + * met à jour les liens d'un formulaire + * @param json conf du formulaire + * @param formInfos métadonnées sur les formulaires chargés + * @param form formulaire dont on met à jour les liens + * @param uidMap table de correspondance uid dans le fichier de conf <-> uid en mémoire + */ + private updateFormLinks(json: {}, formInfos: any[], form: FormulaireDefinition, uidMap: {}[]) { + for (const i of formInfos) { + if (i["uid"] === json["uid"] && i["selected"]) { + form.updateParamsLinks(json, uidMap); + } + } + } + + /** + * MAJ des liens entre paramètres lors de la désérialisation JSON + */ + + private updateParamsLinks(json: {}, formInfos: any[], oldFormCount: number) { + // table de correspondance des uid fichier <-> objets mémoire + // forme : tableau d'objets de la forme : + // { "type" : <type de l'objet. "form" pour formulaire>, + // "old": <uid dans le fichier>, + // "new": <uid de l'objet mémoire>} + + const uidMap = []; + for (const ks in json) { + switch (ks) { + case "elements": + let n = oldFormCount; + for (const e of json[ks]) { + if (Object.keys(e)[0] === "form") { + uidMap.push({ + "type": "form", + "old": e["form"]["uid"], + "new": this._formulaires[n].uid + }); + n++; + } + } + } + } + + // MAJ liens + + for (const ks in json) { + switch (ks) { + case "elements": + let n = 0; + for (const e of json[ks]) { + if (Object.keys(e)[0] === "form") { + this.updateFormLinks(e["form"], formInfos, this._formulaires[n + oldFormCount], uidMap); + n++; + } + } + break; + + default: + throw new Error(`session file : invalid key '${ks}' in session object`); + } + } + } + private deserialiseSession(elements: {}, formInfos: any[]) { + let p: Promise<FormulaireDefinition>; + + const oldFormCount = this._formulaires.length; for (const ks in elements) { switch (ks) { case "elements": for (const e of elements[ks]) { - this.deserialiseSessionElement(e, formInfos); + if (p === undefined) { + p = this.deserialiseSessionElement(e, formInfos); + } else { + p = p.then(_ => { + return this.deserialiseSessionElement(e, formInfos); + }); + } } break; @@ -468,11 +538,12 @@ export class FormulaireService extends Observable { throw new Error(`session file : invalid key '${ks}' in session object`); } } + p.then(_ => this.updateParamsLinks(elements, formInfos, oldFormCount)); } /** * @returns liste des valeurs liables à un paramètre sous la forme d'un tableau d'objets - * {"param":<paramètre lié>, "nub":<Nub d'origine du paramètre lié>, "formTitle":<nom de la calculette liée au nub>} + * {"param":<paramètre lié>, "nub":<Nub d'origine du paramètre lié>, "formTitle":<nom du module de calcul liée au nub>} * @param p paramètre qui sert de clé de recherche des paramètres liables */ public getLinkableValues(p: NgParameter): any[] { diff --git a/src/app/services/http/http.service.ts b/src/app/services/http/http.service.ts index 613c8fd3de71d5e92493f2ee06974aa18db08aa0..580ffee36e0cc66d25d3c35202180008b424fa45 100644 --- a/src/app/services/http/http.service.ts +++ b/src/app/services/http/http.service.ts @@ -10,52 +10,25 @@ export class HttpService { /** * Lance une requête GET (version standard Observable) - * @param protocol ex: "https" - * @param host ex: "domaine.fr" - * @param port ex: 8080 * @param path ex: /mon-service/toto * @param headers ex: new HttpHeaders { "Authorization": "bla" } */ - public httpGetRequest(protocol: string, host: string, port: number, path: string, - headers?: HttpHeaders): Observable<Object> { - - let url = ""; - // 1. construire URL - if (host) { - url = host; - } // else throw Error ? - if (protocol) { - url = protocol + "://" + url; - } - if (port) { - url += ":" + String(port); - } - const p = (path === "/") ? "" : path; - if (url === "") { - url = p; - } else { - url += "/" + p; - } - url = encodeURI(url); - - // 2. ajout entêtes + public httpGetRequest(path: string, headers?: HttpHeaders): Observable<Object> { + // ajout entêtes const opts = {}; if (headers) { opts["headers"] = headers; } - - // 3. lancement requête - return this.http.get(url, opts); + // lancement requête + return this.http.get(encodeURI(path), opts); } /** * Lance une requête GET (version Promise) * @see httpGetRequest */ - public httpGetRequestPromise(protocol: string, host: string, port: number, path: string, - headers?: HttpHeaders): Promise<Object> { - - const res$: Observable<Object> = this.httpGetRequest(protocol, host, port, path, headers); + public httpGetRequestPromise(path: string, headers?: HttpHeaders): Promise<Object> { + const res$: Observable<Object> = this.httpGetRequest(path, headers); return res$.toPromise(); } @@ -65,12 +38,12 @@ export class HttpService { * @param errorCallback callback en cas d'erreur * @see httpGetRequest */ - public httpGetRequestCallbacks(protocol: string, host: string, port: number, path: string, + public httpGetRequestCallbacks(path: string, processDataCallback: (s: any) => void, errorCallback?: (err: any) => void, headers?: HttpHeaders): Subscription { - const res$: Observable<Object> = this.httpGetRequest(protocol, host, port, path, headers); + const res$: Observable<Object> = this.httpGetRequest(path, headers); const annulable = res$.subscribe( data => { diff --git a/src/app/services/internationalisation/internationalisation.service.ts b/src/app/services/internationalisation/internationalisation.service.ts index 3d571aa73dfef737f65f017f8389b1fb96fb9eb1..5eb90bcc6c84752e416a77a2d2184de4e5e33a93 100644 --- a/src/app/services/internationalisation/internationalisation.service.ts +++ b/src/app/services/internationalisation/internationalisation.service.ts @@ -1,10 +1,10 @@ import { Injectable } from "@angular/core"; -import { Response } from "@angular/http"; import { Message, MessageCode, Observable } from "jalhyd"; import { StringMap } from "../../stringmap"; -import { ServiceFactory } from "../service-factory"; +import { ApplicationSetupService } from "../app-setup/app-setup.service"; +import { HttpService } from "../http/http.service"; /* language tag : fr-FR @@ -43,14 +43,16 @@ export class Language { } @Injectable() -export class InternationalisationService extends Observable { +export class I18nService extends Observable { + private _currLang: Language; - private _sLang: string; private _Messages: StringMap; - private _languages: Language[]; - public constructor() { + constructor( + private applicationSetupService: ApplicationSetupService, + private httpService: HttpService) { + super(); this._languages = []; this._languages.push(new Language(LanguageCode.FRENCH, "fr", "Français")); @@ -106,7 +108,7 @@ export class InternationalisationService extends Observable { this._Messages = undefined; const prom = this.httpGetMessages(); - const is: InternationalisationService = this; + const is: I18nService = this; prom.then((res) => { is.notifyObservers(undefined); }); @@ -114,7 +116,7 @@ export class InternationalisationService extends Observable { } private httpGetMessages(): Promise<void> { - const is: InternationalisationService = this; + const is: I18nService = this; const processData = function (s: string) { // fermeture nécessaire pour capturer la valeur de this (undefined sinon) is._Messages = JSON.parse(s); @@ -131,12 +133,15 @@ export class InternationalisationService extends Observable { } const f: string = "messages." + l + ".json"; - return ServiceFactory.instance.httpService.httpGetRequestPromise(undefined, undefined, undefined, "locale/" + f).then( + return this.httpService.httpGetRequestPromise("locale/" + f).then( (res: any) => { is._Messages = res; } ); } private getMessageFromCode(c: MessageCode): string { + if (! this._Messages) { + return `*** Messages not loaded yet ***`; + } if (this._Messages[MessageCode[c]] === undefined) { return `*** Message ${MessageCode[c]} non traduit ***`; } @@ -222,7 +227,7 @@ export class InternationalisationService extends Observable { if (match > -1) { return this.localizeText(`INFO_EXTRARES_${label.substring(match).toUpperCase()}_${value}`); } - const nDigits = ServiceFactory.instance.applicationSetupService.displayDigits; + const nDigits = this.applicationSetupService.displayDigits; return value.toFixed(nDigits); } diff --git a/src/app/services/param/param.service.ts b/src/app/services/param/param.service.ts index 7f3ef4039a349d0262f1b77a944c5d906dea55e6..d8d36ce021e17b7983832358c5f14dcdcea10a99 100644 --- a/src/app/services/param/param.service.ts +++ b/src/app/services/param/param.service.ts @@ -2,19 +2,24 @@ import { ParamDomain, ParamDefinition, ParamDomainValue, ParamCalculability, Ses import { NgParameter } from "../../formulaire/ngparam"; import { Injectable } from "@angular/core"; -import { ServiceFactory } from "../service-factory"; -import { InternationalisationService } from "../internationalisation/internationalisation.service"; +import { I18nService } from "../internationalisation/internationalisation.service"; import { ApplicationSetupService } from "../app-setup/app-setup.service"; import { FormulaireNode } from "../../formulaire/formulaire-node"; @Injectable() export class ParamService { - private get _intlService(): InternationalisationService { - return ServiceFactory.instance.internationalisationService; + + constructor( + private i18nService: I18nService, + private applicationSetupService: ApplicationSetupService + ) { } + + private get _intlService(): I18nService { + return this.i18nService; } private get _appSetupService(): ApplicationSetupService { - return ServiceFactory.instance.applicationSetupService; + return this.applicationSetupService; } private createAccuracyParameter(): ParamDefinition { diff --git a/src/app/services/service-factory.ts b/src/app/services/service-factory.ts index 682cc5c087028c83d8fa68fe58282fe8e783ab5e..0e84febabaaa2f1120406de9e2370b4be7b5d9da 100644 --- a/src/app/services/service-factory.ts +++ b/src/app/services/service-factory.ts @@ -1,7 +1,7 @@ import { ApplicationSetupService } from "./app-setup/app-setup.service"; import { ParamService } from "./param/param.service"; import { FormulaireService } from "./formulaire/formulaire.service"; -import { InternationalisationService } from "./internationalisation/internationalisation.service"; +import { I18nService } from "./internationalisation/internationalisation.service"; import { HttpService } from "./http/http.service"; export class ServiceFactory { @@ -15,7 +15,7 @@ export class ServiceFactory { public formulaireService: FormulaireService; - public internationalisationService: InternationalisationService; + public i18nService: I18nService; public httpService: HttpService; diff --git a/src/assets/images/themes/autres.jpg b/src/assets/images/themes/autres.jpg new file mode 100644 index 0000000000000000000000000000000000000000..504bcc57bfb9ca3731a109a8ef3866653dc0ef07 Binary files /dev/null and b/src/assets/images/themes/autres.jpg differ diff --git a/src/assets/images/themes/en-charge.jpg b/src/assets/images/themes/en-charge.jpg new file mode 100644 index 0000000000000000000000000000000000000000..f78e1369a0f4b57397270f3ce7138d5a33a7c60d Binary files /dev/null and b/src/assets/images/themes/en-charge.jpg differ diff --git a/src/assets/images/themes/ouvrages.jpg b/src/assets/images/themes/ouvrages.jpg new file mode 100644 index 0000000000000000000000000000000000000000..d33f5bea990e5b5891d27a9ef454e22a9882b321 Binary files /dev/null and b/src/assets/images/themes/ouvrages.jpg differ diff --git a/src/assets/images/themes/passe-bassin.jpg b/src/assets/images/themes/passe-bassin.jpg new file mode 100644 index 0000000000000000000000000000000000000000..8a6fd88f8dbddb0a90931ca8d4519e824f5d571b Binary files /dev/null and b/src/assets/images/themes/passe-bassin.jpg differ diff --git a/src/assets/images/themes/passe-naturelle.jpg b/src/assets/images/themes/passe-naturelle.jpg new file mode 100644 index 0000000000000000000000000000000000000000..697068b99d6492ec246cb2687813993bf7ff8e51 Binary files /dev/null and b/src/assets/images/themes/passe-naturelle.jpg differ diff --git a/src/assets/images/themes/surface-libre.jpg b/src/assets/images/themes/surface-libre.jpg new file mode 100644 index 0000000000000000000000000000000000000000..9d82f1452b0608abd108e7ccf4220b97b86f268d Binary files /dev/null and b/src/assets/images/themes/surface-libre.jpg differ diff --git a/src/index.html b/src/index.html index 3f118aead63915bdeb163647acea383a103f96a6..f62afd41000d81648d86cc29163e458c7e7045c9 100644 --- a/src/index.html +++ b/src/index.html @@ -8,29 +8,8 @@ <meta name="viewport" content="width=device-width, initial-scale=1"> - <!-- ressources pour faire fonctionner le toggler de la navbar --> - <!-- <script src="https://code.jquery.com/jquery-3.1.1.slim.min.js" integrity="sha384-A7FZj7v+d/sdmMqp/nOQwliLvUsJfDHW+k9Omg/a/EheAdgtzNs3hpfag6Ed950n" --> - <script href="dependencies/jquery-3.1.1.slim.min.js" integrity="sha384-A7FZj7v+d/sdmMqp/nOQwliLvUsJfDHW+k9Omg/a/EheAdgtzNs3hpfag6Ed950n" - crossorigin="anonymous"></script> - - <!-- <script src="https://cdnjs.cloudflare.com/ajax/libs/tether/1.4.0/js/tether.min.js" integrity="sha384-DztdAPBWPRXSA/3eYEEUWrWCy7G5KFbe8fFjk5JAIxUYHKkDx6Qin1DkWx51bBrb" --> - <script href="dependencies/tether.min.js" integrity="sha384-DztdAPBWPRXSA/3eYEEUWrWCy7G5KFbe8fFjk5JAIxUYHKkDx6Qin1DkWx51bBrb" - crossorigin="anonymous"></script> - - <!-- <script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0-alpha.6/js/bootstrap.min.js" integrity="sha384-vBWWzlZJ8ea9aCX4pEW3rVHjgjt7zpkNpZk+02D9phzyeVkE+jo0ieGizqPLForn" --> - <script href="dependencies/bootstrap.min.js" integrity="sha384-vBWWzlZJ8ea9aCX4pEW3rVHjgjt7zpkNpZk+02D9phzyeVkE+jo0ieGizqPLForn" - crossorigin="anonymous"></script> - - <!-- Load the Angular Material stylesheet --> - <!-- - <link href="https://unpkg.com/@angular/material/prebuilt-themes/indigo-pink.css" rel="stylesheet"> <link href="https://fonts.googleapis.com/icon?family=Material+Icons" rel="stylesheet"> - <style> - body { - font-family: Roboto, Arial, sans-serif; - } - </style> ---> + <link href="https://fonts.googleapis.com/css?family=Roboto:300,400,500" rel="stylesheet"> </head> <body> diff --git a/src/locale/messages.en.json b/src/locale/messages.en.json index 01e69db11bc9fde4f4effc872fd0e6d299e02c3f..34099e643b960efc8817c7fcda4d0e3c7a1225d2 100644 --- a/src/locale/messages.en.json +++ b/src/locale/messages.en.json @@ -8,8 +8,11 @@ "ERROR_DICHO_NULL_STEP": "Dichotomy (initial interval search): invalid null step", "ERROR_INTERVAL_OUTSIDE": "Interval: value %value% is outside of %interval", "ERROR_INTERVAL_UNDEF": "Interval: invalid 'undefined' value", + "ERROR_INVALID_AT_POSITION": "Position %s:", "ERROR_LANG_UNSUPPORTED": "internationalisation: unsupported '%locale%' locale", "ERROR_NEWTON_DERIVEE_NULLE": "Null function derivative in Newton computation", + "ERROR_PARAM_NULL": "Parameter value must not be NULL", + "ERROR_PARAM_MUST_BE_A_NUMBER": "Please type a numeric value", "ERROR_PARAMDEF_CALC_UNDEFINED": "calculability of '%symbol%' parameter is undefined", "ERROR_PARAMDEF_VALUE_FIXED": "value of '%symbol%' parameter cannot be changed", "ERROR_PARAMDEF_VALUE_INTERVAL": "parameter '%symbol%': value %value% is out of [%minValue%, %maxValue%] interval", @@ -29,8 +32,10 @@ "ERROR_SECTION_NON_CONVERGENCE_NEWTON_HTOR": "Non convergence of the calculation of the corresponding height (Newton's method) for the calculation of the supercritical depth", "ERROR_SECTION_PENTE_NEG_NULLE_HNORMALE_INF": "The slope is negative or zero, the normal depth is infinite", "ERROR_STRUCTURE_Q_TROP_ELEVE": "The flow passing through the other devices is too high: the requested parameter is not calculable.", + "INFO_CALCULATOR_CALC_NAME": "Calculator name", "INFO_CALCULATOR_CALCULER": "Compute", "INFO_CALCULATOR_PARAMFIXES": "Fixed parameters", + "INFO_CALCULATOR_RESULTS_TITLE": "Results", "INFO_CALCULATOR_VALEURS": "Values", "INFO_CLOISONS_TITRE": "Fish ladder: Cross walls", "INFO_CLOSE_DIALOGUE_TEXT": "Warning ! Parameters and results will be lost. Really close?", @@ -48,6 +53,20 @@ "INFO_EXTRARES_ENUM_STRUCTUREFLOWREGIME_1": "Partially submerged", "INFO_EXTRARES_ENUM_STRUCTUREFLOWREGIME_2": "Submerged", "INFO_EXTRARES_ENUM_STRUCTUREFLOWREGIME_3": "Zero flow", + "INFO_DIALOG_COMPUTED_VALUE_TITLE": "Edit initial value", + "INFO_DIALOG_LOAD_SESSION_FILENAME": "Choose a file", + "INFO_DIALOG_LOAD_SESSION_TITLE": "Load calculator modules", + "INFO_DIALOG_SAVE_SESSION_FILENAME": "File name", + "INFO_DIALOG_SAVE_SESSION_TITLE": "Save calculator modules", + "INFO_EMPTY_SESSION_DIALOGUE_TEXT": "Warning ! All open calculators will be lost. Continue ?", + "INFO_EMPTY_SESSION_DIALOGUE_TITRE": "New session", + "INFO_EXTRARES_ENUM_OUVRAGE_Q_MODE_0": "Weir", + "INFO_EXTRARES_ENUM_OUVRAGE_Q_MODE_1": "Orifice", + "INFO_EXTRARES_ENUM_OUVRAGE_Q_MODE_2": "Zero flow", + "INFO_EXTRARES_ENUM_OUVRAGE_Q_REGIME_0": "Free flow", + "INFO_EXTRARES_ENUM_OUVRAGE_Q_REGIME_1": "Partially submerged", + "INFO_EXTRARES_ENUM_OUVRAGE_Q_REGIME_2": "Submerged", + "INFO_EXTRARES_ENUM_OUVRAGE_Q_REGIME_3": "Zero flow", "INFO_EXTRARES_LIB_B": "Surface width (m)", "INFO_EXTRARES_LIB_CV": "Cv: Velocity coefficient", "INFO_EXTRARES_LIB_CVQT": "CV.QT: Corrected discharge (m³/s)", @@ -98,23 +117,52 @@ "INFO_LIB_ZDV": "Crest weir elevation or gate base", "INFO_LIB_ZRAM": "Upstream apron elevation (m)", "INFO_LIB_ZT": "Triangle top elevation (m)", + "INFO_MACRORUGO_TITRE": "Rock-ramp fishpasses", "INFO_MENU_HELP_TITLE": "Help", "INFO_MENU_LOAD_SESSION_TITLE": "Load session", "INFO_MENU_NOUVELLE_CALC": "New calculation module", - "INFO_MACRORUGO_TITRE": "Rock-ramp fishpasses", + "INFO_MENU_SAVE_SESSION_TITLE": "Save session", + "INFO_MENU_SELECT_CALC": "Select calculator module", + "INFO_MENU_EMPTY_SESSION_TITLE": "New session", "INFO_OPTION_NO": "No", "INFO_OPTION_YES": "Yes", + "INFO_OPTION_CANCEL": "Cancel", + "INFO_OPTION_CLOSE": "Close", + "INFO_OPTION_LOAD": "Load", + "INFO_OPTION_SAVE": "Save", + "INFO_OPTION_VALIDATE": "Validate", + "INFO_OPTION_ALL": "All", + "INFO_OPTION_ALL_F": "All", + "INFO_OPTION_NONE": "None", + "INFO_OPTION_NONE_F": "None", "INFO_OUVRAGE": "Structure", "INFO_PABDIMENSIONS_TITRE": "Fish ladder: dimensions", "INFO_PABPUISSANCE_TITRE": "Fish ladder: dissipated power", "INFO_PARALLELSTRUCTURE_TITRE": "Parallel structures", + "INFO_PARAMFIELD_GRAPH_TYPE": "Graph type", + "INFO_PARAMFIELD_GRAPH_TYPE_HISTOGRAM": "Histogram", + "INFO_PARAMFIELD_IN_CALCULATION": "In calculation", + "INFO_PARAMFIELD_IN_CALCULATION_INITIAL_VALUE": "initial value", "INFO_PARAMFIELD_PARAMCALCULER": "Calculate", "INFO_PARAMFIELD_PARAMFIXE": "Fixed", "INFO_PARAMFIELD_PARAMLIE": "Link", + "INFO_PARAMFIELD_PARAMLIE_LABEL": "Linked parameter", "INFO_PARAMFIELD_PARAMVARIER": "Vary", - "INFO_PARAMFIELD_PASVARIATION": "with a variation step of:", - "INFO_PARAMFIELD_VALEURMAXI": "to maximum value", + "INFO_PARAMFIELD_PASVARIATION": "With a variation step of", + "INFO_PARAMFIELD_PARAMVARIER_IMPORT_FICHIER": "Import file", + "INFO_PARAMFIELD_PARAMVARIER_MINMAXSTEP": "min: %s, max: %s, step: %s", + "INFO_PARAMFIELD_PARAMVARIER_SEPARATEUR_DECIMAL": "Decimal separator", + "INFO_PARAMFIELD_PARAMVARIER_SEPARATEUR_POINT": ". (dot)", + "INFO_PARAMFIELD_PARAMVARIER_SEPARATEUR_VIRGULE": ", (comma)", + "INFO_PARAMFIELD_PARAMVARIER_TITLE": "Multiple values", + "INFO_PARAMFIELD_PARAMVARIER_MODE": "Mode", + "INFO_PARAMFIELD_PARAMVARIER_VALUES": "Values:", + "INFO_PARAMFIELD_PARAMVARIER_VALUES_FORMAT": "Values list", + "INFO_PARAMFIELD_PARAMVARIER_VALUES_FORMAT_ERROR": "Incorrect format; accepted separator: %s", + "INFO_PARAMFIELD_VALEURMAXI": "To maximum value", "INFO_PARAMFIELD_VALEURMINI": "From minimum value", + "INFO_PARAMMODE_MINMAX": "Min/max", + "INFO_PARAMMODE_LIST": "Values list", "INFO_REGIMEUNIFORME_TITRE": "Uniform flow calculation", "INFO_REMOUSRESULTS_ABSCISSE": "Abscissa (m)", "INFO_REMOUSRESULTS_BERGE": "Embankment", @@ -135,6 +183,19 @@ "INFO_SETUP_PRECISION_AFFICHAGE": "Display accuracy", "INFO_SETUP_PRECISION_CALCUL": "Computation accuracy", "INFO_SETUP_TITLE": "Application setup", + "INFO_THEME_CREDITS": "Credit", + "INFO_THEME_MODULES_INUTILISES_TITRE": "Other calculation modules", + "INFO_THEME_MODULES_INUTILISES_DESCRIPTION": "Various calculation modules", + "INFO_THEME_PASSE_A_BASSIN_TITRE": "Fish ladder", + "INFO_THEME_PASSE_A_BASSIN_DESCRIPTION": "Tools for sizing a fish pass made with pools also called fish steps", + "INFO_THEME_PASSE_NATURELLE_TITRE": "Natural pass", + "INFO_THEME_PASSE_NATURELLE_DESCRIPTION": "Tools for sizing a natural fish pass also called macroroughness pass or rock-ramp fish pass", + "INFO_THEME_HYDRAULIQUE_A_SURFACE_LIBRE_TITRE": "Open-channel flow", + "INFO_THEME_HYDRAULIQUE_A_SURFACE_LIBRE_DESCRIPTION": "Calculation modules for flows in channels and rivers", + "INFO_THEME_HYDRAULIQUE_EN_CHARGE_TITRE": "Pipe flow", + "INFO_THEME_HYDRAULIQUE_EN_CHARGE_DESCRIPTION": "Modules for calculating head losses in pressure pipes", + "INFO_THEME_LOIS_D_OUVRAGES_TITRE": "Hydraulic structures", + "INFO_THEME_LOIS_D_OUVRAGES_DESCRIPTION": "Flow calculation for hydraulic devices (gates, weir, orifices)", "WARNING_REMOUS_ARRET_CRITIQUE": "Calculation stopped: critical elevation reached at abscissa %x%", "WARNING_STRUCTUREKIVI_HP_TROP_ELEVE": "h/p must not be greater than 2.5. h/p is forced to 2.5", "WARNING_STRUCTUREKIVI_PELLE_TROP_FAIBLE": "Threshold height should be greater than 0.1 m. Beta coefficient is forced to 0" diff --git a/src/locale/messages.fr.json b/src/locale/messages.fr.json index cd700e267286a4ab7e0a38c2af12f168cce5a949..505f25e4aaa91256a7698fe58474de8a03df6644 100644 --- a/src/locale/messages.fr.json +++ b/src/locale/messages.fr.json @@ -8,8 +8,11 @@ "ERROR_DICHO_NULL_STEP": "Dichotomie : le pas pour la recherche de l'intervalle de départ ne devrait pas être nul", "ERROR_INTERVAL_OUTSIDE": "Interval : la valeur %value% est hors de l'intervalle %interval", "ERROR_INTERVAL_UNDEF": "Interval : valeur 'undefined' incorrecte", + "ERROR_INVALID_AT_POSITION": "Position %s :", "ERROR_LANG_UNSUPPORTED": "Internationalisation : locale '%locale%' non prise en charge", "ERROR_NEWTON_DERIVEE_NULLE": "Dérivée nulle dans un calcul par la méthode de Newton", + "ERROR_PARAM_NULL": "La valeur du paramètre ne peut pas être NULL", + "ERROR_PARAM_MUST_BE_A_NUMBER": "Veuillez entrer une valeur numérique", "ERROR_PARAMDEF_CALC_UNDEFINED": "La calculabilité du paramètre %symbol% n'est pas définie", "ERROR_PARAMDEF_VALUE_FIXED": "La valeur du paramètre %symbol% ne peut pas être changée", "ERROR_PARAMDEF_VALUE_INTERVAL": "Paramètre '%symbol%' : la valeur %value% est en dehors de l'intervalle [%minValue%, %maxValue%]", @@ -29,11 +32,13 @@ "ERROR_SECTION_NON_CONVERGENCE_NEWTON_HTOR": "Non convergence du calcul de la hauteur correspondante (Méthode de Newton) pour le calcul de la hauteur torrentielle", "ERROR_SECTION_PENTE_NEG_NULLE_HNORMALE_INF": "La pente est négative ou nulle, la hauteur normale est infinie", "ERROR_STRUCTURE_Q_TROP_ELEVE": "Le débit passant par les autres ouvrages est trop élevé: le paramètre demandé n'est pas calculable.", + "INFO_CALCULATOR_CALC_NAME": "Nom du module de calcul", "INFO_CALCULATOR_CALCULER": "Calculer", "INFO_CALCULATOR_PARAMFIXES": "Paramètres fixés", + "INFO_CALCULATOR_RESULTS_TITLE": "Résultats", "INFO_CALCULATOR_VALEURS": "Valeurs", "INFO_CLOISONS_TITRE": "Passe à bassin : Cloisons", - "INFO_CLOSE_DIALOGUE_TEXT": "Attention ! Les paramètres et résultats de la calculette seront perdus. Vraiment fermer ?", + "INFO_CLOSE_DIALOGUE_TEXT": "Attention ! Les paramètres et résultats du module de calcul seront perdus. Vraiment fermer ?", "INFO_CLOSE_DIALOGUE_TITRE": "Confirmer la fermeture", "INFO_CONDUITEDISTRIBUTRICE_TITRE": "Conduite distributrice", "INFO_COURBEREMOUS_TITRE": "Courbes de remous", @@ -48,6 +53,20 @@ "INFO_EXTRARES_ENUM_STRUCTUREFLOWREGIME_1": "Partiellement noyé", "INFO_EXTRARES_ENUM_STRUCTUREFLOWREGIME_2": "Noyé", "INFO_EXTRARES_ENUM_STRUCTUREFLOWREGIME_3": "Débit nul", + "INFO_DIALOG_COMPUTED_VALUE_TITLE": "Modifier la valeur initiale", + "INFO_DIALOG_LOAD_SESSION_FILENAME": "Choisir un fichier", + "INFO_DIALOG_LOAD_SESSION_TITLE": "Charger des modules de calcul", + "INFO_DIALOG_SAVE_SESSION_FILENAME": "Nom de fichier", + "INFO_DIALOG_SAVE_SESSION_TITLE": "Enregistrer les modules de calcul", + "INFO_EMPTY_SESSION_DIALOGUE_TEXT": "Attention ! Tous les modules de calcul ouverts seront perdus. Continuer ?", + "INFO_EMPTY_SESSION_DIALOGUE_TITRE": "Démarrer une nouvelle session", + "INFO_EXTRARES_ENUM_OUVRAGE_Q_MODE_0": "Surface libre", + "INFO_EXTRARES_ENUM_OUVRAGE_Q_MODE_1": "En charge", + "INFO_EXTRARES_ENUM_OUVRAGE_Q_MODE_2": "Débit nul", + "INFO_EXTRARES_ENUM_OUVRAGE_Q_REGIME_0": "Dénoyé", + "INFO_EXTRARES_ENUM_OUVRAGE_Q_REGIME_1": "Partiellement noyé", + "INFO_EXTRARES_ENUM_OUVRAGE_Q_REGIME_2": "Noyé", + "INFO_EXTRARES_ENUM_OUVRAGE_Q_REGIME_3": "Débit nul", "INFO_EXTRARES_LIB_B": "Largeur au miroir (m)", "INFO_EXTRARES_LIB_CV": "Cv: Coefficient de vitesse d'approche", "INFO_EXTRARES_LIB_CVQT": "CV.QT: Débit corrigé (m³/s)", @@ -100,21 +119,50 @@ "INFO_LIB_ZT": "Cote haute du triangle (m)", "INFO_MENU_HELP_TITLE": "Aide", "INFO_MENU_LOAD_SESSION_TITLE": "Charger une session", + "INFO_MENU_SAVE_SESSION_TITLE": "Enregistrer la session", + "INFO_MENU_SELECT_CALC": "Choisir un module de calcul", + "INFO_MENU_EMPTY_SESSION_TITLE": "Nouvelle session", "INFO_MENU_NOUVELLE_CALC": "Nouveau module de calcul", - "INFO_MACRORUGO_TITRE": "Passe à macro-rugosité", + "INFO_MACRORUGO_TITRE": "Passe à macro-rugosités", "INFO_OPTION_NO": "Non", "INFO_OPTION_YES": "Oui", + "INFO_OPTION_CANCEL": "Annuler", + "INFO_OPTION_CLOSE": "Fermer", + "INFO_OPTION_LOAD": "Charger", + "INFO_OPTION_SAVE": "Enregistrer", + "INFO_OPTION_VALIDATE": "Valider", + "INFO_OPTION_ALL": "Tous", + "INFO_OPTION_ALL_F": "Toutes", + "INFO_OPTION_NONE": "Aucun", + "INFO_OPTION_NONE_F": "Aucune", "INFO_OUVRAGE": "Ouvrage", "INFO_PABDIMENSIONS_TITRE": "Passe à bassin : dimensions", "INFO_PABPUISSANCE_TITRE": "Passe à bassin : puissance dissipée", "INFO_PARALLELSTRUCTURE_TITRE": "Lois d'ouvrages", + "INFO_PARAMFIELD_GRAPH_TYPE": "Type de graphe", + "INFO_PARAMFIELD_GRAPH_TYPE_HISTOGRAM": "Histogramme", + "INFO_PARAMFIELD_IN_CALCULATION": "En calcul", + "INFO_PARAMFIELD_IN_CALCULATION_INITIAL_VALUE": "valeur initiale", "INFO_PARAMFIELD_PARAMCALCULER": "calculer", "INFO_PARAMFIELD_PARAMFIXE": "fixé", "INFO_PARAMFIELD_PARAMLIE": "lié", + "INFO_PARAMFIELD_PARAMLIE_LABEL": "Paramètre lié", "INFO_PARAMFIELD_PARAMVARIER": "varier", - "INFO_PARAMFIELD_PASVARIATION": "avec un pas de :", - "INFO_PARAMFIELD_VALEURMAXI": "à la valeur maximum", + "INFO_PARAMFIELD_PASVARIATION": "Avec un pas de", + "INFO_PARAMFIELD_PARAMVARIER_IMPORT_FICHIER": "Importer un fichier", + "INFO_PARAMFIELD_PARAMVARIER_MINMAXSTEP": "min : %s, max : %s, pas : %s", + "INFO_PARAMFIELD_PARAMVARIER_SEPARATEUR_DECIMAL": "Séparateur décimal", + "INFO_PARAMFIELD_PARAMVARIER_SEPARATEUR_POINT": ". (point)", + "INFO_PARAMFIELD_PARAMVARIER_SEPARATEUR_VIRGULE": ", (virgule)", + "INFO_PARAMFIELD_PARAMVARIER_TITLE": "Valeurs multiples", + "INFO_PARAMFIELD_PARAMVARIER_MODE": "Mode", + "INFO_PARAMFIELD_PARAMVARIER_VALUES": "Valeurs :", + "INFO_PARAMFIELD_PARAMVARIER_VALUES_FORMAT": "Liste de valeurs", + "INFO_PARAMFIELD_PARAMVARIER_VALUES_FORMAT_ERROR": "Format incorrect; séparateurs acceptés: %s", + "INFO_PARAMFIELD_VALEURMAXI": "À la valeur maximum", "INFO_PARAMFIELD_VALEURMINI": "De la valeur minimum", + "INFO_PARAMMODE_MINMAX": "Min/max", + "INFO_PARAMMODE_LIST": "Liste de valeurs", "INFO_REGIMEUNIFORME_TITRE": "Régime uniforme", "INFO_REMOUSRESULTS_ABSCISSE": "Abscisse (m)", "INFO_REMOUSRESULTS_BERGE": "Berge", @@ -135,6 +183,19 @@ "INFO_SETUP_PRECISION_AFFICHAGE": "Précision d'affichage", "INFO_SETUP_PRECISION_CALCUL": "Précision de calcul", "INFO_SETUP_TITLE": "Paramètres de l'application", + "INFO_THEME_CREDITS": "Crédit", + "INFO_THEME_MODULES_INUTILISES_TITRE": "Autres modules de calcul", + "INFO_THEME_MODULES_INUTILISES_DESCRIPTION": "Modules de calculs divers", + "INFO_THEME_PASSE_A_BASSIN_TITRE": "Passe à bassin", + "INFO_THEME_PASSE_A_BASSIN_DESCRIPTION": "Outils de dimensionnement d'une passe à poissons de type passe à bassin ou encore appelée échelle à poisson", + "INFO_THEME_PASSE_NATURELLE_TITRE": "Passe naturelle", + "INFO_THEME_PASSE_NATURELLE_DESCRIPTION": "Outils de dimensionnement d'une passe à poissons de type passe naturelle ou encore appelée passe à macro-rugosités", + "INFO_THEME_HYDRAULIQUE_A_SURFACE_LIBRE_TITRE": "Hydraulique à surface libre", + "INFO_THEME_HYDRAULIQUE_A_SURFACE_LIBRE_DESCRIPTION": "Modules de calcul pour les écoulements en canaux et rivières", + "INFO_THEME_HYDRAULIQUE_EN_CHARGE_TITRE": "Hydraulique en charge", + "INFO_THEME_HYDRAULIQUE_EN_CHARGE_DESCRIPTION": "Modules de calcul de perte de charge dans les conduites sous pression", + "INFO_THEME_LOIS_D_OUVRAGES_TITRE": "Lois d'ouvrages", + "INFO_THEME_LOIS_D_OUVRAGES_DESCRIPTION": "Calculs basés sur les lois de débits d'ouvrages hydrauliques (Vannes, seuils, orifices)", "WARNING_REMOUS_ARRET_CRITIQUE": "Arrêt du calcul : hauteur critique atteinte à l'abscisse %x%", "WARNING_STRUCTUREKIVI_HP_TROP_ELEVE": "h/p ne doit pas être supérieur à 2,5. h/p est forcé à 2,5", "WARNING_STRUCTUREKIVI_PELLE_TROP_FAIBLE": "La pelle du seuil doit mesurer au moins 0,1 m. Le coefficient béta est forcé à 0" diff --git a/src/main.ts b/src/main.ts index 6373f498c5643cadce8e0e8d3ddd4ba9a6e521e1..9b8fff7b96bcd6f42218db26ef282901d5136450 100644 --- a/src/main.ts +++ b/src/main.ts @@ -1,3 +1,4 @@ +import "hammerjs"; import { enableProdMode } from "@angular/core"; import { platformBrowserDynamic } from "@angular/platform-browser-dynamic"; diff --git a/src/styles.scss b/src/styles.scss index 90d4ee0072ce3fc41812f8af910219f9eea3c3de..013d064f64343a703326db51277fd2409092bfa2 100644 --- a/src/styles.scss +++ b/src/styles.scss @@ -1 +1,69 @@ /* You can add global styles to this file, and also import other style files */ +// @import "~@angular/material/prebuilt-themes/indigo-pink.css"; +// @import "~@angular/material/prebuilt-themes/deeppurple-amber.css"; +// @import "~@angular/material/prebuilt-themes/pink-bluegrey.css"; +// @import "~@angular/material/prebuilt-themes/purple-green.css"; + +html, body { height: 100%; } + +body { margin: 0; font-family: Roboto, "Helvetica Neue", sans-serif; } + +button { + &:focus { + outline: 0; + } +} + +mat-dialog-container { + min-width: 280px; + + .mat-dialog-actions { + margin-bottom: -5px; + } +} + +mat-error { + font-weight: 500; + font-size: 1.1em; +} + +mat-form-field { + // not applied globally; why ?? + ::ng-deep .mat-form-field-label { + font-size: 1.1em; + line-height: 1.4em; + margin-top: -2px; + + &.mat-form-field-empty { + font-size: 1em; + } + } +} + +.eight-em-bottom-padding { + padding-bottom: 8em; +} + +table.mat-table { + width: 100%; +} + +// bootstrap inspired styles + +h1 { + margin-top: 0; + margin-bottom: .5rem; + font-size: 2.5rem; + font-weight: 300; + line-height: 1.2; +} + +// debug +field-set { + margin-bottom: 2em; +} + +// hide elements having "hidden" attribute even if they have explicit "display:" property +[hidden] { + display: none !important; +} diff --git a/src/theme.scss b/src/theme.scss new file mode 100644 index 0000000000000000000000000000000000000000..3ff27ba26eb9f75fb36ca08593d3c606d7e87e66 --- /dev/null +++ b/src/theme.scss @@ -0,0 +1,218 @@ +@import '~@angular/material/theming'; +@include mat-core(); + +// palettes générées sur http://mcg.mbitson.com +$mat-irstea-marine: ( + 50 : #e0e7f0, + 100 : #b3c4d9, + 200 : #809dc0, + 300 : #4d75a6, + 400 : #265893, + 500 : #003a80, + 600 : #003478, + 700 : #002c6d, + 800 : #002563, + 900 : #001850, + A100 : #839cff, + A200 : #5073ff, + A400 : #1d4bff, + A700 : #0336ff, + contrast: ( + 50 : #000000, + 100 : #000000, + 200 : #000000, + 300 : #ffffff, + 400 : #ffffff, + 500 : #ffffff, + 600 : #ffffff, + 700 : #ffffff, + 800 : #ffffff, + 900 : #ffffff, + A100 : #000000, + A200 : #ffffff, + A400 : #ffffff, + A700 : #ffffff, + ) +); + +$mat-irstea-ocean: ( + 50 : #e0f3fb, + 100 : #b3e2f6, + 200 : #80cff0, + 300 : #4dbbe9, + 400 : #26ade5, + 500 : #009ee0, + 600 : #0096dc, + 700 : #008cd8, + 800 : #0082d3, + 900 : #0070cb, + A100 : #f3f9ff, + A200 : #c0dfff, + A400 : #8dc5ff, + A700 : #74b9ff, + contrast: ( + 50 : #000000, + 100 : #000000, + 200 : #000000, + 300 : #000000, + 400 : #000000, + 500 : #ffffff, + 600 : #ffffff, + 700 : #ffffff, + 800 : #ffffff, + 900 : #ffffff, + A100 : #000000, + A200 : #000000, + A400 : #000000, + A700 : #000000, + ) +); + +$mat-irstea-prune: ( + 50 : #f5e3f0, + 100 : #e7b8d9, + 200 : #d789c0, + 300 : #c759a6, + 400 : #bb3693, + 500 : #af1280, + 600 : #a81078, + 700 : #9f0d6d, + 800 : #960a63, + 900 : #860550, + A100 : #ffb3db, + A200 : #ff80c3, + A400 : #ff4dab, + A700 : #ff349f, + contrast: ( + 50 : #000000, + 100 : #000000, + 200 : #000000, + 300 : #000000, + 400 : #ffffff, + 500 : #ffffff, + 600 : #ffffff, + 700 : #ffffff, + 800 : #ffffff, + 900 : #ffffff, + A100 : #000000, + A200 : #000000, + A400 : #000000, + A700 : #ffffff, + ) +); + +$mat-irstea-brique: ( + 50 : #fae3e3, + 100 : #f2b8b9, + 200 : #ea898b, + 300 : #e25a5d, + 400 : #db363a, + 500 : #d51317, + 600 : #d01114, + 700 : #ca0e11, + 800 : #c40b0d, + 900 : #ba0607, + A100 : #ffe4e4, + A200 : #ffb1b1, + A400 : #ff7e7f, + A700 : #ff6465, + contrast: ( + 50 : #000000, + 100 : #000000, + 200 : #000000, + 300 : #000000, + 400 : #ffffff, + 500 : #ffffff, + 600 : #ffffff, + 700 : #ffffff, + 800 : #ffffff, + 900 : #ffffff, + A100 : #000000, + A200 : #000000, + A400 : #000000, + A700 : #000000, + ) +); + +$mat-irstea-rouille: ( + 50 : #fcebe2, + 100 : #f8ceb6, + 200 : #f4ad86, + 300 : #f08c55, + 400 : #ec7430, + 500 : #e95b0c, + 600 : #e6530a, + 700 : #e34908, + 800 : #df4006, + 900 : #d92f03, + A100 : #ffffff, + A200 : #ffd5ce, + A400 : #ffaa9b, + A700 : #ff9481, + contrast: ( + 50 : #000000, + 100 : #000000, + 200 : #000000, + 300 : #000000, + 400 : #000000, + 500 : #ffffff, + 600 : #ffffff, + 700 : #ffffff, + 800 : #ffffff, + 900 : #ffffff, + A100 : #000000, + A200 : #000000, + A400 : #000000, + A700 : #000000, + ) +); + + +$nghyd-primary: mat-palette($mat-irstea-marine); +$nghyd-accent: mat-palette($mat-irstea-ocean); +$nghyd-warn: mat-palette($mat-irstea-prune); +// $nghyd-warn: mat-palette($mat-irstea-rouille); + +$nghyd-theme: mat-light-theme($nghyd-primary, $nghyd-accent, $nghyd-warn); + +@include angular-material-theme($nghyd-theme); + +// reuse custom base colors anywhere +$primary: map-get($nghyd-theme, primary); +$accent: map-get($nghyd-theme, accent); +$warn: map-get($nghyd-theme, warn); + +// convenience classes (functions mat-* cannot be used outside of this file) +.color-primary { + color: mat-color($primary); +} +.bg-primary { + background-color: mat-color($primary); +} +.color-accent { + color: mat-color($accent); +} +.bg-accent { + background-color: mat-color($accent); +} +.bg-accent-light { + background-color: mat-color($accent, 300); +} +.color-warn { + color: mat-color($warn); +} +.bg-warn { + background-color: mat-color($warn); +} + +// make toggle buttons more visible +/* .mat-button-toggle { + background-color: mat-color($primary); + color: mat-color($primary, default-contrast); +} + */ + +.mat-button-toggle-checked { + background-color: mat-color($accent); + color: mat-color($accent, default-contrast) !important; +} diff --git a/tsconfig.json b/tsconfig.json index cb174fd8a71047dfd9d30bce1acb17757e54f155..f6d913f28b3fb0497654c6b9cc9f5c726ac0ad09 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -20,7 +20,6 @@ "baseUrl": "./" }, "include": [ - "node_modules/angular-bootstrap-md/**/*.ts", "src/**/*.ts" ] } \ No newline at end of file