diff --git a/package-lock.json b/package-lock.json index 11d8457b76..faf6674bcf 100644 --- a/package-lock.json +++ b/package-lock.json @@ -54,6 +54,7 @@ "leaflet.markercluster": "^1.4.1", "msal": "^1.4.4", "rxjs": "~6.6.7", + "speak-tts": "^2.0.8", "subscriptions-transport-ws": "^0.9.18", "survey-angular": "^1.8.54", "survey-creator": "^1.8.54", @@ -481,6 +482,7 @@ "resolved": "https://registry.npmjs.org/@angular/cdk/-/cdk-11.2.13.tgz", "integrity": "sha512-FkE4iCwoLbQxLDUOjV1I7M/6hmpyb7erAjEdWgch7nGRNxF1hqX5Bqf1lvLFKPNCbx5NRI5K7YVAdIUQUR8vug==", "dependencies": { + "parse5": "^5.0.0", "tslib": "^2.0.0" }, "optionalDependencies": { @@ -554,7 +556,6 @@ "version": "11.2.14", "resolved": "https://registry.npmjs.org/@angular/compiler-cli/-/compiler-cli-11.2.14.tgz", "integrity": "sha512-A7ltnCp03/EVqK/Q3tVUDsokgz5GHW3dSPGl0Csk7Ys5uBB9ibHTmVt4eiXA4jt0+6Bk+mKxwe5BEDqLvwYFAg==", - "dev": true, "dependencies": { "@babel/core": "^7.8.6", "@babel/types": "^7.8.6", @@ -590,7 +591,6 @@ "version": "6.3.0", "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", - "dev": true, "bin": { "semver": "bin/semver.js" } @@ -599,7 +599,6 @@ "version": "0.6.1", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "dev": true, "engines": { "node": ">=0.10.0" } @@ -866,7 +865,6 @@ "version": "7.14.7", "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.14.7.tgz", "integrity": "sha512-nS6dZaISCXJ3+518CWiBfEr//gHyMO02uDxBkXTKZDN5POruCnOZ1N4YBRZDCabwF8nZMWBpRxIicmXtBs+fvw==", - "dev": true, "engines": { "node": ">=6.9.0" } @@ -875,7 +873,6 @@ "version": "7.14.6", "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.14.6.tgz", "integrity": "sha512-gJnOEWSqTk96qG5BoIrl5bVtc23DCycmIePPYnamY9RboYdI4nFy5vAQMSl81O5K/W0sLDWfGysnOECC+KUUCA==", - "dev": true, "dependencies": { "@babel/code-frame": "^7.14.5", "@babel/generator": "^7.14.5", @@ -905,7 +902,6 @@ "version": "7.14.5", "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.14.5.tgz", "integrity": "sha512-y3rlP+/G25OIX3mYKKIOlQRcqj7YgrvHxOLbVmyLJ9bPmi5ttvUmpydVjcFjZphOktWuA7ovbx91ECloWTfjIA==", - "dev": true, "dependencies": { "@babel/types": "^7.14.5", "jsesc": "^2.5.1", @@ -919,7 +915,6 @@ "version": "7.14.5", "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.14.5.tgz", "integrity": "sha512-6Z3Po85sfxRGachLULUhOmvAaOo7xCvqGQtxINai2mEGPFm6pQ4z5QInFnUrRpfoSV60BnjyF5F3c+15fxFV1g==", - "dev": true, "dependencies": { "@babel/code-frame": "^7.14.5", "@babel/parser": "^7.14.5", @@ -933,7 +928,6 @@ "version": "6.3.0", "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", - "dev": true, "bin": { "semver": "bin/semver.js" } @@ -942,7 +936,6 @@ "version": "0.5.7", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", - "dev": true, "engines": { "node": ">=0.10.0" } @@ -994,7 +987,6 @@ "version": "7.14.5", "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.14.5.tgz", "integrity": "sha512-v+QtZqXEiOnpO6EYvlImB6zCD2Lel06RzOPzmkz/D/XgQiUu3C/Jb1LOqSt/AIA34TYi/Q+KlT8vTQrgdxkbLw==", - "dev": true, "dependencies": { "@babel/compat-data": "^7.14.5", "@babel/helper-validator-option": "^7.14.5", @@ -1012,7 +1004,6 @@ "version": "6.3.0", "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", - "dev": true, "bin": { "semver": "bin/semver.js" } @@ -1145,7 +1136,6 @@ "version": "7.14.7", "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.14.7.tgz", "integrity": "sha512-TMUt4xKxJn6ccjcOW7c4hlwyJArizskAhoSTOCkA0uZ+KghIaci0Qg9R043kUMWI9mtQfgny+NQ5QATnZ+paaA==", - "dev": true, "dependencies": { "@babel/types": "^7.14.5" }, @@ -1157,7 +1147,6 @@ "version": "7.14.5", "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.14.5.tgz", "integrity": "sha512-SwrNHu5QWS84XlHwGYPDtCxcA0hrSlL2yhWYLgeOc0w7ccOl2qv4s/nARI0aYZW+bSwAL5CukeXA47B/1NKcnQ==", - "dev": true, "dependencies": { "@babel/types": "^7.14.5" }, @@ -1169,7 +1158,6 @@ "version": "7.14.5", "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.14.5.tgz", "integrity": "sha512-iXpX4KW8LVODuAieD7MzhNjmM6dzYY5tfRqT+R9HDXWl0jPn/djKmA+G9s/2C2T9zggw5tK1QNqZ70USfedOwA==", - "dev": true, "dependencies": { "@babel/helper-module-imports": "^7.14.5", "@babel/helper-replace-supers": "^7.14.5", @@ -1188,7 +1176,6 @@ "version": "7.14.5", "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.14.5.tgz", "integrity": "sha512-6Z3Po85sfxRGachLULUhOmvAaOo7xCvqGQtxINai2mEGPFm6pQ4z5QInFnUrRpfoSV60BnjyF5F3c+15fxFV1g==", - "dev": true, "dependencies": { "@babel/code-frame": "^7.14.5", "@babel/parser": "^7.14.5", @@ -1202,7 +1189,6 @@ "version": "7.14.5", "resolved": "https://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.14.5.tgz", "integrity": "sha512-IqiLIrODUOdnPU9/F8ib1Fx2ohlgDhxnIDU7OEVi+kAbEZcyiF7BLU8W6PfvPi9LzztjS7kcbzbmL7oG8kD6VA==", - "dev": true, "dependencies": { "@babel/types": "^7.14.5" }, @@ -1237,7 +1223,6 @@ "version": "7.14.5", "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.14.5.tgz", "integrity": "sha512-3i1Qe9/8x/hCHINujn+iuHy+mMRLoc77b2nI9TB0zjH1hvn9qGlXjWlggdwUcju36PkPCy/lpM7LLUdcTyH4Ow==", - "dev": true, "dependencies": { "@babel/helper-member-expression-to-functions": "^7.14.5", "@babel/helper-optimise-call-expression": "^7.14.5", @@ -1252,7 +1237,6 @@ "version": "7.14.5", "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.14.5.tgz", "integrity": "sha512-nfBN9xvmCt6nrMZjfhkl7i0oTV3yxR4/FztsbOASyTvVcoYd0TRHh7eMLdlEcCqobydC0LAF3LtC92Iwxo0wyw==", - "dev": true, "dependencies": { "@babel/types": "^7.14.5" }, @@ -1295,7 +1279,6 @@ "version": "7.14.5", "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.14.5.tgz", "integrity": "sha512-OX8D5eeX4XwcroVW45NMvoYaIuFI+GQpA2a8Gi+X/U/cDUIRsV37qQfF905F0htTRCREQIB4KqPeaveRJUl3Ow==", - "dev": true, "engines": { "node": ">=6.9.0" } @@ -2936,6 +2919,7 @@ "integrity": "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==", "dev": true, "dependencies": { + "graceful-fs": "^4.1.6", "universalify": "^2.0.0" }, "optionalDependencies": { @@ -4713,7 +4697,8 @@ "esprima": "^4.0.1", "estraverse": "^5.2.0", "esutils": "^2.0.2", - "optionator": "^0.8.1" + "optionator": "^0.8.1", + "source-map": "~0.6.1" }, "bin": { "escodegen": "bin/escodegen.js", @@ -5387,6 +5372,7 @@ "integrity": "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==", "dev": true, "dependencies": { + "graceful-fs": "^4.1.6", "universalify": "^2.0.0" }, "optionalDependencies": { @@ -6099,6 +6085,7 @@ "integrity": "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==", "dev": true, "dependencies": { + "graceful-fs": "^4.1.6", "universalify": "^2.0.0" }, "optionalDependencies": { @@ -6391,6 +6378,7 @@ "integrity": "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==", "dev": true, "dependencies": { + "graceful-fs": "^4.1.6", "universalify": "^2.0.0" }, "optionalDependencies": { @@ -6474,6 +6462,7 @@ "integrity": "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==", "dev": true, "dependencies": { + "graceful-fs": "^4.1.6", "universalify": "^2.0.0" }, "optionalDependencies": { @@ -6717,6 +6706,7 @@ "integrity": "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==", "dev": true, "dependencies": { + "graceful-fs": "^4.1.6", "universalify": "^2.0.0" }, "optionalDependencies": { @@ -8505,7 +8495,6 @@ "version": "3.1.2", "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.2.tgz", "integrity": "sha512-P43ePfOAIupkguHUycrc4qJ9kz8ZiuOUijaETwX7THt0Y/GNK7v0aa8rY816xWjZ7rJdA5XdMcpVFTKMq+RvWg==", - "dev": true, "dependencies": { "normalize-path": "^3.0.0", "picomatch": "^2.0.4" @@ -9413,7 +9402,6 @@ "version": "2.2.0", "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz", "integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==", - "dev": true, "engines": { "node": ">=8" } @@ -9646,7 +9634,6 @@ "version": "3.0.2", "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", - "dev": true, "dependencies": { "fill-range": "^7.0.1" }, @@ -9807,7 +9794,6 @@ "version": "4.16.6", "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.16.6.tgz", "integrity": "sha512-Wspk/PqO+4W9qp5iUTJsa1B/QrYn1keNCcEP5OvP7WBwT4KaDly0uONYmC6Xa3Z5IqnUgS0KcgLYu1l74x0ZXQ==", - "dev": true, "dependencies": { "caniuse-lite": "^1.0.30001219", "colorette": "^1.2.2", @@ -10122,7 +10108,6 @@ "version": "1.0.30001241", "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001241.tgz", "integrity": "sha512-1uoSZ1Pq1VpH0WerIMqwptXHNNGfdl7d1cJUFs80CwQ/lVzdhTvsFZCeNFslze7AjsQnb4C85tzclPa1VShbeQ==", - "dev": true, "funding": { "type": "opencollective", "url": "https://opencollective.com/browserslist" @@ -10131,8 +10116,7 @@ "node_modules/canonical-path": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/canonical-path/-/canonical-path-1.0.0.tgz", - "integrity": "sha512-feylzsbDxi1gPZ1IjystzIQZagYYLvfKrSuygUCgf7z6x790VEzze5QEkdSV1U58RA7Hi0+v6fv4K54atOzATg==", - "dev": true + "integrity": "sha512-feylzsbDxi1gPZ1IjystzIQZagYYLvfKrSuygUCgf7z6x790VEzze5QEkdSV1U58RA7Hi0+v6fv4K54atOzATg==" }, "node_modules/capture-exit": { "version": "2.0.0", @@ -10267,10 +10251,10 @@ "version": "3.5.2", "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.2.tgz", "integrity": "sha512-ekGhOnNVPgT77r4K/U3GDhu+FQ2S8TnK/s2KbIGXi0SZWuwkZ2QNyfWdZW+TVfn84DpEP7rLeCt2UI6bJ8GwbQ==", - "dev": true, "dependencies": { "anymatch": "~3.1.2", "braces": "~3.0.2", + "fsevents": "~2.3.2", "glob-parent": "~5.1.2", "is-binary-path": "~2.1.0", "is-glob": "~4.0.1", @@ -10504,6 +10488,7 @@ "integrity": "sha512-gnB85c3MGC7Nm9I/FkiasNBOKjOiO1RNuXXarQms37q4QMpWdlbBgD/VnOStA2faG1dpXMv31RFApjX1/QdgWQ==", "dev": true, "dependencies": { + "colors": "^1.1.2", "object-assign": "^4.1.0", "string-width": "^4.2.0" }, @@ -10726,8 +10711,7 @@ "node_modules/colorette": { "version": "1.2.2", "resolved": "https://registry.npmjs.org/colorette/-/colorette-1.2.2.tgz", - "integrity": "sha512-MKGMzyfeuutC/ZJ1cba9NqcNpfeqMUcYmyF1ZFY6/Cn7CNSAKx6a+s48sqLqyAiZuaP2TcqMhoo+dlwFnVxT9w==", - "dev": true + "integrity": "sha512-MKGMzyfeuutC/ZJ1cba9NqcNpfeqMUcYmyF1ZFY6/Cn7CNSAKx6a+s48sqLqyAiZuaP2TcqMhoo+dlwFnVxT9w==" }, "node_modules/colors": { "version": "1.4.0", @@ -12454,7 +12438,6 @@ "version": "0.7.2", "resolved": "https://registry.npmjs.org/dependency-graph/-/dependency-graph-0.7.2.tgz", "integrity": "sha512-KqtH4/EZdtdfWX0p6MGP9jljvxSY6msy/pRUD4jgNwVpv3v1QmNLlsB3LDSSUg79BRVSn7jI1QPRtArGABovAQ==", - "dev": true, "engines": { "node": ">= 0.6.0" } @@ -12956,8 +12939,7 @@ "node_modules/electron-to-chromium": { "version": "1.3.762", "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.762.tgz", - "integrity": "sha512-LehWjRpfPcK8F1Lf/NZoAwWLWnjJVo0SZeQ9j/tvnBWYcT99qDqgo4raAfS2oTKZjPrR/jxruh85DGgDUmywEA==", - "dev": true + "integrity": "sha512-LehWjRpfPcK8F1Lf/NZoAwWLWnjJVo0SZeQ9j/tvnBWYcT99qDqgo4raAfS2oTKZjPrR/jxruh85DGgDUmywEA==" }, "node_modules/element-resize-detector": { "version": "1.2.3", @@ -13365,7 +13347,8 @@ "dependencies": { "esprima": "~1.0.4", "estraverse": "~1.5.0", - "esutils": "~1.0.0" + "esutils": "~1.0.0", + "source-map": "~0.1.30" }, "bin": { "escodegen": "bin/escodegen.js", @@ -14115,6 +14098,9 @@ "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-2.4.0.tgz", "integrity": "sha1-NzaitCi4e72gzIO1P6PWM6NcKug=", "dev": true, + "dependencies": { + "graceful-fs": "^4.1.6" + }, "optionalDependencies": { "graceful-fs": "^4.1.6" } @@ -14151,7 +14137,6 @@ "version": "7.0.1", "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", - "dev": true, "dependencies": { "to-regex-range": "^5.0.1" }, @@ -14648,7 +14633,6 @@ "version": "4.0.2", "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-4.0.2.tgz", "integrity": "sha1-+RcExT0bRh+JNFKwwwfZmXZHq2s=", - "dev": true, "dependencies": { "graceful-fs": "^4.1.2", "jsonfile": "^4.0.0", @@ -14718,7 +14702,6 @@ "version": "2.3.2", "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz", "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==", - "dev": true, "hasInstallScript": true, "optional": true, "os": [ @@ -14998,7 +14981,6 @@ "version": "5.1.2", "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", - "dev": true, "dependencies": { "is-glob": "^4.0.1" }, @@ -15115,8 +15097,7 @@ "node_modules/graceful-fs": { "version": "4.2.6", "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.6.tgz", - "integrity": "sha512-nTnJ528pbqxYanhpDYsi4Rd8MAeaBA67+RZ10CM1m3bTAVFEDcd5AuA4a6W5YkGZ1iNXHzZz8T6TBKLeBuNriQ==", - "dev": true + "integrity": "sha512-nTnJ528pbqxYanhpDYsi4Rd8MAeaBA67+RZ10CM1m3bTAVFEDcd5AuA4a6W5YkGZ1iNXHzZz8T6TBKLeBuNriQ==" }, "node_modules/graphql": { "version": "15.5.1", @@ -15191,6 +15172,7 @@ "minimist": "^1.2.5", "neo-async": "^2.6.0", "source-map": "^0.6.1", + "uglify-js": "^3.1.4", "wordwrap": "^1.0.0" }, "bin": { @@ -16869,7 +16851,6 @@ "version": "2.1.0", "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", - "dev": true, "dependencies": { "binary-extensions": "^2.0.0" }, @@ -17054,7 +17035,6 @@ "version": "2.1.1", "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=", - "dev": true, "engines": { "node": ">=0.10.0" } @@ -17077,7 +17057,6 @@ "version": "4.0.1", "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.1.tgz", "integrity": "sha512-5G0tKtBTFImOqDnLB2hG6Bp2qcKEFduo4tZu9MT/H6NQv/ghhy30o55ufafxJ/LdH79LLs2Kfrn85TLKyA7BUg==", - "dev": true, "dependencies": { "is-extglob": "^2.1.1" }, @@ -17149,7 +17128,6 @@ "version": "7.0.0", "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", - "dev": true, "engines": { "node": ">=0.12.0" } @@ -17693,6 +17671,7 @@ "@types/node": "*", "anymatch": "^3.0.3", "fb-watchman": "^2.0.0", + "fsevents": "^2.1.2", "graceful-fs": "^4.2.4", "jest-regex-util": "^26.0.0", "jest-serializer": "^26.6.2", @@ -18048,7 +18027,9 @@ "version": "4.0.0", "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz", "integrity": "sha1-h3Gq4HmbZAdrdmQPygWPnBDjPss=", - "dev": true, + "dependencies": { + "graceful-fs": "^4.1.6" + }, "optionalDependencies": { "graceful-fs": "^4.1.6" } @@ -18328,6 +18309,9 @@ "resolved": "https://registry.npmjs.org/klaw/-/klaw-1.3.1.tgz", "integrity": "sha1-QIhDO0azsbolnXh4XY6W9zugJDk=", "dev": true, + "dependencies": { + "graceful-fs": "^4.1.9" + }, "optionalDependencies": { "graceful-fs": "^4.1.9" } @@ -18402,7 +18386,14 @@ "dev": true, "dependencies": { "copy-anything": "^2.0.1", + "errno": "^0.1.1", + "graceful-fs": "^4.1.2", + "image-size": "~0.5.0", + "make-dir": "^2.1.0", + "mime": "^1.4.1", + "needle": "^2.5.2", "parse-node-version": "^1.0.1", + "source-map": "~0.6.0", "tslib": "^1.10.0" }, "bin": { @@ -18702,6 +18693,7 @@ "anymatch": "^2.0.0", "async-each": "^1.0.1", "braces": "^2.3.2", + "fsevents": "^1.2.7", "glob-parent": "^3.1.0", "inherits": "^2.0.3", "is-binary-path": "^1.0.0", @@ -19736,6 +19728,7 @@ "integrity": "sha512-akCrLDWfbdAWkMLBxJEeWTdNsjML+dt5YgOI4gJ53vuO0vrmYQkUPxa6j6V65s9CcePIr2SSWqjT2EcrNseryQ==", "dev": true, "dependencies": { + "encoding": "^0.1.12", "minipass": "^3.1.0", "minipass-sized": "^1.0.3", "minizlib": "^2.0.0" @@ -21678,8 +21671,7 @@ "node_modules/node-releases": { "version": "1.1.73", "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-1.1.73.tgz", - "integrity": "sha512-uW7fodD6pyW2FZNZnp/Z3hvWKeEW1Y8R1+1CnErE8cXFXzl5blBOoVB41CvMer6P6Q0S5FXDwcHgFd1Wj0U9zg==", - "dev": true + "integrity": "sha512-uW7fodD6pyW2FZNZnp/Z3hvWKeEW1Y8R1+1CnErE8cXFXzl5blBOoVB41CvMer6P6Q0S5FXDwcHgFd1Wj0U9zg==" }, "node_modules/node-sass-tilde-importer": { "version": "1.0.2", @@ -21736,7 +21728,6 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", - "dev": true, "engines": { "node": ">=0.10.0" } @@ -22957,7 +22948,6 @@ "version": "2.3.0", "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.0.tgz", "integrity": "sha512-lY1Q/PiJGC2zOv/z391WOTD+Z02bCgsFfvxoXXf6h7kv9o+WmsmzYqrAwY63sNgOxE4xEdq0WyUnXfKeBrSvYw==", - "dev": true, "engines": { "node": ">=8.6" }, @@ -24700,7 +24690,7 @@ "version": "16.14.0", "resolved": "https://registry.npmjs.org/react/-/react-16.14.0.tgz", "integrity": "sha512-0X2CImDkJGApiAlcf0ODKIneSwBPhqJawOa5wCtKbu7ZECrmS26NvtSILynQ66cgkT/RJ4LidJOc3bUESwmU8g==", - "dev": true, + "devOptional": true, "dependencies": { "loose-envify": "^1.1.0", "object-assign": "^4.1.1", @@ -25171,7 +25161,6 @@ "version": "3.6.0", "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", - "dev": true, "dependencies": { "picomatch": "^2.2.1" }, @@ -25199,8 +25188,7 @@ "node_modules/reflect-metadata": { "version": "0.1.13", "resolved": "https://registry.npmjs.org/reflect-metadata/-/reflect-metadata-0.1.13.tgz", - "integrity": "sha512-Ts1Y/anZELhSsjMcU605fU9RE4Oi3p5ORujwbIKXfWa+0Zxs510Qrmrce5/Jowq3cHSZSJqBjypxmHarc+vEWg==", - "dev": true + "integrity": "sha512-Ts1Y/anZELhSsjMcU605fU9RE4Oi3p5ORujwbIKXfWa+0Zxs510Qrmrce5/Jowq3cHSZSJqBjypxmHarc+vEWg==" }, "node_modules/refractor": { "version": "3.4.0", @@ -25864,6 +25852,9 @@ "resolved": "https://registry.npmjs.org/rollup/-/rollup-2.38.4.tgz", "integrity": "sha512-B0LcJhjiwKkTl79aGVF/u5KdzsH8IylVfV56Ut6c9ouWLJcUK17T83aZBetNYSnZtXf2OHD4+2PbmRW+Fp5ulg==", "dev": true, + "dependencies": { + "fsevents": "~2.3.1" + }, "bin": { "rollup": "dist/bin/rollup" }, @@ -27326,6 +27317,11 @@ "wbuf": "^1.7.3" } }, + "node_modules/speak-tts": { + "version": "2.0.8", + "resolved": "https://registry.npmjs.org/speak-tts/-/speak-tts-2.0.8.tgz", + "integrity": "sha512-VY6Q6mRjdou6bF+x0LspvM7GJhBxHx8CLyGPTNQQ7jrztiGutyI4QNZn0cA17c4uk0FnFbA4PaMI3skeZ6PiFg==" + }, "node_modules/speed-measure-webpack-plugin": { "version": "1.4.2", "resolved": "https://registry.npmjs.org/speed-measure-webpack-plugin/-/speed-measure-webpack-plugin-1.4.2.tgz", @@ -27512,7 +27508,8 @@ "esprima": "^4.0.1", "estraverse": "^4.2.0", "esutils": "^2.0.2", - "optionator": "^0.8.1" + "optionator": "^0.8.1", + "source-map": "~0.6.1" }, "bin": { "escodegen": "bin/escodegen.js", @@ -27671,7 +27668,8 @@ "esprima": "^4.0.1", "estraverse": "^4.2.0", "esutils": "^2.0.2", - "optionator": "^0.8.1" + "optionator": "^0.8.1", + "source-map": "~0.6.1" }, "bin": { "escodegen": "bin/escodegen.js", @@ -28797,7 +28795,6 @@ "version": "5.0.1", "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", - "dev": true, "dependencies": { "is-number": "^7.0.0" }, @@ -29691,7 +29688,6 @@ "version": "4.0.8", "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.0.8.tgz", "integrity": "sha512-oz1765PN+imfz1MlZzSZPtC/tqcwsCyIYA8L47EkRnRW97ztRk83SzMiWLrnChC0vqoYxSU1fcFUDA5gV/ZiPg==", - "dev": true, "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" @@ -30086,7 +30082,6 @@ "version": "0.1.2", "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz", "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==", - "dev": true, "engines": { "node": ">= 4.0.0" } @@ -30529,8 +30524,10 @@ "integrity": "sha512-9P3MWk6SrKjHsGkLT2KHXdQ/9SNkyoJbabxnKOoJepsvJjJG8uYTR3yTPxPQvNDI3w4Nz1xnE0TLHK4RIVe/MQ==", "dev": true, "dependencies": { + "chokidar": "^3.4.1", "graceful-fs": "^4.1.2", - "neo-async": "^2.5.0" + "neo-async": "^2.5.0", + "watchpack-chokidar2": "^2.0.1" }, "optionalDependencies": { "chokidar": "^3.4.1", @@ -30627,6 +30624,7 @@ "anymatch": "^2.0.0", "async-each": "^1.0.1", "braces": "^2.3.2", + "fsevents": "^1.2.7", "glob-parent": "^3.1.0", "inherits": "^2.0.3", "is-binary-path": "^1.0.0", @@ -31227,6 +31225,7 @@ "anymatch": "^2.0.0", "async-each": "^1.0.1", "braces": "^2.3.2", + "fsevents": "^1.2.7", "glob-parent": "^3.1.0", "inherits": "^2.0.3", "is-binary-path": "^1.0.0", @@ -33299,7 +33298,6 @@ "version": "11.2.14", "resolved": "https://registry.npmjs.org/@angular/compiler-cli/-/compiler-cli-11.2.14.tgz", "integrity": "sha512-A7ltnCp03/EVqK/Q3tVUDsokgz5GHW3dSPGl0Csk7Ys5uBB9ibHTmVt4eiXA4jt0+6Bk+mKxwe5BEDqLvwYFAg==", - "dev": true, "requires": { "@babel/core": "^7.8.6", "@babel/types": "^7.8.6", @@ -33321,14 +33319,12 @@ "semver": { "version": "6.3.0", "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", - "dev": true + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==" }, "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 + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==" } } }, @@ -33497,14 +33493,12 @@ "@babel/compat-data": { "version": "7.14.7", "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.14.7.tgz", - "integrity": "sha512-nS6dZaISCXJ3+518CWiBfEr//gHyMO02uDxBkXTKZDN5POruCnOZ1N4YBRZDCabwF8nZMWBpRxIicmXtBs+fvw==", - "dev": true + "integrity": "sha512-nS6dZaISCXJ3+518CWiBfEr//gHyMO02uDxBkXTKZDN5POruCnOZ1N4YBRZDCabwF8nZMWBpRxIicmXtBs+fvw==" }, "@babel/core": { "version": "7.14.6", "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.14.6.tgz", "integrity": "sha512-gJnOEWSqTk96qG5BoIrl5bVtc23DCycmIePPYnamY9RboYdI4nFy5vAQMSl81O5K/W0sLDWfGysnOECC+KUUCA==", - "dev": true, "requires": { "@babel/code-frame": "^7.14.5", "@babel/generator": "^7.14.5", @@ -33527,7 +33521,6 @@ "version": "7.14.5", "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.14.5.tgz", "integrity": "sha512-y3rlP+/G25OIX3mYKKIOlQRcqj7YgrvHxOLbVmyLJ9bPmi5ttvUmpydVjcFjZphOktWuA7ovbx91ECloWTfjIA==", - "dev": true, "requires": { "@babel/types": "^7.14.5", "jsesc": "^2.5.1", @@ -33538,7 +33531,6 @@ "version": "7.14.5", "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.14.5.tgz", "integrity": "sha512-6Z3Po85sfxRGachLULUhOmvAaOo7xCvqGQtxINai2mEGPFm6pQ4z5QInFnUrRpfoSV60BnjyF5F3c+15fxFV1g==", - "dev": true, "requires": { "@babel/code-frame": "^7.14.5", "@babel/parser": "^7.14.5", @@ -33548,14 +33540,12 @@ "semver": { "version": "6.3.0", "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", - "dev": true + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==" }, "source-map": { "version": "0.5.7", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", - "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", - "dev": true + "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=" } } }, @@ -33599,7 +33589,6 @@ "version": "7.14.5", "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.14.5.tgz", "integrity": "sha512-v+QtZqXEiOnpO6EYvlImB6zCD2Lel06RzOPzmkz/D/XgQiUu3C/Jb1LOqSt/AIA34TYi/Q+KlT8vTQrgdxkbLw==", - "dev": true, "requires": { "@babel/compat-data": "^7.14.5", "@babel/helper-validator-option": "^7.14.5", @@ -33610,8 +33599,7 @@ "semver": { "version": "6.3.0", "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", - "dev": true + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==" } } }, @@ -33714,7 +33702,6 @@ "version": "7.14.7", "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.14.7.tgz", "integrity": "sha512-TMUt4xKxJn6ccjcOW7c4hlwyJArizskAhoSTOCkA0uZ+KghIaci0Qg9R043kUMWI9mtQfgny+NQ5QATnZ+paaA==", - "dev": true, "requires": { "@babel/types": "^7.14.5" } @@ -33723,7 +33710,6 @@ "version": "7.14.5", "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.14.5.tgz", "integrity": "sha512-SwrNHu5QWS84XlHwGYPDtCxcA0hrSlL2yhWYLgeOc0w7ccOl2qv4s/nARI0aYZW+bSwAL5CukeXA47B/1NKcnQ==", - "dev": true, "requires": { "@babel/types": "^7.14.5" } @@ -33732,7 +33718,6 @@ "version": "7.14.5", "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.14.5.tgz", "integrity": "sha512-iXpX4KW8LVODuAieD7MzhNjmM6dzYY5tfRqT+R9HDXWl0jPn/djKmA+G9s/2C2T9zggw5tK1QNqZ70USfedOwA==", - "dev": true, "requires": { "@babel/helper-module-imports": "^7.14.5", "@babel/helper-replace-supers": "^7.14.5", @@ -33748,7 +33733,6 @@ "version": "7.14.5", "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.14.5.tgz", "integrity": "sha512-6Z3Po85sfxRGachLULUhOmvAaOo7xCvqGQtxINai2mEGPFm6pQ4z5QInFnUrRpfoSV60BnjyF5F3c+15fxFV1g==", - "dev": true, "requires": { "@babel/code-frame": "^7.14.5", "@babel/parser": "^7.14.5", @@ -33761,7 +33745,6 @@ "version": "7.14.5", "resolved": "https://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.14.5.tgz", "integrity": "sha512-IqiLIrODUOdnPU9/F8ib1Fx2ohlgDhxnIDU7OEVi+kAbEZcyiF7BLU8W6PfvPi9LzztjS7kcbzbmL7oG8kD6VA==", - "dev": true, "requires": { "@babel/types": "^7.14.5" } @@ -33787,7 +33770,6 @@ "version": "7.14.5", "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.14.5.tgz", "integrity": "sha512-3i1Qe9/8x/hCHINujn+iuHy+mMRLoc77b2nI9TB0zjH1hvn9qGlXjWlggdwUcju36PkPCy/lpM7LLUdcTyH4Ow==", - "dev": true, "requires": { "@babel/helper-member-expression-to-functions": "^7.14.5", "@babel/helper-optimise-call-expression": "^7.14.5", @@ -33799,7 +33781,6 @@ "version": "7.14.5", "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.14.5.tgz", "integrity": "sha512-nfBN9xvmCt6nrMZjfhkl7i0oTV3yxR4/FztsbOASyTvVcoYd0TRHh7eMLdlEcCqobydC0LAF3LtC92Iwxo0wyw==", - "dev": true, "requires": { "@babel/types": "^7.14.5" } @@ -33829,8 +33810,7 @@ "@babel/helper-validator-option": { "version": "7.14.5", "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.14.5.tgz", - "integrity": "sha512-OX8D5eeX4XwcroVW45NMvoYaIuFI+GQpA2a8Gi+X/U/cDUIRsV37qQfF905F0htTRCREQIB4KqPeaveRJUl3Ow==", - "dev": true + "integrity": "sha512-OX8D5eeX4XwcroVW45NMvoYaIuFI+GQpA2a8Gi+X/U/cDUIRsV37qQfF905F0htTRCREQIB4KqPeaveRJUl3Ow==" }, "@babel/helper-wrap-function": { "version": "7.14.5", @@ -35133,7 +35113,8 @@ "@graphql-typed-document-node/core": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/@graphql-typed-document-node/core/-/core-3.1.0.tgz", - "integrity": "sha512-wYn6r8zVZyQJ6rQaALBEln5B1pzxb9shV5Ef97kTvn6yVGrqyXVnDqnU24MXnFubR+rZjBY9NWuxX3FB2sTsjg==" + "integrity": "sha512-wYn6r8zVZyQJ6rQaALBEln5B1pzxb9shV5Ef97kTvn6yVGrqyXVnDqnU24MXnFubR+rZjBY9NWuxX3FB2sTsjg==", + "requires": {} }, "@istanbuljs/load-nyc-config": { "version": "1.1.0", @@ -35414,7 +35395,8 @@ "version": "1.6.22", "resolved": "https://registry.npmjs.org/@mdx-js/react/-/react-1.6.22.tgz", "integrity": "sha512-TDoPum4SHdfPiGSAaRBw7ECyI8VaHpK8GJugbJIJuqyh6kzw9ZLJZW3HGL3NNrJGxcAixUvqROm+YuQOo5eXtg==", - "dev": true + "dev": true, + "requires": {} }, "@mdx-js/util": { "version": "1.6.22", @@ -35938,7 +35920,8 @@ "@progress/kendo-charts": { "version": "1.18.3", "resolved": "https://registry.npmjs.org/@progress/kendo-charts/-/kendo-charts-1.18.3.tgz", - "integrity": "sha512-d6mGNRE4+JzKM2j4MP+wyu+3smmfBa2bOvbgHu53ljQQPtX5q9jUbr8JOVtboxPAODdItM1HA0MWn8fMN6KmaA==" + "integrity": "sha512-d6mGNRE4+JzKM2j4MP+wyu+3smmfBa2bOvbgHu53ljQQPtX5q9jUbr8JOVtboxPAODdItM1HA0MWn8fMN6KmaA==", + "requires": {} }, "@progress/kendo-common": { "version": "0.2.1", @@ -36384,7 +36367,8 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/@storybook/addon-measure/-/addon-measure-2.0.0.tgz", "integrity": "sha512-ZhdT++cX+L9LwjhGYggvYUUVQH/MGn2rwbrAwCMzA/f2QTFvkjxzX8nDgMxIhaLCDC+gHIxfJG2wrWN0jkBr3g==", - "dev": true + "dev": true, + "requires": {} }, "@storybook/addon-toolbars": { "version": "6.3.2", @@ -38998,7 +38982,8 @@ "version": "5.3.1", "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.1.tgz", "integrity": "sha512-K0Ptm/47OKfQRpNQ2J/oIN/3QYiK6FwW+eJbILhsdxh2WTLdl+30o8aGdTbm5JbffpFFAg/g+zi1E+jvJha5ng==", - "dev": true + "dev": true, + "requires": {} }, "acorn-node": { "version": "1.8.2", @@ -39109,13 +39094,15 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/ajv-errors/-/ajv-errors-1.0.1.tgz", "integrity": "sha512-DCRfO/4nQ+89p/RK43i8Ezd41EqdGIU4ld7nGF8OQ14oc/we5rEntLCUa7+jrn3nn83BosfwZA0wb4pon2o8iQ==", - "dev": true + "dev": true, + "requires": {} }, "ajv-keywords": { "version": "3.5.2", "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.5.2.tgz", "integrity": "sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ==", - "dev": true + "dev": true, + "requires": {} }, "alphanum-sort": { "version": "1.0.2", @@ -39241,7 +39228,6 @@ "version": "3.1.2", "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.2.tgz", "integrity": "sha512-P43ePfOAIupkguHUycrc4qJ9kz8ZiuOUijaETwX7THt0Y/GNK7v0aa8rY816xWjZ7rJdA5XdMcpVFTKMq+RvWg==", - "dev": true, "requires": { "normalize-path": "^3.0.0", "picomatch": "^2.0.4" @@ -39974,8 +39960,7 @@ "binary-extensions": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz", - "integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==", - "dev": true + "integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==" }, "bindings": { "version": "1.5.0", @@ -40170,7 +40155,6 @@ "version": "3.0.2", "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", - "dev": true, "requires": { "fill-range": "^7.0.1" } @@ -40315,7 +40299,6 @@ "version": "4.16.6", "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.16.6.tgz", "integrity": "sha512-Wspk/PqO+4W9qp5iUTJsa1B/QrYn1keNCcEP5OvP7WBwT4KaDly0uONYmC6Xa3Z5IqnUgS0KcgLYu1l74x0ZXQ==", - "dev": true, "requires": { "caniuse-lite": "^1.0.30001219", "colorette": "^1.2.2", @@ -40559,14 +40542,12 @@ "caniuse-lite": { "version": "1.0.30001241", "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001241.tgz", - "integrity": "sha512-1uoSZ1Pq1VpH0WerIMqwptXHNNGfdl7d1cJUFs80CwQ/lVzdhTvsFZCeNFslze7AjsQnb4C85tzclPa1VShbeQ==", - "dev": true + "integrity": "sha512-1uoSZ1Pq1VpH0WerIMqwptXHNNGfdl7d1cJUFs80CwQ/lVzdhTvsFZCeNFslze7AjsQnb4C85tzclPa1VShbeQ==" }, "canonical-path": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/canonical-path/-/canonical-path-1.0.0.tgz", - "integrity": "sha512-feylzsbDxi1gPZ1IjystzIQZagYYLvfKrSuygUCgf7z6x790VEzze5QEkdSV1U58RA7Hi0+v6fv4K54atOzATg==", - "dev": true + "integrity": "sha512-feylzsbDxi1gPZ1IjystzIQZagYYLvfKrSuygUCgf7z6x790VEzze5QEkdSV1U58RA7Hi0+v6fv4K54atOzATg==" }, "capture-exit": { "version": "2.0.0", @@ -40669,7 +40650,6 @@ "version": "3.5.2", "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.2.tgz", "integrity": "sha512-ekGhOnNVPgT77r4K/U3GDhu+FQ2S8TnK/s2KbIGXi0SZWuwkZ2QNyfWdZW+TVfn84DpEP7rLeCt2UI6bJ8GwbQ==", - "dev": true, "requires": { "anymatch": "~3.1.2", "braces": "~3.0.2", @@ -40713,7 +40693,8 @@ "version": "5.2.2", "resolved": "https://registry.npmjs.org/circular-dependency-plugin/-/circular-dependency-plugin-5.2.2.tgz", "integrity": "sha512-g38K9Cm5WRwlaH6g03B9OEz/0qRizI+2I7n+Gz+L5DxXJAPAiWQvwlYNm1V1jkdpUv95bOe/ASm2vfi/G560jQ==", - "dev": true + "dev": true, + "requires": {} }, "class-utils": { "version": "0.3.6", @@ -40943,13 +40924,15 @@ "version": "9.0.0", "resolved": "https://registry.npmjs.org/@angular/compiler/-/compiler-9.0.0.tgz", "integrity": "sha512-ctjwuntPfZZT2mNj2NDIVu51t9cvbhl/16epc5xEwyzyDt76pX9UgwvY+MbXrf/C/FWwdtmNtfP698BKI+9leQ==", - "dev": true + "dev": true, + "requires": {} }, "@angular/core": { "version": "9.0.0", "resolved": "https://registry.npmjs.org/@angular/core/-/core-9.0.0.tgz", "integrity": "sha512-6Pxgsrf0qF9iFFqmIcWmjJGkkCaCm6V5QNnxMy2KloO3SDq6QuMVRbN9RtC8Urmo25LP+eZ6ZgYqFYpdD8Hd9w==", - "dev": true + "dev": true, + "requires": {} }, "source-map": { "version": "0.5.7", @@ -41029,8 +41012,7 @@ "colorette": { "version": "1.2.2", "resolved": "https://registry.npmjs.org/colorette/-/colorette-1.2.2.tgz", - "integrity": "sha512-MKGMzyfeuutC/ZJ1cba9NqcNpfeqMUcYmyF1ZFY6/Cn7CNSAKx6a+s48sqLqyAiZuaP2TcqMhoo+dlwFnVxT9w==", - "dev": true + "integrity": "sha512-MKGMzyfeuutC/ZJ1cba9NqcNpfeqMUcYmyF1ZFY6/Cn7CNSAKx6a+s48sqLqyAiZuaP2TcqMhoo+dlwFnVxT9w==" }, "colors": { "version": "1.4.0", @@ -42188,7 +42170,8 @@ "version": "2.0.1", "resolved": "https://registry.npmjs.org/cssnano-utils/-/cssnano-utils-2.0.1.tgz", "integrity": "sha512-i8vLRZTnEH9ubIyfdZCAdIdgnHAUeQeByEeQ2I7oTilvP9oHO6RScpeq3GsFUVqeB8uZgOQ9pw8utofNn32hhQ==", - "dev": true + "dev": true, + "requires": {} }, "csso": { "version": "4.2.0", @@ -42428,8 +42411,7 @@ "dependency-graph": { "version": "0.7.2", "resolved": "https://registry.npmjs.org/dependency-graph/-/dependency-graph-0.7.2.tgz", - "integrity": "sha512-KqtH4/EZdtdfWX0p6MGP9jljvxSY6msy/pRUD4jgNwVpv3v1QmNLlsB3LDSSUg79BRVSn7jI1QPRtArGABovAQ==", - "dev": true + "integrity": "sha512-KqtH4/EZdtdfWX0p6MGP9jljvxSY6msy/pRUD4jgNwVpv3v1QmNLlsB3LDSSUg79BRVSn7jI1QPRtArGABovAQ==" }, "des.js": { "version": "1.0.1", @@ -42869,8 +42851,7 @@ "electron-to-chromium": { "version": "1.3.762", "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.762.tgz", - "integrity": "sha512-LehWjRpfPcK8F1Lf/NZoAwWLWnjJVo0SZeQ9j/tvnBWYcT99qDqgo4raAfS2oTKZjPrR/jxruh85DGgDUmywEA==", - "dev": true + "integrity": "sha512-LehWjRpfPcK8F1Lf/NZoAwWLWnjJVo0SZeQ9j/tvnBWYcT99qDqgo4raAfS2oTKZjPrR/jxruh85DGgDUmywEA==" }, "element-resize-detector": { "version": "1.2.3", @@ -43872,7 +43853,6 @@ "version": "7.0.1", "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", - "dev": true, "requires": { "to-regex-range": "^5.0.1" } @@ -44282,7 +44262,6 @@ "version": "4.0.2", "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-4.0.2.tgz", "integrity": "sha1-+RcExT0bRh+JNFKwwwfZmXZHq2s=", - "dev": true, "requires": { "graceful-fs": "^4.1.2", "jsonfile": "^4.0.0", @@ -44351,7 +44330,6 @@ "version": "2.3.2", "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz", "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==", - "dev": true, "optional": true }, "function-bind": { @@ -44570,7 +44548,6 @@ "version": "5.1.2", "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", - "dev": true, "requires": { "is-glob": "^4.0.1" } @@ -44659,8 +44636,7 @@ "graceful-fs": { "version": "4.2.6", "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.6.tgz", - "integrity": "sha512-nTnJ528pbqxYanhpDYsi4Rd8MAeaBA67+RZ10CM1m3bTAVFEDcd5AuA4a6W5YkGZ1iNXHzZz8T6TBKLeBuNriQ==", - "dev": true + "integrity": "sha512-nTnJ528pbqxYanhpDYsi4Rd8MAeaBA67+RZ10CM1m3bTAVFEDcd5AuA4a6W5YkGZ1iNXHzZz8T6TBKLeBuNriQ==" }, "graphql": { "version": "15.5.1", @@ -45632,7 +45608,8 @@ "version": "5.1.0", "resolved": "https://registry.npmjs.org/icss-utils/-/icss-utils-5.1.0.tgz", "integrity": "sha512-soFhflCVWLfRNOPU3iv5Z9VUdT44xFRbzjLsEzSr5AQmgqPMTHdU3PMT1Cf1ssx8fLNJDA1juftYl+PUcv3MqA==", - "dev": true + "dev": true, + "requires": {} }, "ieee754": { "version": "1.2.1", @@ -46015,7 +45992,6 @@ "version": "2.1.0", "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", - "dev": true, "requires": { "binary-extensions": "^2.0.0" } @@ -46146,8 +46122,7 @@ "is-extglob": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", - "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=", - "dev": true + "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=" }, "is-fullwidth-code-point": { "version": "3.0.0", @@ -46164,7 +46139,6 @@ "version": "4.0.1", "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.1.tgz", "integrity": "sha512-5G0tKtBTFImOqDnLB2hG6Bp2qcKEFduo4tZu9MT/H6NQv/ghhy30o55ufafxJ/LdH79LLs2Kfrn85TLKyA7BUg==", - "dev": true, "requires": { "is-extglob": "^2.1.1" } @@ -46213,8 +46187,7 @@ "is-number": { "version": "7.0.0", "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", - "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", - "dev": true + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==" }, "is-number-object": { "version": "1.0.5", @@ -46898,7 +46871,6 @@ "version": "4.0.0", "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz", "integrity": "sha1-h3Gq4HmbZAdrdmQPygWPnBDjPss=", - "dev": true, "requires": { "graceful-fs": "^4.1.6" } @@ -47105,7 +47077,8 @@ "version": "1.6.0", "resolved": "https://registry.npmjs.org/karma-jasmine-html-reporter/-/karma-jasmine-html-reporter-1.6.0.tgz", "integrity": "sha512-ELO9yf0cNqpzaNLsfFgXd/wxZVYkE2+ECUwhMHUD4PZ17kcsPsYsVyjquiRqyMn2jkd2sHt0IeMyAyq1MC23Fw==", - "dev": true + "dev": true, + "requires": {} }, "karma-source-map-support": { "version": "1.4.0", @@ -47183,7 +47156,8 @@ "leaflet.markercluster": { "version": "1.5.0", "resolved": "https://registry.npmjs.org/leaflet.markercluster/-/leaflet.markercluster-1.5.0.tgz", - "integrity": "sha512-Fvf/cq4o806mJL50n+fZW9+QALDDLPvt7vuAjlD2vfnxx3srMDs2vWINJze4nKYJYRY45OC6tM/669C3pLwMCA==" + "integrity": "sha512-Fvf/cq4o806mJL50n+fZW9+QALDDLPvt7vuAjlD2vfnxx3srMDs2vWINJze4nKYJYRY45OC6tM/669C3pLwMCA==", + "requires": {} }, "less": { "version": "4.1.1", @@ -47935,7 +47909,8 @@ "version": "7.1.3", "resolved": "https://registry.npmjs.org/markdown-to-jsx/-/markdown-to-jsx-7.1.3.tgz", "integrity": "sha512-jtQ6VyT7rMT5tPV0g2EJakEnXLiPksnvlYtwQsVVZ611JsWGN8bQ1tVSDX4s6JllfEH6wmsYxNjTUAMrPmNA8w==", - "dev": true + "dev": true, + "requires": {} }, "marked": { "version": "0.7.0", @@ -49830,8 +49805,7 @@ "node-releases": { "version": "1.1.73", "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-1.1.73.tgz", - "integrity": "sha512-uW7fodD6pyW2FZNZnp/Z3hvWKeEW1Y8R1+1CnErE8cXFXzl5blBOoVB41CvMer6P6Q0S5FXDwcHgFd1Wj0U9zg==", - "dev": true + "integrity": "sha512-uW7fodD6pyW2FZNZnp/Z3hvWKeEW1Y8R1+1CnErE8cXFXzl5blBOoVB41CvMer6P6Q0S5FXDwcHgFd1Wj0U9zg==" }, "node-sass-tilde-importer": { "version": "1.0.2", @@ -49880,8 +49854,7 @@ "normalize-path": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", - "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", - "dev": true + "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==" }, "normalize-range": { "version": "0.1.2", @@ -50854,8 +50827,7 @@ "picomatch": { "version": "2.3.0", "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.0.tgz", - "integrity": "sha512-lY1Q/PiJGC2zOv/z391WOTD+Z02bCgsFfvxoXXf6h7kv9o+WmsmzYqrAwY63sNgOxE4xEdq0WyUnXfKeBrSvYw==", - "dev": true + "integrity": "sha512-lY1Q/PiJGC2zOv/z391WOTD+Z02bCgsFfvxoXXf6h7kv9o+WmsmzYqrAwY63sNgOxE4xEdq0WyUnXfKeBrSvYw==" }, "pify": { "version": "2.3.0", @@ -51085,25 +51057,29 @@ "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 + "dev": true, + "requires": {} }, "postcss-discard-duplicates": { "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 + "dev": true, + "requires": {} }, "postcss-discard-empty": { "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 + "dev": true, + "requires": {} }, "postcss-discard-overridden": { "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 + "dev": true, + "requires": {} }, "postcss-flexbugs-fixes": { "version": "4.2.1", @@ -51291,7 +51267,8 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/postcss-modules-extract-imports/-/postcss-modules-extract-imports-3.0.0.tgz", "integrity": "sha512-bdHleFnP3kZ4NYDhuGlVK+CMrQ/pqUm8bx/oGL93K6gVwiclvX5x0n76fYMKuIGKzlABOy13zsvqjb0f92TEXw==", - "dev": true + "dev": true, + "requires": {} }, "postcss-modules-local-by-default": { "version": "4.0.0", @@ -51326,7 +51303,8 @@ "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 + "dev": true, + "requires": {} }, "postcss-normalize-display-values": { "version": "5.0.1", @@ -52138,7 +52116,7 @@ "version": "16.14.0", "resolved": "https://registry.npmjs.org/react/-/react-16.14.0.tgz", "integrity": "sha512-0X2CImDkJGApiAlcf0ODKIneSwBPhqJawOa5wCtKbu7ZECrmS26NvtSILynQ66cgkT/RJ4LidJOc3bUESwmU8g==", - "dev": true, + "devOptional": true, "requires": { "loose-envify": "^1.1.0", "object-assign": "^4.1.1", @@ -52149,7 +52127,8 @@ "version": "5.2.2", "resolved": "https://registry.npmjs.org/react-colorful/-/react-colorful-5.2.2.tgz", "integrity": "sha512-Xdb1Rl6lZ5SMdNBH59eE0lGqR1g2LVD8IgPlw0WeMDrOC65lYI8fgMEwj/0dDpVRVMh5qp73ciISDst/t2O2iQ==", - "dev": true + "dev": true, + "requires": {} }, "react-dev-utils": { "version": "11.0.4", @@ -52505,7 +52484,6 @@ "version": "3.6.0", "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", - "dev": true, "requires": { "picomatch": "^2.2.1" } @@ -52527,8 +52505,7 @@ "reflect-metadata": { "version": "0.1.13", "resolved": "https://registry.npmjs.org/reflect-metadata/-/reflect-metadata-0.1.13.tgz", - "integrity": "sha512-Ts1Y/anZELhSsjMcU605fU9RE4Oi3p5ORujwbIKXfWa+0Zxs510Qrmrce5/Jowq3cHSZSJqBjypxmHarc+vEWg==", - "dev": true + "integrity": "sha512-Ts1Y/anZELhSsjMcU605fU9RE4Oi3p5ORujwbIKXfWa+0Zxs510Qrmrce5/Jowq3cHSZSJqBjypxmHarc+vEWg==" }, "refractor": { "version": "3.4.0", @@ -54246,6 +54223,11 @@ "wbuf": "^1.7.3" } }, + "speak-tts": { + "version": "2.0.8", + "resolved": "https://registry.npmjs.org/speak-tts/-/speak-tts-2.0.8.tgz", + "integrity": "sha512-VY6Q6mRjdou6bF+x0LspvM7GJhBxHx8CLyGPTNQQ7jrztiGutyI4QNZn0cA17c4uk0FnFbA4PaMI3skeZ6PiFg==" + }, "speed-measure-webpack-plugin": { "version": "1.4.2", "resolved": "https://registry.npmjs.org/speed-measure-webpack-plugin/-/speed-measure-webpack-plugin-1.4.2.tgz", @@ -55411,7 +55393,6 @@ "version": "5.0.1", "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", - "dev": true, "requires": { "is-number": "^7.0.0" } @@ -56118,8 +56099,7 @@ "typescript": { "version": "4.0.8", "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.0.8.tgz", - "integrity": "sha512-oz1765PN+imfz1MlZzSZPtC/tqcwsCyIYA8L47EkRnRW97ztRk83SzMiWLrnChC0vqoYxSU1fcFUDA5gV/ZiPg==", - "dev": true + "integrity": "sha512-oz1765PN+imfz1MlZzSZPtC/tqcwsCyIYA8L47EkRnRW97ztRk83SzMiWLrnChC0vqoYxSU1fcFUDA5gV/ZiPg==" }, "ua-parser-js": { "version": "0.7.28", @@ -56408,8 +56388,7 @@ "universalify": { "version": "0.1.2", "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz", - "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==", - "dev": true + "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==" }, "unix-crypt-td-js": { "version": "1.1.4", @@ -56560,7 +56539,8 @@ "version": "1.1.1", "resolved": "https://registry.npmjs.org/use-isomorphic-layout-effect/-/use-isomorphic-layout-effect-1.1.1.tgz", "integrity": "sha512-L7Evj8FGcwo/wpbv/qvSfrkHFtOpCzvM5yl2KVyDJoylVuSvzphiiasmjgQPttIGBAy2WKiBNR98q8w7PiNgKQ==", - "dev": true + "dev": true, + "requires": {} }, "use-latest": { "version": "1.2.0", @@ -58219,7 +58199,8 @@ "version": "1.2.1", "resolved": "https://registry.npmjs.org/webpack-filter-warnings-plugin/-/webpack-filter-warnings-plugin-1.2.1.tgz", "integrity": "sha512-Ez6ytc9IseDMLPo0qCuNNYzgtUl8NovOqjIq4uAU8LTD4uoa1w1KpZyyzFtLTEMZpkkOkLfL9eN+KGYdk1Qtwg==", - "dev": true + "dev": true, + "requires": {} }, "webpack-hot-middleware": { "version": "2.25.0", @@ -58586,7 +58567,8 @@ "ws": { "version": "7.4.6", "resolved": "https://registry.npmjs.org/ws/-/ws-7.4.6.tgz", - "integrity": "sha512-YmhHDO4MzaDLB+M9ym/mDA5z0naX8j7SIlT8f8z+I0VtzsRbekxEutHSme7NPS2qE8StCYQNUnfWdXta/Yu85A==" + "integrity": "sha512-YmhHDO4MzaDLB+M9ym/mDA5z0naX8j7SIlT8f8z+I0VtzsRbekxEutHSme7NPS2qE8StCYQNUnfWdXta/Yu85A==", + "requires": {} }, "xml2js": { "version": "0.4.23", diff --git a/package.json b/package.json index b4172a77b9..9392c06f2d 100644 --- a/package.json +++ b/package.json @@ -71,6 +71,7 @@ "leaflet.markercluster": "^1.4.1", "msal": "^1.4.4", "rxjs": "~6.6.7", + "speak-tts": "^2.0.8", "subscriptions-transport-ws": "^0.9.18", "survey-angular": "^1.8.54", "survey-creator": "^1.8.54", diff --git a/projects/back-office/src/app/app-routing.module.ts b/projects/back-office/src/app/app-routing.module.ts index 5d4bf2dad1..2ece9de3a3 100644 --- a/projects/back-office/src/app/app-routing.module.ts +++ b/projects/back-office/src/app/app-routing.module.ts @@ -2,6 +2,7 @@ import { NgModule } from '@angular/core'; import { Routes, RouterModule } from '@angular/router'; import { MsalGuard } from '@azure/msal-angular'; import { AccessGuard } from './guards/access.guard'; +import {VirtualAssistantComponent} from './virtual-assistant/virtual-assistant.component'; const routes: Routes = [ { @@ -31,7 +32,17 @@ const routes: Routes = [ .then(m => m.AppPreviewModule), } ] - } + }, + { + path: 'va', + children: [ + { + path: ':id', + loadChildren: () => import('./virtual-assistant/virtual-assistant.module') + .then(m => m.VirtualAssistantModule), + } + ] + }, ], canActivate: [MsalGuard, AccessGuard] }, diff --git a/projects/back-office/src/app/dashboard/pages/forms/forms.component.html b/projects/back-office/src/app/dashboard/pages/forms/forms.component.html index 52d4f1721b..cc79d522e5 100644 --- a/projects/back-office/src/app/dashboard/pages/forms/forms.component.html +++ b/projects/back-office/src/app/dashboard/pages/forms/forms.component.html @@ -179,6 +179,10 @@ delete Delete + @@ -188,4 +192,4 @@ [ngClass]="{'clickable': ( row.canCreate && (row.status === 'active') )}" [routerLink]="( row.canCreate && (row.status === 'active') ) ? ['/forms/answer', row.id] : []"> - \ No newline at end of file + diff --git a/projects/back-office/src/app/dashboard/pages/forms/forms.component.ts b/projects/back-office/src/app/dashboard/pages/forms/forms.component.ts index cefc9942ab..de05b0b7b0 100644 --- a/projects/back-office/src/app/dashboard/pages/forms/forms.component.ts +++ b/projects/back-office/src/app/dashboard/pages/forms/forms.component.ts @@ -19,6 +19,7 @@ import { AddFormComponent } from '../../../components/add-form/add-form.componen import { MatTableDataSource } from '@angular/material/table'; import { MatSort } from '@angular/material/sort'; import { MatEndDate, MatStartDate } from '@angular/material/datepicker'; +import {SafeDownloadService} from '../../../../../../safe/src/lib/services/download.service'; @Component({ @@ -57,7 +58,8 @@ export class FormsComponent implements OnInit, OnDestroy, AfterViewInit { public dialog: MatDialog, private router: Router, private snackBar: SafeSnackBarService, - private authService: SafeAuthService + private authService: SafeAuthService, + private downloadService: SafeDownloadService ) {} /* Load the forms. @@ -191,4 +193,13 @@ export class FormsComponent implements OnInit, OnDestroy, AfterViewInit { this.coreFilter = ''; this.clearDateFilter(); } + + async onExportAssistant(element: any, $event: any): Promise { + console.log(element); + // const path = `download/form/${element.id}`; + // const dataReturn = await this.downloadService.getForm(path); + window.open(`/va/${element.id}`); + // this.router.navigate([`/va/${element.id}`]); + // return dataReturn; + } } diff --git a/projects/back-office/src/app/graphql/mutations.ts b/projects/back-office/src/app/graphql/mutations.ts index 7b8e585e4c..8ee4885967 100644 --- a/projects/back-office/src/app/graphql/mutations.ts +++ b/projects/back-office/src/app/graphql/mutations.ts @@ -198,6 +198,28 @@ export interface DeleteResourceMutationResponse{ deletedResource: Resource; } +// === ADD RECORD === +export const ADD_RECORD = gql` +mutation addRecord($form: ID!, $data: JSON!, $display: Boolean) { + addRecord(form: $form, data: $data) { + id + createdAt + modifiedAt + data(display: $display) + form { + uniqueRecord { + id + modifiedAt + data + } + } + } +}`; + +export interface AddRecordMutationResponse { + loading: boolean; + addRecord: Record; +} // === DELETE RECORD === export const DELETE_RECORD = gql` diff --git a/projects/back-office/src/app/virtual-assistant/models/choices.model.ts b/projects/back-office/src/app/virtual-assistant/models/choices.model.ts new file mode 100644 index 0000000000..3bb8f7795c --- /dev/null +++ b/projects/back-office/src/app/virtual-assistant/models/choices.model.ts @@ -0,0 +1,9 @@ +export class Choices { + value: any; + text: string; + + constructor(value: any, text: string) { + this.value = value; + this.text = text; + } +} diff --git a/projects/back-office/src/app/virtual-assistant/models/message.model.ts b/projects/back-office/src/app/virtual-assistant/models/message.model.ts new file mode 100644 index 0000000000..b4df089824 --- /dev/null +++ b/projects/back-office/src/app/virtual-assistant/models/message.model.ts @@ -0,0 +1,26 @@ +import { User } from './user.model'; +import {Choices} from './choices.model'; + +export class Message { + type: string; + text: string; + reply: boolean; + user: User; + date: number; + choices: Choices[]; + + // tslint:disable-next-line:max-line-length + constructor(type: string, + text: string, + reply: boolean, + user: User, + date: number, + choices: Choices[]) { + this.type = type; + this.text = text; + this.reply = reply; + this.user = user; + this.date = date; + this.choices = choices; + } +} diff --git a/projects/back-office/src/app/virtual-assistant/models/user.model.ts b/projects/back-office/src/app/virtual-assistant/models/user.model.ts new file mode 100644 index 0000000000..12aa02e5d7 --- /dev/null +++ b/projects/back-office/src/app/virtual-assistant/models/user.model.ts @@ -0,0 +1,9 @@ +export class User { + name: string; + avatar: string; + + constructor(name: string, avatar: string) { + this.name = name; + this.avatar = avatar; + } +} diff --git a/projects/back-office/src/app/virtual-assistant/va-conversation/conversation-footer/conversation-footer.component.html b/projects/back-office/src/app/virtual-assistant/va-conversation/conversation-footer/conversation-footer.component.html new file mode 100644 index 0000000000..ead10c8f5c --- /dev/null +++ b/projects/back-office/src/app/virtual-assistant/va-conversation/conversation-footer/conversation-footer.component.html @@ -0,0 +1,5 @@ + diff --git a/projects/back-office/src/app/virtual-assistant/va-conversation/conversation-footer/conversation-footer.component.scss b/projects/back-office/src/app/virtual-assistant/va-conversation/conversation-footer/conversation-footer.component.scss new file mode 100644 index 0000000000..be17b5968b --- /dev/null +++ b/projects/back-office/src/app/virtual-assistant/va-conversation/conversation-footer/conversation-footer.component.scss @@ -0,0 +1,30 @@ +#footer { + height: 50px; + border-top: 1px solid lightgray; + border-radius: 0 0 5px 5px; + text-align: center; +} + +#inputMsg { + height: 30px; + margin-top: 7px; + margin-left: 5px; + width: 390px; + border: 1px solid lightgray; + border-radius: 5px; + padding-left: 5px; +} + +.btnFoot { + margin-left: 10px; +} + +#btnSend { + background-color: green; + color: white; +} + +#btnRec { + background-color: indianred; + color: white; +} diff --git a/projects/back-office/src/app/virtual-assistant/va-conversation/conversation-footer/conversation-footer.component.spec.ts b/projects/back-office/src/app/virtual-assistant/va-conversation/conversation-footer/conversation-footer.component.spec.ts new file mode 100644 index 0000000000..815d8161c2 --- /dev/null +++ b/projects/back-office/src/app/virtual-assistant/va-conversation/conversation-footer/conversation-footer.component.spec.ts @@ -0,0 +1,25 @@ +import { ComponentFixture, TestBed } from '@angular/core/testing'; + +import { ConversationFooterComponent } from './conversation-footer.component'; + +describe('ConversationFooterComponent', () => { + let component: ConversationFooterComponent; + let fixture: ComponentFixture; + + beforeEach(async () => { + await TestBed.configureTestingModule({ + declarations: [ ConversationFooterComponent ] + }) + .compileComponents(); + }); + + beforeEach(() => { + fixture = TestBed.createComponent(ConversationFooterComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/projects/back-office/src/app/virtual-assistant/va-conversation/conversation-footer/conversation-footer.component.ts b/projects/back-office/src/app/virtual-assistant/va-conversation/conversation-footer/conversation-footer.component.ts new file mode 100644 index 0000000000..1ad7e827ac --- /dev/null +++ b/projects/back-office/src/app/virtual-assistant/va-conversation/conversation-footer/conversation-footer.component.ts @@ -0,0 +1,60 @@ +import {Component, EventEmitter, Input, OnChanges, OnInit, Output, SimpleChanges} from '@angular/core'; + +@Component({ + selector: 'app-conversation-footer', + templateUrl: './conversation-footer.component.html', + styleUrls: ['./conversation-footer.component.scss'] +}) + +export class ConversationFooterComponent implements OnInit, OnChanges { + + @Output() btnSendClick: EventEmitter = new EventEmitter(); + @Output() btnRecClick: EventEmitter = new EventEmitter(); + + @Output() inputChange: EventEmitter = new EventEmitter(); + + public input: any; + public btnSend: any; + public btnRec: any; + + @Input() inputValue = ''; + @Input() inputType = ''; + + ngOnChanges(changes: SimpleChanges): void { + // we skip that at the beginning when object are not yet set + if (this.input !== undefined && changes.inputValue !== undefined){ + console.log('ngOnChanges : ' + this.inputValue); + this.input.value = null; + this.input.value = ''; + console.log('this.input.value : ' + this.input.value); + console.log('changes.inputValue.currentValue : ' + changes.inputValue.currentValue); + console.log('this.inputValue : ' + this.inputValue); + console.log('this.inputType : ' + this.inputType); + console.log('this.input.value : ' + this.input.value); + if (changes.inputValue.currentValue === '' && this.inputValue !== ''){ + // this.msgChange(this.inputValue); + } + else if (changes.inputValue.currentValue !== ''){ + this.msgChange(changes.inputValue.currentValue); + } + this.inputFocus(); + } + } + + constructor() { + } + + ngOnInit(): void { + this.input = document.getElementById('inputMsg'); + this.btnSend = document.getElementById('btnSend'); + this.btnRec = document.getElementById('btnRec'); + } + + inputFocus(): void { + this.input.focus(); + } + + msgChange(text: string): void { + this.inputChange.emit(text); + } +} diff --git a/projects/back-office/src/app/virtual-assistant/va-conversation/conversation-header/conversation-header.component.html b/projects/back-office/src/app/virtual-assistant/va-conversation/conversation-header/conversation-header.component.html new file mode 100644 index 0000000000..b330f61b39 --- /dev/null +++ b/projects/back-office/src/app/virtual-assistant/va-conversation/conversation-header/conversation-header.component.html @@ -0,0 +1,3 @@ + diff --git a/projects/back-office/src/app/virtual-assistant/va-conversation/conversation-header/conversation-header.component.scss b/projects/back-office/src/app/virtual-assistant/va-conversation/conversation-header/conversation-header.component.scss new file mode 100644 index 0000000000..fda5d35839 --- /dev/null +++ b/projects/back-office/src/app/virtual-assistant/va-conversation/conversation-header/conversation-header.component.scss @@ -0,0 +1,13 @@ +#header { + height: 50px; + border-radius: 5px 5px 0 0; + background-color: #60d295; + display: flex; + align-items: center; + color: white; +} + +#convName { + display: inline; + margin-left: 10px; +} diff --git a/projects/back-office/src/app/virtual-assistant/va-conversation/conversation-header/conversation-header.component.spec.ts b/projects/back-office/src/app/virtual-assistant/va-conversation/conversation-header/conversation-header.component.spec.ts new file mode 100644 index 0000000000..0d1dc60a6f --- /dev/null +++ b/projects/back-office/src/app/virtual-assistant/va-conversation/conversation-header/conversation-header.component.spec.ts @@ -0,0 +1,25 @@ +import { ComponentFixture, TestBed } from '@angular/core/testing'; + +import { ConversationHeaderComponent } from './conversation-header.component'; + +describe('ConversationHeaderComponent', () => { + let component: ConversationHeaderComponent; + let fixture: ComponentFixture; + + beforeEach(async () => { + await TestBed.configureTestingModule({ + declarations: [ ConversationHeaderComponent ] + }) + .compileComponents(); + }); + + beforeEach(() => { + fixture = TestBed.createComponent(ConversationHeaderComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/projects/back-office/src/app/virtual-assistant/va-conversation/conversation-header/conversation-header.component.ts b/projects/back-office/src/app/virtual-assistant/va-conversation/conversation-header/conversation-header.component.ts new file mode 100644 index 0000000000..b7d91b779c --- /dev/null +++ b/projects/back-office/src/app/virtual-assistant/va-conversation/conversation-header/conversation-header.component.ts @@ -0,0 +1,15 @@ +import { Component, OnInit } from '@angular/core'; + +@Component({ + selector: 'app-conversation-header', + templateUrl: './conversation-header.component.html', + styleUrls: ['./conversation-header.component.scss'] +}) +export class ConversationHeaderComponent implements OnInit { + + constructor() { } + + ngOnInit(): void { + } + +} diff --git a/projects/back-office/src/app/virtual-assistant/va-conversation/conversation-message/conversation-message.component.html b/projects/back-office/src/app/virtual-assistant/va-conversation/conversation-message/conversation-message.component.html new file mode 100644 index 0000000000..86f4a7e609 --- /dev/null +++ b/projects/back-office/src/app/virtual-assistant/va-conversation/conversation-message/conversation-message.component.html @@ -0,0 +1,24 @@ +
+ +
+ profile_photo +

+
+
+ +
+ profile_photo +

+
+
+
+ +
+
+
+ +
+
+ +
+
diff --git a/projects/back-office/src/app/virtual-assistant/va-conversation/conversation-message/conversation-message.component.scss b/projects/back-office/src/app/virtual-assistant/va-conversation/conversation-message/conversation-message.component.scss new file mode 100644 index 0000000000..48eb71d98f --- /dev/null +++ b/projects/back-office/src/app/virtual-assistant/va-conversation/conversation-message/conversation-message.component.scss @@ -0,0 +1,36 @@ +.messageGlobal{ + display: flex; + align-items: center; + width: fit-content; + padding: 5px; + border-radius: 15px; + margin-left: 0; + margin-right: auto; + margin-bottom: 10px; +} + +img { + display: inline; + height: 40px; + width:40px; + border-radius: 100px; +} + +p { + display: inline; + margin-left: 10px; + color: white; +} + +.btnChoices { + margin-right: 5px; + margin-bottom: 5px; +} + +.btnChoicesCont { + +} + +#btnChoicesValidate { + background-color: #60d295; +} diff --git a/projects/back-office/src/app/virtual-assistant/va-conversation/conversation-message/conversation-message.component.spec.ts b/projects/back-office/src/app/virtual-assistant/va-conversation/conversation-message/conversation-message.component.spec.ts new file mode 100644 index 0000000000..35223bfbee --- /dev/null +++ b/projects/back-office/src/app/virtual-assistant/va-conversation/conversation-message/conversation-message.component.spec.ts @@ -0,0 +1,25 @@ +import { ComponentFixture, TestBed } from '@angular/core/testing'; + +import { ConversationMessageComponent } from './conversation-message.component'; + +describe('ConversationMessageComponent', () => { + let component: ConversationMessageComponent; + let fixture: ComponentFixture; + + beforeEach(async () => { + await TestBed.configureTestingModule({ + declarations: [ ConversationMessageComponent ] + }) + .compileComponents(); + }); + + beforeEach(() => { + fixture = TestBed.createComponent(ConversationMessageComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/projects/back-office/src/app/virtual-assistant/va-conversation/conversation-message/conversation-message.component.ts b/projects/back-office/src/app/virtual-assistant/va-conversation/conversation-message/conversation-message.component.ts new file mode 100644 index 0000000000..61acb1bf69 --- /dev/null +++ b/projects/back-office/src/app/virtual-assistant/va-conversation/conversation-message/conversation-message.component.ts @@ -0,0 +1,79 @@ +import {Component, EventEmitter, Input, OnInit, Output} from '@angular/core'; +import {Choices} from '../../models/choices.model'; + +@Component({ + selector: 'app-conversation-message', + templateUrl: './conversation-message.component.html', + styleUrls: ['./conversation-message.component.scss'] +}) +export class ConversationMessageComponent implements OnInit { + + @Input() type = ''; + + @Input() imgSrc = ''; + + @Input() backgroundColor = ''; + + @Input() backgroundColorReply = ''; + + @Input() text = ''; + + @Input() reply = ''; + + @Input() choices: Choices[]; + + @Output() btnChoiceClick: EventEmitter = new EventEmitter(); + @Output() btnChoiceCheckBoxValidateClick: EventEmitter = new EventEmitter(); + @Output() btnChoiceCheckBoxClick: EventEmitter = new EventEmitter(); + + public ml = ''; + public mr = ''; + + public checkBoxChoices: Choices[]; + + constructor() { + // this.imgSrc = environment.profilePhotoDefault; + this.choices = [{value: '', text: ''}]; + + this.checkBoxChoices = []; + } + + ngOnInit(): void { + const msg = document.getElementsByClassName('messageGlobal'); + if (msg !== null) { + if (this.reply === 'true'){ + this.ml = 'auto'; + this.mr = '0'; + } + else { + this.ml = '0'; + this.mr = 'auto'; + } + } + } + + btnChoiceClickFn($event: any , ch: Choices): void{ + this.btnChoiceClick.emit(ch); + // console.log($event.target); + $event.currentTarget.parentElement.setAttribute('style', 'display: none'); + } + + btnChoiceCheckBoxClickFn($event: any, ch: Choices): void { + console.log($event.currentTarget); + let e; + if (this.checkBoxChoices.includes(ch)){ + e = {choice: ch, state: false}; + this.checkBoxChoices.splice(this.checkBoxChoices.indexOf(ch), 1); + } + else { + e = {choice: ch, state: true}; + this.checkBoxChoices.push(ch); + } + this.btnChoiceCheckBoxClick.emit(e); + } + + btnChoiceCheckBoxValidateClickFn($event: any): void { + this.btnChoiceCheckBoxValidateClick.emit(this.checkBoxChoices); + $event.currentTarget.parentElement.parentElement.setAttribute('style', 'display: none'); + } +} diff --git a/projects/back-office/src/app/virtual-assistant/va-conversation/va-conversation.component.html b/projects/back-office/src/app/virtual-assistant/va-conversation/va-conversation.component.html new file mode 100644 index 0000000000..22b5677f10 --- /dev/null +++ b/projects/back-office/src/app/virtual-assistant/va-conversation/va-conversation.component.html @@ -0,0 +1,16 @@ +
+ +
+ + + + +
+ +
diff --git a/projects/back-office/src/app/virtual-assistant/va-conversation/va-conversation.component.scss b/projects/back-office/src/app/virtual-assistant/va-conversation/va-conversation.component.scss new file mode 100644 index 0000000000..259e2ab133 --- /dev/null +++ b/projects/back-office/src/app/virtual-assistant/va-conversation/va-conversation.component.scss @@ -0,0 +1,18 @@ +#chat-global { + height: 100%; + box-sizing: border-box; + border-radius: 5px; + box-shadow: 0 5px 5px 2px gray; + background-color: white; +} + +#conversation { + //height: 100px; + height: calc(100% - 100px); +} + +.example-viewport { + //height: 300px; + width: 100%; + height: 100%; +} diff --git a/projects/back-office/src/app/virtual-assistant/va-conversation/va-conversation.component.spec.ts b/projects/back-office/src/app/virtual-assistant/va-conversation/va-conversation.component.spec.ts new file mode 100644 index 0000000000..192370ecec --- /dev/null +++ b/projects/back-office/src/app/virtual-assistant/va-conversation/va-conversation.component.spec.ts @@ -0,0 +1,25 @@ +import { ComponentFixture, TestBed } from '@angular/core/testing'; + +import { VaConversationComponent } from './va-conversation.component'; + +describe('VaConversationComponent', () => { + let component: VaConversationComponent; + let fixture: ComponentFixture; + + beforeEach(async () => { + await TestBed.configureTestingModule({ + declarations: [ VaConversationComponent ] + }) + .compileComponents(); + }); + + beforeEach(() => { + fixture = TestBed.createComponent(VaConversationComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/projects/back-office/src/app/virtual-assistant/va-conversation/va-conversation.component.ts b/projects/back-office/src/app/virtual-assistant/va-conversation/va-conversation.component.ts new file mode 100644 index 0000000000..07e679ee4d --- /dev/null +++ b/projects/back-office/src/app/virtual-assistant/va-conversation/va-conversation.component.ts @@ -0,0 +1,371 @@ +import { + Component, + EventEmitter, + Input, + OnChanges, + OnInit, + Output, + SimpleChanges, + ViewChild +} from '@angular/core'; +import {CdkVirtualScrollViewport} from '@angular/cdk/scrolling'; +import {Message} from '../models/message.model'; +import {User} from '../models/user.model'; +import {Choices} from '../models/choices.model'; +// @ts-ignore +import Speech from 'speak-tts'; +import {ConversationFooterComponent} from './conversation-footer/conversation-footer.component'; + + +@Component({ + selector: 'app-va-conversation', + templateUrl: './va-conversation.component.html', + styleUrls: ['./va-conversation.component.scss'] +}) +export class VaConversationComponent implements OnInit, OnChanges { + + // @ts-ignore + @ViewChild('footerComponent') conversationFooterComponent: ConversationFooterComponent; + @Input() form: any[] = []; + @Input() td: {title: string, description: string}; + public records: any[] = []; + public currentRecord: any; + + @Input() language: string; + + public currentText: string; + @ViewChild(CdkVirtualScrollViewport) viewport: any; + + public conv: Message[] = []; + public iCurrentQuestion: number; + + public restartChoiceMsg: string; + public endChoiceMsg: string; + + public endMessage: string; + + @Output() endConversation: EventEmitter = new EventEmitter(); + + public speech: any; + public speechData: any; + + public userMe: User; + public userVa: User; + + public inputMsgType: string; + + public mtObjectTemp: any; + public iCurMtQ: number; + + constructor() { + this.currentText = ''; + + this.iCurrentQuestion = -1; + + this.restartChoiceMsg = 'restart'; + this.endChoiceMsg = 'end'; + + this.currentRecord = {}; + + this.userMe = new User('Me', 'https://upload.wikimedia.org/wikipedia/commons/thumb/7/7e/Circle-icons-profile.svg/1024px-Circle-icons-profile.svg.png'); + this.userVa = new User('Assistant', 'https://www.121outsource.com/wp-content/uploads/2018/08/virtual-assitants.png'); + + this.endMessage = 'Thank you for your time, do you want to start another session or end now?'; + + this.inputMsgType = 'text'; + + this.mtObjectTemp = {}; + this.iCurMtQ = -1; + + this.speech = new Speech(); + + this.td = {title: '', description: ''}; + + this.language = 'en-GB'; + } + + ngOnInit(): void { + this.speakInit(this.speech, this.speechData); + console.log('this.form'); + console.log(this.form); + } + + ngOnChanges(changes: SimpleChanges): void{ + if (this.form !== undefined) { + // this.sendNextQuestion(); + } + } + + msgUpdated(msg: any): void{ + console.log('MSGGG'); + if (typeof msg === 'string'){ + console.log('msgUpdated'); + console.log(msg); + this.currentText = msg; + } + } + + // send simple reply message (TEXT) (click on send msg or enter) + sendReplyMsgText(): void { + console.log('sendReplyMsgText()'); + console.log(this.iCurrentQuestion); + if (this.iCurrentQuestion < this.form.length){ + if (this.currentText !== '' && (this.form[this.iCurrentQuestion].type === 'text' || this.form[this.iCurrentQuestion].type === 'comment')){ + this.addMsg('', this.currentText, true, this.userMe, Date.now(), []); + this.currentRecord[this.form[this.iCurrentQuestion].name] = this.currentText; + this.afterReply(); + } + else if (this.currentText !== '' && this.form[this.iCurrentQuestion].type === 'multipletext'){ + this.addMsg('', this.currentText, true, this.userMe, Date.now(), []); + this.mtObjectTemp[this.form[this.iCurrentQuestion].items[this.iCurMtQ ].name] = this.currentText; + this.currentText = ''; + this.updateScrollViewPos(); + this.sendNextMtQuestion(); + } + } + console.log('this.currentText = '); + console.log(this.currentText); + } + + // send reply message after clicking on a choice (RADIOGROUP) + sendReplyMsgChoice(ch: Choices): void { + if (ch.text !== ''){ + this.speak(this.speech, ch.text); + this.addMsg('', ch.text, true, this.userMe, Date.now(), []); + this.currentRecord[this.form[this.iCurrentQuestion].name] = ch.value; + this.afterReply(); + } + } + + // click on a checkbox choice + choiceCheckBoxClick(e: any): void { + if (e.state === true){ + this.speak(this.speech, e.choice.text); + } + else { + this.speak(this.speech, e.choice.text + ' removed'); + } + } + + // click on a validate button (CHECKBOX) + choiceCheckBoxValidateClick(choices: any[]): void { + let text = ''; const choicesRecord: string[] = []; + + choices.forEach((ch) => { + choicesRecord.push(ch.value); + text = text + ' ' + ch.text; + }); + + this.addMsg('', text, true, this.userMe, Date.now(), []); + this.currentRecord[this.form[this.iCurrentQuestion].name] = choicesRecord; + this.afterReply(); + } + + // send final conversation message + sendReplyMsgTextEnd(): void { + if (this.restartChoiceMsg !== '') { + this.addMsg('', this.restartChoiceMsg, true, this.userMe, Date.now(), []); + this.afterReply(); + } + } + + afterReply(): void { + this.currentText = ''; + this.updateScrollViewPos(); + this.sendNextQuestion(); + } + + restartForm(): void { + this.sendReplyMsgTextEnd(); + this.iCurrentQuestion = -1; + this.currentRecord = {}; + window.setTimeout(() => { + this.sendNextQuestion(); + }, 500); + } + + sendNextQuestion(): void { + console.log('sendNextQuestion'); + console.log(this.currentText); + if (this.conv.length === 0){ + if (this.td.title !== undefined){ + this.addMsg('text', this.td.title, false, this.userVa, Date.now(), []); + } + if (this.td.description !== undefined){ + this.addMsg('text', this.td.description, false, this.userVa, Date.now(), []); + } + this.sendNextQuestion(); + } + else { + this.iCurrentQuestion++; + if (this.iCurrentQuestion < this.form.length){ + const r = this.questionController(); + this.updateScrollViewPos(); + if (!r){ + this.sendNextQuestion(); + } + } + else if (this.iCurrentQuestion === this.form.length) { + // add this record + this.records.push(this.currentRecord); + console.log(this.records); + + this.addMsg('text', this.endMessage, false, this.userVa, Date.now(), + [ + new Choices(this.restartChoiceMsg, this.restartChoiceMsg + '?'), + new Choices(this.endChoiceMsg, this.endChoiceMsg + '?') + ]); + this.inputMsgType = 'text'; + this.updateScrollViewPos(); + } + } + } + + // control the bot format message depending on the type + questionController(): boolean { + this.inputMsgType = 'text'; + let r = true; + const t = this.form[this.iCurrentQuestion].type; + switch (t){ + case 'text': + if (this.form[this.iCurrentQuestion].inputType !== null) { + this.inputMsgType = this.form[this.iCurrentQuestion].inputType; + console.log(this.inputMsgType); + if (this.inputMsgType === 'color'){ + this.currentText = '#3131dc'; + } + if (this.inputMsgType === 'range'){ + this.currentText = '67'; + } + } + this.addMsg(this.form[this.iCurrentQuestion].type, this.form[this.iCurrentQuestion].title, false, + this.userVa, Date.now(), []); + break; + case 'comment': + this.addMsg(this.form[this.iCurrentQuestion].type, this.form[this.iCurrentQuestion].title, false, + this.userVa, Date.now(), []); + break; + case 'boolean': + this.addMsg(this.form[this.iCurrentQuestion].type, this.form[this.iCurrentQuestion].title, false, + this.userVa, Date.now(), [new Choices(false, this.form[this.iCurrentQuestion].labelFalse), + new Choices(true, this.form[this.iCurrentQuestion].labelTrue)]); + break; + case 'radiogroup': + case 'dropdown': + case 'checkbox': + case 'tagbox': + this.addMsg(this.form[this.iCurrentQuestion].type, this.form[this.iCurrentQuestion].title, false, + this.userVa, Date.now(), this.form[this.iCurrentQuestion].choices); + break; + case 'expression': + if (this.form[this.iCurrentQuestion].description){ + this.addMsg(this.form[this.iCurrentQuestion].type, + this.form[this.iCurrentQuestion].title + '\n' + this.form[this.iCurrentQuestion].description, + false, + this.userVa, Date.now(), []); + } + r = false; + break; + case 'multipletext': + this.iCurMtQ = -1; + this.mtObjectTemp = {}; + this.sendNextMtQuestion(); + break; + default: + this.currentRecord[this.form[this.iCurrentQuestion].name] = null, + r = false; + break; + } + return r; + } + + sendNextMtQuestion(): void { + this.iCurMtQ ++ ; + if (this.iCurMtQ < this.form[this.iCurrentQuestion].items.length){ + this.addMsg('text', this.form[this.iCurrentQuestion].items[this.iCurMtQ].title, false, this.userVa, Date.now(), []); + } + else { + this.currentRecord[this.form[this.iCurrentQuestion].name] = this.mtObjectTemp; + this.sendNextQuestion(); + } + } + + // click on a choice (radio) + choiceClick(choice: Choices): void{ + if (choice.value === this.restartChoiceMsg){ + this.restartForm(); + } + else if (choice.value === this.endChoiceMsg){ + this.endConversation.emit(this.records); + } + else { + this.sendReplyMsgChoice(choice); + } + } + + // add a message to the conversation + addMsg(type: string, + text: string, + reply: boolean, + user: User, + date: number, + choices: Choices[]): void { + if (!reply){ + console.log('speak'); + this.speak(this.speech, text); + } + this.conv.push(new Message(type, text, reply, user, date, choices)); + this.conversationFooterComponent.inputFocus(); + } + + /* ----- STYLE ----- */ + + updateScrollViewPos(): void { + setTimeout(() => { + this.viewport.scrollTo({ + bottom: 0, + behavior: 'auto', + }); + }, 0); + setTimeout(() => { + this.viewport.scrollTo({ + bottom: 0, + behavior: 'auto', + }); + }, 50); + } + + /* ----- TTS ----- */ + + speakInit(speech: Speech, speechData: any): void { + if (speech.hasBrowserSupport()) { + console.log('speech synthesis supported'); + speech.init({ + volume: 1, + lang: this.language, + rate: 1, + pitch: 1, + splitSentences: true, + listeners: { + } + }).then((data: any) => { + console.log('Speech is ready, voices are available', data); + speechData = data; + this.sendNextQuestion(); + + }).catch((e: any) => { + console.error('An error occured while initializing : ', e); + }); + } + } + + speak(speech: Speech, msg: string): void { + speech.speak({ + text: msg, + }).then(() => { + console.log('Success !'); + }).catch((e: any) => { + console.error('An error occurred :', e); + }); + } +} diff --git a/projects/back-office/src/app/virtual-assistant/virtual-assistant-routing.module.ts b/projects/back-office/src/app/virtual-assistant/virtual-assistant-routing.module.ts new file mode 100644 index 0000000000..8914cf2e70 --- /dev/null +++ b/projects/back-office/src/app/virtual-assistant/virtual-assistant-routing.module.ts @@ -0,0 +1,16 @@ +import { NgModule } from '@angular/core'; +import { Routes, RouterModule } from '@angular/router'; +import {VirtualAssistantComponent} from './virtual-assistant.component'; + +const routes: Routes = [ + { + path: '', + component: VirtualAssistantComponent + } +]; + +@NgModule({ + imports: [RouterModule.forChild(routes)], + exports: [RouterModule] +}) +export class VirtualAssistantRoutingModule { } diff --git a/projects/back-office/src/app/virtual-assistant/virtual-assistant.component.html b/projects/back-office/src/app/virtual-assistant/virtual-assistant.component.html new file mode 100644 index 0000000000..471f77b10e --- /dev/null +++ b/projects/back-office/src/app/virtual-assistant/virtual-assistant.component.html @@ -0,0 +1,40 @@ +
+ + + + + va-face + + + + + + + + Choose language + + Select language + + {{ lang.text }} + + + + This field is required + + You can choose your language here + + + + + + + +
+ + + va-face + + + + + diff --git a/projects/back-office/src/app/virtual-assistant/virtual-assistant.component.scss b/projects/back-office/src/app/virtual-assistant/virtual-assistant.component.scss new file mode 100644 index 0000000000..4ba24c8706 --- /dev/null +++ b/projects/back-office/src/app/virtual-assistant/virtual-assistant.component.scss @@ -0,0 +1,32 @@ +.va-face { + width: 200px; +} +.conversation .mat-figure { + top: 0; + left: 0; + right: 0; + bottom: 0; + position: absolute; + display: block !important ; + align-items: flex-start; + justify-content: flex-start; + height: 100%; + padding: 0; + margin: 0; +} + +#btn-start { + font-size: large; + height: 50px; + width: 100px; +} + +#select-lang { + margin-right: 10px; +} + +//#spinner-loading-form { +// position: absolute; +// top: 90%; +// left: calc(50% - 50px); +//} diff --git a/projects/back-office/src/app/virtual-assistant/virtual-assistant.component.spec.ts b/projects/back-office/src/app/virtual-assistant/virtual-assistant.component.spec.ts new file mode 100644 index 0000000000..344b3a0746 --- /dev/null +++ b/projects/back-office/src/app/virtual-assistant/virtual-assistant.component.spec.ts @@ -0,0 +1,25 @@ +import { ComponentFixture, TestBed } from '@angular/core/testing'; + +import { VirtualAssistantComponent } from './virtual-assistant.component'; + +describe('VirtualAssistantComponent', () => { + let component: VirtualAssistantComponent; + let fixture: ComponentFixture; + + beforeEach(async () => { + await TestBed.configureTestingModule({ + declarations: [ VirtualAssistantComponent ] + }) + .compileComponents(); + }); + + beforeEach(() => { + fixture = TestBed.createComponent(VirtualAssistantComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/projects/back-office/src/app/virtual-assistant/virtual-assistant.component.ts b/projects/back-office/src/app/virtual-assistant/virtual-assistant.component.ts new file mode 100644 index 0000000000..6065f6eb18 --- /dev/null +++ b/projects/back-office/src/app/virtual-assistant/virtual-assistant.component.ts @@ -0,0 +1,158 @@ +import {Component, OnInit, ViewEncapsulation} from '@angular/core'; +import {Subscription} from 'rxjs'; +import {ActivatedRoute} from '@angular/router'; +import {SafeDownloadService} from '../../../../safe/src/lib/services/download.service'; +import {Apollo} from 'apollo-angular'; +import {GET_FORM_BY_ID, GetFormByIdQueryResponse} from '../graphql/queries'; +import {ADD_RECORD, AddRecordMutationResponse} from '../graphql/mutations'; +import {FormControl, Validators} from '@angular/forms'; + +@Component({ + selector: 'app-virtual-assistant', + templateUrl: './virtual-assistant.component.html', + styleUrls: ['./virtual-assistant.component.scss'], + encapsulation: ViewEncapsulation.None +}) +export class VirtualAssistantComponent implements OnInit { + + // === DATA === + public id = ''; + public form: any; + public td: {title: string, description: string}; + public iQuestion: any; + public messages: any; + + public start: boolean; + public startBtn: boolean; + public loadingForm: boolean; + + public voiceLanguage: {value: string, text: string}[]; + public curLanguage: string; + + selectFormControl = new FormControl('', Validators.required); + + // === ROUTE === + private routeSubscription?: Subscription; + + constructor(private route: ActivatedRoute, + private downloadService: SafeDownloadService, + private apollo: Apollo) { + this.iQuestion = 0; + + this.start = false; + this.startBtn = false; + this.loadingForm = true; + + this.td = { + title: '', + description: '' + }; + + this.voiceLanguage = [ + {value: 'ar-SA', text: 'ar'}, + {value: 'cs-CZ', text: 'cs'}, + {value: 'da-DK', text: 'danmark'}, + {value: 'de-DE', text: 'german - DE'}, + {value: 'el-GR', text: 'gr'}, + {value: 'en', text: 'english'}, + {value: 'en-AU', text: 'english - AU'}, + {value: 'en-GB', text: 'english - GB'}, + {value: 'en-IE', text: 'english - IE'}, + {value: 'en-IN', text: 'english - IN'}, + {value: 'en-US', text: 'english - US'}, + {value: 'en-ZA', text: 'english - ZA'}, + {value: 'es-AR', text: 'spanish - AR'}, + {value: 'es-ES', text: 'spanish - ES'}, + {value: 'es-MX', text: 'spanish - MX'}, + {value: 'es-US', text: 'spanish - US'}, + {value: 'fi-FI', text: 'fi'}, + {value: 'fr-CA', text: 'french - CA'}, + {value: 'fr-FR', text: 'french - FR'}, + {value: 'he-IL', text: 'hr'}, + {value: 'hi-IN', text: 'hi'}, + {value: 'hu-HU', text: 'hu'}, + {value: 'id-ID', text: 'id'}, + {value: 'it-IT', text: 'it'}, + {value: 'ja-JP', text: 'ja'}, + {value: 'ko-KR', text: 'ko'}, + {value: 'nb-NO', text: 'nb'}, + {value: 'nl-BE', text: 'dutch - BE'}, + {value: 'nl-NL', text: 'dutch - NL'}, + {value: 'pl-PL', text: 'polish - PL'}, + {value: 'pt-BR', text: 'pt - BR'}, + {value: 'pt-PT', text: 'pt - PT'}, + {value: 'ro-RO', text: 'ro - RO'}, + {value: 'ru-RU', text: 'ru - RU'}, + {value: 'sk-SK', text: 'sk - SK'}, + {value: 'sv-SE', text: 'sv - SE'}, + {value: 'th-TH', text: 'th - TH'}, + {value: 'tr-TR', text: 'tr - TR'}, + {value: 'zh-CN', text: 'zh - CN'}, + {value: 'zh-HK', text: 'zh - HK'}, + {value: 'zh-TW', text: 'zh - TW'}]; + + this.curLanguage = 'ar-SA'; + } + + ngOnInit(): void { + this.routeSubscription = this.route.params.subscribe((params) => { + this.id = params.id; + console.log('this.id'); + console.log(this.id); + this.getForm(); + }); + } + + async getForm(): Promise{ + this.apollo.watchQuery({ + query: GET_FORM_BY_ID, + variables: { + id: this.id + } + }).valueChanges.subscribe((res: any) => { + console.log('APOLLO: res.data.form'); + console.log(res); + const formStruct = JSON.parse(res.data.form.structure).pages[0]; + this.form = formStruct.elements; + if (formStruct.title !== undefined){ + console.log(JSON.parse(res.data.form.structure).pages[0].title); + this.td.title = formStruct.title; + } + if (formStruct.description !== undefined){ + console.log(formStruct.description); + this.td.description = formStruct.description; + } + console.log(this.form); + this.startBtn = true; + this.loadingForm = false; + }); + } + + vaEndConversation(records: any): void { + console.log('vaEndConversation'); + console.log(records); + for (const r of records){ + console.log(r); + this.apollo.mutate({ + mutation: ADD_RECORD, + variables: { + form: this.id, + data: r + } + }).subscribe((res) => { + console.log(res); + window.close(); + }); + } + } + + btnStartClick(): void { + this.start = true; + this.startBtn = false; + } + + langChanges(lang: any): void { + console.log(lang); + this.curLanguage = lang; + } +} diff --git a/projects/back-office/src/app/virtual-assistant/virtual-assistant.module.ts b/projects/back-office/src/app/virtual-assistant/virtual-assistant.module.ts new file mode 100644 index 0000000000..431b2ee167 --- /dev/null +++ b/projects/back-office/src/app/virtual-assistant/virtual-assistant.module.ts @@ -0,0 +1,38 @@ +import { NgModule } from '@angular/core'; +import { CommonModule } from '@angular/common'; +import {VirtualAssistantComponent} from './virtual-assistant.component'; +import {VirtualAssistantRoutingModule} from './virtual-assistant-routing.module'; +import {MatIconModule} from '@angular/material/icon'; +import {MatButtonModule} from '@angular/material/button'; +import {MatGridListModule} from '@angular/material/grid-list'; +import {ScrollingModule} from '@angular/cdk/scrolling'; +import { VaConversationComponent } from './va-conversation/va-conversation.component'; +import {ConversationHeaderComponent} from './va-conversation/conversation-header/conversation-header.component'; +import {ConversationMessageComponent} from './va-conversation/conversation-message/conversation-message.component'; +import {ConversationFooterComponent} from './va-conversation/conversation-footer/conversation-footer.component'; +import {MatSlideToggleModule} from '@angular/material/slide-toggle'; +import {MatProgressSpinnerModule} from '@angular/material/progress-spinner'; +import {MatSelectModule} from '@angular/material/select'; +import {ReactiveFormsModule} from '@angular/forms'; + +@NgModule({ + declarations: [VirtualAssistantComponent, + VaConversationComponent, + ConversationHeaderComponent, + ConversationMessageComponent, + ConversationFooterComponent], + imports: [ + CommonModule, + VirtualAssistantRoutingModule, + MatIconModule, + MatButtonModule, + MatGridListModule, + ScrollingModule, + MatSlideToggleModule, + MatProgressSpinnerModule, + MatSelectModule, + ReactiveFormsModule + ], + exports: [VirtualAssistantComponent] +}) +export class VirtualAssistantModule { }