From 0ba5677c0190318f93c1e2cca622dc93ad3e6981 Mon Sep 17 00:00:00 2001 From: sercan Date: Mon, 31 May 2021 10:49:51 +0300 Subject: [PATCH 1/9] (Dependencies) Updated Angular & Angular Material to v12.0.2 --- package-lock.json | 932 ++++++++++++++++++++++++++-------------------- package.json | 30 +- 2 files changed, 547 insertions(+), 415 deletions(-) diff --git a/package-lock.json b/package-lock.json index a13a9b37..01394f4f 100644 --- a/package-lock.json +++ b/package-lock.json @@ -5,35 +5,35 @@ "requires": true, "dependencies": { "@angular-devkit/architect": { - "version": "0.1200.0", - "resolved": "https://registry.npmjs.org/@angular-devkit/architect/-/architect-0.1200.0.tgz", - "integrity": "sha512-6E42oQ8e3zbeUE5O5YXc+q/vTBHyFn6YSsZEn0kb/3r48zl+9MBb4np1Q8077/GxQtD4G/TN/DhgCa9muLSgzA==", + "version": "0.1200.2", + "resolved": "https://registry.npmjs.org/@angular-devkit/architect/-/architect-0.1200.2.tgz", + "integrity": "sha512-Vy/dE1iwEiV63cxcU+SC+Lf5SUnY64vg9J3YA3jxFlJnELbxxN+T7xDfjMEMPoLzTY02K9XNb8ZGLStZxVmZLg==", "dev": true, "requires": { - "@angular-devkit/core": "12.0.0", + "@angular-devkit/core": "12.0.2", "rxjs": "6.6.7" } }, "@angular-devkit/build-angular": { - "version": "12.0.0", - "resolved": "https://registry.npmjs.org/@angular-devkit/build-angular/-/build-angular-12.0.0.tgz", - "integrity": "sha512-+hljBhcT0NHjbbLMiUmPxMQf1/Fuo6F/O89gcRNZ1RyNMNQO6XqysqsXL1z/eofHcMs3T+Erv4JfdQ9Gn4Thkw==", + "version": "12.0.2", + "resolved": "https://registry.npmjs.org/@angular-devkit/build-angular/-/build-angular-12.0.2.tgz", + "integrity": "sha512-s7tAnqT3L+4uMnDHOwx4nncxDjHrmfPGiQFdi2hI2VTbuB7ZUU7LE9M/2O5MWnRcwNKOlE/Ls6tWZRYD2HoBsA==", "dev": true, "requires": { - "@angular-devkit/architect": "0.1200.0", - "@angular-devkit/build-optimizer": "0.1200.0", - "@angular-devkit/build-webpack": "0.1200.0", - "@angular-devkit/core": "12.0.0", - "@babel/core": "7.14.0", - "@babel/generator": "7.14.1", + "@angular-devkit/architect": "0.1200.2", + "@angular-devkit/build-optimizer": "0.1200.2", + "@angular-devkit/build-webpack": "0.1200.2", + "@angular-devkit/core": "12.0.2", + "@babel/core": "7.14.3", + "@babel/generator": "7.14.3", "@babel/plugin-transform-async-to-generator": "7.13.0", - "@babel/plugin-transform-runtime": "7.13.15", - "@babel/preset-env": "7.14.1", + "@babel/plugin-transform-runtime": "7.14.3", + "@babel/preset-env": "7.14.2", "@babel/runtime": "7.14.0", "@babel/template": "7.12.13", "@discoveryjs/json-ext": "0.5.2", "@jsdevtools/coverage-istanbul-loader": "3.0.5", - "@ngtools/webpack": "12.0.0", + "@ngtools/webpack": "12.0.2", "ansi-colors": "4.1.1", "babel-loader": "8.2.2", "browserslist": "^4.9.1", @@ -44,7 +44,7 @@ "core-js": "3.12.0", "critters": "0.0.10", "css-loader": "5.2.4", - "cssnano": "5.0.2", + "css-minimizer-webpack-plugin": "3.0.0", "find-cache-dir": "3.3.1", "glob": "7.1.7", "https-proxy-agent": "5.0.0", @@ -57,10 +57,10 @@ "loader-utils": "2.0.0", "mini-css-extract-plugin": "1.5.1", "minimatch": "3.0.4", - "open": "8.0.7", + "open": "8.0.2", "ora": "5.4.0", "parse5-html-rewriting-stream": "6.0.1", - "postcss": "8.2.14", + "postcss": "8.3.0", "postcss-import": "14.0.1", "postcss-loader": "5.2.0", "postcss-preset-env": "6.7.0", @@ -79,7 +79,7 @@ "stylus": "0.54.8", "stylus-loader": "5.0.0", "terser": "5.7.0", - "terser-webpack-plugin": "4.2.3", + "terser-webpack-plugin": "5.1.2", "text-table": "0.2.0", "tree-kill": "1.2.2", "webpack": "5.36.2", @@ -89,31 +89,74 @@ "webpack-subresource-integrity": "1.5.2" }, "dependencies": { - "postcss": { - "version": "8.2.14", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.2.14.tgz", - "integrity": "sha512-+jD0ZijcvyCqPQo/m/CW0UcARpdFylq04of+Q7RKX6f/Tu+dvpUI/9Sp81+i6/vJThnOBX09Quw0ZLOVwpzX3w==", + "@babel/core": { + "version": "7.14.3", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.14.3.tgz", + "integrity": "sha512-jB5AmTKOCSJIZ72sd78ECEhuPiDMKlQdDI/4QRI6lzYATx5SSogS1oQA2AoPecRCknm30gHi2l+QVvNUu3wZAg==", "dev": true, "requires": { - "colorette": "^1.2.2", - "nanoid": "^3.1.22", - "source-map": "^0.6.1" + "@babel/code-frame": "^7.12.13", + "@babel/generator": "^7.14.3", + "@babel/helper-compilation-targets": "^7.13.16", + "@babel/helper-module-transforms": "^7.14.2", + "@babel/helpers": "^7.14.0", + "@babel/parser": "^7.14.3", + "@babel/template": "^7.12.13", + "@babel/traverse": "^7.14.2", + "@babel/types": "^7.14.2", + "convert-source-map": "^1.7.0", + "debug": "^4.1.0", + "gensync": "^1.0.0-beta.2", + "json5": "^2.1.2", + "semver": "^6.3.0", + "source-map": "^0.5.0" }, "dependencies": { + "semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "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==", + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", + "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", "dev": true } } + }, + "@babel/generator": { + "version": "7.14.3", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.14.3.tgz", + "integrity": "sha512-bn0S6flG/j0xtQdz3hsjJ624h3W0r3llttBMfyHX3YrZ/KtLYr15bjA0FXkgW7FpvrDuTuElXeVjiKlYRpnOFA==", + "dev": true, + "requires": { + "@babel/types": "^7.14.2", + "jsesc": "^2.5.1", + "source-map": "^0.5.0" + }, + "dependencies": { + "source-map": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", + "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", + "dev": true + } + } + }, + "@babel/parser": { + "version": "7.14.4", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.14.4.tgz", + "integrity": "sha512-ArliyUsWDUqEGfWcmzpGUzNfLxTdTp6WU4IuP6QFSp9gGfWS6boxFCkJSJ/L4+RG8z/FnIU3WxCk6hPL9SSWeA==", + "dev": true } } }, "@angular-devkit/build-optimizer": { - "version": "0.1200.0", - "resolved": "https://registry.npmjs.org/@angular-devkit/build-optimizer/-/build-optimizer-0.1200.0.tgz", - "integrity": "sha512-0ZkQX6FXfV2Q56BE6HeNLieG5S5V9cTzb2Mlr26oxPSHeEMoxoCO/fej4cj0cuJRLlmtu/ZFQUrlMLqWPteRxg==", + "version": "0.1200.2", + "resolved": "https://registry.npmjs.org/@angular-devkit/build-optimizer/-/build-optimizer-0.1200.2.tgz", + "integrity": "sha512-46z35d4oOHiF7Peiez7DRcsB5dwjnYP3fm6KwVNm/8Zq6nnykxvipywgJB6inkGdcI0j2m8v3+shVAaWvdS93w==", "dev": true, "requires": { "source-map": "0.7.3", @@ -122,19 +165,19 @@ } }, "@angular-devkit/build-webpack": { - "version": "0.1200.0", - "resolved": "https://registry.npmjs.org/@angular-devkit/build-webpack/-/build-webpack-0.1200.0.tgz", - "integrity": "sha512-4NXJUbDkIbwjXiUe5ANRXfr+65EHnEQgdkZxSppyXLIfJJAgAQ7oUPI5FtzpASkuGWIPoWaxqVZOLj901I4tbg==", + "version": "0.1200.2", + "resolved": "https://registry.npmjs.org/@angular-devkit/build-webpack/-/build-webpack-0.1200.2.tgz", + "integrity": "sha512-tqHq2Ld91CQfIJpdsA8b5q6wq4tS3eX5Z1rwzy2j0gJ5s0I/cpklfTXHBh6StSoS9Df4uHl5V2oLRBagky1pDA==", "dev": true, "requires": { - "@angular-devkit/architect": "0.1200.0", + "@angular-devkit/architect": "0.1200.2", "rxjs": "6.6.7" } }, "@angular-devkit/core": { - "version": "12.0.0", - "resolved": "https://registry.npmjs.org/@angular-devkit/core/-/core-12.0.0.tgz", - "integrity": "sha512-4Cys++a684hCDTL/1X6j9izsjsqvYs3m6LF58zvKZHeG/Yhdofv1rV+3YGVYAorOx9w4spAgYTmr99TYnBGQWQ==", + "version": "12.0.2", + "resolved": "https://registry.npmjs.org/@angular-devkit/core/-/core-12.0.2.tgz", + "integrity": "sha512-n7BmZAW0nx4pEigdAsibvtIm4Vjk1IwY3Bbc8fqD+AQpdYCo+Ake1Eu6fL2XoW8Yco7U4JYYdn/uodWEgBdroQ==", "dev": true, "requires": { "ajv": "8.2.0", @@ -146,12 +189,12 @@ } }, "@angular-devkit/schematics": { - "version": "12.0.0", - "resolved": "https://registry.npmjs.org/@angular-devkit/schematics/-/schematics-12.0.0.tgz", - "integrity": "sha512-xp6b8QF+MYT3kXEDo6MFRQRDGkFxAHBdBCo2wdo8qvoNHIr+8XYZwDEb8z0SbzzJmXFbDXk1vmavcNSd6+uLXg==", + "version": "12.0.2", + "resolved": "https://registry.npmjs.org/@angular-devkit/schematics/-/schematics-12.0.2.tgz", + "integrity": "sha512-PS+SrRhAc/lyRfuBsi6Rt2yV7IA34B7T6J0K8/Av0GABZ83x+0vLiZC39eSPS1X8qcM/U09pCfDT8Q6ZQPCICA==", "dev": true, "requires": { - "@angular-devkit/core": "12.0.0", + "@angular-devkit/core": "12.0.2", "ora": "5.4.0", "rxjs": "6.6.7" } @@ -216,32 +259,32 @@ } }, "@angular/animations": { - "version": "12.0.0", - "resolved": "https://registry.npmjs.org/@angular/animations/-/animations-12.0.0.tgz", - "integrity": "sha512-BG/Ksk3863I7GKUem73Kty4UeU289oN+iPo/0O0x2dJCzNcpafML0GJpz4lg/RT9l6UddFviI4q9NiopR+eJfw==", + "version": "12.0.2", + "resolved": "https://registry.npmjs.org/@angular/animations/-/animations-12.0.2.tgz", + "integrity": "sha512-5RZ5a8ouVZ3iDy29uZ7jCryisWjX2c9xjIG5F5rn+mBL3UkxzzUDFhql9rP0PB5G+aGgaElSlTatGJ85mY0XvA==", "requires": { "tslib": "^2.1.0" } }, "@angular/cdk": { - "version": "12.0.0", - "resolved": "https://registry.npmjs.org/@angular/cdk/-/cdk-12.0.0.tgz", - "integrity": "sha512-Ij1wNlufbwH2R3zVwkiJgrI0Oc4+yuveEFWMnckcZ7t6E3drmeS1/YeHSbYlWau+fglWs7LtJWC4dEIpGymvzg==", + "version": "12.0.2", + "resolved": "https://registry.npmjs.org/@angular/cdk/-/cdk-12.0.2.tgz", + "integrity": "sha512-1JGayyUJmwaul5YSEgb780aWxk+MLVG5FakVaxz5NtbPZx19ZyOuZqytCh5js11LsBDipF5/kirYhJPBFlMbWQ==", "requires": { "parse5": "^5.0.0", "tslib": "^2.1.0" } }, "@angular/cli": { - "version": "12.0.0", - "resolved": "https://registry.npmjs.org/@angular/cli/-/cli-12.0.0.tgz", - "integrity": "sha512-A8vGhLKTQI/1P2Ia3Wv3/SfUBJGcy7B/MS3Dp+ueEs2purMG23z4UDmAp2EcxCJKKx0fKM++XKpbHIanELfOeA==", + "version": "12.0.2", + "resolved": "https://registry.npmjs.org/@angular/cli/-/cli-12.0.2.tgz", + "integrity": "sha512-hXxnOxPl6+v/O+OnkJxPPupCeQJNmI08EdtnER5z/UCSpmlJibbTAqLF9rFaOi/7dPLS0RCNWmCRA6grgTlP9g==", "dev": true, "requires": { - "@angular-devkit/architect": "0.1200.0", - "@angular-devkit/core": "12.0.0", - "@angular-devkit/schematics": "12.0.0", - "@schematics/angular": "12.0.0", + "@angular-devkit/architect": "0.1200.2", + "@angular-devkit/core": "12.0.2", + "@angular-devkit/schematics": "12.0.2", + "@schematics/angular": "12.0.2", "@yarnpkg/lockfile": "1.1.0", "ansi-colors": "4.1.1", "debug": "4.3.1", @@ -250,7 +293,7 @@ "jsonc-parser": "3.0.0", "npm-package-arg": "8.1.2", "npm-pick-manifest": "6.1.1", - "open": "8.0.7", + "open": "8.0.2", "ora": "5.4.0", "pacote": "11.3.2", "resolve": "1.20.0", @@ -269,25 +312,25 @@ } }, "@angular/common": { - "version": "12.0.0", - "resolved": "https://registry.npmjs.org/@angular/common/-/common-12.0.0.tgz", - "integrity": "sha512-d6+WSnCFcxAHBsbCvBC3Rutmk+tB5CEdKhkTBY/vGe0A/MjbayzHR4IDv2i0+UZDLSgMJubqh3iCPUcSglXSEg==", + "version": "12.0.2", + "resolved": "https://registry.npmjs.org/@angular/common/-/common-12.0.2.tgz", + "integrity": "sha512-KJFtqdIGVrF97iK3zcN9FoQ1fDsc/u4ez1Qtx0HdH21qAuAvK/FYybg4r1G6miXoUJcO8hu9oRddEoiNPkXAew==", "requires": { "tslib": "^2.1.0" } }, "@angular/compiler": { - "version": "12.0.0", - "resolved": "https://registry.npmjs.org/@angular/compiler/-/compiler-12.0.0.tgz", - "integrity": "sha512-7NdZNyxm9KLlRMmmtId6RfV6VbQIUMDxN44R+ax66BoWsuhdYXUDsDO554LwYwrjnnXXGkurDJhv7umeRwaZGw==", + "version": "12.0.2", + "resolved": "https://registry.npmjs.org/@angular/compiler/-/compiler-12.0.2.tgz", + "integrity": "sha512-PLkDb1mxWpsOJwR0t9yDI8A9dSMUEmVf+HdNWFO1aFY84nZ3sH8t6e/BpoaRcbLJCkNgtm9YD8FmRHE30LZ3CA==", "requires": { "tslib": "^2.1.0" } }, "@angular/compiler-cli": { - "version": "12.0.0", - "resolved": "https://registry.npmjs.org/@angular/compiler-cli/-/compiler-cli-12.0.0.tgz", - "integrity": "sha512-6cBocQd/Umi8gVI6Jo8VsyvHuRjDO4TrFFUkbVwNAG9FacXEFP0zYABT5ywe2lVkUxs5e8WyDqvDf7fxr7CI4Q==", + "version": "12.0.2", + "resolved": "https://registry.npmjs.org/@angular/compiler-cli/-/compiler-cli-12.0.2.tgz", + "integrity": "sha512-ocm/c4ZcdtlvMSlN1L6Asyx4nYC4qA0j3+H3mKl/ds8bq/8Gb9cxOiu3hqmUKgovXF/Wue6orsWLzHowuxfagA==", "dev": true, "requires": { "@babel/core": "^7.8.6", @@ -388,63 +431,63 @@ } }, "@angular/core": { - "version": "12.0.0", - "resolved": "https://registry.npmjs.org/@angular/core/-/core-12.0.0.tgz", - "integrity": "sha512-fwXtF6qP8pr07+El/dg67RmgsI4Ubfi+E5YLjYKQ62gM8MzYyYGmLPakFzFnbzYrOr05zdprrbcVgGtMRHapMA==", + "version": "12.0.2", + "resolved": "https://registry.npmjs.org/@angular/core/-/core-12.0.2.tgz", + "integrity": "sha512-RBTl8L2ckSI3n2lo9rmwlUeZAuEd/TWUjoidoxPYWrKfbnFwKX65idCCbWLJivSVIBnPQYvAdC+3k4w40N9AWA==", "requires": { "tslib": "^2.1.0" } }, "@angular/forms": { - "version": "12.0.0", - "resolved": "https://registry.npmjs.org/@angular/forms/-/forms-12.0.0.tgz", - "integrity": "sha512-/Z2AWd2k/9cs+WwXBlZ8yUqgGsHYcp8g6PUCehZQk1gd/4n4FOKvTIGiypajGUPwO4GOHJDzibfCsGw8MenCpQ==", + "version": "12.0.2", + "resolved": "https://registry.npmjs.org/@angular/forms/-/forms-12.0.2.tgz", + "integrity": "sha512-tHIYb3c6H2M9qSi/SJOtZqJ8XWi3LM5mhA4sDpEGxfJ8RLVTcujd2gYnJ0N3vcpmWwy3mA/EayhAC2bhgWAazA==", "requires": { "tslib": "^2.1.0" } }, "@angular/language-service": { - "version": "12.0.0", - "resolved": "https://registry.npmjs.org/@angular/language-service/-/language-service-12.0.0.tgz", - "integrity": "sha512-LDS1+dOdXUEf0kiqcYnOfXBIs2HAD6vJ5HWb58kq6z/8AHRMvvHiwSV26UlIbnnD+CBnTu36xmbCyZtIJluhqw==", + "version": "12.0.2", + "resolved": "https://registry.npmjs.org/@angular/language-service/-/language-service-12.0.2.tgz", + "integrity": "sha512-H1aauvtS9qnq0FCdr3J2UROF7+AnOTCksD2AYuGS2/9O8tZLwwNz/UkXfxS3bHYzndYCsNiLPwAW7d0dWIjlqQ==", "dev": true }, "@angular/material": { - "version": "12.0.0", - "resolved": "https://registry.npmjs.org/@angular/material/-/material-12.0.0.tgz", - "integrity": "sha512-ToWfr4ge2ZINLBtUQOseGm7mzscLMsrKLWYM0HzfVL9lkm6EtfTlReZV84DEzDf6/htky41t9nY5SBPWs2dtug==", + "version": "12.0.2", + "resolved": "https://registry.npmjs.org/@angular/material/-/material-12.0.2.tgz", + "integrity": "sha512-jTH53w4iVNk+3K5ciFyHeRhNNtV6TzeuNTSELeme4l3t5FP3VqFTdE56Q55MrV2RMIzDKLYEpiqSiQf+8ZuGSA==", "requires": { "tslib": "^2.1.0" } }, "@angular/material-moment-adapter": { - "version": "12.0.0", - "resolved": "https://registry.npmjs.org/@angular/material-moment-adapter/-/material-moment-adapter-12.0.0.tgz", - "integrity": "sha512-KHj28LoEp+LAhu8ohm4RO4ox7yYSO2e3eMYHF2IlX1lZ9k/g62tMbB01QffqroZuHelNdja3aGH0mnwrXUiH4g==", + "version": "12.0.2", + "resolved": "https://registry.npmjs.org/@angular/material-moment-adapter/-/material-moment-adapter-12.0.2.tgz", + "integrity": "sha512-Xa28TbGGqfO/WYNhAiK0t7IqiA4sTIOXxZfacmvfaYMmsAv5DQrOm7snRHkcZSE5i4qpeR9BdJ54pTYd8Jyw9Q==", "requires": { "tslib": "^2.1.0" } }, "@angular/platform-browser": { - "version": "12.0.0", - "resolved": "https://registry.npmjs.org/@angular/platform-browser/-/platform-browser-12.0.0.tgz", - "integrity": "sha512-h+uMMluRh4dqJIor7EpvwNKRjv4xCxpttizJlqbo3vfcoOoLDoc9SvEFiXxd+UVh3S0re8zBsyBIJl+gTVFKWQ==", + "version": "12.0.2", + "resolved": "https://registry.npmjs.org/@angular/platform-browser/-/platform-browser-12.0.2.tgz", + "integrity": "sha512-m1tPOpNZdnp8jrtFP3FrjpBV+S/rd5HLd4Q9MaC62LJYf8VvRx8wKdUO8tBDJYPbGiHGL4q4BUvKswrzfFWbXg==", "requires": { "tslib": "^2.1.0" } }, "@angular/platform-browser-dynamic": { - "version": "12.0.0", - "resolved": "https://registry.npmjs.org/@angular/platform-browser-dynamic/-/platform-browser-dynamic-12.0.0.tgz", - "integrity": "sha512-Rkxr/KVOZGuGSuIYo2XZYbOpyS2t2jpLPS65KUUcOEwktj4hSv5VZ2soZF18tG5ZNbx06C1QDW/j9HwmZjEh5g==", + "version": "12.0.2", + "resolved": "https://registry.npmjs.org/@angular/platform-browser-dynamic/-/platform-browser-dynamic-12.0.2.tgz", + "integrity": "sha512-FVJBIxn85EX3a6kSdqwXAC8i7jxeo5iwHBKUEFYukbAXrHuMmwFz7Nvqkqqo0xIJXymFz8Q04VbTThkgp2uerg==", "requires": { "tslib": "^2.1.0" } }, "@angular/router": { - "version": "12.0.0", - "resolved": "https://registry.npmjs.org/@angular/router/-/router-12.0.0.tgz", - "integrity": "sha512-n5YHa24NgiRttAfMOzSa/H+nbx8j8c+2f1HgyrOftxoExH1FPTRnKd/mJ32A6iies8glOj9ImQBO/91C0yaQeA==", + "version": "12.0.2", + "resolved": "https://registry.npmjs.org/@angular/router/-/router-12.0.2.tgz", + "integrity": "sha512-ATUPPz+dpuPNNWlvg6PtLBDN97nbT8Bu7tUwjL8G0xOwxAxsJqgoImcxYWAKaovAoK4YntVQXqP+UPxpZQtLLA==", "requires": { "tslib": "^2.1.0" } @@ -559,23 +602,47 @@ } }, "@babel/helper-create-class-features-plugin": { - "version": "7.14.2", - "resolved": "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.14.2.tgz", - "integrity": "sha512-6YctwVsmlkchxfGUogvVrrhzyD3grFJyluj5JgDlQrwfMLJSt5tdAzFZfPf4H2Xoi5YLcQ6BxfJlaOBHuctyIw==", + "version": "7.14.4", + "resolved": "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.14.4.tgz", + "integrity": "sha512-idr3pthFlDCpV+p/rMgGLGYIVtazeatrSOQk8YzO2pAepIjQhCN3myeihVg58ax2bbbGK9PUE1reFi7axOYIOw==", "dev": true, "requires": { "@babel/helper-annotate-as-pure": "^7.12.13", "@babel/helper-function-name": "^7.14.2", "@babel/helper-member-expression-to-functions": "^7.13.12", "@babel/helper-optimise-call-expression": "^7.12.13", - "@babel/helper-replace-supers": "^7.13.12", + "@babel/helper-replace-supers": "^7.14.4", "@babel/helper-split-export-declaration": "^7.12.13" + }, + "dependencies": { + "@babel/helper-replace-supers": { + "version": "7.14.4", + "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.14.4.tgz", + "integrity": "sha512-zZ7uHCWlxfEAAOVDYQpEf/uyi1dmeC7fX4nCf2iz9drnCwi1zvwXL3HwWWNXUQEJ1k23yVn3VbddiI9iJEXaTQ==", + "dev": true, + "requires": { + "@babel/helper-member-expression-to-functions": "^7.13.12", + "@babel/helper-optimise-call-expression": "^7.12.13", + "@babel/traverse": "^7.14.2", + "@babel/types": "^7.14.4" + } + }, + "@babel/types": { + "version": "7.14.4", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.14.4.tgz", + "integrity": "sha512-lCj4aIs0xUefJFQnwwQv2Bxg7Omd6bgquZ6LGC+gGMh6/s5qDVfjuCMlDmYQ15SLsWHd9n+X3E75lKIhl5Lkiw==", + "dev": true, + "requires": { + "@babel/helper-validator-identifier": "^7.14.0", + "to-fast-properties": "^2.0.0" + } + } } }, "@babel/helper-create-regexp-features-plugin": { - "version": "7.12.17", - "resolved": "https://registry.npmjs.org/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.12.17.tgz", - "integrity": "sha512-p2VGmBu9oefLZ2nQpgnEnG0ZlRPvL8gAGvPUMQwUdaE8k49rOMuZpOwdQoy5qJf6K8jL3bcAMhVUlHAjIgJHUg==", + "version": "7.14.3", + "resolved": "https://registry.npmjs.org/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.14.3.tgz", + "integrity": "sha512-JIB2+XJrb7v3zceV2XzDhGIB902CmKGSpSl4q2C6agU9SNLG/2V1RtFRGPG1Ajh9STj3+q6zJMOC+N/pp2P9DA==", "dev": true, "requires": { "@babel/helper-annotate-as-pure": "^7.12.13", @@ -583,9 +650,9 @@ } }, "@babel/helper-define-polyfill-provider": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/@babel/helper-define-polyfill-provider/-/helper-define-polyfill-provider-0.2.0.tgz", - "integrity": "sha512-JT8tHuFjKBo8NnaUbblz7mIu1nnvUDiHVjXXkulZULyidvo/7P6TY7+YqpV37IfF+KUFxmlK04elKtGKXaiVgw==", + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/@babel/helper-define-polyfill-provider/-/helper-define-polyfill-provider-0.2.3.tgz", + "integrity": "sha512-RH3QDAfRMzj7+0Nqu5oqgO5q9mFtQEVvCRsi8qCEfzLR9p2BHfn5FzhSB2oj1fF7I2+DcTORkYaQ6aTR9Cofew==", "dev": true, "requires": { "@babel/helper-compilation-targets": "^7.13.0", @@ -827,11 +894,12 @@ } }, "@babel/plugin-proposal-class-static-block": { - "version": "7.13.11", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-class-static-block/-/plugin-proposal-class-static-block-7.13.11.tgz", - "integrity": "sha512-fJTdFI4bfnMjvxJyNuaf8i9mVcZ0UhetaGEUHaHV9KEnibLugJkZAtXikR8KcYj+NYmI4DZMS8yQAyg+hvfSqg==", + "version": "7.14.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-class-static-block/-/plugin-proposal-class-static-block-7.14.3.tgz", + "integrity": "sha512-HEjzp5q+lWSjAgJtSluFDrGGosmwTgKwCXdDQZvhKsRlwv3YdkUEqxNrrjesJd+B9E9zvr1PVPVBvhYZ9msjvQ==", "dev": true, "requires": { + "@babel/helper-create-class-features-plugin": "^7.14.3", "@babel/helper-plugin-utils": "^7.13.0", "@babel/plugin-syntax-class-static-block": "^7.12.13" } @@ -897,16 +965,42 @@ } }, "@babel/plugin-proposal-object-rest-spread": { - "version": "7.14.2", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-object-rest-spread/-/plugin-proposal-object-rest-spread-7.14.2.tgz", - "integrity": "sha512-hBIQFxwZi8GIp934+nj5uV31mqclC1aYDhctDu5khTi9PCCUOczyy0b34W0oE9U/eJXiqQaKyVsmjeagOaSlbw==", + "version": "7.14.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-object-rest-spread/-/plugin-proposal-object-rest-spread-7.14.4.tgz", + "integrity": "sha512-AYosOWBlyyXEagrPRfLJ1enStufsr7D1+ddpj8OLi9k7B6+NdZ0t/9V7Fh+wJ4g2Jol8z2JkgczYqtWrZd4vbA==", "dev": true, "requires": { - "@babel/compat-data": "^7.14.0", - "@babel/helper-compilation-targets": "^7.13.16", + "@babel/compat-data": "^7.14.4", + "@babel/helper-compilation-targets": "^7.14.4", "@babel/helper-plugin-utils": "^7.13.0", "@babel/plugin-syntax-object-rest-spread": "^7.8.3", "@babel/plugin-transform-parameters": "^7.14.2" + }, + "dependencies": { + "@babel/compat-data": { + "version": "7.14.4", + "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.14.4.tgz", + "integrity": "sha512-i2wXrWQNkH6JplJQGn3Rd2I4Pij8GdHkXwHMxm+zV5YG/Jci+bCNrWZEWC4o+umiDkRrRs4dVzH3X4GP7vyjQQ==", + "dev": true + }, + "@babel/helper-compilation-targets": { + "version": "7.14.4", + "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.14.4.tgz", + "integrity": "sha512-JgdzOYZ/qGaKTVkn5qEDV/SXAh8KcyUVkCoSWGN8T3bwrgd6m+/dJa2kVGi6RJYJgEYPBdZ84BZp9dUjNWkBaA==", + "dev": true, + "requires": { + "@babel/compat-data": "^7.14.4", + "@babel/helper-validator-option": "^7.12.17", + "browserslist": "^4.16.6", + "semver": "^6.3.0" + } + }, + "semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "dev": true + } } }, "@babel/plugin-proposal-optional-catch-binding": { @@ -1118,27 +1212,51 @@ } }, "@babel/plugin-transform-block-scoping": { - "version": "7.14.2", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.14.2.tgz", - "integrity": "sha512-neZZcP19NugZZqNwMTH+KoBjx5WyvESPSIOQb4JHpfd+zPfqcH65RMu5xJju5+6q/Y2VzYrleQTr+b6METyyxg==", + "version": "7.14.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.14.4.tgz", + "integrity": "sha512-5KdpkGxsZlTk+fPleDtGKsA+pon28+ptYmMO8GBSa5fHERCJWAzj50uAfCKBqq42HO+Zot6JF1x37CRprwmN4g==", "dev": true, "requires": { "@babel/helper-plugin-utils": "^7.13.0" } }, "@babel/plugin-transform-classes": { - "version": "7.14.2", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-classes/-/plugin-transform-classes-7.14.2.tgz", - "integrity": "sha512-7oafAVcucHquA/VZCsXv/gmuiHeYd64UJyyTYU+MPfNu0KeNlxw06IeENBO8bJjXVbolu+j1MM5aKQtH1OMCNg==", + "version": "7.14.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-classes/-/plugin-transform-classes-7.14.4.tgz", + "integrity": "sha512-p73t31SIj6y94RDVX57rafVjttNr8MvKEgs5YFatNB/xC68zM3pyosuOEcQmYsYlyQaGY9R7rAULVRcat5FKJQ==", "dev": true, "requires": { "@babel/helper-annotate-as-pure": "^7.12.13", "@babel/helper-function-name": "^7.14.2", "@babel/helper-optimise-call-expression": "^7.12.13", "@babel/helper-plugin-utils": "^7.13.0", - "@babel/helper-replace-supers": "^7.13.12", + "@babel/helper-replace-supers": "^7.14.4", "@babel/helper-split-export-declaration": "^7.12.13", "globals": "^11.1.0" + }, + "dependencies": { + "@babel/helper-replace-supers": { + "version": "7.14.4", + "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.14.4.tgz", + "integrity": "sha512-zZ7uHCWlxfEAAOVDYQpEf/uyi1dmeC7fX4nCf2iz9drnCwi1zvwXL3HwWWNXUQEJ1k23yVn3VbddiI9iJEXaTQ==", + "dev": true, + "requires": { + "@babel/helper-member-expression-to-functions": "^7.13.12", + "@babel/helper-optimise-call-expression": "^7.12.13", + "@babel/traverse": "^7.14.2", + "@babel/types": "^7.14.4" + } + }, + "@babel/types": { + "version": "7.14.4", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.14.4.tgz", + "integrity": "sha512-lCj4aIs0xUefJFQnwwQv2Bxg7Omd6bgquZ6LGC+gGMh6/s5qDVfjuCMlDmYQ15SLsWHd9n+X3E75lKIhl5Lkiw==", + "dev": true, + "requires": { + "@babel/helper-validator-identifier": "^7.14.0", + "to-fast-properties": "^2.0.0" + } + } } }, "@babel/plugin-transform-computed-properties": { @@ -1151,9 +1269,9 @@ } }, "@babel/plugin-transform-destructuring": { - "version": "7.13.17", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.13.17.tgz", - "integrity": "sha512-UAUqiLv+uRLO+xuBKKMEpC+t7YRNVRqBsWWq1yKXbBZBje/t3IXCiSinZhjn/DC3qzBfICeYd2EFGEbHsh5RLA==", + "version": "7.14.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.14.4.tgz", + "integrity": "sha512-JyywKreTCGTUsL1OKu1A3ms/R1sTP0WxbpXlALeGzF53eB3bxtNkYdMj9SDgK7g6ImPy76J5oYYKoTtQImlhQA==", "dev": true, "requires": { "@babel/helper-plugin-utils": "^7.13.0" @@ -1336,9 +1454,9 @@ } }, "@babel/plugin-transform-runtime": { - "version": "7.13.15", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-runtime/-/plugin-transform-runtime-7.13.15.tgz", - "integrity": "sha512-d+ezl76gx6Jal08XngJUkXM4lFXK/5Ikl9Mh4HKDxSfGJXmZ9xG64XT2oivBzfxb/eQ62VfvoMkaCZUKJMVrBA==", + "version": "7.14.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-runtime/-/plugin-transform-runtime-7.14.3.tgz", + "integrity": "sha512-t960xbi8wpTFE623ef7sd+UpEC5T6EEguQlTBJDEO05+XwnIWVfuqLw/vdLWY6IdFmtZE+65CZAfByT39zRpkg==", "dev": true, "requires": { "@babel/helper-module-imports": "^7.13.12", @@ -1423,9 +1541,9 @@ } }, "@babel/preset-env": { - "version": "7.14.1", - "resolved": "https://registry.npmjs.org/@babel/preset-env/-/preset-env-7.14.1.tgz", - "integrity": "sha512-0M4yL1l7V4l+j/UHvxcdvNfLB9pPtIooHTbEhgD/6UGyh8Hy3Bm1Mj0buzjDXATCSz3JFibVdnoJZCrlUCanrQ==", + "version": "7.14.2", + "resolved": "https://registry.npmjs.org/@babel/preset-env/-/preset-env-7.14.2.tgz", + "integrity": "sha512-7dD7lVT8GMrE73v4lvDEb85cgcQhdES91BSD7jS/xjC6QY8PnRhux35ac+GCpbiRhp8crexBvZZqnaL6VrY8TQ==", "dev": true, "requires": { "@babel/compat-data": "^7.14.0", @@ -1433,18 +1551,18 @@ "@babel/helper-plugin-utils": "^7.13.0", "@babel/helper-validator-option": "^7.12.17", "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": "^7.13.12", - "@babel/plugin-proposal-async-generator-functions": "^7.13.15", + "@babel/plugin-proposal-async-generator-functions": "^7.14.2", "@babel/plugin-proposal-class-properties": "^7.13.0", "@babel/plugin-proposal-class-static-block": "^7.13.11", - "@babel/plugin-proposal-dynamic-import": "^7.13.8", - "@babel/plugin-proposal-export-namespace-from": "^7.12.13", - "@babel/plugin-proposal-json-strings": "^7.13.8", - "@babel/plugin-proposal-logical-assignment-operators": "^7.13.8", - "@babel/plugin-proposal-nullish-coalescing-operator": "^7.13.8", - "@babel/plugin-proposal-numeric-separator": "^7.12.13", - "@babel/plugin-proposal-object-rest-spread": "^7.13.8", - "@babel/plugin-proposal-optional-catch-binding": "^7.13.8", - "@babel/plugin-proposal-optional-chaining": "^7.13.12", + "@babel/plugin-proposal-dynamic-import": "^7.14.2", + "@babel/plugin-proposal-export-namespace-from": "^7.14.2", + "@babel/plugin-proposal-json-strings": "^7.14.2", + "@babel/plugin-proposal-logical-assignment-operators": "^7.14.2", + "@babel/plugin-proposal-nullish-coalescing-operator": "^7.14.2", + "@babel/plugin-proposal-numeric-separator": "^7.14.2", + "@babel/plugin-proposal-object-rest-spread": "^7.14.2", + "@babel/plugin-proposal-optional-catch-binding": "^7.14.2", + "@babel/plugin-proposal-optional-chaining": "^7.14.2", "@babel/plugin-proposal-private-methods": "^7.13.0", "@babel/plugin-proposal-private-property-in-object": "^7.14.0", "@babel/plugin-proposal-unicode-property-regex": "^7.12.13", @@ -1465,8 +1583,8 @@ "@babel/plugin-transform-arrow-functions": "^7.13.0", "@babel/plugin-transform-async-to-generator": "^7.13.0", "@babel/plugin-transform-block-scoped-functions": "^7.12.13", - "@babel/plugin-transform-block-scoping": "^7.14.1", - "@babel/plugin-transform-classes": "^7.13.0", + "@babel/plugin-transform-block-scoping": "^7.14.2", + "@babel/plugin-transform-classes": "^7.14.2", "@babel/plugin-transform-computed-properties": "^7.13.0", "@babel/plugin-transform-destructuring": "^7.13.17", "@babel/plugin-transform-dotall-regex": "^7.12.13", @@ -1476,14 +1594,14 @@ "@babel/plugin-transform-function-name": "^7.12.13", "@babel/plugin-transform-literals": "^7.12.13", "@babel/plugin-transform-member-expression-literals": "^7.12.13", - "@babel/plugin-transform-modules-amd": "^7.14.0", + "@babel/plugin-transform-modules-amd": "^7.14.2", "@babel/plugin-transform-modules-commonjs": "^7.14.0", "@babel/plugin-transform-modules-systemjs": "^7.13.8", "@babel/plugin-transform-modules-umd": "^7.14.0", "@babel/plugin-transform-named-capturing-groups-regex": "^7.12.13", "@babel/plugin-transform-new-target": "^7.12.13", "@babel/plugin-transform-object-super": "^7.12.13", - "@babel/plugin-transform-parameters": "^7.13.0", + "@babel/plugin-transform-parameters": "^7.14.2", "@babel/plugin-transform-property-literals": "^7.12.13", "@babel/plugin-transform-regenerator": "^7.13.15", "@babel/plugin-transform-reserved-words": "^7.12.13", @@ -1495,7 +1613,7 @@ "@babel/plugin-transform-unicode-escapes": "^7.12.13", "@babel/plugin-transform-unicode-regex": "^7.12.13", "@babel/preset-modules": "^0.1.4", - "@babel/types": "^7.14.1", + "@babel/types": "^7.14.2", "babel-plugin-polyfill-corejs2": "^0.2.0", "babel-plugin-polyfill-corejs3": "^0.2.0", "babel-plugin-polyfill-regenerator": "^0.2.0", @@ -1868,9 +1986,9 @@ } }, "@ngtools/webpack": { - "version": "12.0.0", - "resolved": "https://registry.npmjs.org/@ngtools/webpack/-/webpack-12.0.0.tgz", - "integrity": "sha512-uo3w6/FQesqn8YZrO9QvcXR33f/eJqA5AEZrZqMBXRrCrxyVug1gNvFlx9ZFfKKsmokUfxyWPruei7mQ32DEKQ==", + "version": "12.0.2", + "resolved": "https://registry.npmjs.org/@ngtools/webpack/-/webpack-12.0.2.tgz", + "integrity": "sha512-q+AzIMxWb/8jEDhNrKM2THlJrhUCkX18sKBWY+r221uXtt1sz58MdJyE0UTALvOvjHxEF5OvbWpeAbKUOKgVFA==", "dev": true, "requires": { "enhanced-resolve": "5.7.0" @@ -1978,13 +2096,13 @@ } }, "@schematics/angular": { - "version": "12.0.0", - "resolved": "https://registry.npmjs.org/@schematics/angular/-/angular-12.0.0.tgz", - "integrity": "sha512-6fS1MuzLvuiuS8ruSl919+mXTBDgpMY+mC+n1iM70rHvDms6+wEIwuyEty6Mw7JsPFXwcFAsIBt3EZCplzHhmg==", + "version": "12.0.2", + "resolved": "https://registry.npmjs.org/@schematics/angular/-/angular-12.0.2.tgz", + "integrity": "sha512-DMUfp7226QY2FkJeBm1xAUUKRX9umVCRhqEcku4Zaig6PylVd9LZFLjZvGKA4Vq2DkYRtClll3z5FIhAOSY3SQ==", "dev": true, "requires": { - "@angular-devkit/core": "12.0.0", - "@angular-devkit/schematics": "12.0.0", + "@angular-devkit/core": "12.0.2", + "@angular-devkit/schematics": "12.0.2", "jsonc-parser": "3.0.0" } }, @@ -2055,9 +2173,9 @@ "dev": true }, "@types/eslint": { - "version": "7.2.10", - "resolved": "https://registry.npmjs.org/@types/eslint/-/eslint-7.2.10.tgz", - "integrity": "sha512-kUEPnMKrqbtpCq/KTaGFFKAcz6Ethm2EjCoKIDaCmfRBWLbFuTcOJfTlorwbnboXBzahqWLgUp1BQeKHiJzPUQ==", + "version": "7.2.12", + "resolved": "https://registry.npmjs.org/@types/eslint/-/eslint-7.2.12.tgz", + "integrity": "sha512-HjikV/jX6e0Pg4DcB+rtOBKSrG6w5IaxWpmi3efL/eLxMz5lZTK+W1DKERrX5a+mNzL78axfsDNXu7JHFP4uLg==", "dev": true, "requires": { "@types/estree": "*", @@ -2561,9 +2679,9 @@ } }, "acorn": { - "version": "8.2.4", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.2.4.tgz", - "integrity": "sha512-Ibt84YwBDDA890eDiDCEqcbwvHlBvzzDkU2cGBBDDI1QWT12jTiXIOn2CIw5KK4i6N5Z2HUxwYjzriDyqaqqZg==", + "version": "8.3.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.3.0.tgz", + "integrity": "sha512-tqPKHZ5CaBJw0Xmy0ZZvLs1qTV+BNFSyvn77ASXkpBNfIRk8ev26fKrD9iLGwGA9zedPao52GSHzq8lyZG0NUw==", "dev": true }, "acorn-jsx": { @@ -3014,13 +3132,13 @@ } }, "babel-plugin-polyfill-corejs2": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs2/-/babel-plugin-polyfill-corejs2-0.2.0.tgz", - "integrity": "sha512-9bNwiR0dS881c5SHnzCmmGlMkJLl0OUZvxrxHo9w/iNoRuqaPjqlvBf4HrovXtQs/au5yKkpcdgfT1cC5PAZwg==", + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs2/-/babel-plugin-polyfill-corejs2-0.2.2.tgz", + "integrity": "sha512-kISrENsJ0z5dNPq5eRvcctITNHYXWOA4DUZRFYCz3jYCcvTb/A546LIddmoGNMVYg2U38OyFeNosQwI9ENTqIQ==", "dev": true, "requires": { "@babel/compat-data": "^7.13.11", - "@babel/helper-define-polyfill-provider": "^0.2.0", + "@babel/helper-define-polyfill-provider": "^0.2.2", "semver": "^6.1.1" }, "dependencies": { @@ -3033,22 +3151,22 @@ } }, "babel-plugin-polyfill-corejs3": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs3/-/babel-plugin-polyfill-corejs3-0.2.0.tgz", - "integrity": "sha512-zZyi7p3BCUyzNxLx8KV61zTINkkV65zVkDAFNZmrTCRVhjo1jAS+YLvDJ9Jgd/w2tsAviCwFHReYfxO3Iql8Yg==", + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs3/-/babel-plugin-polyfill-corejs3-0.2.2.tgz", + "integrity": "sha512-l1Cf8PKk12eEk5QP/NQ6TH8A1pee6wWDJ96WjxrMXFLHLOBFzYM4moG80HFgduVhTqAFez4alnZKEhP/bYHg0A==", "dev": true, "requires": { - "@babel/helper-define-polyfill-provider": "^0.2.0", + "@babel/helper-define-polyfill-provider": "^0.2.2", "core-js-compat": "^3.9.1" } }, "babel-plugin-polyfill-regenerator": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-regenerator/-/babel-plugin-polyfill-regenerator-0.2.0.tgz", - "integrity": "sha512-J7vKbCuD2Xi/eEHxquHN14bXAW9CXtecwuLrOIDJtcZzTaPzV1VdEfoUf9AzcRBMolKUQKM9/GVojeh0hFiqMg==", + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-regenerator/-/babel-plugin-polyfill-regenerator-0.2.2.tgz", + "integrity": "sha512-Goy5ghsc21HgPDFtzRkSirpZVW35meGoTmTOb2bxqdl60ghub4xOidgNTHaZfQ2FaxQsKmwvXtOAkcIS4SMBWg==", "dev": true, "requires": { - "@babel/helper-define-polyfill-provider": "^0.2.0" + "@babel/helper-define-polyfill-provider": "^0.2.2" } }, "balanced-match": { @@ -3684,6 +3802,12 @@ "simple-swizzle": "^0.2.2" } }, + "colord": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/colord/-/colord-2.0.1.tgz", + "integrity": "sha512-vm5YpaWamD0Ov6TSG0GGmUIwstrWcfKQV/h2CmbR7PbNu41+qdB5PW9lpzhjedrpm08uuYvcXi0Oel1RLZIJuA==", + "dev": true + }, "colorette": { "version": "1.2.2", "resolved": "https://registry.npmjs.org/colorette/-/colorette-1.2.2.tgz", @@ -3949,9 +4073,9 @@ "dev": true }, "core-js-compat": { - "version": "3.12.1", - "resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.12.1.tgz", - "integrity": "sha512-i6h5qODpw6EsHAoIdQhKoZdWn+dGBF3dSS8m5tif36RlWvW3A6+yu2S16QHUo3CrkzrnEskMAt9f8FxmY9fhWQ==", + "version": "3.13.1", + "resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.13.1.tgz", + "integrity": "sha512-mdrcxc0WznfRd8ZicEZh1qVeJ2mu6bwQFh8YVUK48friy/FOwFV5EJj9/dlh+nMQ74YusdVfBFDuomKgUspxWQ==", "dev": true, "requires": { "browserslist": "^4.16.6", @@ -4212,9 +4336,9 @@ "dev": true }, "css-declaration-sorter": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/css-declaration-sorter/-/css-declaration-sorter-6.0.0.tgz", - "integrity": "sha512-S0TE4E0ha5+tBHdLWPc5n+S8E4dFBS5xScPvgHkLNZwWvX4ISoFGhGeerLC9uS1cKA/sC+K2wHq6qEbcagT/fg==", + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/css-declaration-sorter/-/css-declaration-sorter-6.0.3.tgz", + "integrity": "sha512-52P95mvW1SMzuRZegvpluT6yEv0FqQusydKQPZsNN5Q7hh8EwQvN8E2nwuJ16BBvNN6LcoIZXu/Bk58DAhrrxw==", "dev": true, "requires": { "timsort": "^0.3.0" @@ -4325,6 +4449,67 @@ } } }, + "css-minimizer-webpack-plugin": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/css-minimizer-webpack-plugin/-/css-minimizer-webpack-plugin-3.0.0.tgz", + "integrity": "sha512-yIrqG0pPphR1RoNx2wDxYmxRf2ubRChLDXxv7ccipEm5bRKsZRYp8n+2peeXehtTF5s3yNxlqsdz3WQOsAgUkw==", + "dev": true, + "requires": { + "cssnano": "^5.0.0", + "jest-worker": "^26.3.0", + "p-limit": "^3.0.2", + "postcss": "^8.2.9", + "schema-utils": "^3.0.0", + "serialize-javascript": "^5.0.1", + "source-map": "^0.6.1" + }, + "dependencies": { + "ajv": { + "version": "6.12.6", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", + "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "dev": true, + "requires": { + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + } + }, + "json-schema-traverse": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", + "dev": true + }, + "p-limit": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", + "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", + "dev": true, + "requires": { + "yocto-queue": "^0.1.0" + } + }, + "schema-utils": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.0.0.tgz", + "integrity": "sha512-6D82/xSzO094ajanoOSbe4YvXWMfn2A//8Y1+MUqFAJul5Bs+yn36xbK9OtNDcRVSBJ9jjeoXftM6CfztsjOAA==", + "dev": true, + "requires": { + "@types/json-schema": "^7.0.6", + "ajv": "^6.12.5", + "ajv-keywords": "^3.5.2" + } + }, + "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 + } + } + }, "css-parse": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/css-parse/-/css-parse-2.0.0.tgz", @@ -4460,57 +4645,57 @@ "dev": true }, "cssnano": { - "version": "5.0.2", - "resolved": "https://registry.npmjs.org/cssnano/-/cssnano-5.0.2.tgz", - "integrity": "sha512-8JK3EnPsjQsULme9/e5M2hF564f/480hwsdcHvQ7ZtAIMfQ1O3SCfs+b8Mjf5KJxhYApyRshR2QSovEJi2K72Q==", + "version": "5.0.5", + "resolved": "https://registry.npmjs.org/cssnano/-/cssnano-5.0.5.tgz", + "integrity": "sha512-L2VtPXnq6rmcMC9vkBOP131sZu3ccRQI27ejKZdmQiPDpUlFkUbpXHgKN+cibeO1U4PItxVZp1zTIn5dHsXoyg==", "dev": true, "requires": { "cosmiconfig": "^7.0.0", - "cssnano-preset-default": "^5.0.1", + "cssnano-preset-default": "^5.1.2", "is-resolvable": "^1.1.0" } }, "cssnano-preset-default": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/cssnano-preset-default/-/cssnano-preset-default-5.0.1.tgz", - "integrity": "sha512-cfmfThYODGqhpQKDq9H0MTAqkMvZ3dGbOUTBKw0xWZiIycMqHid22LsJXJl4r1qX4qzDeKxcSyQ/Xb5Mu3Z//Q==", + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/cssnano-preset-default/-/cssnano-preset-default-5.1.2.tgz", + "integrity": "sha512-spilp8LRw0sacuxiN9A/dyyPr6G/WISKMBKcBD4NMoPV0ENx4DeuWvIIrSx9PII2nJIDCO3kywkqTPreECBVOg==", "dev": true, "requires": { - "css-declaration-sorter": "6.0.0", - "cssnano-utils": "^2.0.0", + "css-declaration-sorter": "^6.0.3", + "cssnano-utils": "^2.0.1", "postcss-calc": "^8.0.0", - "postcss-colormin": "^5.0.0", - "postcss-convert-values": "^5.0.0", - "postcss-discard-comments": "^5.0.0", - "postcss-discard-duplicates": "^5.0.0", - "postcss-discard-empty": "^5.0.0", - "postcss-discard-overridden": "^5.0.0", - "postcss-merge-longhand": "^5.0.1", - "postcss-merge-rules": "^5.0.0", - "postcss-minify-font-values": "^5.0.0", - "postcss-minify-gradients": "^5.0.0", - "postcss-minify-params": "^5.0.0", - "postcss-minify-selectors": "^5.0.0", - "postcss-normalize-charset": "^5.0.0", - "postcss-normalize-display-values": "^5.0.0", - "postcss-normalize-positions": "^5.0.0", - "postcss-normalize-repeat-style": "^5.0.0", - "postcss-normalize-string": "^5.0.0", - "postcss-normalize-timing-functions": "^5.0.0", - "postcss-normalize-unicode": "^5.0.0", - "postcss-normalize-url": "^5.0.0", - "postcss-normalize-whitespace": "^5.0.0", - "postcss-ordered-values": "^5.0.0", - "postcss-reduce-initial": "^5.0.0", - "postcss-reduce-transforms": "^5.0.0", - "postcss-svgo": "^5.0.0", - "postcss-unique-selectors": "^5.0.0" + "postcss-colormin": "^5.2.0", + "postcss-convert-values": "^5.0.1", + "postcss-discard-comments": "^5.0.1", + "postcss-discard-duplicates": "^5.0.1", + "postcss-discard-empty": "^5.0.1", + "postcss-discard-overridden": "^5.0.1", + "postcss-merge-longhand": "^5.0.2", + "postcss-merge-rules": "^5.0.2", + "postcss-minify-font-values": "^5.0.1", + "postcss-minify-gradients": "^5.0.1", + "postcss-minify-params": "^5.0.1", + "postcss-minify-selectors": "^5.1.0", + "postcss-normalize-charset": "^5.0.1", + "postcss-normalize-display-values": "^5.0.1", + "postcss-normalize-positions": "^5.0.1", + "postcss-normalize-repeat-style": "^5.0.1", + "postcss-normalize-string": "^5.0.1", + "postcss-normalize-timing-functions": "^5.0.1", + "postcss-normalize-unicode": "^5.0.1", + "postcss-normalize-url": "^5.0.1", + "postcss-normalize-whitespace": "^5.0.1", + "postcss-ordered-values": "^5.0.1", + "postcss-reduce-initial": "^5.0.1", + "postcss-reduce-transforms": "^5.0.1", + "postcss-svgo": "^5.0.2", + "postcss-unique-selectors": "^5.0.1" } }, "cssnano-utils": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/cssnano-utils/-/cssnano-utils-2.0.0.tgz", - "integrity": "sha512-xvxmTszdrvSyTACdPe8VU5J6p4sm3egpgw54dILvNqt5eBUv6TFjACLhSxtRuEsxYrgy8uDy269YjScO5aKbGA==", + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/cssnano-utils/-/cssnano-utils-2.0.1.tgz", + "integrity": "sha512-i8vLRZTnEH9ubIyfdZCAdIdgnHAUeQeByEeQ2I7oTilvP9oHO6RScpeq3GsFUVqeB8uZgOQ9pw8utofNn32hhQ==", "dev": true }, "csso": { @@ -4767,9 +4952,9 @@ "dev": true }, "detect-node": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/detect-node/-/detect-node-2.0.5.tgz", - "integrity": "sha512-qi86tE6hRcFHy8jI1m2VG+LaPUR1LhqDa5G8tVjuUXmOrpuAgqsA1pN0+ldgr3aKUH+QLI9hCY/OcRYisERejw==", + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/detect-node/-/detect-node-2.1.0.tgz", + "integrity": "sha512-T0NIuQpnTvFDATNuHN5roPwSBG83rFsuO+MXXH9/3N1eFbn4wcPjttvjMLEPWJ0RGUYgQE7cGgS3tNxbqCGM7g==", "dev": true }, "detective": { @@ -4817,9 +5002,9 @@ "dev": true }, "dns-packet": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/dns-packet/-/dns-packet-1.3.1.tgz", - "integrity": "sha512-0UxfQkMhYAUaZI+xrNZOz/as5KgDU0M/fQ9b6SpkyLbk3GEswDi6PADJVaYJradtRVsRIlF1zLyOodbcTCDzUg==", + "version": "1.3.4", + "resolved": "https://registry.npmjs.org/dns-packet/-/dns-packet-1.3.4.tgz", + "integrity": "sha512-BQ6F4vycLXBvdrJZ6S3gZewt6rcrks9KBgM9vrhW+knGRqc8uEdT7fuCwloc7nny5xNoMJ17HGH0R/6fpo8ECA==", "dev": true, "requires": { "ip": "^1.1.0", @@ -4857,13 +5042,13 @@ } }, "dom-serializer": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-1.3.1.tgz", - "integrity": "sha512-Pv2ZluG5ife96udGgEDovOOOA5UELkltfJpnIExPrAk1LTvecolUGn6lIaoLh86d83GiB86CjzciMd9BuRB71Q==", + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-1.3.2.tgz", + "integrity": "sha512-5c54Bk5Dw4qAxNOI1pFEizPSjVsx5+bpJKmL2kPn8JhBUq2q09tTCa3mjijun2NfK78NMouDYNMBkOrPZiS+ig==", "dev": true, "requires": { "domelementtype": "^2.0.1", - "domhandler": "^4.0.0", + "domhandler": "^4.2.0", "entities": "^2.0.0" } }, @@ -4893,15 +5078,6 @@ "domhandler": "^4.2.0" } }, - "dot-prop": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/dot-prop/-/dot-prop-5.3.0.tgz", - "integrity": "sha512-QM8q3zDe58hqUqjraQOmzZ1LIH9SWQJTlEKCH4kJ2oQvLZk7RbQXvtDM2XEq3fwkV9CCvvH4LA0AV+ogFsBM2Q==", - "dev": true, - "requires": { - "is-obj": "^2.0.0" - } - }, "ecc-jsbn": { "version": "0.1.2", "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz", @@ -4957,9 +5133,9 @@ }, "dependencies": { "iconv-lite": { - "version": "0.6.2", - "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.2.tgz", - "integrity": "sha512-2y91h5OpQlolefMPmUlivelittSWy0rP+oYVpn6A7GwVHNE8AWzoYOBNmlwks3LobaJxgHCYZAnyNo2GgpNRNQ==", + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz", + "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==", "dev": true, "optional": true, "requires": { @@ -5983,9 +6159,9 @@ } }, "faye-websocket": { - "version": "0.11.3", - "resolved": "https://registry.npmjs.org/faye-websocket/-/faye-websocket-0.11.3.tgz", - "integrity": "sha512-D2y4bovYpzziGgbHYtGCMjlJM36vAl/y+xUyn1C+FVx8szd1E+86KwVw6XvYSzOP8iMpm1X0I4xJD+QtUb36OA==", + "version": "0.11.4", + "resolved": "https://registry.npmjs.org/faye-websocket/-/faye-websocket-0.11.4.tgz", + "integrity": "sha512-CzbClwlXAuiRQAlUyfqPgvPoNKTckTPGfwZV4ZdAhVcP2lh9KUxJg2b5GkE7XbjKQ3YJnQ9z6D9ntLAlB+tP8g==", "dev": true, "requires": { "websocket-driver": ">=0.5.1" @@ -7326,12 +7502,6 @@ "integrity": "sha512-RU0lI/n95pMoUKu9v1BZP5MBcZuNSVJkMkAG2dJqC4z2GlkGUNeH68SuHuBKBD/XFe+LHZ+f9BKkLET60Niedw==", "dev": true }, - "is-obj": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-obj/-/is-obj-2.0.0.tgz", - "integrity": "sha512-drqDG3cbczxxEJRoOXcOjtdp1J/lyp1mNn0xaznRs8+muBhgQcrnbspox5X5fOw0HnMnbfDzvnEMEtqDEJEo8w==", - "dev": true - }, "is-path-cwd": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/is-path-cwd/-/is-path-cwd-2.2.0.tgz", @@ -8947,9 +9117,9 @@ "dev": true }, "normalize-url": { - "version": "4.5.0", - "resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-4.5.0.tgz", - "integrity": "sha512-2s47yzUxdexf1OhyRi4Em83iQk0aPvwTddtFz4hnSSw9dCEsLEGf6SwIO8ss/19S9iBb5sJaOuTvTGDeZI00BQ==", + "version": "4.5.1", + "resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-4.5.1.tgz", + "integrity": "sha512-9UZCFRHQdNrfTpGg8+1INIg93B6zE0aXMVFkw1WFwvO4SlZywU6aLg5Of0Ap/PgcbSw4LNxvMWXMeugwMCX0AA==", "dev": true }, "npm-bundled": { @@ -9012,9 +9182,9 @@ } }, "npm-registry-fetch": { - "version": "10.1.1", - "resolved": "https://registry.npmjs.org/npm-registry-fetch/-/npm-registry-fetch-10.1.1.tgz", - "integrity": "sha512-F6a3l+ffCQ7hvvN16YG5bpm1rPZntCg66PLHDQ1apWJPOCUVHoKnL2w5fqEaTVhp42dmossTyXeR7hTGirfXrg==", + "version": "10.1.2", + "resolved": "https://registry.npmjs.org/npm-registry-fetch/-/npm-registry-fetch-10.1.2.tgz", + "integrity": "sha512-KsM/TdPmntqgBFlfsbkOLkkE9ovZo7VpVcd+/eTdYszCrgy5zFl5JzWm+OxavFaEWlbkirpkou+ZYI00RmOBFA==", "dev": true, "requires": { "lru-cache": "^6.0.0", @@ -9218,9 +9388,9 @@ } }, "open": { - "version": "8.0.7", - "resolved": "https://registry.npmjs.org/open/-/open-8.0.7.tgz", - "integrity": "sha512-qoyG0kpdaWVoL5MiwTRQWujSdivwBOgfLadVEdpsZNHOK1+kBvmVtLYdgWr8G4cgBpG9zaxezn6jz6PPdQW5xg==", + "version": "8.0.2", + "resolved": "https://registry.npmjs.org/open/-/open-8.0.2.tgz", + "integrity": "sha512-NV5QmWJrTaNBLHABJyrb+nd5dXI5zfea/suWawBhkHzAbVhLLiJdrqMgxMypGK9Eznp2Ltoh7SAVkQ3XAucX7Q==", "dev": true, "requires": { "define-lazy-prop": "^2.0.0", @@ -10016,20 +10186,21 @@ } }, "postcss-colormin": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/postcss-colormin/-/postcss-colormin-5.0.0.tgz", - "integrity": "sha512-Yt84+5V6CgS/AhK7d7MA58vG8dSZ7+ytlRtWLaQhag3HXOncTfmYpuUOX4cDoXjvLfw1sHRCHMiBjYhc35CymQ==", + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/postcss-colormin/-/postcss-colormin-5.2.0.tgz", + "integrity": "sha512-+HC6GfWU3upe5/mqmxuqYZ9B2Wl4lcoUUNkoaX59nEWV4EtADCMiBqui111Bu8R8IvaZTmqmxrqOAqjbHIwXPw==", "dev": true, "requires": { - "browserslist": "^4.16.0", - "color": "^3.1.1", + "browserslist": "^4.16.6", + "caniuse-api": "^3.0.0", + "colord": "^2.0.1", "postcss-value-parser": "^4.1.0" } }, "postcss-convert-values": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/postcss-convert-values/-/postcss-convert-values-5.0.0.tgz", - "integrity": "sha512-V5kmYm4xoBAjNs+eHY/6XzXJkkGeg4kwNf2ocfqhLb1WBPEa4oaSmoi1fnVO7Dkblqvus9h+AenDvhCKUCK7uQ==", + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/postcss-convert-values/-/postcss-convert-values-5.0.1.tgz", + "integrity": "sha512-C3zR1Do2BkKkCgC0g3sF8TS0koF2G+mN8xxayZx3f10cIRmTaAnpgpRQZjNekTZxM2ciSPoh2IWJm0VZx8NoQg==", "dev": true, "requires": { "postcss-value-parser": "^4.1.0" @@ -10221,27 +10392,27 @@ } }, "postcss-discard-comments": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/postcss-discard-comments/-/postcss-discard-comments-5.0.0.tgz", - "integrity": "sha512-Umig6Gxs8m20RihiXY6QkePd6mp4FxkA1Dg+f/Kd6uw0gEMfKRjDeQOyFkLibexbJJGHpE3lrN/Q0R9SMrUMbQ==", + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/postcss-discard-comments/-/postcss-discard-comments-5.0.1.tgz", + "integrity": "sha512-lgZBPTDvWrbAYY1v5GYEv8fEO/WhKOu/hmZqmCYfrpD6eyDWWzAOsl2rF29lpvziKO02Gc5GJQtlpkTmakwOWg==", "dev": true }, "postcss-discard-duplicates": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/postcss-discard-duplicates/-/postcss-discard-duplicates-5.0.0.tgz", - "integrity": "sha512-vEJJ+Y3pFUnO1FyCBA6PSisGjHtnphL3V6GsNvkASq/VkP3OX5/No5RYXXLxHa2QegStNzg6HYrYdo71uR4caQ==", + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/postcss-discard-duplicates/-/postcss-discard-duplicates-5.0.1.tgz", + "integrity": "sha512-svx747PWHKOGpAXXQkCc4k/DsWo+6bc5LsVrAsw+OU+Ibi7klFZCyX54gjYzX4TH+f2uzXjRviLARxkMurA2bA==", "dev": true }, "postcss-discard-empty": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/postcss-discard-empty/-/postcss-discard-empty-5.0.0.tgz", - "integrity": "sha512-+wigy099Y1xZxG36WG5L1f2zeH1oicntkJEW4TDIqKKDO2g9XVB3OhoiHTu08rDEjLnbcab4rw0BAccwi2VjiQ==", + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/postcss-discard-empty/-/postcss-discard-empty-5.0.1.tgz", + "integrity": "sha512-vfU8CxAQ6YpMxV2SvMcMIyF2LX1ZzWpy0lqHDsOdaKKLQVQGVP1pzhrI9JlsO65s66uQTfkQBKBD/A5gp9STFw==", "dev": true }, "postcss-discard-overridden": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/postcss-discard-overridden/-/postcss-discard-overridden-5.0.0.tgz", - "integrity": "sha512-hybnScTaZM2iEA6kzVQ6Spozy7kVdLw+lGw8hftLlBEzt93uzXoltkYp9u0tI8xbfhxDLTOOzHsHQCkYdmzRUg==", + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/postcss-discard-overridden/-/postcss-discard-overridden-5.0.1.tgz", + "integrity": "sha512-Y28H7y93L2BpJhrdUR2SR2fnSsT+3TVx1NmVQLbcnZWwIUpJ7mfcTC6Za9M2PG6w8j7UQRfzxqn8jU2VwFxo3Q==", "dev": true }, "postcss-double-position-gradients": { @@ -10726,83 +10897,70 @@ } }, "postcss-merge-longhand": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/postcss-merge-longhand/-/postcss-merge-longhand-5.0.1.tgz", - "integrity": "sha512-H1RO8le5deFGumQzuhJjuL0bIXPRysa+w7xtk5KrHe38oiaSS9ksPXDo24+IOS3SETPhip0J5+1uCOW+ALs3Yw==", + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/postcss-merge-longhand/-/postcss-merge-longhand-5.0.2.tgz", + "integrity": "sha512-BMlg9AXSI5G9TBT0Lo/H3PfUy63P84rVz3BjCFE9e9Y9RXQZD3+h3YO1kgTNsNJy7bBc1YQp8DmSnwLIW5VPcw==", "dev": true, "requires": { "css-color-names": "^1.0.1", "postcss-value-parser": "^4.1.0", - "stylehacks": "^5.0.0" + "stylehacks": "^5.0.1" } }, "postcss-merge-rules": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/postcss-merge-rules/-/postcss-merge-rules-5.0.0.tgz", - "integrity": "sha512-TfsXbKjNYCGfUPEXGIGPySnMiJbdS+3gcVeV8gwmJP4RajyKZHW8E0FYDL1WmggTj3hi+m+WUCAvqRpX2ut4Kg==", + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/postcss-merge-rules/-/postcss-merge-rules-5.0.2.tgz", + "integrity": "sha512-5K+Md7S3GwBewfB4rjDeol6V/RZ8S+v4B66Zk2gChRqLTCC8yjnHQ601omj9TKftS19OPGqZ/XzoqpzNQQLwbg==", "dev": true, "requires": { - "browserslist": "^4.16.0", + "browserslist": "^4.16.6", "caniuse-api": "^3.0.0", - "cssnano-utils": "^2.0.0", - "postcss-selector-parser": "^6.0.4", + "cssnano-utils": "^2.0.1", + "postcss-selector-parser": "^6.0.5", "vendors": "^1.0.3" } }, "postcss-minify-font-values": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/postcss-minify-font-values/-/postcss-minify-font-values-5.0.0.tgz", - "integrity": "sha512-zi2JhFaMOcIaNxhndX5uhsqSY1rexKDp23wV8EOmC9XERqzLbHsoRye3aYF716Zm+hkcR4loqKDt8LZlmihwAg==", + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/postcss-minify-font-values/-/postcss-minify-font-values-5.0.1.tgz", + "integrity": "sha512-7JS4qIsnqaxk+FXY1E8dHBDmraYFWmuL6cgt0T1SWGRO5bzJf8sUoelwa4P88LEWJZweHevAiDKxHlofuvtIoA==", "dev": true, "requires": { "postcss-value-parser": "^4.1.0" } }, "postcss-minify-gradients": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/postcss-minify-gradients/-/postcss-minify-gradients-5.0.0.tgz", - "integrity": "sha512-/jPtNgs6JySMwgsE5dPOq8a2xEopWTW3RyqoB9fLqxgR+mDUNLSi7joKd+N1z7FXWgVkc4l/dEBMXHgNAaUbvg==", + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/postcss-minify-gradients/-/postcss-minify-gradients-5.0.1.tgz", + "integrity": "sha512-odOwBFAIn2wIv+XYRpoN2hUV3pPQlgbJ10XeXPq8UY2N+9ZG42xu45lTn/g9zZ+d70NKSQD6EOi6UiCMu3FN7g==", "dev": true, "requires": { - "cssnano-utils": "^2.0.0", + "cssnano-utils": "^2.0.1", "is-color-stop": "^1.1.0", "postcss-value-parser": "^4.1.0" } }, "postcss-minify-params": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/postcss-minify-params/-/postcss-minify-params-5.0.0.tgz", - "integrity": "sha512-KvZYIxTPBVKjdd+XgObq9A+Sfv8lMkXTpbZTsjhr42XbfWIeLaTItMlygsDWfjArEc3muUfDaUFgNSeDiJ5jug==", + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/postcss-minify-params/-/postcss-minify-params-5.0.1.tgz", + "integrity": "sha512-4RUC4k2A/Q9mGco1Z8ODc7h+A0z7L7X2ypO1B6V8057eVK6mZ6xwz6QN64nHuHLbqbclkX1wyzRnIrdZehTEHw==", "dev": true, "requires": { "alphanum-sort": "^1.0.2", "browserslist": "^4.16.0", - "cssnano-utils": "^2.0.0", + "cssnano-utils": "^2.0.1", "postcss-value-parser": "^4.1.0", "uniqs": "^2.0.0" } }, "postcss-minify-selectors": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/postcss-minify-selectors/-/postcss-minify-selectors-5.0.0.tgz", - "integrity": "sha512-cEM0O0eWwFIvmo6nfB0lH0vO/XFwgqIvymODbfPXZ1gTA3i76FKnb7TGUrEpiTxaXH6tgYQ6DcTHwRiRS+YQLQ==", + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/postcss-minify-selectors/-/postcss-minify-selectors-5.1.0.tgz", + "integrity": "sha512-NzGBXDa7aPsAcijXZeagnJBKBPMYLaJJzB8CQh6ncvyl2sIndLVWfbcDi0SBjRWk5VqEjXvf8tYwzoKf4Z07og==", "dev": true, "requires": { "alphanum-sort": "^1.0.2", - "postcss-selector-parser": "^3.1.2" - }, - "dependencies": { - "postcss-selector-parser": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-3.1.2.tgz", - "integrity": "sha512-h7fJ/5uWuRVyOtkO45pnt1Ih40CEleeyCHzipqAZO2e5H20g25Y48uYnFUiShvY4rZWNJ/Bib/KVPmanaCtOhA==", - "dev": true, - "requires": { - "dot-prop": "^5.2.0", - "indexes-of": "^1.0.1", - "uniq": "^1.0.1" - } - } + "postcss-selector-parser": "^6.0.5" } }, "postcss-modules-extract-imports": { @@ -10887,63 +11045,63 @@ } }, "postcss-normalize-charset": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/postcss-normalize-charset/-/postcss-normalize-charset-5.0.0.tgz", - "integrity": "sha512-pqsCkgo9KmQP0ew6DqSA+uP9YN6EfsW20pQ3JU5JoQge09Z6Too4qU0TNDsTNWuEaP8SWsMp+19l15210MsDZQ==", + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/postcss-normalize-charset/-/postcss-normalize-charset-5.0.1.tgz", + "integrity": "sha512-6J40l6LNYnBdPSk+BHZ8SF+HAkS4q2twe5jnocgd+xWpz/mx/5Sa32m3W1AA8uE8XaXN+eg8trIlfu8V9x61eg==", "dev": true }, "postcss-normalize-display-values": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/postcss-normalize-display-values/-/postcss-normalize-display-values-5.0.0.tgz", - "integrity": "sha512-t4f2d//gH1f7Ns0Jq3eNdnWuPT7TeLuISZ6RQx4j8gpl5XrhkdshdNcOnlrEK48YU6Tcb6jqK7dorME3N4oOGA==", + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/postcss-normalize-display-values/-/postcss-normalize-display-values-5.0.1.tgz", + "integrity": "sha512-uupdvWk88kLDXi5HEyI9IaAJTE3/Djbcrqq8YgjvAVuzgVuqIk3SuJWUisT2gaJbZm1H9g5k2w1xXilM3x8DjQ==", "dev": true, "requires": { - "cssnano-utils": "^2.0.0", + "cssnano-utils": "^2.0.1", "postcss-value-parser": "^4.1.0" } }, "postcss-normalize-positions": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/postcss-normalize-positions/-/postcss-normalize-positions-5.0.0.tgz", - "integrity": "sha512-0o6/qU5ky74X/eWYj/tv4iiKCm3YqJnrhmVADpIMNXxzFZywsSQxl8F7cKs8jQEtF3VrJBgcDHTexZy1zgDoYg==", + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/postcss-normalize-positions/-/postcss-normalize-positions-5.0.1.tgz", + "integrity": "sha512-rvzWAJai5xej9yWqlCb1OWLd9JjW2Ex2BCPzUJrbaXmtKtgfL8dBMOOMTX6TnvQMtjk3ei1Lswcs78qKO1Skrg==", "dev": true, "requires": { "postcss-value-parser": "^4.1.0" } }, "postcss-normalize-repeat-style": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/postcss-normalize-repeat-style/-/postcss-normalize-repeat-style-5.0.0.tgz", - "integrity": "sha512-KRT14JbrXKcFMYuc4q7lh8lvv8u22wLyMrq+UpHKLtbx2H/LOjvWXYdoDxmNrrrJzomAWL+ViEXr48/IhSUJnQ==", + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/postcss-normalize-repeat-style/-/postcss-normalize-repeat-style-5.0.1.tgz", + "integrity": "sha512-syZ2itq0HTQjj4QtXZOeefomckiV5TaUO6ReIEabCh3wgDs4Mr01pkif0MeVwKyU/LHEkPJnpwFKRxqWA/7O3w==", "dev": true, "requires": { - "cssnano-utils": "^2.0.0", + "cssnano-utils": "^2.0.1", "postcss-value-parser": "^4.1.0" } }, "postcss-normalize-string": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/postcss-normalize-string/-/postcss-normalize-string-5.0.0.tgz", - "integrity": "sha512-wSO4pf7GNcDZpmelREWYADF1+XZWrAcbFLQCOqoE92ZwYgaP/RLumkUTaamEzdT2YKRZAH8eLLKGWotU/7FNPw==", + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/postcss-normalize-string/-/postcss-normalize-string-5.0.1.tgz", + "integrity": "sha512-Ic8GaQ3jPMVl1OEn2U//2pm93AXUcF3wz+OriskdZ1AOuYV25OdgS7w9Xu2LO5cGyhHCgn8dMXh9bO7vi3i9pA==", "dev": true, "requires": { "postcss-value-parser": "^4.1.0" } }, "postcss-normalize-timing-functions": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/postcss-normalize-timing-functions/-/postcss-normalize-timing-functions-5.0.0.tgz", - "integrity": "sha512-TwPaDX+wl9wO3MUm23lzGmOzGCGKnpk+rSDgzB2INpakD5dgWR3L6bJq1P1LQYzBAvz8fRIj2NWdnZdV4EV98Q==", + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/postcss-normalize-timing-functions/-/postcss-normalize-timing-functions-5.0.1.tgz", + "integrity": "sha512-cPcBdVN5OsWCNEo5hiXfLUnXfTGtSFiBU9SK8k7ii8UD7OLuznzgNRYkLZow11BkQiiqMcgPyh4ZqXEEUrtQ1Q==", "dev": true, "requires": { - "cssnano-utils": "^2.0.0", + "cssnano-utils": "^2.0.1", "postcss-value-parser": "^4.1.0" } }, "postcss-normalize-unicode": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/postcss-normalize-unicode/-/postcss-normalize-unicode-5.0.0.tgz", - "integrity": "sha512-2CpVoz/67rXU5s9tsPZDxG1YGS9OFHwoY9gsLAzrURrCxTAb0H7Vp87/62LvVPgRWTa5ZmvgmqTp2rL8tlm72A==", + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/postcss-normalize-unicode/-/postcss-normalize-unicode-5.0.1.tgz", + "integrity": "sha512-kAtYD6V3pK0beqrU90gpCQB7g6AOfP/2KIPCVBKJM2EheVsBQmx/Iof+9zR9NFKLAx4Pr9mDhogB27pmn354nA==", "dev": true, "requires": { "browserslist": "^4.16.0", @@ -10951,9 +11109,9 @@ } }, "postcss-normalize-url": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/postcss-normalize-url/-/postcss-normalize-url-5.0.0.tgz", - "integrity": "sha512-ICDaGFBqLgA3dlrCIRuhblLl80D13YtgEV9NJPTYJtgR72vu61KgxAHv+z/lKMs1EbwfSQa3ALjOFLSmXiE34A==", + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/postcss-normalize-url/-/postcss-normalize-url-5.0.1.tgz", + "integrity": "sha512-hkbG0j58Z1M830/CJ73VsP7gvlG1yF+4y7Fd1w4tD2c7CaA2Psll+pQ6eQhth9y9EaqZSLzamff/D0MZBMbYSg==", "dev": true, "requires": { "is-absolute-url": "^3.0.3", @@ -10962,21 +11120,21 @@ } }, "postcss-normalize-whitespace": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/postcss-normalize-whitespace/-/postcss-normalize-whitespace-5.0.0.tgz", - "integrity": "sha512-KRnxQvQAVkJfaeXSz7JlnD9nBN9sFZF9lrk9452Q2uRoqrRSkinqifF8Iex7wZGei2DZVG/qpmDFDmRvbNAOGA==", + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/postcss-normalize-whitespace/-/postcss-normalize-whitespace-5.0.1.tgz", + "integrity": "sha512-iPklmI5SBnRvwceb/XH568yyzK0qRVuAG+a1HFUsFRf11lEJTiQQa03a4RSCQvLKdcpX7XsI1Gen9LuLoqwiqA==", "dev": true, "requires": { "postcss-value-parser": "^4.1.0" } }, "postcss-ordered-values": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/postcss-ordered-values/-/postcss-ordered-values-5.0.0.tgz", - "integrity": "sha512-dPr+SRObiHueCIc4IUaG0aOGQmYkuNu50wQvdXTGKy+rzi2mjmPsbeDsheLk5WPb9Zyf2tp8E+I+h40cnivm6g==", + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/postcss-ordered-values/-/postcss-ordered-values-5.0.1.tgz", + "integrity": "sha512-6mkCF5BQ25HvEcDfrMHCLLFHlraBSlOXFnQMHYhSpDO/5jSR1k8LdEXOkv+7+uzW6o6tBYea1Km0wQSRkPJkwA==", "dev": true, "requires": { - "cssnano-utils": "^2.0.0", + "cssnano-utils": "^2.0.1", "postcss-value-parser": "^4.1.0" } }, @@ -11236,9 +11394,9 @@ } }, "postcss-reduce-initial": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/postcss-reduce-initial/-/postcss-reduce-initial-5.0.0.tgz", - "integrity": "sha512-wR6pXUaFbSMG1oCKx8pKVA+rnSXCHlca5jMrlmkmif+uig0HNUTV9oGN5kjKsM3mATQAldv2PF9Tbl2vqLFjnA==", + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/postcss-reduce-initial/-/postcss-reduce-initial-5.0.1.tgz", + "integrity": "sha512-zlCZPKLLTMAqA3ZWH57HlbCjkD55LX9dsRyxlls+wfuRfqCi5mSlZVan0heX5cHr154Dq9AfbH70LyhrSAezJw==", "dev": true, "requires": { "browserslist": "^4.16.0", @@ -11246,12 +11404,12 @@ } }, "postcss-reduce-transforms": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/postcss-reduce-transforms/-/postcss-reduce-transforms-5.0.0.tgz", - "integrity": "sha512-iHdGODW4YzM3WjVecBhPQt6fpJC4lGQZxJKjkBNHpp2b8dzmvj0ogKThqya+IRodQEFzjfXgYeESkf172FH5Lw==", + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/postcss-reduce-transforms/-/postcss-reduce-transforms-5.0.1.tgz", + "integrity": "sha512-a//FjoPeFkRuAguPscTVmRQUODP+f3ke2HqFNgGPwdYnpeC29RZdCBvGRGTsKpMURb/I3p6jdKoBQ2zI+9Q7kA==", "dev": true, "requires": { - "cssnano-utils": "^2.0.0", + "cssnano-utils": "^2.0.1", "postcss-value-parser": "^4.1.0" } }, @@ -11379,9 +11537,9 @@ } }, "postcss-svgo": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/postcss-svgo/-/postcss-svgo-5.0.0.tgz", - "integrity": "sha512-M3/VS4sFI1Yp9g0bPL+xzzCNz5iLdRUztoFaugMit5a8sMfkVzzhwqbsOlD8IFFymCdJDmXmh31waYHWw1K4BA==", + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/postcss-svgo/-/postcss-svgo-5.0.2.tgz", + "integrity": "sha512-YzQuFLZu3U3aheizD+B1joQ94vzPfE6BNUcSYuceNxlVnKKsOtdo6hL9/zyC168Q8EwfLSgaDSalsUGa9f2C0A==", "dev": true, "requires": { "postcss-value-parser": "^4.1.0", @@ -11389,13 +11547,13 @@ } }, "postcss-unique-selectors": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/postcss-unique-selectors/-/postcss-unique-selectors-5.0.0.tgz", - "integrity": "sha512-o9l4pF8SRn7aCMTmzb/kNv/kjV7wPZpZ8Nlb1Gq8v/Qvw969K1wanz1RVA0ehHzWe9+wHXaC2DvZlak/gdMJ5w==", + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/postcss-unique-selectors/-/postcss-unique-selectors-5.0.1.tgz", + "integrity": "sha512-gwi1NhHV4FMmPn+qwBNuot1sG1t2OmacLQ/AX29lzyggnjd+MnVD5uqQmpXO3J17KGL2WAxQruj1qTd3H0gG/w==", "dev": true, "requires": { "alphanum-sort": "^1.0.2", - "postcss-selector-parser": "^6.0.2", + "postcss-selector-parser": "^6.0.5", "uniqs": "^2.0.0" } }, @@ -13267,9 +13425,9 @@ }, "dependencies": { "iconv-lite": { - "version": "0.6.2", - "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.2.tgz", - "integrity": "sha512-2y91h5OpQlolefMPmUlivelittSWy0rP+oYVpn6A7GwVHNE8AWzoYOBNmlwks3LobaJxgHCYZAnyNo2GgpNRNQ==", + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz", + "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==", "dev": true, "requires": { "safer-buffer": ">= 2.1.2 < 3.0.0" @@ -13584,9 +13742,9 @@ } }, "stylehacks": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/stylehacks/-/stylehacks-5.0.0.tgz", - "integrity": "sha512-QOWm6XivDLb+fqffTZP8jrmPmPITVChl2KCY2R05nsCWwLi3VGhCdVc3IVGNwd1zzTt1jPd67zIKjpQfxzQZeA==", + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/stylehacks/-/stylehacks-5.0.1.tgz", + "integrity": "sha512-Es0rVnHIqbWzveU1b24kbw92HsebBepxfcqe5iix7t9j0PQqhs0IxXVXv0pY2Bxa08CgMkzD6OWql7kbGOuEdA==", "dev": true, "requires": { "browserslist": "^4.16.0", @@ -13961,20 +14119,17 @@ } }, "terser-webpack-plugin": { - "version": "4.2.3", - "resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-4.2.3.tgz", - "integrity": "sha512-jTgXh40RnvOrLQNgIkwEKnQ8rmHjHK4u+6UBEi+W+FPmvb+uo+chJXntKe7/3lW5mNysgSWD60KyesnhW8D6MQ==", + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-5.1.2.tgz", + "integrity": "sha512-6QhDaAiVHIQr5Ab3XUWZyDmrIPCHMiqJVljMF91YKyqwKkL5QHnYMkrMBy96v9Z7ev1hGhSEw1HQZc2p/s5Z8Q==", "dev": true, "requires": { - "cacache": "^15.0.5", - "find-cache-dir": "^3.3.1", - "jest-worker": "^26.5.0", - "p-limit": "^3.0.2", + "jest-worker": "^26.6.2", + "p-limit": "^3.1.0", "schema-utils": "^3.0.0", "serialize-javascript": "^5.0.1", "source-map": "^0.6.1", - "terser": "^5.3.4", - "webpack-sources": "^1.4.3" + "terser": "^5.7.0" }, "dependencies": { "ajv": { @@ -14490,9 +14645,9 @@ "dev": true }, "watchpack": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-2.1.1.tgz", - "integrity": "sha512-Oo7LXCmc1eE1AjyuSBmtC3+Wy4HcV8PxWh2kP6fOl8yTlNS7r0K9l1ao2lrrUza7V39Y3D/BbJgY8VeSlc5JKw==", + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-2.2.0.tgz", + "integrity": "sha512-up4YAn/XHgZHIxFBVCdlMiWDj6WaLKpwVeGQk2I5thdYxF/KmF0aaz6TfJZ/hfl1h/XlcDr7k1KH7ThDagpFaA==", "dev": true, "requires": { "glob-to-regexp": "^0.4.1", @@ -14590,15 +14745,6 @@ "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", "dev": true }, - "p-limit": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", - "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", - "dev": true, - "requires": { - "yocto-queue": "^0.1.0" - } - }, "schema-utils": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.0.0.tgz", @@ -14616,24 +14762,10 @@ "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", "dev": true }, - "terser-webpack-plugin": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-5.1.2.tgz", - "integrity": "sha512-6QhDaAiVHIQr5Ab3XUWZyDmrIPCHMiqJVljMF91YKyqwKkL5QHnYMkrMBy96v9Z7ev1hGhSEw1HQZc2p/s5Z8Q==", - "dev": true, - "requires": { - "jest-worker": "^26.6.2", - "p-limit": "^3.1.0", - "schema-utils": "^3.0.0", - "serialize-javascript": "^5.0.1", - "source-map": "^0.6.1", - "terser": "^5.7.0" - } - }, "webpack-sources": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/webpack-sources/-/webpack-sources-2.2.0.tgz", - "integrity": "sha512-bQsA24JLwcnWGArOKUxYKhX3Mz/nK1Xf6hxullKERyktjNMC4x8koOeaDNTA2fEJ09BdWLbM/iTW0ithREUP0w==", + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/webpack-sources/-/webpack-sources-2.3.0.tgz", + "integrity": "sha512-WyOdtwSvOML1kbgtXbTDnEW0jkJ7hZr/bDByIwszhWd/4XX1A3XMkrbFMsuH4+/MfLlZCUzlAdg4r7jaGKEIgQ==", "dev": true, "requires": { "source-list-map": "^2.0.1", diff --git a/package.json b/package.json index a79100db..8803d076 100644 --- a/package.json +++ b/package.json @@ -12,17 +12,17 @@ "e2e": "ng e2e" }, "dependencies": { - "@angular/animations": "12.0.0", - "@angular/cdk": "12.0.0", - "@angular/common": "12.0.0", - "@angular/compiler": "12.0.0", - "@angular/core": "12.0.0", - "@angular/forms": "12.0.0", - "@angular/material": "12.0.0", - "@angular/material-moment-adapter": "12.0.0", - "@angular/platform-browser": "12.0.0", - "@angular/platform-browser-dynamic": "12.0.0", - "@angular/router": "12.0.0", + "@angular/animations": "12.0.2", + "@angular/cdk": "12.0.2", + "@angular/common": "12.0.2", + "@angular/compiler": "12.0.2", + "@angular/core": "12.0.2", + "@angular/forms": "12.0.2", + "@angular/material": "12.0.2", + "@angular/material-moment-adapter": "12.0.2", + "@angular/platform-browser": "12.0.2", + "@angular/platform-browser-dynamic": "12.0.2", + "@angular/router": "12.0.2", "@fullcalendar/angular": "4.4.5-beta", "@fullcalendar/core": "4.4.2", "@fullcalendar/daygrid": "4.4.2", @@ -49,15 +49,15 @@ "zone.js": "0.11.4" }, "devDependencies": { - "@angular-devkit/build-angular": "12.0.0", + "@angular-devkit/build-angular": "12.0.2", "@angular-eslint/builder": "12.0.0", "@angular-eslint/eslint-plugin": "12.0.0", "@angular-eslint/eslint-plugin-template": "12.0.0", "@angular-eslint/schematics": "12.0.0", "@angular-eslint/template-parser": "12.0.0", - "@angular/cli": "12.0.0", - "@angular/compiler-cli": "12.0.0", - "@angular/language-service": "12.0.0", + "@angular/cli": "12.0.2", + "@angular/compiler-cli": "12.0.2", + "@angular/language-service": "12.0.2", "@tailwindcss/aspect-ratio": "0.2.0", "@tailwindcss/line-clamp": "0.2.0", "@tailwindcss/typography": "0.4.0", From b98cfc1d3723f1ce36bdd3a8ab5a02e4938a5c12 Mon Sep 17 00:00:00 2001 From: sercan Date: Mon, 31 May 2021 16:12:08 +0300 Subject: [PATCH 2/9] (Angular Material) Increased default MatDialog border radius to 16px for better consistency --- src/@fuse/styles/overrides/angular-material.scss | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/@fuse/styles/overrides/angular-material.scss b/src/@fuse/styles/overrides/angular-material.scss index dbac6f4a..96b7b261 100644 --- a/src/@fuse/styles/overrides/angular-material.scss +++ b/src/@fuse/styles/overrides/angular-material.scss @@ -410,6 +410,13 @@ font-weight: 500 !important; } +/* ----------------------------------------------------------------------------------------------------- */ +/* @ Dialog +/* ----------------------------------------------------------------------------------------------------- */ +.mat-dialog-container { + border-radius: 16px !important; +} + /* ----------------------------------------------------------------------------------------------------- */ /* @ Drawer /* ----------------------------------------------------------------------------------------------------- */ From f295fd9061c5dd126734a6256d36e9ce9ff588dd Mon Sep 17 00:00:00 2001 From: sercan Date: Mon, 31 May 2021 17:14:03 +0300 Subject: [PATCH 3/9] (fuse/autogrow) BREAKING: Removed fuseAutogrow in favor of matTextareaAutosize since all of its problems solved, use [matTextareaAutosize] without any vertical padding on the textarea itself. --- .../directives/autogrow/autogrow.directive.ts | 114 ------------------ .../directives/autogrow/autogrow.module.ts | 14 --- src/@fuse/directives/autogrow/index.ts | 1 - src/@fuse/directives/autogrow/public-api.ts | 2 - .../styles/overrides/angular-material.scss | 4 +- .../apps/calendar/calendar.component.html | 4 +- .../modules/admin/apps/chat/chat.module.ts | 2 - .../admin/apps/contacts/contacts.module.ts | 2 - .../contacts/details/details.component.html | 6 +- .../support/support.component.html | 7 +- .../apps/notes/details/details.component.html | 8 +- .../modules/admin/apps/notes/notes.module.ts | 2 - .../apps/tasks/details/details.component.html | 7 +- .../modules/admin/apps/tasks/tasks.module.ts | 2 - .../core-features/core-features.component.ts | 6 - .../core-features/core-features.module.ts | 2 - .../core-features/core-features.routing.ts | 7 +- .../autogrow/autogrow.component.html | 99 --------------- .../directives/autogrow/autogrow.component.ts | 30 ----- .../pages/profile/profile.component.html | 12 +- .../settings/account/account.component.html | 6 +- .../admin/pages/settings/settings.module.ts | 2 - .../admin/ui/cards/cards.component.html | 17 +-- .../ui/forms/fields/fields.component.html | 16 +-- .../admin/ui/forms/fields/fields.module.ts | 2 - 25 files changed, 44 insertions(+), 330 deletions(-) delete mode 100644 src/@fuse/directives/autogrow/autogrow.directive.ts delete mode 100644 src/@fuse/directives/autogrow/autogrow.module.ts delete mode 100644 src/@fuse/directives/autogrow/index.ts delete mode 100644 src/@fuse/directives/autogrow/public-api.ts delete mode 100644 src/app/modules/admin/docs/core-features/directives/autogrow/autogrow.component.html delete mode 100644 src/app/modules/admin/docs/core-features/directives/autogrow/autogrow.component.ts diff --git a/src/@fuse/directives/autogrow/autogrow.directive.ts b/src/@fuse/directives/autogrow/autogrow.directive.ts deleted file mode 100644 index 20624005..00000000 --- a/src/@fuse/directives/autogrow/autogrow.directive.ts +++ /dev/null @@ -1,114 +0,0 @@ -import { ChangeDetectorRef, Directive, ElementRef, HostBinding, HostListener, Input, NgZone, OnChanges, OnDestroy, OnInit, SimpleChanges } from '@angular/core'; -import { Subject } from 'rxjs'; - -@Directive({ - selector: 'textarea[fuseAutogrow]', - exportAs: 'fuseAutogrow' -}) -export class FuseAutogrowDirective implements OnChanges, OnInit, OnDestroy -{ - // eslint-disable-next-line @angular-eslint/no-input-rename - @Input('fuseAutogrowVerticalPadding') padding: number = 8; - @HostBinding('rows') private _rows: number = 1; - - private _height: string = 'auto'; - private _unsubscribeAll: Subject = new Subject(); - - /** - * Constructor - */ - constructor( - private _elementRef: ElementRef, - private _changeDetectorRef: ChangeDetectorRef, - private _ngZone: NgZone - ) - { - } - - // ----------------------------------------------------------------------------------------------------- - // @ Accessors - // ----------------------------------------------------------------------------------------------------- - - /** - * Host binding for component inline styles - */ - @HostBinding('style') get styleList(): any - { - return { - 'height' : this._height, - 'overflow': 'hidden', - 'resize' : 'none' - }; - } - - // ----------------------------------------------------------------------------------------------------- - // @ Decorated methods - // ----------------------------------------------------------------------------------------------------- - - /** - * Resize on 'input' and 'ngModelChange' events - * - * @private - */ - @HostListener('input') - @HostListener('ngModelChange') - private _resize(): void - { - // This doesn't need to trigger Angular's change detection by itself - this._ngZone.runOutsideAngular(() => { - - setTimeout(() => { - - // Set the height to 'auto' so we can correctly read the scrollHeight - this._height = 'auto'; - - // Detect the changes so the height is applied - this._changeDetectorRef.detectChanges(); - - // Get the scrollHeight and subtract the vertical padding - this._height = `${this._elementRef.nativeElement.scrollHeight - this.padding}px`; - - // Detect the changes one more time to apply the final height - this._changeDetectorRef.detectChanges(); - }); - }); - } - - // ----------------------------------------------------------------------------------------------------- - // @ Lifecycle hooks - // ----------------------------------------------------------------------------------------------------- - - /** - * On changes - * - * @param changes - */ - ngOnChanges(changes: SimpleChanges): void - { - // Padding - if ( 'fuseAutogrowVerticalPadding' in changes ) - { - // Resize - this._resize(); - } - } - - /** - * On init - */ - ngOnInit(): void - { - // Resize for the first time - this._resize(); - } - - /** - * On destroy - */ - ngOnDestroy(): void - { - // Unsubscribe from all subscriptions - this._unsubscribeAll.next(); - this._unsubscribeAll.complete(); - } -} diff --git a/src/@fuse/directives/autogrow/autogrow.module.ts b/src/@fuse/directives/autogrow/autogrow.module.ts deleted file mode 100644 index 15d08b86..00000000 --- a/src/@fuse/directives/autogrow/autogrow.module.ts +++ /dev/null @@ -1,14 +0,0 @@ -import { NgModule } from '@angular/core'; -import { FuseAutogrowDirective } from '@fuse/directives/autogrow/autogrow.directive'; - -@NgModule({ - declarations: [ - FuseAutogrowDirective - ], - exports : [ - FuseAutogrowDirective - ] -}) -export class FuseAutogrowModule -{ -} diff --git a/src/@fuse/directives/autogrow/index.ts b/src/@fuse/directives/autogrow/index.ts deleted file mode 100644 index c689e4bb..00000000 --- a/src/@fuse/directives/autogrow/index.ts +++ /dev/null @@ -1 +0,0 @@ -export * from '@fuse/directives/autogrow/public-api'; diff --git a/src/@fuse/directives/autogrow/public-api.ts b/src/@fuse/directives/autogrow/public-api.ts deleted file mode 100644 index 1bb75d2d..00000000 --- a/src/@fuse/directives/autogrow/public-api.ts +++ /dev/null @@ -1,2 +0,0 @@ -export * from '@fuse/directives/autogrow/autogrow.directive'; -export * from '@fuse/directives/autogrow/autogrow.module'; diff --git a/src/@fuse/styles/overrides/angular-material.scss b/src/@fuse/styles/overrides/angular-material.scss index 96b7b261..736a68fc 100644 --- a/src/@fuse/styles/overrides/angular-material.scss +++ b/src/@fuse/styles/overrides/angular-material.scss @@ -690,8 +690,8 @@ align-self: stretch; min-height: 36px; height: auto; - margin: 10px 0; - padding: 4px 6px 4px 0 !important; + margin: 14px 0; + padding: 0 6px 0 0; transform: none; } diff --git a/src/app/modules/admin/apps/calendar/calendar.component.html b/src/app/modules/admin/apps/calendar/calendar.component.html index 688384df..03d9a4b5 100644 --- a/src/app/modules/admin/apps/calendar/calendar.component.html +++ b/src/app/modules/admin/apps/calendar/calendar.component.html @@ -341,8 +341,8 @@ diff --git a/src/app/modules/admin/apps/chat/chat.module.ts b/src/app/modules/admin/apps/chat/chat.module.ts index d2ecdc80..ad612551 100644 --- a/src/app/modules/admin/apps/chat/chat.module.ts +++ b/src/app/modules/admin/apps/chat/chat.module.ts @@ -7,7 +7,6 @@ import { MatIconModule } from '@angular/material/icon'; import { MatInputModule } from '@angular/material/input'; import { MatMenuModule } from '@angular/material/menu'; import { MatSidenavModule } from '@angular/material/sidenav'; -import { FuseAutogrowModule } from '@fuse/directives/autogrow'; import { SharedModule } from 'app/shared/shared.module'; import { chatRoutes } from 'app/modules/admin/apps/chat/chat.routing'; import { ChatComponent } from 'app/modules/admin/apps/chat/chat.component'; @@ -35,7 +34,6 @@ import { ProfileComponent } from 'app/modules/admin/apps/chat/profile/profile.co MatInputModule, MatMenuModule, MatSidenavModule, - FuseAutogrowModule, SharedModule ] }) diff --git a/src/app/modules/admin/apps/contacts/contacts.module.ts b/src/app/modules/admin/apps/contacts/contacts.module.ts index bfbebc32..35bc0607 100644 --- a/src/app/modules/admin/apps/contacts/contacts.module.ts +++ b/src/app/modules/admin/apps/contacts/contacts.module.ts @@ -17,7 +17,6 @@ import { MatSidenavModule } from '@angular/material/sidenav'; import { MatTableModule } from '@angular/material/table'; import { MatTooltipModule } from '@angular/material/tooltip'; import * as moment from 'moment'; -import { FuseAutogrowModule } from '@fuse/directives/autogrow'; import { FuseFindByKeyPipeModule } from '@fuse/pipes/find-by-key'; import { SharedModule } from 'app/shared/shared.module'; import { contactsRoutes } from 'app/modules/admin/apps/contacts/contacts.routing'; @@ -49,7 +48,6 @@ import { ContactsListComponent } from 'app/modules/admin/apps/contacts/list/list MatSidenavModule, MatTableModule, MatTooltipModule, - FuseAutogrowModule, FuseFindByKeyPipeModule, SharedModule ], diff --git a/src/app/modules/admin/apps/contacts/details/details.component.html b/src/app/modules/admin/apps/contacts/details/details.component.html index 0d61995c..a2d130d4 100644 --- a/src/app/modules/admin/apps/contacts/details/details.component.html +++ b/src/app/modules/admin/apps/contacts/details/details.component.html @@ -598,11 +598,11 @@ [svgIcon]="'heroicons_solid:menu-alt-2'"> + [rows]="5" + [spellcheck]="false" + matTextareaAutosize> diff --git a/src/app/modules/admin/apps/help-center/support/support.component.html b/src/app/modules/admin/apps/help-center/support/support.component.html index 2c4d4cc6..328a3a16 100644 --- a/src/app/modules/admin/apps/help-center/support/support.component.html +++ b/src/app/modules/admin/apps/help-center/support/support.component.html @@ -74,11 +74,10 @@ + [required]="true" + [rows]="5" + matTextareaAutosize> Message Required diff --git a/src/app/modules/admin/apps/notes/details/details.component.html b/src/app/modules/admin/apps/notes/details/details.component.html index b2c6e5e1..363be7d8 100644 --- a/src/app/modules/admin/apps/notes/details/details.component.html +++ b/src/app/modules/admin/apps/notes/details/details.component.html @@ -27,13 +27,13 @@ (input)="updateNoteDetails(note)"> -
+
+ (input)="updateNoteDetails(note)" + matTextareaAutosize>
diff --git a/src/app/modules/admin/apps/notes/notes.module.ts b/src/app/modules/admin/apps/notes/notes.module.ts index 23aaf7d8..1f78ec92 100644 --- a/src/app/modules/admin/apps/notes/notes.module.ts +++ b/src/app/modules/admin/apps/notes/notes.module.ts @@ -9,7 +9,6 @@ import { MatInputModule } from '@angular/material/input'; import { MatMenuModule } from '@angular/material/menu'; import { MatRippleModule } from '@angular/material/core'; import { MatSidenavModule } from '@angular/material/sidenav'; -import { FuseAutogrowModule } from '@fuse/directives/autogrow'; import { FuseMasonryModule } from '@fuse/components/masonry'; import { SharedModule } from 'app/shared/shared.module'; import { NotesComponent } from 'app/modules/admin/apps/notes/notes.component'; @@ -36,7 +35,6 @@ import { notesRoutes } from 'app/modules/admin/apps/notes/notes.routing'; MatMenuModule, MatRippleModule, MatSidenavModule, - FuseAutogrowModule, FuseMasonryModule, SharedModule ] diff --git a/src/app/modules/admin/apps/tasks/details/details.component.html b/src/app/modules/admin/apps/tasks/details/details.component.html index 09ab4c8e..496667d6 100644 --- a/src/app/modules/admin/apps/tasks/details/details.component.html +++ b/src/app/modules/admin/apps/tasks/details/details.component.html @@ -66,9 +66,9 @@ {{task.type === 'task' ? 'Task title' : 'Section title'}}
@@ -323,11 +323,10 @@ Notes + [spellcheck]="false" + matTextareaAutosize> diff --git a/src/app/modules/admin/apps/tasks/tasks.module.ts b/src/app/modules/admin/apps/tasks/tasks.module.ts index b6a8e939..3004d4f1 100644 --- a/src/app/modules/admin/apps/tasks/tasks.module.ts +++ b/src/app/modules/admin/apps/tasks/tasks.module.ts @@ -18,7 +18,6 @@ import { MatSelectModule } from '@angular/material/select'; import { MatSidenavModule } from '@angular/material/sidenav'; import { MatTooltipModule } from '@angular/material/tooltip'; import * as moment from 'moment'; -import { FuseAutogrowModule } from '@fuse/directives/autogrow'; import { FuseFindByKeyPipeModule } from '@fuse/pipes/find-by-key'; import { SharedModule } from 'app/shared/shared.module'; import { tasksRoutes } from 'app/modules/admin/apps/tasks/tasks.routing'; @@ -51,7 +50,6 @@ import { TasksListComponent } from 'app/modules/admin/apps/tasks/list/list.compo MatSelectModule, MatSidenavModule, MatTooltipModule, - FuseAutogrowModule, FuseFindByKeyPipeModule, SharedModule ], diff --git a/src/app/modules/admin/docs/core-features/core-features.component.ts b/src/app/modules/admin/docs/core-features/core-features.component.ts index 7d0d10cd..44445d0d 100644 --- a/src/app/modules/admin/docs/core-features/core-features.component.ts +++ b/src/app/modules/admin/docs/core-features/core-features.component.ts @@ -96,12 +96,6 @@ export class CoreFeaturesComponent implements OnInit, OnDestroy title : 'Directives', type : 'group', children: [ - { - id : 'core-features.directives.autogrow', - title: 'Autogrow', - type : 'basic', - link : '/docs/core-features/directives/autogrow' - }, { id : 'core-features.directives.scrollbar', title: 'Scrollbar', diff --git a/src/app/modules/admin/docs/core-features/core-features.module.ts b/src/app/modules/admin/docs/core-features/core-features.module.ts index d927298f..1330895c 100644 --- a/src/app/modules/admin/docs/core-features/core-features.module.ts +++ b/src/app/modules/admin/docs/core-features/core-features.module.ts @@ -23,7 +23,6 @@ import { DrawerComponent } from 'app/modules/admin/docs/core-features/components import { HighlightComponent } from 'app/modules/admin/docs/core-features/components/highlight/highlight.component'; import { NavigationComponent } from 'app/modules/admin/docs/core-features/components/navigation/navigation.component'; import { MasonryComponent } from 'app/modules/admin/docs/core-features/components/masonry/masonry.component'; -import { AutogrowComponent } from 'app/modules/admin/docs/core-features/directives/autogrow/autogrow.component'; import { ScrollbarComponent } from 'app/modules/admin/docs/core-features/directives/scrollbar/scrollbar.component'; import { ScrollResetComponent } from 'app/modules/admin/docs/core-features/directives/scroll-reset/scroll-reset.component'; import { ConfigComponent } from 'app/modules/admin/docs/core-features/services/config/config.component'; @@ -44,7 +43,6 @@ import { coreFeaturesRoutes } from 'app/modules/admin/docs/core-features/core-fe HighlightComponent, MasonryComponent, NavigationComponent, - AutogrowComponent, ScrollbarComponent, ScrollResetComponent, ConfigComponent, diff --git a/src/app/modules/admin/docs/core-features/core-features.routing.ts b/src/app/modules/admin/docs/core-features/core-features.routing.ts index 0ab76c3f..350932b7 100644 --- a/src/app/modules/admin/docs/core-features/core-features.routing.ts +++ b/src/app/modules/admin/docs/core-features/core-features.routing.ts @@ -8,7 +8,6 @@ import { DrawerComponent } from 'app/modules/admin/docs/core-features/components import { HighlightComponent } from 'app/modules/admin/docs/core-features/components/highlight/highlight.component'; import { MasonryComponent } from 'app/modules/admin/docs/core-features/components/masonry/masonry.component'; import { NavigationComponent } from 'app/modules/admin/docs/core-features/components/navigation/navigation.component'; -import { AutogrowComponent } from 'app/modules/admin/docs/core-features/directives/autogrow/autogrow.component'; import { ScrollbarComponent } from 'app/modules/admin/docs/core-features/directives/scrollbar/scrollbar.component'; import { ScrollResetComponent } from 'app/modules/admin/docs/core-features/directives/scroll-reset/scroll-reset.component'; import { ConfigComponent } from 'app/modules/admin/docs/core-features/services/config/config.component'; @@ -80,11 +79,7 @@ export const coreFeaturesRoutes: Route[] = [ { path : '', pathMatch : 'full', - redirectTo: 'autogrow' - }, - { - path : 'autogrow', - component: AutogrowComponent + redirectTo: 'scrollbar' }, { path : 'scrollbar', diff --git a/src/app/modules/admin/docs/core-features/directives/autogrow/autogrow.component.html b/src/app/modules/admin/docs/core-features/directives/autogrow/autogrow.component.html deleted file mode 100644 index 509dee8b..00000000 --- a/src/app/modules/admin/docs/core-features/directives/autogrow/autogrow.component.html +++ /dev/null @@ -1,99 +0,0 @@ -
- - -
-
- -
- - -
- - Directives -
-
- -
-

- Autogrow -

-
-
- -
- -
- -

- fuseAutogrow is a <textarea> directive to make them automatically grow depending on their content. It's an alternative for - Angular Material's cdkTextareaAutosize directive with a more native and lightweight approach. -

-

- Exported as: fuseAutogrow -

- -

Module

- - -

Usage

-

- Here's the basic usage of the fuseAutogrow: -

- - - - -

Properties

-
- - - - - - - - - - - - - - - -
NameDescriptionDefault
-
@Input()
-
fuseAutogrowVerticalPadding: number
-
- Padding of the textarea. Must be inline with textarea's padding style. - - 8 -
-
- -
- -
diff --git a/src/app/modules/admin/docs/core-features/directives/autogrow/autogrow.component.ts b/src/app/modules/admin/docs/core-features/directives/autogrow/autogrow.component.ts deleted file mode 100644 index bfa6d789..00000000 --- a/src/app/modules/admin/docs/core-features/directives/autogrow/autogrow.component.ts +++ /dev/null @@ -1,30 +0,0 @@ -import { Component } from '@angular/core'; -import { CoreFeaturesComponent } from 'app/modules/admin/docs/core-features/core-features.component'; - -@Component({ - selector : 'autogrow', - templateUrl: './autogrow.component.html', - styles : [''] -}) -export class AutogrowComponent -{ - /** - * Constructor - */ - constructor(private _coreFeaturesComponent: CoreFeaturesComponent) - { - } - - // ----------------------------------------------------------------------------------------------------- - // @ Public methods - // ----------------------------------------------------------------------------------------------------- - - /** - * Toggle the drawer - */ - toggleDrawer(): void - { - // Toggle the drawer - this._coreFeaturesComponent.matDrawer.toggle(); - } -} diff --git a/src/app/modules/admin/pages/profile/profile.component.html b/src/app/modules/admin/pages/profile/profile.component.html index bc5c1328..d818416c 100644 --- a/src/app/modules/admin/pages/profile/profile.component.html +++ b/src/app/modules/admin/pages/profile/profile.component.html @@ -541,9 +541,9 @@ + [placeholder]="'What\'s on your mind?'" + [rows]="3" + matTextareaAutosize>
@@ -804,9 +804,9 @@ + [placeholder]="'Write a comment...'" + [rows]="3" + matTextareaAutosize>
diff --git a/src/app/modules/admin/pages/settings/account/account.component.html b/src/app/modules/admin/pages/settings/account/account.component.html index e500a3e7..e15b6891 100644 --- a/src/app/modules/admin/pages/settings/account/account.component.html +++ b/src/app/modules/admin/pages/settings/account/account.component.html @@ -67,10 +67,10 @@ About + matTextareaAutosize + [matAutosizeMinRows]="5">
Brief description for your profile. Basic HTML and Emoji are allowed.
diff --git a/src/app/modules/admin/pages/settings/settings.module.ts b/src/app/modules/admin/pages/settings/settings.module.ts index 2040765f..f469c58e 100644 --- a/src/app/modules/admin/pages/settings/settings.module.ts +++ b/src/app/modules/admin/pages/settings/settings.module.ts @@ -9,7 +9,6 @@ import { MatSelectModule } from '@angular/material/select'; import { MatSlideToggleModule } from '@angular/material/slide-toggle'; import { MatSidenavModule } from '@angular/material/sidenav'; import { FuseAlertModule } from '@fuse/components/alert'; -import { FuseAutogrowModule } from '@fuse/directives/autogrow'; import { SharedModule } from 'app/shared/shared.module'; import { SettingsComponent } from 'app/modules/admin/pages/settings/settings.component'; import { SettingsAccountComponent } from 'app/modules/admin/pages/settings/account/account.component'; @@ -39,7 +38,6 @@ import { settingsRoutes } from 'app/modules/admin/pages/settings/settings.routin MatSidenavModule, MatSlideToggleModule, FuseAlertModule, - FuseAutogrowModule, SharedModule ] }) diff --git a/src/app/modules/admin/ui/cards/cards.component.html b/src/app/modules/admin/ui/cards/cards.component.html index fb5fd024..642dbc30 100644 --- a/src/app/modules/admin/ui/cards/cards.component.html +++ b/src/app/modules/admin/ui/cards/cards.component.html @@ -2176,9 +2176,9 @@ + [placeholder]="'What\'s on your mind?'" + [rows]="3" + matTextareaAutosize>
@@ -2440,9 +2440,9 @@ + [rows]="3" + [placeholder]="'Write a comment...'" + matTextareaAutosize>
@@ -4012,8 +4012,9 @@ + [placeholder]="'Write a comment...'" + matTextareaAutosize + [rows]="3">
diff --git a/src/app/modules/admin/ui/forms/fields/fields.component.html b/src/app/modules/admin/ui/forms/fields/fields.component.html index e2e54c5b..87835287 100644 --- a/src/app/modules/admin/ui/forms/fields/fields.component.html +++ b/src/app/modules/admin/ui/forms/fields/fields.component.html @@ -70,8 +70,8 @@ Address + [rows]="3" + matTextareaAutosize> Textarea with autosize + matTextareaAutosize>
@@ -367,7 +367,7 @@ Textarea with autosize, prefix & suffix + matTextareaAutosize> + [placeholder]="'Textarea with autosize'" + matTextareaAutosize>
@@ -635,8 +635,8 @@ class="fuse-mat-textarea flex-auto"> + [placeholder]="'Textarea with autosize, prefix & suffix'" + matTextareaAutosize> Date: Wed, 2 Jun 2021 11:41:47 +0300 Subject: [PATCH 4/9] (apps/ecommerce) Small tweaks (apps/mailbox) Small tweaks --- .../apps/ecommerce/inventory/list/inventory.component.ts | 6 +++--- .../admin/apps/mailbox/compose/compose.component.html | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/app/modules/admin/apps/ecommerce/inventory/list/inventory.component.ts b/src/app/modules/admin/apps/ecommerce/inventory/list/inventory.component.ts index df0ec284..6912826d 100644 --- a/src/app/modules/admin/apps/ecommerce/inventory/list/inventory.component.ts +++ b/src/app/modules/admin/apps/ecommerce/inventory/list/inventory.component.ts @@ -332,15 +332,15 @@ export class InventoryListComponent implements OnInit, AfterViewInit, OnDestroy const tag = this.filteredTags[0]; const isTagApplied = this.selectedProduct.tags.find(id => id === tag.id); - // If the found tag is already applied to the contact... + // If the found tag is already applied to the product... if ( isTagApplied ) { - // Remove the tag from the contact + // Remove the tag from the product this.removeTagFromProduct(tag); } else { - // Otherwise add the tag to the contact + // Otherwise add the tag to the product this.addTagToProduct(tag); } } diff --git a/src/app/modules/admin/apps/mailbox/compose/compose.component.html b/src/app/modules/admin/apps/mailbox/compose/compose.component.html index 6179e661..c9495448 100644 --- a/src/app/modules/admin/apps/mailbox/compose/compose.component.html +++ b/src/app/modules/admin/apps/mailbox/compose/compose.component.html @@ -2,7 +2,7 @@
-
New Message
+
New Message
+
+
+ +
+
+ + +
+
+
+
diff --git a/src/app/modules/admin/apps/scrumboard/board/add-card/add-card.component.ts b/src/app/modules/admin/apps/scrumboard/board/add-card/add-card.component.ts new file mode 100644 index 00000000..3c45018e --- /dev/null +++ b/src/app/modules/admin/apps/scrumboard/board/add-card/add-card.component.ts @@ -0,0 +1,95 @@ +import { ChangeDetectionStrategy, ChangeDetectorRef, Component, ElementRef, EventEmitter, Input, OnInit, Output, ViewChild, ViewEncapsulation } from '@angular/core'; +import { CdkTextareaAutosize } from '@angular/cdk/text-field'; +import { FormBuilder, FormGroup } from '@angular/forms'; + +@Component({ + selector : 'scrumboard-board-add-card', + templateUrl : './add-card.component.html', + encapsulation : ViewEncapsulation.None, + changeDetection: ChangeDetectionStrategy.OnPush +}) +export class ScrumboardBoardAddCardComponent implements OnInit +{ + @ViewChild('titleInput') titleInput: ElementRef; + @ViewChild('titleAutosize') titleAutosize: CdkTextareaAutosize; + @Input() buttonTitle: string = 'Add a card'; + @Output() readonly saved: EventEmitter = new EventEmitter(); + + form: FormGroup; + formVisible: boolean = false; + + /** + * Constructor + */ + constructor( + private _changeDetectorRef: ChangeDetectorRef, + private _formBuilder: FormBuilder + ) + { + } + + // ----------------------------------------------------------------------------------------------------- + // @ Lifecycle hooks + // ----------------------------------------------------------------------------------------------------- + + /** + * On init + */ + ngOnInit(): void + { + // Initialize the new list form + this.form = this._formBuilder.group({ + title: [''] + }); + } + + // ----------------------------------------------------------------------------------------------------- + // @ Public methods + // ----------------------------------------------------------------------------------------------------- + + /** + * Save + */ + save(): void + { + // Get the new list title + const title = this.form.get('title').value; + + // Return, if the title is empty + if ( !title || title.trim() === '' ) + { + return; + } + + // Execute the observable + this.saved.next(title.trim()); + + // Clear the new list title and hide the form + this.formVisible = false; + this.form.get('title').setValue(''); + + // Reset the size of the textarea + setTimeout(() => { + this.titleInput.nativeElement.value = ''; + this.titleAutosize.reset(); + }); + + // Mark for check + this._changeDetectorRef.markForCheck(); + } + + /** + * Toggle the visibility of the form + */ + toggleFormVisibility(): void + { + // Toggle the visibility + this.formVisible = !this.formVisible; + + // If the form becomes visible, focus on the title field + if ( this.formVisible ) + { + this.titleInput.nativeElement.focus(); + } + } +} diff --git a/src/app/modules/admin/apps/scrumboard/board/add-list/add-list.component.html b/src/app/modules/admin/apps/scrumboard/board/add-list/add-list.component.html new file mode 100644 index 00000000..13940db4 --- /dev/null +++ b/src/app/modules/admin/apps/scrumboard/board/add-list/add-list.component.html @@ -0,0 +1,48 @@ +
+
+ +
+ +
+ + +
+
+
+
diff --git a/src/app/modules/admin/apps/scrumboard/board/add-list/add-list.component.ts b/src/app/modules/admin/apps/scrumboard/board/add-list/add-list.component.ts new file mode 100644 index 00000000..b55aaceb --- /dev/null +++ b/src/app/modules/admin/apps/scrumboard/board/add-list/add-list.component.ts @@ -0,0 +1,87 @@ +import { ChangeDetectionStrategy, ChangeDetectorRef, Component, ElementRef, EventEmitter, Input, OnInit, Output, ViewChild, ViewEncapsulation } from '@angular/core'; +import { FormBuilder, FormGroup } from '@angular/forms'; + +@Component({ + selector : 'scrumboard-board-add-list', + templateUrl : './add-list.component.html', + encapsulation : ViewEncapsulation.None, + changeDetection: ChangeDetectionStrategy.OnPush +}) +export class ScrumboardBoardAddListComponent implements OnInit +{ + @ViewChild('titleInput') titleInput: ElementRef; + @Input() buttonTitle: string = 'Add a list'; + @Output() readonly saved: EventEmitter = new EventEmitter(); + + form: FormGroup; + formVisible: boolean = false; + + /** + * Constructor + */ + constructor( + private _changeDetectorRef: ChangeDetectorRef, + private _formBuilder: FormBuilder + ) + { + } + + // ----------------------------------------------------------------------------------------------------- + // @ Lifecycle hooks + // ----------------------------------------------------------------------------------------------------- + + /** + * On init + */ + ngOnInit(): void + { + // Initialize the new list form + this.form = this._formBuilder.group({ + title: [''] + }); + } + + // ----------------------------------------------------------------------------------------------------- + // @ Public methods + // ----------------------------------------------------------------------------------------------------- + + /** + * Save + */ + save(): void + { + // Get the new list title + const title = this.form.get('title').value; + + // Return, if the title is empty + if ( !title || title.trim() === '' ) + { + return; + } + + // Execute the observable + this.saved.next(title.trim()); + + // Clear the new list title and hide the form + this.form.get('title').setValue(''); + this.formVisible = false; + + // Mark for check + this._changeDetectorRef.markForCheck(); + } + + /** + * Toggle the visibility of the form + */ + toggleFormVisibility(): void + { + // Toggle the visibility + this.formVisible = !this.formVisible; + + // If the form becomes visible, focus on the title field + if ( this.formVisible ) + { + this.titleInput.nativeElement.focus(); + } + } +} diff --git a/src/app/modules/admin/apps/scrumboard/board/board.component.html b/src/app/modules/admin/apps/scrumboard/board/board.component.html new file mode 100644 index 00000000..e212afb3 --- /dev/null +++ b/src/app/modules/admin/apps/scrumboard/board/board.component.html @@ -0,0 +1,182 @@ +
+ + +
+ +
+

+ {{board.title}} +

+
+ +
+ + + Boards + + +
+
+ + +
+ + +
+ + +
+ + + +
+ +
+
+ +
+
+ {{list.cards.length}} +
+
+ + + + + +
+
+ + + +
+
+ + + + + +
+ +
+ +
+ +
+ + + diff --git a/src/app/modules/admin/apps/scrumboard/board/board.component.scss b/src/app/modules/admin/apps/scrumboard/board/board.component.scss new file mode 100644 index 00000000..97427056 --- /dev/null +++ b/src/app/modules/admin/apps/scrumboard/board/board.component.scss @@ -0,0 +1,15 @@ +.cdk-drag-preview { + @apply shadow-2xl; +} + +.cdk-drag-placeholder { + opacity: 0; +} + +.cdk-drag-animating { + transition: transform 250ms cubic-bezier(0, 0, 0.2, 1); +} + +.cdk-drop-list-dragging div:not(.cdk-drag-placeholder) { + transition: transform 250ms cubic-bezier(0, 0, 0.2, 1); +} diff --git a/src/app/modules/admin/apps/scrumboard/board/board.component.ts b/src/app/modules/admin/apps/scrumboard/board/board.component.ts new file mode 100644 index 00000000..15d22a3b --- /dev/null +++ b/src/app/modules/admin/apps/scrumboard/board/board.component.ts @@ -0,0 +1,298 @@ +import { ChangeDetectionStrategy, ChangeDetectorRef, Component, OnDestroy, OnInit, ViewEncapsulation } from '@angular/core'; +import { FormBuilder, FormGroup } from '@angular/forms'; +import { CdkDragDrop, moveItemInArray, transferArrayItem } from '@angular/cdk/drag-drop'; +import { Subject } from 'rxjs'; +import { takeUntil } from 'rxjs/operators'; +import { ScrumboardService } from 'app/modules/admin/apps/scrumboard/scrumboard.service'; +import { Board, Card, List } from 'app/modules/admin/apps/scrumboard/scrumboard.models'; +import * as moment from 'moment'; + +@Component({ + selector : 'scrumboard-board', + templateUrl : './board.component.html', + styleUrls : ['./board.component.scss'], + encapsulation : ViewEncapsulation.None, + changeDetection: ChangeDetectionStrategy.OnPush +}) +export class ScrumboardBoardComponent implements OnInit, OnDestroy +{ + board: Board; + listTitleForm: FormGroup; + + // Private + private readonly _positionStep: number = 65536; + private readonly _maxListCount: number = 200; + private readonly _maxPosition: number = this._positionStep * 500; + private _unsubscribeAll: Subject = new Subject(); + + /** + * Constructor + */ + constructor( + private _changeDetectorRef: ChangeDetectorRef, + private _formBuilder: FormBuilder, + private _scrumboardService: ScrumboardService + ) + { + } + + // ----------------------------------------------------------------------------------------------------- + // @ Lifecycle hooks + // ----------------------------------------------------------------------------------------------------- + + /** + * On init + */ + ngOnInit(): void + { + // Initialize the list title form + this.listTitleForm = this._formBuilder.group({ + title: [''] + }); + + // Get the board + this._scrumboardService.board$ + .pipe(takeUntil(this._unsubscribeAll)) + .subscribe((board: Board) => { + this.board = {...board}; + + // Mark for check + this._changeDetectorRef.markForCheck(); + }); + } + + /** + * On destroy + */ + ngOnDestroy(): void + { + // Unsubscribe from all subscriptions + this._unsubscribeAll.next(); + this._unsubscribeAll.complete(); + } + + // ----------------------------------------------------------------------------------------------------- + // @ Public methods + // ----------------------------------------------------------------------------------------------------- + + /** + * Focus on the given element to start editing the list title + * + * @param listTitleInput + */ + renameList(listTitleInput: HTMLElement): void + { + // Use timeout so it can wait for menu to close + setTimeout(() => { + listTitleInput.focus(); + }); + } + + /** + * Add new list + * + * @param title + */ + addList(title: string): void + { + // Limit the max list count + if ( this.board.lists.length >= this._maxListCount ) + { + return; + } + + // Create a new list model + const list = new List({ + boardId : this.board.id, + position: this.board.lists.length ? this.board.lists[this.board.lists.length - 1].position + this._positionStep : this._positionStep, + title : title + }); + + // Save the list + this._scrumboardService.createList(list).subscribe(); + } + + /** + * Update the list title + * + * @param event + * @param list + */ + updateListTitle(event: any, list: List): void + { + // Get the target element + const element: HTMLInputElement = event.target; + + // Get the new title + const newTitle = element.value; + + // If the title is empty... + if ( !newTitle || newTitle.trim() === '' ) + { + // Reset to original title and return + element.value = list.title; + return; + } + + // Update the list title and element value + list.title = element.value = newTitle.trim(); + + // Update the list + this._scrumboardService.updateList(list).subscribe(); + } + + /** + * Delete the list + * + * @param id + */ + deleteList(id): void + { + // Delete the list + this._scrumboardService.deleteList(id).subscribe(); + } + + /** + * Add new card + */ + addCard(list: List, title: string): void + { + // Create a new card model + const card = new Card({ + boardId : this.board.id, + listId : list.id, + position: list.cards.length ? list.cards[list.cards.length - 1].position + this._positionStep : this._positionStep, + title : title + }); + + // Save the card + this._scrumboardService.createCard(card).subscribe(); + } + + /** + * List dropped + * + * @param event + */ + listDropped(event: CdkDragDrop): void + { + // Move the item + moveItemInArray(event.container.data, event.previousIndex, event.currentIndex); + + // Calculate the positions + const updated = this._calculatePositions(event); + + // Update the lists + this._scrumboardService.updateLists(updated).subscribe(); + } + + /** + * Card dropped + * + * @param event + */ + cardDropped(event: CdkDragDrop): void + { + // Move or transfer the item + if ( event.previousContainer === event.container ) + { + // Move the item + moveItemInArray(event.container.data, event.previousIndex, event.currentIndex); + } + else + { + // Transfer the item + transferArrayItem(event.previousContainer.data, event.container.data, event.previousIndex, event.currentIndex); + + // Update the card's list it + event.container.data[event.currentIndex].listId = event.container.id; + } + + // Calculate the positions + const updated = this._calculatePositions(event); + + // Update the cards + this._scrumboardService.updateCards(updated).subscribe(); + } + + /** + * Check if the given ISO_8601 date string is overdue + * + * @param date + */ + isOverdue(date: string): boolean + { + return moment(date, moment.ISO_8601).isBefore(moment(), 'days'); + } + + /** + * Track by function for ngFor loops + * + * @param index + * @param item + */ + trackByFn(index: number, item: any): any + { + return item.id || index; + } + + // ----------------------------------------------------------------------------------------------------- + // @ Private methods + // ----------------------------------------------------------------------------------------------------- + + /** + * Calculate and set item positions + * from given CdkDragDrop event + * + * @param event + * @private + */ + private _calculatePositions(event: CdkDragDrop): any[] + { + // Get the items + let items = event.container.data; + const currentItem = items[event.currentIndex]; + const prevItem = items[event.currentIndex - 1] || null; + const nextItem = items[event.currentIndex + 1] || null; + + // If the item moved to the top... + if ( !prevItem ) + { + // If the item moved to an empty container + if ( !nextItem ) + { + currentItem.position = this._positionStep; + } + else + { + currentItem.position = nextItem.position / 2; + } + } + // If the item moved to the bottom... + else if ( !nextItem ) + { + currentItem.position = prevItem.position + this._positionStep; + } + // If the item moved in between other items... + else + { + currentItem.position = (prevItem.position + nextItem.position) / 2; + } + + // Check if all item positions need to be updated + if ( !Number.isInteger(currentItem.position) || currentItem.position >= this._maxPosition ) + { + // Re-calculate all orders + items = items.map((value, index) => { + value.position = (index + 1) * this._positionStep; + return value; + }); + + // Return items + return items; + } + + // Return currentItem + return [currentItem]; + } +} diff --git a/src/app/modules/admin/apps/scrumboard/boards/boards.component.html b/src/app/modules/admin/apps/scrumboard/boards/boards.component.html new file mode 100644 index 00000000..c26bc342 --- /dev/null +++ b/src/app/modules/admin/apps/scrumboard/boards/boards.component.html @@ -0,0 +1,66 @@ + + + diff --git a/src/app/modules/admin/apps/scrumboard/boards/boards.component.ts b/src/app/modules/admin/apps/scrumboard/boards/boards.component.ts new file mode 100644 index 00000000..c4329077 --- /dev/null +++ b/src/app/modules/admin/apps/scrumboard/boards/boards.component.ts @@ -0,0 +1,85 @@ +import { ChangeDetectionStrategy, ChangeDetectorRef, Component, OnDestroy, OnInit, ViewEncapsulation } from '@angular/core'; +import { Subject } from 'rxjs'; +import { takeUntil } from 'rxjs/operators'; +import * as moment from 'moment'; +import { Board } from 'app/modules/admin/apps/scrumboard/scrumboard.models'; +import { ScrumboardService } from 'app/modules/admin/apps/scrumboard/scrumboard.service'; + +@Component({ + selector : 'scrumboard-boards', + templateUrl : './boards.component.html', + encapsulation : ViewEncapsulation.None, + changeDetection: ChangeDetectionStrategy.OnPush +}) +export class ScrumboardBoardsComponent implements OnInit, OnDestroy +{ + boards: Board[]; + + // Private + private _unsubscribeAll: Subject = new Subject(); + + /** + * Constructor + */ + constructor( + private _changeDetectorRef: ChangeDetectorRef, + private _scrumboardService: ScrumboardService + ) + { + } + + // ----------------------------------------------------------------------------------------------------- + // @ Lifecycle hooks + // ----------------------------------------------------------------------------------------------------- + + /** + * On init + */ + ngOnInit(): void + { + // Get the boards + this._scrumboardService.boards$ + .pipe(takeUntil(this._unsubscribeAll)) + .subscribe((boards: Board[]) => { + this.boards = boards; + + // Mark for check + this._changeDetectorRef.markForCheck(); + }); + } + + /** + * On destroy + */ + ngOnDestroy(): void + { + // Unsubscribe from all subscriptions + this._unsubscribeAll.next(); + this._unsubscribeAll.complete(); + } + + // ----------------------------------------------------------------------------------------------------- + // @ Public methods + // ----------------------------------------------------------------------------------------------------- + + /** + * Format the given ISO_8601 date as a relative date + * + * @param date + */ + formatDateAsRelative(date: string): string + { + return moment(date, moment.ISO_8601).fromNow(); + } + + /** + * Track by function for ngFor loops + * + * @param index + * @param item + */ + trackByFn(index: number, item: any): any + { + return item.id || index; + } +} diff --git a/src/app/modules/admin/apps/scrumboard/card/card.component.html b/src/app/modules/admin/apps/scrumboard/card/card.component.html new file mode 100644 index 00000000..15ccfcf0 --- /dev/null +++ b/src/app/modules/admin/apps/scrumboard/card/card.component.html @@ -0,0 +1 @@ +SCRUMBOARD -> BOARDS -> LIST -> CARD diff --git a/src/app/modules/admin/apps/scrumboard/card/card.component.ts b/src/app/modules/admin/apps/scrumboard/card/card.component.ts new file mode 100644 index 00000000..db9fe147 --- /dev/null +++ b/src/app/modules/admin/apps/scrumboard/card/card.component.ts @@ -0,0 +1,43 @@ +import { ChangeDetectionStrategy, Component, OnInit, ViewEncapsulation } from '@angular/core'; +import { MatDialog } from '@angular/material/dialog'; +import { ScrumboardCardDetailsComponent } from 'app/modules/admin/apps/scrumboard/card/details/details.component'; +import { ActivatedRoute, Router } from '@angular/router'; + +@Component({ + selector : 'scrumboard-card', + templateUrl : './card.component.html', + encapsulation : ViewEncapsulation.None, + changeDetection: ChangeDetectionStrategy.OnPush +}) +export class ScrumboardCardComponent implements OnInit +{ + /** + * Constructor + */ + constructor( + private _activatedRoute: ActivatedRoute, + private _matDialog: MatDialog, + private _router: Router + ) + { + } + + // ----------------------------------------------------------------------------------------------------- + // @ Lifecycle hooks + // ----------------------------------------------------------------------------------------------------- + + /** + * On init + */ + ngOnInit(): void + { + // Launch the modal + this._matDialog.open(ScrumboardCardDetailsComponent, {autoFocus: false}) + .afterClosed() + .subscribe(() => { + + // Go up twice because card routes are setup like this; "card/CARD_ID" + this._router.navigate(['./../..'], {relativeTo: this._activatedRoute}); + }); + } +} diff --git a/src/app/modules/admin/apps/scrumboard/card/details/details.component.html b/src/app/modules/admin/apps/scrumboard/card/details/details.component.html new file mode 100644 index 00000000..d5c3f9c6 --- /dev/null +++ b/src/app/modules/admin/apps/scrumboard/card/details/details.component.html @@ -0,0 +1,122 @@ +
+ + +
+
Card
+ +
+ + +
+ + + + Title + + + + + + Description + + + + +
+
Due date
+
+ + + {{card.dueDate | date:'longDate'}} + Not set + + +
+
+ + +
+
Labels
+
+ +
+
+ + +
+
+ +
+ + + + {{label.title}} + + +
+
+
+ +
+
diff --git a/src/app/modules/admin/apps/scrumboard/card/details/details.component.ts b/src/app/modules/admin/apps/scrumboard/card/details/details.component.ts new file mode 100644 index 00000000..6d5229c3 --- /dev/null +++ b/src/app/modules/admin/apps/scrumboard/card/details/details.component.ts @@ -0,0 +1,286 @@ +import { ChangeDetectionStrategy, ChangeDetectorRef, Component, ElementRef, OnDestroy, OnInit, ViewChild, ViewEncapsulation } from '@angular/core'; +import { FormBuilder, FormGroup, Validators } from '@angular/forms'; +import { MatCheckboxChange } from '@angular/material/checkbox'; +import { MatDialogRef } from '@angular/material/dialog'; +import { Subject } from 'rxjs'; +import { debounceTime, takeUntil, tap } from 'rxjs/operators'; +import * as moment from 'moment'; +import { assign } from 'lodash-es'; +import { ScrumboardService } from 'app/modules/admin/apps/scrumboard/scrumboard.service'; +import { Board, Card, Label } from 'app/modules/admin/apps/scrumboard/scrumboard.models'; + +@Component({ + selector : 'scrumboard-card-details', + templateUrl : './details.component.html', + encapsulation : ViewEncapsulation.None, + changeDetection: ChangeDetectionStrategy.OnPush +}) +export class ScrumboardCardDetailsComponent implements OnInit, OnDestroy +{ + @ViewChild('labelInput') labelInput: ElementRef; + board: Board; + card: Card; + cardForm: FormGroup; + labels: Label[]; + filteredLabels: Label[]; + + // Private + private _unsubscribeAll: Subject = new Subject(); + + /** + * Constructor + */ + constructor( + public matDialogRef: MatDialogRef, + private _changeDetectorRef: ChangeDetectorRef, + private _formBuilder: FormBuilder, + private _scrumboardService: ScrumboardService + ) + { + } + + // ----------------------------------------------------------------------------------------------------- + // @ Lifecycle hooks + // ----------------------------------------------------------------------------------------------------- + + /** + * On init + */ + ngOnInit(): void + { + // Get the board + this._scrumboardService.board$ + .pipe(takeUntil(this._unsubscribeAll)) + .subscribe((board) => { + + // Board data + this.board = board; + + // Get the labels + this.labels = this.filteredLabels = board.labels; + }); + + // Get the card details + this._scrumboardService.card$ + .pipe(takeUntil(this._unsubscribeAll)) + .subscribe((card) => { + this.card = card; + }); + + // Prepare the card form + this.cardForm = this._formBuilder.group({ + id : [''], + title : ['', Validators.required], + description: [''], + labels : [[]], + dueDate : [null] + }); + + // Fill the form + this.cardForm.setValue({ + id : this.card.id, + title : this.card.title, + description: this.card.description, + labels : this.card.labels, + dueDate : this.card.dueDate + }); + + // Update card when there is a value change on the card form + this.cardForm.valueChanges + .pipe( + tap((value) => { + + // Update the card object + this.card = assign(this.card, value); + }), + debounceTime(300), + takeUntil(this._unsubscribeAll) + ) + .subscribe((value) => { + + // Update the card on the server + this._scrumboardService.updateCard(value.id, value).subscribe(); + + // Mark for check + this._changeDetectorRef.markForCheck(); + }); + } + + /** + * On destroy + */ + ngOnDestroy(): void + { + // Unsubscribe from all subscriptions + this._unsubscribeAll.next(); + this._unsubscribeAll.complete(); + } + + // ----------------------------------------------------------------------------------------------------- + // @ Public methods + // ----------------------------------------------------------------------------------------------------- + + /** + * Return whether the card has the given label + * + * @param label + */ + hasLabel(label: Label): boolean + { + return !!this.card.labels.find(cardLabel => cardLabel.id === label.id); + } + + /** + * Filter labels + * + * @param event + */ + filterLabels(event): void + { + // Get the value + const value = event.target.value.toLowerCase(); + + // Filter the labels + this.filteredLabels = this.labels.filter(label => label.title.toLowerCase().includes(value)); + } + + /** + * Filter labels input key down event + * + * @param event + */ + filterLabelsInputKeyDown(event): void + { + // Return if the pressed key is not 'Enter' + if ( event.key !== 'Enter' ) + { + return; + } + + // If there is no label available... + if ( this.filteredLabels.length === 0 ) + { + // Return + return; + } + + // If there is a label... + const label = this.filteredLabels[0]; + const isLabelApplied = this.card.labels.find(cardLabel => cardLabel.id === label.id); + + // If the found label is already applied to the card... + if ( isLabelApplied ) + { + // Remove the label from the card + this.removeLabelFromCard(label); + } + else + { + // Otherwise add the label to the card + this.addLabelToCard(label); + } + } + + /** + * Toggle card label + * + * @param label + * @param change + */ + toggleProductTag(label: Label, change: MatCheckboxChange): void + { + if ( change.checked ) + { + this.addLabelToCard(label); + } + else + { + this.removeLabelFromCard(label); + } + } + + /** + * Add label to the card + * + * @param label + */ + addLabelToCard(label: Label): void + { + // Add the label + this.card.labels.unshift(label); + + // Update the card form data + this.cardForm.get('labels').patchValue(this.card.labels); + + // Mark for check + this._changeDetectorRef.markForCheck(); + } + + /** + * Remove label from the card + * + * @param label + */ + removeLabelFromCard(label: Label): void + { + // Remove the label + this.card.labels.splice(this.card.labels.findIndex(cardLabel => cardLabel.id === label.id), 1); + + // Update the card form data + this.cardForm.get('labels').patchValue(this.card.labels); + + // Mark for check + this._changeDetectorRef.markForCheck(); + } + + /** + * Check if the given date is overdue + */ + isOverdue(date: string): boolean + { + return moment(date, moment.ISO_8601).isBefore(moment(), 'days'); + } + + /** + * Track by function for ngFor loops + * + * @param index + * @param item + */ + trackByFn(index: number, item: any): any + { + return item.id || index; + } + + // ----------------------------------------------------------------------------------------------------- + // @ Private methods + // ----------------------------------------------------------------------------------------------------- + + /** + * Read the given file for demonstration purposes + * + * @param file + */ + private _readAsDataURL(file: File): Promise + { + // Return a new promise + return new Promise((resolve, reject) => { + + // Create a new reader + const reader = new FileReader(); + + // Resolve the promise on success + reader.onload = (): void => { + resolve(reader.result); + }; + + // Reject the promise on error + reader.onerror = (e): void => { + reject(e); + }; + + // Read the file as the + reader.readAsDataURL(file); + }); + } +} diff --git a/src/app/modules/admin/apps/scrumboard/scrumboard.component.html b/src/app/modules/admin/apps/scrumboard/scrumboard.component.html new file mode 100644 index 00000000..0680b43f --- /dev/null +++ b/src/app/modules/admin/apps/scrumboard/scrumboard.component.html @@ -0,0 +1 @@ + diff --git a/src/app/modules/admin/apps/scrumboard/scrumboard.component.ts b/src/app/modules/admin/apps/scrumboard/scrumboard.component.ts new file mode 100644 index 00000000..2a42579b --- /dev/null +++ b/src/app/modules/admin/apps/scrumboard/scrumboard.component.ts @@ -0,0 +1,17 @@ +import { ChangeDetectionStrategy, Component, ViewEncapsulation } from '@angular/core'; + +@Component({ + selector : 'scrumboard', + templateUrl : './scrumboard.component.html', + encapsulation : ViewEncapsulation.None, + changeDetection: ChangeDetectionStrategy.OnPush +}) +export class ScrumboardComponent +{ + /** + * Constructor + */ + constructor() + { + } +} diff --git a/src/app/modules/admin/apps/scrumboard/scrumboard.models.ts b/src/app/modules/admin/apps/scrumboard/scrumboard.models.ts new file mode 100644 index 00000000..e0e4b607 --- /dev/null +++ b/src/app/modules/admin/apps/scrumboard/scrumboard.models.ts @@ -0,0 +1,190 @@ +import { IBoard, ICard, ILabel, IList, IMember } from 'app/modules/admin/apps/scrumboard/scrumboard.types'; + +// ----------------------------------------------------------------------------------------------------- +// @ Board +// ----------------------------------------------------------------------------------------------------- +export class Board implements Required +{ + id: string | null; + title: string; + description: string | null; + icon: string | null; + lastActivity: string | null; + lists: List[]; + labels: Label[]; + members: Member[]; + + /** + * Constructor + */ + constructor(board: IBoard) + { + this.id = board.id || null; + this.title = board.title; + this.description = board.description || null; + this.icon = board.icon || null; + this.lastActivity = board.lastActivity || null; + this.lists = []; + this.labels = []; + this.members = []; + + // Lists + if ( board.lists ) + { + this.lists = board.lists.map((list) => { + if ( !(list instanceof List) ) + { + return new List(list); + } + + return list; + }); + } + + // Labels + if ( board.labels ) + { + this.labels = board.labels.map((label) => { + if ( !(label instanceof Label) ) + { + return new Label(label); + } + + return label; + }); + } + + // Members + if ( board.members ) + { + this.members = board.members.map((member) => { + if ( !(member instanceof Member) ) + { + return new Member(member); + } + + return member; + }); + } + } +} + +// ----------------------------------------------------------------------------------------------------- +// @ List +// ----------------------------------------------------------------------------------------------------- +export class List implements Required +{ + id: string | null; + boardId: string; + position: number; + title: string; + cards: Card[]; + + /** + * Constructor + */ + constructor(list: IList) + { + this.id = list.id || null; + this.boardId = list.boardId; + this.position = list.position; + this.title = list.title; + this.cards = []; + + // Cards + if ( list.cards ) + { + this.cards = list.cards.map((card) => { + if ( !(card instanceof Card) ) + { + return new Card(card); + } + + return card; + }); + } + } +} + +// ----------------------------------------------------------------------------------------------------- +// @ Card +// ----------------------------------------------------------------------------------------------------- +export class Card implements Required +{ + id: string | null; + boardId: string; + listId: string; + position: number; + title: string; + description: string | null; + labels: Label[]; + dueDate: string | null; + + /** + * Constructor + */ + constructor(card: ICard) + { + this.id = card.id || null; + this.boardId = card.boardId; + this.listId = card.listId; + this.position = card.position; + this.title = card.title; + this.description = card.description || null; + this.labels = []; + this.dueDate = card.dueDate || null; + + // Labels + if ( card.labels ) + { + this.labels = card.labels.map((label) => { + if ( !(label instanceof Label) ) + { + return new Label(label); + } + + return label; + }); + } + } +} + +// ----------------------------------------------------------------------------------------------------- +// @ Member +// ----------------------------------------------------------------------------------------------------- +export class Member implements Required +{ + id: string | null; + name: string; + avatar: string | null; + + /** + * Constructor + */ + constructor(member: IMember) + { + this.id = member.id || null; + this.name = member.name; + this.avatar = member.avatar || null; + } +} + +// ----------------------------------------------------------------------------------------------------- +// @ Label +// ----------------------------------------------------------------------------------------------------- +export class Label implements Required +{ + id: string | null; + boardId: string; + title: string; + + /** + * Constructor + */ + constructor(label: ILabel) + { + this.id = label.id || null; + this.boardId = label.boardId; + this.title = label.title; + } +} diff --git a/src/app/modules/admin/apps/scrumboard/scrumboard.module.ts b/src/app/modules/admin/apps/scrumboard/scrumboard.module.ts new file mode 100644 index 00000000..7501e603 --- /dev/null +++ b/src/app/modules/admin/apps/scrumboard/scrumboard.module.ts @@ -0,0 +1,70 @@ +import { NgModule } from '@angular/core'; +import { RouterModule } from '@angular/router'; +import { DragDropModule } from '@angular/cdk/drag-drop'; +import { MatButtonModule } from '@angular/material/button'; +import { MatCheckboxModule } from '@angular/material/checkbox'; +import { MatDialogModule } from '@angular/material/dialog'; +import { MAT_DATE_FORMATS } from '@angular/material/core'; +import { MatDatepickerModule } from '@angular/material/datepicker'; +import { MatFormFieldModule } from '@angular/material/form-field'; +import { MatIconModule } from '@angular/material/icon'; +import { MatInputModule } from '@angular/material/input'; +import { MatMenuModule } from '@angular/material/menu'; +import { MatMomentDateModule } from '@angular/material-moment-adapter'; +import { MatProgressBarModule } from '@angular/material/progress-bar'; +import * as moment from 'moment'; +import { SharedModule } from 'app/shared/shared.module'; +import { ScrumboardComponent } from 'app/modules/admin/apps/scrumboard/scrumboard.component'; +import { ScrumboardBoardsComponent } from 'app/modules/admin/apps/scrumboard/boards/boards.component'; +import { ScrumboardBoardComponent } from 'app/modules/admin/apps/scrumboard/board/board.component'; +import { ScrumboardBoardAddCardComponent } from 'app/modules/admin/apps/scrumboard/board/add-card/add-card.component'; +import { ScrumboardBoardAddListComponent } from 'app/modules/admin/apps/scrumboard/board/add-list/add-list.component'; +import { ScrumboardCardComponent } from 'app/modules/admin/apps/scrumboard/card/card.component'; +import { ScrumboardCardDetailsComponent } from 'app/modules/admin/apps/scrumboard/card/details/details.component'; +import { scrumboardRoutes } from 'app/modules/admin/apps/scrumboard/scrumboard.routing'; + +@NgModule({ + declarations: [ + ScrumboardComponent, + ScrumboardBoardsComponent, + ScrumboardBoardComponent, + ScrumboardBoardAddCardComponent, + ScrumboardBoardAddListComponent, + ScrumboardCardComponent, + ScrumboardCardDetailsComponent + ], + imports : [ + RouterModule.forChild(scrumboardRoutes), + DragDropModule, + MatButtonModule, + MatCheckboxModule, + MatDatepickerModule, + MatDialogModule, + MatFormFieldModule, + MatIconModule, + MatInputModule, + MatMenuModule, + MatMomentDateModule, + MatProgressBarModule, + SharedModule + ], + providers : [ + { + provide : MAT_DATE_FORMATS, + useValue: { + parse : { + dateInput: moment.ISO_8601 + }, + display: { + dateInput : 'll', + monthYearLabel : 'MMM YYYY', + dateA11yLabel : 'LL', + monthYearA11yLabel: 'MMMM YYYY' + } + } + } + ] +}) +export class ScrumboardModule +{ +} diff --git a/src/app/modules/admin/apps/scrumboard/scrumboard.resolvers.ts b/src/app/modules/admin/apps/scrumboard/scrumboard.resolvers.ts new file mode 100644 index 00000000..22314148 --- /dev/null +++ b/src/app/modules/admin/apps/scrumboard/scrumboard.resolvers.ts @@ -0,0 +1,132 @@ +import { Injectable } from '@angular/core'; +import { ActivatedRouteSnapshot, Resolve, Router, RouterStateSnapshot } from '@angular/router'; +import { Observable, throwError } from 'rxjs'; +import { catchError } from 'rxjs/operators'; +import { Board, Card } from 'app/modules/admin/apps/scrumboard/scrumboard.models'; +import { ScrumboardService } from 'app/modules/admin/apps/scrumboard/scrumboard.service'; + +@Injectable({ + providedIn: 'root' +}) +export class ScrumboardBoardsResolver implements Resolve +{ + /** + * Constructor + */ + constructor( + private _scrumboardService: ScrumboardService + ) + { + } + + // ----------------------------------------------------------------------------------------------------- + // @ Public methods + // ----------------------------------------------------------------------------------------------------- + + /** + * Resolver + * + * @param route + * @param state + */ + resolve(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable + { + return this._scrumboardService.getBoards(); + } +} + +@Injectable({ + providedIn: 'root' +}) +export class ScrumboardBoardResolver implements Resolve +{ + /** + * Constructor + */ + constructor( + private _router: Router, + private _scrumboardService: ScrumboardService + ) + { + } + + // ----------------------------------------------------------------------------------------------------- + // @ Public methods + // ----------------------------------------------------------------------------------------------------- + + /** + * Resolver + * + * @param route + * @param state + */ + resolve(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable + { + return this._scrumboardService.getBoard(route.paramMap.get('boardId')) + .pipe( + // Error here means the requested task is not available + catchError((error) => { + + // Log the error + console.error(error); + + // Get the parent url + const parentUrl = state.url.split('/').slice(0, -1).join('/'); + + // Navigate to there + this._router.navigateByUrl(parentUrl); + + // Throw an error + return throwError(error); + }) + ); + } +} + +@Injectable({ + providedIn: 'root' +}) +export class ScrumboardCardResolver implements Resolve +{ + /** + * Constructor + */ + constructor( + private _router: Router, + private _scrumboardService: ScrumboardService + ) + { + } + + // ----------------------------------------------------------------------------------------------------- + // @ Public methods + // ----------------------------------------------------------------------------------------------------- + + /** + * Resolver + * + * @param route + * @param state + */ + resolve(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable + { + return this._scrumboardService.getCard(route.paramMap.get('cardId')) + .pipe( + // Error here means the requested task is not available + catchError((error) => { + + // Log the error + console.error(error); + + // Get the parent url + const parentUrl = state.url.split('/').slice(0, -1).join('/'); + + // Navigate to there + this._router.navigateByUrl(parentUrl); + + // Throw an error + return throwError(error); + }) + ); + } +} diff --git a/src/app/modules/admin/apps/scrumboard/scrumboard.routing.ts b/src/app/modules/admin/apps/scrumboard/scrumboard.routing.ts new file mode 100644 index 00000000..781d0ca2 --- /dev/null +++ b/src/app/modules/admin/apps/scrumboard/scrumboard.routing.ts @@ -0,0 +1,31 @@ +import { Route } from '@angular/router'; +import { ScrumboardBoardsComponent } from 'app/modules/admin/apps/scrumboard/boards/boards.component'; +import { ScrumboardBoardResolver, ScrumboardBoardsResolver, ScrumboardCardResolver } from 'app/modules/admin/apps/scrumboard/scrumboard.resolvers'; +import { ScrumboardBoardComponent } from 'app/modules/admin/apps/scrumboard/board/board.component'; +import { ScrumboardCardComponent } from 'app/modules/admin/apps/scrumboard/card/card.component'; + +export const scrumboardRoutes: Route[] = [ + { + path : '', + component: ScrumboardBoardsComponent, + resolve : { + boards: ScrumboardBoardsResolver + } + }, + { + path : ':boardId', + component: ScrumboardBoardComponent, + resolve : { + board: ScrumboardBoardResolver + }, + children : [ + { + path : 'card/:cardId', + component: ScrumboardCardComponent, + resolve : { + card: ScrumboardCardResolver + } + } + ] + } +]; diff --git a/src/app/modules/admin/apps/scrumboard/scrumboard.service.ts b/src/app/modules/admin/apps/scrumboard/scrumboard.service.ts new file mode 100644 index 00000000..5db02899 --- /dev/null +++ b/src/app/modules/admin/apps/scrumboard/scrumboard.service.ts @@ -0,0 +1,608 @@ +import { Injectable } from '@angular/core'; +import { HttpClient } from '@angular/common/http'; +import { BehaviorSubject, Observable, of, throwError } from 'rxjs'; +import { map, switchMap, take, tap } from 'rxjs/operators'; +import { Board, Card, Label, List } from 'app/modules/admin/apps/scrumboard/scrumboard.models'; + +@Injectable({ + providedIn: 'root' +}) +export class ScrumboardService +{ + // Private + private _board: BehaviorSubject; + private _boards: BehaviorSubject; + private _card: BehaviorSubject; + + /** + * Constructor + */ + constructor( + private _httpClient: HttpClient + ) + { + // Set the private defaults + this._board = new BehaviorSubject(null); + this._boards = new BehaviorSubject(null); + this._card = new BehaviorSubject(null); + } + + // ----------------------------------------------------------------------------------------------------- + // @ Accessors + // ----------------------------------------------------------------------------------------------------- + + /** + * Getter for board + */ + get board$(): Observable + { + return this._board.asObservable(); + } + + /** + * Getter for boards + */ + get boards$(): Observable + { + return this._boards.asObservable(); + } + + /** + * Getter for card + */ + get card$(): Observable + { + return this._card.asObservable(); + } + + // ----------------------------------------------------------------------------------------------------- + // @ Public methods + // ----------------------------------------------------------------------------------------------------- + + /** + * Get boards + */ + getBoards(): Observable + { + return this._httpClient.get('api/apps/scrumboard/boards').pipe( + map(response => response.map(item => new Board(item))), + tap(boards => this._boards.next(boards)) + ); + } + + /** + * Get board + * + * @param id + */ + getBoard(id: string): Observable + { + return this._httpClient.get('api/apps/scrumboard/board', {params: {id}}).pipe( + map(response => new Board(response)), + tap(board => this._board.next(board)) + ); + } + + /** + * Create board + * + * @param board + */ + createBoard(board: Board): Observable + { + return this.boards$.pipe( + take(1), + switchMap(boards => this._httpClient.put('api/apps/scrumboard/board', {board}).pipe( + map((newBoard) => { + + // Update the boards with the new board + this._boards.next([...boards, newBoard]); + + // Return new board from observable + return newBoard; + }) + )) + ); + } + + /** + * Update the board + * + * @param id + * @param board + */ + updateBoard(id: string, board: Board): Observable + { + return this.boards$.pipe( + take(1), + switchMap(boards => this._httpClient.patch('api/apps/scrumboard/board', { + id, + board + }).pipe( + map((updatedBoard) => { + + // Find the index of the updated board + const index = boards.findIndex(item => item.id === id); + + // Update the board + boards[index] = updatedBoard; + + // Update the boards + this._boards.next(boards); + + // Return the updated board + return updatedBoard; + }) + )) + ); + } + + /** + * Delete the board + * + * @param id + */ + deleteBoard(id: string): Observable + { + return this.boards$.pipe( + take(1), + switchMap(boards => this._httpClient.delete('api/apps/scrumboard/board', {params: {id}}).pipe( + map((isDeleted: boolean) => { + + // Find the index of the deleted board + const index = boards.findIndex(item => item.id === id); + + // Delete the board + boards.splice(index, 1); + + // Update the boards + this._boards.next(boards); + + // Update the board + this._board.next(null); + + // Update the card + this._card.next(null); + + // Return the deleted status + return isDeleted; + }) + )) + ); + } + + /** + * Create list + * + * @param list + */ + createList(list: List): Observable + { + return this._httpClient.post('api/apps/scrumboard/board/list', {list}).pipe( + map(response => new List(response)), + tap((newList) => { + + // Get the board value + const board = this._board.value; + + // Update the board lists with the new list + board.lists = [...board.lists, newList]; + + // Sort the board lists + board.lists.sort((a, b) => a.position - b.position); + + // Update the board + this._board.next(board); + }) + ); + } + + /** + * Update the list + * + * @param list + */ + updateList(list: List): Observable + { + return this._httpClient.patch('api/apps/scrumboard/board/list', {list}).pipe( + map(response => new List(response)), + tap((updatedList) => { + + // Get the board value + const board = this._board.value; + + // Find the index of the updated list + const index = board.lists.findIndex(item => item.id === list.id); + + // Update the list + board.lists[index] = updatedList; + + // Sort the board lists + board.lists.sort((a, b) => a.position - b.position); + + // Update the board + this._board.next(board); + }) + ); + } + + /** + * Update the lists + * + * @param lists + */ + updateLists(lists: List[]): Observable + { + return this._httpClient.patch('api/apps/scrumboard/board/lists', {lists}).pipe( + map(response => response.map(item => new List(item))), + tap((updatedLists) => { + + // Get the board value + const board = this._board.value; + + // Go through the updated lists + updatedLists.forEach((updatedList) => { + + // Find the index of the updated list + const index = board.lists.findIndex(item => item.id === updatedList.id); + + // Update the list + board.lists[index] = updatedList; + }); + + // Sort the board lists + board.lists.sort((a, b) => a.position - b.position); + + // Update the board + this._board.next(board); + }) + ); + } + + /** + * Delete the list + * + * @param id + */ + deleteList(id: string): Observable + { + return this._httpClient.delete('api/apps/scrumboard/board/list', {params: {id}}).pipe( + tap((isDeleted) => { + + // Get the board value + const board = this._board.value; + + // Find the index of the deleted list + const index = board.lists.findIndex(item => item.id === id); + + // Delete the list + board.lists.splice(index, 1); + + // Sort the board lists + board.lists.sort((a, b) => a.position - b.position); + + // Update the board + this._board.next(board); + }) + ); + } + + /** + * Get card + */ + getCard(id: string): Observable + { + return this._board.pipe( + take(1), + map((board) => { + + // Find the card + const card = board.lists.find(list => list.cards.some(item => item.id === id)) + .cards.find(item => item.id === id); + + // Update the card + this._card.next(card); + + // Return the card + return card; + }), + switchMap((card) => { + + if ( !card ) + { + return throwError('Could not found the card with id of ' + id + '!'); + } + + return of(card); + }) + ); + } + + /** + * Create card + * + * @param card + */ + createCard(card: Card): Observable + { + return this._httpClient.put('api/apps/scrumboard/board/card', {card}).pipe( + map(response => new Card(response)), + tap((newCard) => { + + // Get the board value + const board = this._board.value; + + // Find the list and push the new card in it + board.lists.forEach((listItem, index, list) => { + if ( listItem.id === newCard.listId ) + { + list[index].cards.push(newCard); + } + }); + + // Update the board + this._board.next(board); + + // Return the new card + return newCard; + }) + ); + } + + /** + * Update the card + * + * @param id + * @param card + */ + updateCard(id: string, card: Card): Observable + { + return this.board$.pipe( + take(1), + switchMap(board => this._httpClient.patch('api/apps/scrumboard/board/card', { + id, + card + }).pipe( + map((updatedCard) => { + + // Find the card and update it + board.lists.forEach((listItem) => { + listItem.cards.forEach((cardItem, index, array) => { + if ( cardItem.id === id ) + { + array[index] = updatedCard; + } + }); + }); + + // Update the board + this._board.next(board); + + // Update the card + this._card.next(updatedCard); + + // Return the updated card + return updatedCard; + }) + )) + ); + } + + /** + * Update the cards + * + * @param cards + */ + updateCards(cards: Card[]): Observable + { + return this._httpClient.patch('api/apps/scrumboard/board/cards', {cards}).pipe( + map(response => response.map(item => new Card(item))), + tap((updatedCards) => { + + // Get the board value + const board = this._board.value; + + // Go through the updated cards + updatedCards.forEach((updatedCard) => { + + // Find the index of the updated card's list + const listIndex = board.lists.findIndex(list => list.id === updatedCard.listId); + + // Find the index of the updated card + const cardIndex = board.lists[listIndex].cards.findIndex(item => item.id === updatedCard.id); + + // Update the card + board.lists[listIndex].cards[cardIndex] = updatedCard; + + // Sort the cards + board.lists[listIndex].cards.sort((a, b) => a.position - b.position); + }); + + // Update the board + this._board.next(board); + }) + ); + } + + /** + * Delete the card + * + * @param id + */ + deleteCard(id: string): Observable + { + return this.board$.pipe( + take(1), + switchMap(board => this._httpClient.delete('api/apps/scrumboard/board/card', {params: {id}}).pipe( + map((isDeleted: boolean) => { + + // Find the card and delete it + board.lists.forEach((listItem) => { + listItem.cards.forEach((cardItem, index, array) => { + if ( cardItem.id === id ) + { + array.splice(index, 1); + } + }); + }); + + // Update the board + this._board.next(board); + + // Update the card + this._card.next(null); + + // Return the deleted status + return isDeleted; + }) + )) + ); + } + + /** + * Update card positions + * + * @param cards + */ + updateCardPositions(cards: Card[]): void // Observable + { + /*return this._httpClient.patch('api/apps/scrumboard/board/card/positions', {cards}).pipe( + map((response) => response.map((item) => new Card(item))), + tap((updatedCards) => { + + // Get the board value + const board = this._board.value; + + // Find the card and update it + board.lists.forEach((listItem) => { + listItem.cards.forEach((cardItem, index, array) => { + if ( cardItem.id === id ) + { + array[index] = updatedCard; + } + }); + }); + + // Update the lists + board.lists = updatedLists; + + // Sort the board lists + board.lists.sort((a, b) => a.position - b.position); + + // Update the board + this._board.next(board); + }) + );*/ + } + + /** + * Create label + * + * @param label + */ + createLabel(label: Label): Observable