diff --git a/.gitignore b/.gitignore index d874ad67..a7b61d71 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1,4 @@ *.tar + +# ignore user/workspace settings etc. of VSCode +.vscode diff --git a/frontend/docs/changelog/changelog-de.md b/frontend/docs/changelog/changelog-de.md index 91576c76..7a3326c0 100644 --- a/frontend/docs/changelog/changelog-de.md +++ b/frontend/docs/changelog/changelog-de.md @@ -18,6 +18,7 @@ - Es wurden einige Verbesserungen gemacht, die das Laden der Seite beschleunigen. - Wenn neue Funktionen zur Verfügung gestellt werden, wird der Browser-Cache nicht mehr verhindern, dass Benutzer:innen diese sehen. - Das DLR-Logo wurde durch das LOKI-Logo ersetzt und verkleinert. +- Das Modul für das Liniendiagramm wurde von AmCharts 4 auf 5 gewechselt für eine bessere Leistung. ### Fehlerbehebungen diff --git a/frontend/docs/changelog/changelog-en.md b/frontend/docs/changelog/changelog-en.md index 33e05d2a..b3a8d2e6 100644 --- a/frontend/docs/changelog/changelog-en.md +++ b/frontend/docs/changelog/changelog-en.md @@ -18,6 +18,7 @@ - Some improvements to page load speed have been made. - If a new feature gets rolled out, the browser cache will no longer prevent the users from seeing it. - The DLR logo was replaced by the LOKI logo and the size was reduced. +- The line chart module is upgraded from AmCharts 4 to 5 for better performance. ### Bug fixes diff --git a/frontend/package-lock.json b/frontend/package-lock.json index 8ea9ab56..e9c92cd1 100644 --- a/frontend/package-lock.json +++ b/frontend/package-lock.json @@ -9,8 +9,7 @@ "version": "0.0.1", "license": "UNLICENSED", "dependencies": { - "@amcharts/amcharts4": "^4.10.17", - "@amcharts/amcharts5": "^5.1.8", + "@amcharts/amcharts5": "^5.3.8", "@emotion/react": "^11.10.5", "@emotion/styled": "^11.10.5", "@mui/icons-material": "^5.10.9", @@ -83,35 +82,14 @@ "webpack-merge": "^5.7.3" } }, - "node_modules/@amcharts/amcharts4": { - "version": "4.10.29", - "resolved": "https://registry.npmjs.org/@amcharts/amcharts4/-/amcharts4-4.10.29.tgz", - "integrity": "sha512-uDCvm4V0Xs2jtI0Aa7XFH0jqoyEGx9I2ukFEwaaQzYq11vwowhJsgE3sSv2jsfKETYUvPXb32NbzrXZulE2ESg==", - "dependencies": { - "@babel/runtime": "^7.6.3", - "core-js": "^3.0.0", - "d3-force": "^3.0.0", - "d3-geo": "^3.0.1", - "d3-geo-projection": "^4.0.0", - "d3-selection": "^3.0.0", - "d3-transition": "^3.0.1", - "pdfmake": "^0.2.2", - "polylabel": "^1.0.2", - "raf": "^3.4.1", - "regression": "^2.0.1", - "rgbcolor": "^1.0.1", - "stackblur-canvas": "^2.0.0", - "tslib": "^2.0.1", - "xlsx": "^0.17.0" - } - }, "node_modules/@amcharts/amcharts5": { - "version": "5.2.8", - "resolved": "https://registry.npmjs.org/@amcharts/amcharts5/-/amcharts5-5.2.8.tgz", - "integrity": "sha512-hD9dwWrmemyypzEeFvl80rBYdurLt0w13zO+C6vkm/7uAwLZ20CnPeJsutlUwR1DFbX3UgEITVUshknY/Oez0Q==", + "version": "5.3.16", + "resolved": "https://registry.npmjs.org/@amcharts/amcharts5/-/amcharts5-5.3.16.tgz", + "integrity": "sha512-mtYsLmJ/7DrAF61y/m79MNshFC9x9BnoRjlHAk1WBjyWPXtpKthO/FrsdJGPezl44pflnusKgsJEqOQXVOA2Qw==", "dependencies": { "@types/d3": "^7.0.0", "@types/d3-chord": "^3.0.0", + "@types/d3-hierarchy": "3.1.1", "@types/d3-sankey": "^0.11.1", "@types/d3-shape": "^3.0.0", "@types/geojson": "^7946.0.8", @@ -124,41 +102,12 @@ "d3-selection": "^3.0.0", "d3-transition": "^3.0.0", "flatpickr": "^4.6.9", - "markerjs2": "^2.17.2", + "markerjs2": "^2.29.4", "pdfmake": "^0.2.2", "polylabel": "^1.1.0", "regression": "^2.0.1", "svg-arc-to-cubic-bezier": "^3.2.0", - "tslib": "^2.2.0", - "xlsx": "^0.18.0" - } - }, - "node_modules/@amcharts/amcharts5/node_modules/adler-32": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/adler-32/-/adler-32-1.3.1.tgz", - "integrity": "sha512-ynZ4w/nUUv5rrsR8UUGoe1VC9hZj6V5hU9Qw1HlMDJGEJw5S7TfTErWTjMys6M7vr0YWcPqs3qAr4ss0nDfP+A==", - "engines": { - "node": ">=0.8" - } - }, - "node_modules/@amcharts/amcharts5/node_modules/xlsx": { - "version": "0.18.5", - "resolved": "https://registry.npmjs.org/xlsx/-/xlsx-0.18.5.tgz", - "integrity": "sha512-dmg3LCjBPHZnQp5/F/+nnTa+miPJxUXB6vtk42YjBBKayDNagxGEeIdWApkYPOf3Z3pm3k62Knjzp7lMeTEtFQ==", - "dependencies": { - "adler-32": "~1.3.0", - "cfb": "~1.2.1", - "codepage": "~1.15.0", - "crc-32": "~1.2.1", - "ssf": "~0.11.2", - "wmf": "~1.0.1", - "word": "~0.3.0" - }, - "bin": { - "xlsx": "bin/xlsx.njs" - }, - "engines": { - "node": ">=0.8" + "tslib": "^2.2.0" } }, "node_modules/@ampproject/remapping": { @@ -1783,9 +1732,9 @@ } }, "node_modules/@jridgewell/resolve-uri": { - "version": "3.0.7", - "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.0.7.tgz", - "integrity": "sha512-8cXDaBBHOr2pQ7j77Y6Vp5VDT2sIqWyWQ56TjEq4ih/a4iST3dItRe8Q9fp0rrIl9DoKhWQtUQz/YpOxLkXbNA==", + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.0.tgz", + "integrity": "sha512-F2msla3tad+Mfht5cJq7LSXcdudKTWCVYUgw6pLFOOHSTtZlj6SWNYAp+AhuqLmWdBO2X5hPrLcu8cVP8fy28w==", "engines": { "node": ">=6.0.0" } @@ -1799,9 +1748,9 @@ } }, "node_modules/@jridgewell/source-map": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/@jridgewell/source-map/-/source-map-0.3.2.tgz", - "integrity": "sha512-m7O9o2uR8k2ObDysZYzdfhb08VuEml5oWGiosa1VdaPZ/A6QyPkAJuwN0Q1lhULOf6B7MtQmHENS743hWtCrgw==", + "version": "0.3.3", + "resolved": "https://registry.npmjs.org/@jridgewell/source-map/-/source-map-0.3.3.tgz", + "integrity": "sha512-b+fsZXeLYi9fEULmfBrhxn4IrPlINf8fiNarzTof004v3lFdntdwa9PF7vFJqm3mg7s+ScJMxXaE3Acp1irZcg==", "dev": true, "dependencies": { "@jridgewell/gen-mapping": "^0.3.0", @@ -1809,12 +1758,12 @@ } }, "node_modules/@jridgewell/source-map/node_modules/@jridgewell/gen-mapping": { - "version": "0.3.1", - "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.1.tgz", - "integrity": "sha512-GcHwniMlA2z+WFPWuY8lp3fsza0I8xPFMWL5+n8LYyP6PSvPrXf4+n8stDHZY2DM0zy9sVkRDy1jDI4XGzYVqg==", + "version": "0.3.3", + "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.3.tgz", + "integrity": "sha512-HLhSWOLRi875zjjMG/r+Nv0oCW8umGb0BgEhyX3dDX3egwZtB8PqLnjz3yedt8R5StBrzcg4aBpnh8UA9D1BoQ==", "dev": true, "dependencies": { - "@jridgewell/set-array": "^1.0.0", + "@jridgewell/set-array": "^1.0.1", "@jridgewell/sourcemap-codec": "^1.4.10", "@jridgewell/trace-mapping": "^0.3.9" }, @@ -1823,17 +1772,17 @@ } }, "node_modules/@jridgewell/sourcemap-codec": { - "version": "1.4.13", - "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.13.tgz", - "integrity": "sha512-GryiOJmNcWbovBxTfZSF71V/mXbgcV3MewDe3kIMCLyIh5e7SKAeUZs+rMnJ8jkMolZ/4/VsdBmMrw3l+VdZ3w==" + "version": "1.4.14", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.14.tgz", + "integrity": "sha512-XPSJHWmi394fuUuzDnGz1wiKqWfo1yXecHQMRf2l6hztTO+nPru658AyDngaBe7isIxEkRsPR3FZh+s7iVa4Uw==" }, "node_modules/@jridgewell/trace-mapping": { - "version": "0.3.13", - "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.13.tgz", - "integrity": "sha512-o1xbKhp9qnIAoHJSWd6KlCZfqslL4valSF81H8ImioOAxluWYWOpWkpyktY2vnt4tbrX9XYaxovq6cgowaJp2w==", + "version": "0.3.18", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.18.tgz", + "integrity": "sha512-w+niJYzMHdd7USdiH2U6869nqhD2nbfZXND5Yp93qIbEmnDNk7PD48o+YchRVpzMU7M6jVCbenTR7PA1FLQ9pA==", "dependencies": { - "@jridgewell/resolve-uri": "^3.0.3", - "@jridgewell/sourcemap-codec": "^1.4.10" + "@jridgewell/resolve-uri": "3.1.0", + "@jridgewell/sourcemap-codec": "1.4.14" } }, "node_modules/@leichtgewicht/ip-codec": { @@ -2918,9 +2867,9 @@ } }, "node_modules/@types/d3-hierarchy": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/@types/d3-hierarchy/-/d3-hierarchy-3.1.0.tgz", - "integrity": "sha512-g+sey7qrCa3UbsQlMZZBOHROkFqx7KZKvUpRzI/tAp/8erZWpYq7FgNKvYwebi2LaEiVs1klhUfd3WCThxmmWQ==" + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/@types/d3-hierarchy/-/d3-hierarchy-3.1.1.tgz", + "integrity": "sha512-QwjxA3+YCKH3N1Rs3uSiSy1bdxlLB1uUiENXeJudBoAFvtDuswUxLcanoOaR2JYn1melDTuIXR8VhnVyI3yG/A==" }, "node_modules/@types/d3-interpolate": { "version": "3.0.1", @@ -3050,9 +2999,9 @@ } }, "node_modules/@types/estree": { - "version": "0.0.51", - "resolved": "https://registry.npmjs.org/@types/estree/-/estree-0.0.51.tgz", - "integrity": "sha512-CuPgU6f3eT/XgKKPqKd/gLZV1Xmvf1a2R5POBOGQa6uv82xpls89HU5zKeVoyR8XzHd1RGNOlQlvUe3CFkjWNQ==", + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.1.tgz", + "integrity": "sha512-LG4opVs2ANWZ1TJoKc937iMmNstM/d0ae1vNbnBvBhqCSezgVUOzcLCqbI5elV8Vy6WKwKjaqR+zO9VKirBBCA==", "dev": true }, "node_modules/@types/express": { @@ -3960,148 +3909,148 @@ } }, "node_modules/@webassemblyjs/ast": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.11.1.tgz", - "integrity": "sha512-ukBh14qFLjxTQNTXocdyksN5QdM28S1CxHt2rdskFyL+xFV7VremuBLVbmCePj+URalXBENx/9Lm7lnhihtCSw==", + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.11.6.tgz", + "integrity": "sha512-IN1xI7PwOvLPgjcf180gC1bqn3q/QaOCwYUahIOhbYUu8KA/3tw2RT/T0Gidi1l7Hhj5D/INhJxiICObqpMu4Q==", "dev": true, "dependencies": { - "@webassemblyjs/helper-numbers": "1.11.1", - "@webassemblyjs/helper-wasm-bytecode": "1.11.1" + "@webassemblyjs/helper-numbers": "1.11.6", + "@webassemblyjs/helper-wasm-bytecode": "1.11.6" } }, "node_modules/@webassemblyjs/floating-point-hex-parser": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.11.1.tgz", - "integrity": "sha512-iGRfyc5Bq+NnNuX8b5hwBrRjzf0ocrJPI6GWFodBFzmFnyvrQ83SHKhmilCU/8Jv67i4GJZBMhEzltxzcNagtQ==", + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.11.6.tgz", + "integrity": "sha512-ejAj9hfRJ2XMsNHk/v6Fu2dGS+i4UaXBXGemOfQ/JfQ6mdQg/WXtwleQRLLS4OvfDhv8rYnVwH27YJLMyYsxhw==", "dev": true }, "node_modules/@webassemblyjs/helper-api-error": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-api-error/-/helper-api-error-1.11.1.tgz", - "integrity": "sha512-RlhS8CBCXfRUR/cwo2ho9bkheSXG0+NwooXcc3PAILALf2QLdFyj7KGsKRbVc95hZnhnERon4kW/D3SZpp6Tcg==", + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-api-error/-/helper-api-error-1.11.6.tgz", + "integrity": "sha512-o0YkoP4pVu4rN8aTJgAyj9hC2Sv5UlkzCHhxqWj8butaLvnpdc2jOwh4ewE6CX0txSfLn/UYaV/pheS2Txg//Q==", "dev": true }, "node_modules/@webassemblyjs/helper-buffer": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-buffer/-/helper-buffer-1.11.1.tgz", - "integrity": "sha512-gwikF65aDNeeXa8JxXa2BAk+REjSyhrNC9ZwdT0f8jc4dQQeDQ7G4m0f2QCLPJiMTTO6wfDmRmj/pW0PsUvIcA==", + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-buffer/-/helper-buffer-1.11.6.tgz", + "integrity": "sha512-z3nFzdcp1mb8nEOFFk8DrYLpHvhKC3grJD2ardfKOzmbmJvEf/tPIqCY+sNcwZIY8ZD7IkB2l7/pqhUhqm7hLA==", "dev": true }, "node_modules/@webassemblyjs/helper-numbers": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-numbers/-/helper-numbers-1.11.1.tgz", - "integrity": "sha512-vDkbxiB8zfnPdNK9Rajcey5C0w+QJugEglN0of+kmO8l7lDb77AnlKYQF7aarZuCrv+l0UvqL+68gSDr3k9LPQ==", + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-numbers/-/helper-numbers-1.11.6.tgz", + "integrity": "sha512-vUIhZ8LZoIWHBohiEObxVm6hwP034jwmc9kuq5GdHZH0wiLVLIPcMCdpJzG4C11cHoQ25TFIQj9kaVADVX7N3g==", "dev": true, "dependencies": { - "@webassemblyjs/floating-point-hex-parser": "1.11.1", - "@webassemblyjs/helper-api-error": "1.11.1", + "@webassemblyjs/floating-point-hex-parser": "1.11.6", + "@webassemblyjs/helper-api-error": "1.11.6", "@xtuc/long": "4.2.2" } }, "node_modules/@webassemblyjs/helper-wasm-bytecode": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.11.1.tgz", - "integrity": "sha512-PvpoOGiJwXeTrSf/qfudJhwlvDQxFgelbMqtq52WWiXC6Xgg1IREdngmPN3bs4RoO83PnL/nFrxucXj1+BX62Q==", + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.11.6.tgz", + "integrity": "sha512-sFFHKwcmBprO9e7Icf0+gddyWYDViL8bpPjJJl0WHxCdETktXdmtWLGVzoHbqUcY4Be1LkNfwTmXOJUFZYSJdA==", "dev": true }, "node_modules/@webassemblyjs/helper-wasm-section": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.11.1.tgz", - "integrity": "sha512-10P9No29rYX1j7F3EVPX3JvGPQPae+AomuSTPiF9eBQeChHI6iqjMIwR9JmOJXwpnn/oVGDk7I5IlskuMwU/pg==", + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.11.6.tgz", + "integrity": "sha512-LPpZbSOwTpEC2cgn4hTydySy1Ke+XEu+ETXuoyvuyezHO3Kjdu90KK95Sh9xTbmjrCsUwvWwCOQQNta37VrS9g==", "dev": true, "dependencies": { - "@webassemblyjs/ast": "1.11.1", - "@webassemblyjs/helper-buffer": "1.11.1", - "@webassemblyjs/helper-wasm-bytecode": "1.11.1", - "@webassemblyjs/wasm-gen": "1.11.1" + "@webassemblyjs/ast": "1.11.6", + "@webassemblyjs/helper-buffer": "1.11.6", + "@webassemblyjs/helper-wasm-bytecode": "1.11.6", + "@webassemblyjs/wasm-gen": "1.11.6" } }, "node_modules/@webassemblyjs/ieee754": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/ieee754/-/ieee754-1.11.1.tgz", - "integrity": "sha512-hJ87QIPtAMKbFq6CGTkZYJivEwZDbQUgYd3qKSadTNOhVY7p+gfP6Sr0lLRVTaG1JjFj+r3YchoqRYxNH3M0GQ==", + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/ieee754/-/ieee754-1.11.6.tgz", + "integrity": "sha512-LM4p2csPNvbij6U1f19v6WR56QZ8JcHg3QIJTlSwzFcmx6WSORicYj6I63f9yU1kEUtrpG+kjkiIAkevHpDXrg==", "dev": true, "dependencies": { "@xtuc/ieee754": "^1.2.0" } }, "node_modules/@webassemblyjs/leb128": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/leb128/-/leb128-1.11.1.tgz", - "integrity": "sha512-BJ2P0hNZ0u+Th1YZXJpzW6miwqQUGcIHT1G/sf72gLVD9DZ5AdYTqPNbHZh6K1M5VmKvFXwGSWZADz+qBWxeRw==", + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/leb128/-/leb128-1.11.6.tgz", + "integrity": "sha512-m7a0FhE67DQXgouf1tbN5XQcdWoNgaAuoULHIfGFIEVKA6tu/edls6XnIlkmS6FrXAquJRPni3ZZKjw6FSPjPQ==", "dev": true, "dependencies": { "@xtuc/long": "4.2.2" } }, "node_modules/@webassemblyjs/utf8": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/utf8/-/utf8-1.11.1.tgz", - "integrity": "sha512-9kqcxAEdMhiwQkHpkNiorZzqpGrodQQ2IGrHHxCy+Ozng0ofyMA0lTqiLkVs1uzTRejX+/O0EOT7KxqVPuXosQ==", + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/utf8/-/utf8-1.11.6.tgz", + "integrity": "sha512-vtXf2wTQ3+up9Zsg8sa2yWiQpzSsMyXj0qViVP6xKGCUT8p8YJ6HqI7l5eCnWx1T/FYdsv07HQs2wTFbbof/RA==", "dev": true }, "node_modules/@webassemblyjs/wasm-edit": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-edit/-/wasm-edit-1.11.1.tgz", - "integrity": "sha512-g+RsupUC1aTHfR8CDgnsVRVZFJqdkFHpsHMfJuWQzWU3tvnLC07UqHICfP+4XyL2tnr1amvl1Sdp06TnYCmVkA==", + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-edit/-/wasm-edit-1.11.6.tgz", + "integrity": "sha512-Ybn2I6fnfIGuCR+Faaz7YcvtBKxvoLV3Lebn1tM4o/IAJzmi9AWYIPWpyBfU8cC+JxAO57bk4+zdsTjJR+VTOw==", "dev": true, "dependencies": { - "@webassemblyjs/ast": "1.11.1", - "@webassemblyjs/helper-buffer": "1.11.1", - "@webassemblyjs/helper-wasm-bytecode": "1.11.1", - "@webassemblyjs/helper-wasm-section": "1.11.1", - "@webassemblyjs/wasm-gen": "1.11.1", - "@webassemblyjs/wasm-opt": "1.11.1", - "@webassemblyjs/wasm-parser": "1.11.1", - "@webassemblyjs/wast-printer": "1.11.1" + "@webassemblyjs/ast": "1.11.6", + "@webassemblyjs/helper-buffer": "1.11.6", + "@webassemblyjs/helper-wasm-bytecode": "1.11.6", + "@webassemblyjs/helper-wasm-section": "1.11.6", + "@webassemblyjs/wasm-gen": "1.11.6", + "@webassemblyjs/wasm-opt": "1.11.6", + "@webassemblyjs/wasm-parser": "1.11.6", + "@webassemblyjs/wast-printer": "1.11.6" } }, "node_modules/@webassemblyjs/wasm-gen": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-gen/-/wasm-gen-1.11.1.tgz", - "integrity": "sha512-F7QqKXwwNlMmsulj6+O7r4mmtAlCWfO/0HdgOxSklZfQcDu0TpLiD1mRt/zF25Bk59FIjEuGAIyn5ei4yMfLhA==", + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-gen/-/wasm-gen-1.11.6.tgz", + "integrity": "sha512-3XOqkZP/y6B4F0PBAXvI1/bky7GryoogUtfwExeP/v7Nzwo1QLcq5oQmpKlftZLbT+ERUOAZVQjuNVak6UXjPA==", "dev": true, "dependencies": { - "@webassemblyjs/ast": "1.11.1", - "@webassemblyjs/helper-wasm-bytecode": "1.11.1", - "@webassemblyjs/ieee754": "1.11.1", - "@webassemblyjs/leb128": "1.11.1", - "@webassemblyjs/utf8": "1.11.1" + "@webassemblyjs/ast": "1.11.6", + "@webassemblyjs/helper-wasm-bytecode": "1.11.6", + "@webassemblyjs/ieee754": "1.11.6", + "@webassemblyjs/leb128": "1.11.6", + "@webassemblyjs/utf8": "1.11.6" } }, "node_modules/@webassemblyjs/wasm-opt": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-opt/-/wasm-opt-1.11.1.tgz", - "integrity": "sha512-VqnkNqnZlU5EB64pp1l7hdm3hmQw7Vgqa0KF/KCNO9sIpI6Fk6brDEiX+iCOYrvMuBWDws0NkTOxYEb85XQHHw==", + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-opt/-/wasm-opt-1.11.6.tgz", + "integrity": "sha512-cOrKuLRE7PCe6AsOVl7WasYf3wbSo4CeOk6PkrjS7g57MFfVUF9u6ysQBBODX0LdgSvQqRiGz3CXvIDKcPNy4g==", "dev": true, "dependencies": { - "@webassemblyjs/ast": "1.11.1", - "@webassemblyjs/helper-buffer": "1.11.1", - "@webassemblyjs/wasm-gen": "1.11.1", - "@webassemblyjs/wasm-parser": "1.11.1" + "@webassemblyjs/ast": "1.11.6", + "@webassemblyjs/helper-buffer": "1.11.6", + "@webassemblyjs/wasm-gen": "1.11.6", + "@webassemblyjs/wasm-parser": "1.11.6" } }, "node_modules/@webassemblyjs/wasm-parser": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-parser/-/wasm-parser-1.11.1.tgz", - "integrity": "sha512-rrBujw+dJu32gYB7/Lup6UhdkPx9S9SnobZzRVL7VcBH9Bt9bCBLEuX/YXOOtBsOZ4NQrRykKhffRWHvigQvOA==", + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-parser/-/wasm-parser-1.11.6.tgz", + "integrity": "sha512-6ZwPeGzMJM3Dqp3hCsLgESxBGtT/OeCvCZ4TA1JUPYgmhAx38tTPR9JaKy0S5H3evQpO/h2uWs2j6Yc/fjkpTQ==", "dev": true, "dependencies": { - "@webassemblyjs/ast": "1.11.1", - "@webassemblyjs/helper-api-error": "1.11.1", - "@webassemblyjs/helper-wasm-bytecode": "1.11.1", - "@webassemblyjs/ieee754": "1.11.1", - "@webassemblyjs/leb128": "1.11.1", - "@webassemblyjs/utf8": "1.11.1" + "@webassemblyjs/ast": "1.11.6", + "@webassemblyjs/helper-api-error": "1.11.6", + "@webassemblyjs/helper-wasm-bytecode": "1.11.6", + "@webassemblyjs/ieee754": "1.11.6", + "@webassemblyjs/leb128": "1.11.6", + "@webassemblyjs/utf8": "1.11.6" } }, "node_modules/@webassemblyjs/wast-printer": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wast-printer/-/wast-printer-1.11.1.tgz", - "integrity": "sha512-IQboUWM4eKzWW+N/jij2sRatKMh99QEelo3Eb2q0qXkvPRISAj8Qxtmw5itwqK+TTkBuUIE45AxYPToqPtL5gg==", + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wast-printer/-/wast-printer-1.11.6.tgz", + "integrity": "sha512-JM7AhRcE+yW2GWYaKeHL5vt4xqee5N2WcezptmgyhNS+ScggqcT1OtXykhAb13Sn5Yas0j2uv9tHgrjwvzAP4A==", "dev": true, "dependencies": { - "@webassemblyjs/ast": "1.11.1", + "@webassemblyjs/ast": "1.11.6", "@xtuc/long": "4.2.2" } }, @@ -4220,21 +4169,6 @@ "node": ">=0.4.0" } }, - "node_modules/adler-32": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/adler-32/-/adler-32-1.2.0.tgz", - "integrity": "sha512-/vUqU/UY4MVeFsg+SsK6c+/05RZXIHZMGJA+PX5JyWI0ZRcBpupnRuPLU/NXXoFwMYCPCoxIfElM2eS+DUXCqQ==", - "dependencies": { - "exit-on-epipe": "~1.0.1", - "printj": "~1.1.0" - }, - "bin": { - "adler32": "bin/adler32.njs" - }, - "engines": { - "node": ">=0.8" - } - }, "node_modules/agent-base": { "version": "6.0.2", "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz", @@ -5081,26 +5015,6 @@ } ] }, - "node_modules/cfb": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/cfb/-/cfb-1.2.2.tgz", - "integrity": "sha512-KfdUZsSOw19/ObEWasvBP/Ac4reZvAGauZhs6S/gqNhXhI7cKwvlH7ulj+dOEYnca4bm4SGo8C1bTAQvnTjgQA==", - "dependencies": { - "adler-32": "~1.3.0", - "crc-32": "~1.2.0" - }, - "engines": { - "node": ">=0.8" - } - }, - "node_modules/cfb/node_modules/adler-32": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/adler-32/-/adler-32-1.3.1.tgz", - "integrity": "sha512-ynZ4w/nUUv5rrsR8UUGoe1VC9hZj6V5hU9Qw1HlMDJGEJw5S7TfTErWTjMys6M7vr0YWcPqs3qAr4ss0nDfP+A==", - "engines": { - "node": ">=0.8" - } - }, "node_modules/chalk": { "version": "2.4.2", "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", @@ -5315,14 +5229,6 @@ "node": ">= 0.12.0" } }, - "node_modules/codepage": { - "version": "1.15.0", - "resolved": "https://registry.npmjs.org/codepage/-/codepage-1.15.0.tgz", - "integrity": "sha512-3g6NUTPd/YtuuGrhMnOMRjFc+LJw/bnMp3+0r/Wcz3IXUuCosKRJvMphm5+Q+bvTVGcJJuRvVLuYba+WojaFaA==", - "engines": { - "node": ">=0.8" - } - }, "node_modules/collect-v8-coverage": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/collect-v8-coverage/-/collect-v8-coverage-1.0.1.tgz", @@ -5540,16 +5446,6 @@ "webpack": "^5.1.0" } }, - "node_modules/core-js": { - "version": "3.23.2", - "resolved": "https://registry.npmjs.org/core-js/-/core-js-3.23.2.tgz", - "integrity": "sha512-ELJOWxNrJfOH/WK4VJ3Qd+fOqZuOuDNDJz0xG6Bt4mGg2eO/UT9CljCrbqDGovjLKUrGajEEBcoTOc0w+yBYeQ==", - "hasInstallScript": true, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/core-js" - } - }, "node_modules/core-js-pure": { "version": "3.23.2", "resolved": "https://registry.npmjs.org/core-js-pure/-/core-js-pure-3.23.2.tgz", @@ -5586,17 +5482,6 @@ "resolved": "https://registry.npmjs.org/country-flag-icons/-/country-flag-icons-1.5.7.tgz", "integrity": "sha512-AdvXhMcmSp7nBSkpGfW4qR/luAdRUutJqya9PuwRbsBzuoknThfultbv7Ib6fWsHXC43Es/4QJ8gzQQdBNm75A==" }, - "node_modules/crc-32": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/crc-32/-/crc-32-1.2.2.tgz", - "integrity": "sha512-ROmzCKrTnOwybPcJApAA6WBWij23HVfGVNKqqrZpuyZOHqK2CwHSvpGuyt/UNNvaIjEd8X5IFGp4Mh+Ie1IHJQ==", - "bin": { - "crc32": "bin/crc32.njs" - }, - "engines": { - "node": ">=0.8" - } - }, "node_modules/create-require": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/create-require/-/create-require-1.1.1.tgz", @@ -5970,26 +5855,6 @@ "node": ">=12" } }, - "node_modules/d3-geo-projection": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/d3-geo-projection/-/d3-geo-projection-4.0.0.tgz", - "integrity": "sha512-p0bK60CEzph1iqmnxut7d/1kyTmm3UWtPlwdkM31AU+LW+BXazd5zJdoCn7VFxNCHXRngPHRnsNn5uGjLRGndg==", - "dependencies": { - "commander": "7", - "d3-array": "1 - 3", - "d3-geo": "1.12.0 - 3" - }, - "bin": { - "geo2svg": "bin/geo2svg.js", - "geograticule": "bin/geograticule.js", - "geoproject": "bin/geoproject.js", - "geoquantize": "bin/geoquantize.js", - "geostitch": "bin/geostitch.js" - }, - "engines": { - "node": ">=12" - } - }, "node_modules/d3-hierarchy": { "version": "3.1.2", "resolved": "https://registry.npmjs.org/d3-hierarchy/-/d3-hierarchy-3.1.2.tgz", @@ -6735,9 +6600,9 @@ } }, "node_modules/es-module-lexer": { - "version": "0.9.3", - "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-0.9.3.tgz", - "integrity": "sha512-1HQ2M2sPtxwnvOvT1ZClHyQDiggdNjURWpY2we6aMKCQiUVxTmVs2UYPLIrD84sS+kMdUwfBSylbJPwNnBrnHQ==", + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-1.3.0.tgz", + "integrity": "sha512-vZK7T0N2CBmBOixhmjdqx2gWVbFZ4DXZ/NyRMZVlJXPa7CyFS+/a4QQsDGDQy9ZfEzxFuNEsMLeQJnKP2p5/JA==", "dev": true }, "node_modules/es-shim-unscopables": { @@ -7474,14 +7339,6 @@ "node": ">= 0.8.0" } }, - "node_modules/exit-on-epipe": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/exit-on-epipe/-/exit-on-epipe-1.0.1.tgz", - "integrity": "sha512-h2z5mrROTxce56S+pnvAV890uu7ls7f1kEvVGJbw1OlFH3/mlJ5bkXu0KRyW94v37zzHPiUd55iLn3DA7TjWpw==", - "engines": { - "node": ">=0.8" - } - }, "node_modules/expect": { "version": "27.5.1", "resolved": "https://registry.npmjs.org/expect/-/expect-27.5.1.tgz", @@ -7809,14 +7666,6 @@ "node": ">= 0.6" } }, - "node_modules/frac": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/frac/-/frac-1.1.2.tgz", - "integrity": "sha512-w/XBfkibaTl3YDqASwfDUqkna4Z2p9cFSr1aHDt0WoMTECnRfBOv2WArlZILlqgWlmdIlALXGpM2AOhEk5W3IA==", - "engines": { - "node": ">=0.8" - } - }, "node_modules/fresh": { "version": "0.5.2", "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", @@ -10919,9 +10768,9 @@ "dev": true }, "node_modules/json5": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.1.tgz", - "integrity": "sha512-1hqLFMSrGHRHxav9q9gNjJ5EXznIxGVO09xQRrwplcS8qs28pZ8s8hupZAmqDwZUmVZ2Qb2jnyPOWcDH8m8dlA==", + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz", + "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==", "bin": { "json5": "lib/cli.js" }, @@ -11270,9 +11119,9 @@ } }, "node_modules/loader-utils": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-2.0.2.tgz", - "integrity": "sha512-TM57VeHptv569d/GKh6TAYdzKblwDNiumOdkFnejjD0XwTH87K90w3O7AiJRqdQoXygvi1VQTJTLGhJl7WqA7A==", + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-2.0.4.tgz", + "integrity": "sha512-xXqpXoINfFhgua9xiqD8fPFHgkoq1mmmpE92WlDbm9rNRd/EbRb+Gqf908T2DMfuHjjJlksiK2RbHVOdD/MqSw==", "dev": true, "dependencies": { "big.js": "^5.2.2", @@ -11572,9 +11421,9 @@ } }, "node_modules/markerjs2": { - "version": "2.21.4", - "resolved": "https://registry.npmjs.org/markerjs2/-/markerjs2-2.21.4.tgz", - "integrity": "sha512-KftstbdiYYF1zYM2N87Fb60RnT/TpZsZNBOwH7Kp+yENQbtsP4zvnabqqnPGDBMoojhGNOF55wwG0Hk4ho9sHA==" + "version": "2.29.4", + "resolved": "https://registry.npmjs.org/markerjs2/-/markerjs2-2.29.4.tgz", + "integrity": "sha512-Fvtay7a8lGjy8T+ns3fQdeHF8LnAnjg3TO5HUsgVJ2/xUUaIOCfeKbutvivcyrYyG4tnTaiPUMg+mhsZ+Fa9bQ==" }, "node_modules/mdast-util-definitions": { "version": "4.0.0", @@ -12641,17 +12490,6 @@ "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, - "node_modules/printj": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/printj/-/printj-1.1.2.tgz", - "integrity": "sha512-zA2SmoLaxZyArQTOPj5LXecR+RagfPSU5Kw1qP+jkWeNlrq+eJZyY2oS68SU1Z/7/myXM4lo9716laOFAVStCQ==", - "bin": { - "printj": "bin/printj.njs" - }, - "engines": { - "node": ">=0.8" - } - }, "node_modules/process-nextick-args": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", @@ -13292,14 +13130,6 @@ "integrity": "sha512-V2hovdzFbOi77/WajaSMXk2OLm+xNIeQdMMuB7icj7bk6zi2F8GGAxigcnDFpJHbNyNcgyJDiP+8nOrY5cZGrA==", "dev": true }, - "node_modules/rgbcolor": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/rgbcolor/-/rgbcolor-1.0.1.tgz", - "integrity": "sha512-9aZLIrhRaD97sgVhtJOW6ckOEh6/GnvQtdVNfdZ6s67+3/XwLS9lBcQYzEEhYVeUowN7pRzMLsyGhK2i/xvWbw==", - "engines": { - "node": ">= 0.8.15" - } - }, "node_modules/rifm": { "version": "0.12.1", "resolved": "https://registry.npmjs.org/rifm/-/rifm-0.12.1.tgz", @@ -13469,9 +13299,9 @@ } }, "node_modules/schema-utils": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.1.1.tgz", - "integrity": "sha512-Y5PQxS4ITlC+EahLuXaY86TXfR7Dc5lw294alXOq86JAHCihAIZfqv8nNCWvaEJvaC51uN9hbLGeV0cFBdH+Fw==", + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.2.0.tgz", + "integrity": "sha512-0zTyLGyDJYd/MBxG1AhJkKa6fpEBds4OQO2ut0w7OYG+ZGhGea09lijvzsqegYSik88zc7cUtIlnnO+/BvD6gQ==", "dev": true, "dependencies": { "@types/json-schema": "^7.0.8", @@ -13925,17 +13755,6 @@ "integrity": "sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==", "dev": true }, - "node_modules/ssf": { - "version": "0.11.2", - "resolved": "https://registry.npmjs.org/ssf/-/ssf-0.11.2.tgz", - "integrity": "sha512-+idbmIXoYET47hH+d7dfm2epdOMUDjqcB4648sTZ+t2JwoyBFL/insLfB/racrDmsKB3diwsDA696pZMieAC5g==", - "dependencies": { - "frac": "~1.1.2" - }, - "engines": { - "node": ">=0.8" - } - }, "node_modules/stack-utils": { "version": "2.0.5", "resolved": "https://registry.npmjs.org/stack-utils/-/stack-utils-2.0.5.tgz", @@ -13957,14 +13776,6 @@ "node": ">=8" } }, - "node_modules/stackblur-canvas": { - "version": "2.5.0", - "resolved": "https://registry.npmjs.org/stackblur-canvas/-/stackblur-canvas-2.5.0.tgz", - "integrity": "sha512-EeNzTVfj+1In7aSLPKDD03F/ly4RxEuF/EX0YcOG0cKoPXs+SLZxDawQbexQDBzwROs4VKLWTOaZQlZkGBFEIQ==", - "engines": { - "node": ">=0.1.14" - } - }, "node_modules/static-eval": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/static-eval/-/static-eval-2.1.0.tgz", @@ -14534,13 +14345,13 @@ } }, "node_modules/terser": { - "version": "5.15.1", - "resolved": "https://registry.npmjs.org/terser/-/terser-5.15.1.tgz", - "integrity": "sha512-K1faMUvpm/FBxjBXud0LWVAGxmvoPbZbfTCYbSgaaYQaIXI3/TdI7a7ZGA73Zrou6Q8Zmz3oeUTsp/dj+ag2Xw==", + "version": "5.18.0", + "resolved": "https://registry.npmjs.org/terser/-/terser-5.18.0.tgz", + "integrity": "sha512-pdL757Ig5a0I+owA42l6tIuEycRuM7FPY4n62h44mRLRfnOxJkkOHd6i89dOpwZlpF6JXBwaAHF6yWzFrt+QyA==", "dev": true, "dependencies": { - "@jridgewell/source-map": "^0.3.2", - "acorn": "^8.5.0", + "@jridgewell/source-map": "^0.3.3", + "acorn": "^8.8.2", "commander": "^2.20.0", "source-map-support": "~0.5.20" }, @@ -14552,16 +14363,16 @@ } }, "node_modules/terser-webpack-plugin": { - "version": "5.3.3", - "resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-5.3.3.tgz", - "integrity": "sha512-Fx60G5HNYknNTNQnzQ1VePRuu89ZVYWfjRAeT5rITuCY/1b08s49e5kSQwHDirKZWuoKOBRFS98EUUoZ9kLEwQ==", + "version": "5.3.9", + "resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-5.3.9.tgz", + "integrity": "sha512-ZuXsqE07EcggTWQjXUj+Aot/OMcD0bMKGgF63f7UxYcu5/AJF53aIpK1YoP5xR9l6s/Hy2b+t1AM0bLNPRuhwA==", "dev": true, "dependencies": { - "@jridgewell/trace-mapping": "^0.3.7", + "@jridgewell/trace-mapping": "^0.3.17", "jest-worker": "^27.4.5", "schema-utils": "^3.1.1", - "serialize-javascript": "^6.0.0", - "terser": "^5.7.2" + "serialize-javascript": "^6.0.1", + "terser": "^5.16.8" }, "engines": { "node": ">= 10.13.0" @@ -14586,18 +14397,18 @@ } }, "node_modules/terser-webpack-plugin/node_modules/serialize-javascript": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-6.0.0.tgz", - "integrity": "sha512-Qr3TosvguFt8ePWqsvRfrKyQXIiW+nGbYpy8XK24NQHE83caxWt+mIymTT19DGFbNWNLfEwsrkSmN64lVWB9ag==", + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-6.0.1.tgz", + "integrity": "sha512-owoXEFjWRllis8/M1Q+Cw5k8ZH40e3zhp/ovX+Xr/vi1qj6QesbyXXViFbpNvWvPNAD62SutwEXavefrLJWj7w==", "dev": true, "dependencies": { "randombytes": "^2.1.0" } }, "node_modules/terser/node_modules/acorn": { - "version": "8.7.1", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.7.1.tgz", - "integrity": "sha512-Xx54uLJQZ19lKygFXOWsscKUbsBZW0CPykPhVQdhIeIwrbPmJzqeASDInc8nKBnp/JT6igTs82qPXz069H8I/A==", + "version": "8.8.2", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.8.2.tgz", + "integrity": "sha512-xjIYgE8HBrkpd/sJqOGNspf8uHG+NOHGOw6a/Urj8taM2EXfdNAH2oFcPeIFfsv3+kz/mJrS5VuMqbNLjCa2vw==", "dev": true, "bin": { "acorn": "bin/acorn" @@ -15388,22 +15199,22 @@ } }, "node_modules/webpack": { - "version": "5.76.0", - "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.76.0.tgz", - "integrity": "sha512-l5sOdYBDunyf72HW8dF23rFtWq/7Zgvt/9ftMof71E/yUb1YLOBmTgA2K4vQthB3kotMrSj609txVE0dnr2fjA==", + "version": "5.86.0", + "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.86.0.tgz", + "integrity": "sha512-3BOvworZ8SO/D4GVP+GoRC3fVeg5MO4vzmq8TJJEkdmopxyazGDxN8ClqN12uzrZW9Tv8EED8v5VSb6Sqyi0pg==", "dev": true, "dependencies": { "@types/eslint-scope": "^3.7.3", - "@types/estree": "^0.0.51", - "@webassemblyjs/ast": "1.11.1", - "@webassemblyjs/wasm-edit": "1.11.1", - "@webassemblyjs/wasm-parser": "1.11.1", + "@types/estree": "^1.0.0", + "@webassemblyjs/ast": "^1.11.5", + "@webassemblyjs/wasm-edit": "^1.11.5", + "@webassemblyjs/wasm-parser": "^1.11.5", "acorn": "^8.7.1", - "acorn-import-assertions": "^1.7.6", + "acorn-import-assertions": "^1.9.0", "browserslist": "^4.14.5", "chrome-trace-event": "^1.0.2", - "enhanced-resolve": "^5.10.0", - "es-module-lexer": "^0.9.0", + "enhanced-resolve": "^5.14.1", + "es-module-lexer": "^1.2.1", "eslint-scope": "5.1.1", "events": "^3.2.0", "glob-to-regexp": "^0.4.1", @@ -15412,9 +15223,9 @@ "loader-runner": "^4.2.0", "mime-types": "^2.1.27", "neo-async": "^2.6.2", - "schema-utils": "^3.1.0", + "schema-utils": "^3.1.2", "tapable": "^2.1.1", - "terser-webpack-plugin": "^5.1.3", + "terser-webpack-plugin": "^5.3.7", "watchpack": "^2.4.0", "webpack-sources": "^3.2.3" }, @@ -15705,9 +15516,9 @@ } }, "node_modules/webpack/node_modules/acorn": { - "version": "8.7.1", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.7.1.tgz", - "integrity": "sha512-Xx54uLJQZ19lKygFXOWsscKUbsBZW0CPykPhVQdhIeIwrbPmJzqeASDInc8nKBnp/JT6igTs82qPXz069H8I/A==", + "version": "8.8.2", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.8.2.tgz", + "integrity": "sha512-xjIYgE8HBrkpd/sJqOGNspf8uHG+NOHGOw6a/Urj8taM2EXfdNAH2oFcPeIFfsv3+kz/mJrS5VuMqbNLjCa2vw==", "dev": true, "bin": { "acorn": "bin/acorn" @@ -15717,18 +15528,18 @@ } }, "node_modules/webpack/node_modules/acorn-import-assertions": { - "version": "1.8.0", - "resolved": "https://registry.npmjs.org/acorn-import-assertions/-/acorn-import-assertions-1.8.0.tgz", - "integrity": "sha512-m7VZ3jwz4eK6A4Vtt8Ew1/mNbP24u0FhdyfA7fSvnJR6LMdfOYnmuIrrJAgrYfYJ10F/otaHTtrtrtmHdMNzEw==", + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/acorn-import-assertions/-/acorn-import-assertions-1.9.0.tgz", + "integrity": "sha512-cmMwop9x+8KFhxvKrKfPYmN6/pKTYYHBqLa0DfvVZcKMJWNyWLnaqND7dx/qn66R7ewM1UX5XMaDVP5wlVTaVA==", "dev": true, "peerDependencies": { "acorn": "^8" } }, "node_modules/webpack/node_modules/enhanced-resolve": { - "version": "5.12.0", - "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.12.0.tgz", - "integrity": "sha512-QHTXI/sZQmko1cbDoNAa3mJ5qhWUUNAq3vR0/YiD379fWQrcfuoX1+HW2S0MTt7XmoPLapdaDKUtelUSPic7hQ==", + "version": "5.15.0", + "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.15.0.tgz", + "integrity": "sha512-LXYT42KJ7lpIKECr2mAXIaMldcNCh/7E0KBKOu4KSfkHmP+mZmSs+8V5gBAqisWBy0OO4W5Oyys0GO1Y8KtdKg==", "dev": true, "dependencies": { "graceful-fs": "^4.2.4", @@ -15839,22 +15650,6 @@ "integrity": "sha512-JcKqAHLPxcdb9KM49dufGXn2x3ssnfjbcaQdLlfZsL9rH9wgDQjUtDxbo8NE0F6SFvydeu1VhZe7hZuHsB2/pw==", "dev": true }, - "node_modules/wmf": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/wmf/-/wmf-1.0.2.tgz", - "integrity": "sha512-/p9K7bEh0Dj6WbXg4JG0xvLQmIadrner1bi45VMJTfnbVHsc7yIajZyoSoK60/dtVBs12Fm6WkUI5/3WAVsNMw==", - "engines": { - "node": ">=0.8" - } - }, - "node_modules/word": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/word/-/word-0.3.0.tgz", - "integrity": "sha512-OELeY0Q61OXpdUfTp+oweA/vtLVg5VDOXh+3he3PNzLGG/y0oylSOC1xRVj0+l4vQ3tj/bB1HVHv1ocXkQceFA==", - "engines": { - "node": ">=0.8" - } - }, "node_modules/word-wrap": { "version": "1.2.3", "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.3.tgz", @@ -15952,26 +15747,6 @@ } } }, - "node_modules/xlsx": { - "version": "0.17.5", - "resolved": "https://registry.npmjs.org/xlsx/-/xlsx-0.17.5.tgz", - "integrity": "sha512-lXNU0TuYsvElzvtI6O7WIVb9Zar1XYw7Xb3VAx2wn8N/n0whBYrCnHMxtFyIiUU1Wjf09WzmLALDfBO5PqTb1g==", - "dependencies": { - "adler-32": "~1.2.0", - "cfb": "^1.1.4", - "codepage": "~1.15.0", - "crc-32": "~1.2.0", - "ssf": "~0.11.2", - "wmf": "~1.0.1", - "word": "~0.3.0" - }, - "bin": { - "xlsx": "bin/xlsx.njs" - }, - "engines": { - "node": ">=0.8" - } - }, "node_modules/xml": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/xml/-/xml-1.0.1.tgz", @@ -16079,35 +15854,14 @@ } }, "dependencies": { - "@amcharts/amcharts4": { - "version": "4.10.29", - "resolved": "https://registry.npmjs.org/@amcharts/amcharts4/-/amcharts4-4.10.29.tgz", - "integrity": "sha512-uDCvm4V0Xs2jtI0Aa7XFH0jqoyEGx9I2ukFEwaaQzYq11vwowhJsgE3sSv2jsfKETYUvPXb32NbzrXZulE2ESg==", - "requires": { - "@babel/runtime": "^7.6.3", - "core-js": "^3.0.0", - "d3-force": "^3.0.0", - "d3-geo": "^3.0.1", - "d3-geo-projection": "^4.0.0", - "d3-selection": "^3.0.0", - "d3-transition": "^3.0.1", - "pdfmake": "^0.2.2", - "polylabel": "^1.0.2", - "raf": "^3.4.1", - "regression": "^2.0.1", - "rgbcolor": "^1.0.1", - "stackblur-canvas": "^2.0.0", - "tslib": "^2.0.1", - "xlsx": "^0.17.0" - } - }, "@amcharts/amcharts5": { - "version": "5.2.8", - "resolved": "https://registry.npmjs.org/@amcharts/amcharts5/-/amcharts5-5.2.8.tgz", - "integrity": "sha512-hD9dwWrmemyypzEeFvl80rBYdurLt0w13zO+C6vkm/7uAwLZ20CnPeJsutlUwR1DFbX3UgEITVUshknY/Oez0Q==", + "version": "5.3.16", + "resolved": "https://registry.npmjs.org/@amcharts/amcharts5/-/amcharts5-5.3.16.tgz", + "integrity": "sha512-mtYsLmJ/7DrAF61y/m79MNshFC9x9BnoRjlHAk1WBjyWPXtpKthO/FrsdJGPezl44pflnusKgsJEqOQXVOA2Qw==", "requires": { "@types/d3": "^7.0.0", "@types/d3-chord": "^3.0.0", + "@types/d3-hierarchy": "3.1.1", "@types/d3-sankey": "^0.11.1", "@types/d3-shape": "^3.0.0", "@types/geojson": "^7946.0.8", @@ -16120,34 +15874,12 @@ "d3-selection": "^3.0.0", "d3-transition": "^3.0.0", "flatpickr": "^4.6.9", - "markerjs2": "^2.17.2", + "markerjs2": "^2.29.4", "pdfmake": "^0.2.2", "polylabel": "^1.1.0", "regression": "^2.0.1", "svg-arc-to-cubic-bezier": "^3.2.0", - "tslib": "^2.2.0", - "xlsx": "^0.18.0" - }, - "dependencies": { - "adler-32": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/adler-32/-/adler-32-1.3.1.tgz", - "integrity": "sha512-ynZ4w/nUUv5rrsR8UUGoe1VC9hZj6V5hU9Qw1HlMDJGEJw5S7TfTErWTjMys6M7vr0YWcPqs3qAr4ss0nDfP+A==" - }, - "xlsx": { - "version": "0.18.5", - "resolved": "https://registry.npmjs.org/xlsx/-/xlsx-0.18.5.tgz", - "integrity": "sha512-dmg3LCjBPHZnQp5/F/+nnTa+miPJxUXB6vtk42YjBBKayDNagxGEeIdWApkYPOf3Z3pm3k62Knjzp7lMeTEtFQ==", - "requires": { - "adler-32": "~1.3.0", - "cfb": "~1.2.1", - "codepage": "~1.15.0", - "crc-32": "~1.2.1", - "ssf": "~0.11.2", - "wmf": "~1.0.1", - "word": "~0.3.0" - } - } + "tslib": "^2.2.0" } }, "@ampproject/remapping": { @@ -17359,9 +17091,9 @@ } }, "@jridgewell/resolve-uri": { - "version": "3.0.7", - "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.0.7.tgz", - "integrity": "sha512-8cXDaBBHOr2pQ7j77Y6Vp5VDT2sIqWyWQ56TjEq4ih/a4iST3dItRe8Q9fp0rrIl9DoKhWQtUQz/YpOxLkXbNA==" + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.0.tgz", + "integrity": "sha512-F2msla3tad+Mfht5cJq7LSXcdudKTWCVYUgw6pLFOOHSTtZlj6SWNYAp+AhuqLmWdBO2X5hPrLcu8cVP8fy28w==" }, "@jridgewell/set-array": { "version": "1.1.1", @@ -17369,9 +17101,9 @@ "integrity": "sha512-Ct5MqZkLGEXTVmQYbGtx9SVqD2fqwvdubdps5D3djjAkgkKwT918VNOz65pEHFaYTeWcukmJmH5SwsA9Tn2ObQ==" }, "@jridgewell/source-map": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/@jridgewell/source-map/-/source-map-0.3.2.tgz", - "integrity": "sha512-m7O9o2uR8k2ObDysZYzdfhb08VuEml5oWGiosa1VdaPZ/A6QyPkAJuwN0Q1lhULOf6B7MtQmHENS743hWtCrgw==", + "version": "0.3.3", + "resolved": "https://registry.npmjs.org/@jridgewell/source-map/-/source-map-0.3.3.tgz", + "integrity": "sha512-b+fsZXeLYi9fEULmfBrhxn4IrPlINf8fiNarzTof004v3lFdntdwa9PF7vFJqm3mg7s+ScJMxXaE3Acp1irZcg==", "dev": true, "requires": { "@jridgewell/gen-mapping": "^0.3.0", @@ -17379,12 +17111,12 @@ }, "dependencies": { "@jridgewell/gen-mapping": { - "version": "0.3.1", - "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.1.tgz", - "integrity": "sha512-GcHwniMlA2z+WFPWuY8lp3fsza0I8xPFMWL5+n8LYyP6PSvPrXf4+n8stDHZY2DM0zy9sVkRDy1jDI4XGzYVqg==", + "version": "0.3.3", + "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.3.tgz", + "integrity": "sha512-HLhSWOLRi875zjjMG/r+Nv0oCW8umGb0BgEhyX3dDX3egwZtB8PqLnjz3yedt8R5StBrzcg4aBpnh8UA9D1BoQ==", "dev": true, "requires": { - "@jridgewell/set-array": "^1.0.0", + "@jridgewell/set-array": "^1.0.1", "@jridgewell/sourcemap-codec": "^1.4.10", "@jridgewell/trace-mapping": "^0.3.9" } @@ -17392,17 +17124,17 @@ } }, "@jridgewell/sourcemap-codec": { - "version": "1.4.13", - "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.13.tgz", - "integrity": "sha512-GryiOJmNcWbovBxTfZSF71V/mXbgcV3MewDe3kIMCLyIh5e7SKAeUZs+rMnJ8jkMolZ/4/VsdBmMrw3l+VdZ3w==" + "version": "1.4.14", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.14.tgz", + "integrity": "sha512-XPSJHWmi394fuUuzDnGz1wiKqWfo1yXecHQMRf2l6hztTO+nPru658AyDngaBe7isIxEkRsPR3FZh+s7iVa4Uw==" }, "@jridgewell/trace-mapping": { - "version": "0.3.13", - "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.13.tgz", - "integrity": "sha512-o1xbKhp9qnIAoHJSWd6KlCZfqslL4valSF81H8ImioOAxluWYWOpWkpyktY2vnt4tbrX9XYaxovq6cgowaJp2w==", + "version": "0.3.18", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.18.tgz", + "integrity": "sha512-w+niJYzMHdd7USdiH2U6869nqhD2nbfZXND5Yp93qIbEmnDNk7PD48o+YchRVpzMU7M6jVCbenTR7PA1FLQ9pA==", "requires": { - "@jridgewell/resolve-uri": "^3.0.3", - "@jridgewell/sourcemap-codec": "^1.4.10" + "@jridgewell/resolve-uri": "3.1.0", + "@jridgewell/sourcemap-codec": "1.4.14" } }, "@leichtgewicht/ip-codec": { @@ -18128,9 +17860,9 @@ } }, "@types/d3-hierarchy": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/@types/d3-hierarchy/-/d3-hierarchy-3.1.0.tgz", - "integrity": "sha512-g+sey7qrCa3UbsQlMZZBOHROkFqx7KZKvUpRzI/tAp/8erZWpYq7FgNKvYwebi2LaEiVs1klhUfd3WCThxmmWQ==" + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/@types/d3-hierarchy/-/d3-hierarchy-3.1.1.tgz", + "integrity": "sha512-QwjxA3+YCKH3N1Rs3uSiSy1bdxlLB1uUiENXeJudBoAFvtDuswUxLcanoOaR2JYn1melDTuIXR8VhnVyI3yG/A==" }, "@types/d3-interpolate": { "version": "3.0.1", @@ -18262,9 +17994,9 @@ } }, "@types/estree": { - "version": "0.0.51", - "resolved": "https://registry.npmjs.org/@types/estree/-/estree-0.0.51.tgz", - "integrity": "sha512-CuPgU6f3eT/XgKKPqKd/gLZV1Xmvf1a2R5POBOGQa6uv82xpls89HU5zKeVoyR8XzHd1RGNOlQlvUe3CFkjWNQ==", + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.1.tgz", + "integrity": "sha512-LG4opVs2ANWZ1TJoKc937iMmNstM/d0ae1vNbnBvBhqCSezgVUOzcLCqbI5elV8Vy6WKwKjaqR+zO9VKirBBCA==", "dev": true }, "@types/express": { @@ -18928,148 +18660,148 @@ } }, "@webassemblyjs/ast": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.11.1.tgz", - "integrity": "sha512-ukBh14qFLjxTQNTXocdyksN5QdM28S1CxHt2rdskFyL+xFV7VremuBLVbmCePj+URalXBENx/9Lm7lnhihtCSw==", + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.11.6.tgz", + "integrity": "sha512-IN1xI7PwOvLPgjcf180gC1bqn3q/QaOCwYUahIOhbYUu8KA/3tw2RT/T0Gidi1l7Hhj5D/INhJxiICObqpMu4Q==", "dev": true, "requires": { - "@webassemblyjs/helper-numbers": "1.11.1", - "@webassemblyjs/helper-wasm-bytecode": "1.11.1" + "@webassemblyjs/helper-numbers": "1.11.6", + "@webassemblyjs/helper-wasm-bytecode": "1.11.6" } }, "@webassemblyjs/floating-point-hex-parser": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.11.1.tgz", - "integrity": "sha512-iGRfyc5Bq+NnNuX8b5hwBrRjzf0ocrJPI6GWFodBFzmFnyvrQ83SHKhmilCU/8Jv67i4GJZBMhEzltxzcNagtQ==", + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.11.6.tgz", + "integrity": "sha512-ejAj9hfRJ2XMsNHk/v6Fu2dGS+i4UaXBXGemOfQ/JfQ6mdQg/WXtwleQRLLS4OvfDhv8rYnVwH27YJLMyYsxhw==", "dev": true }, "@webassemblyjs/helper-api-error": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-api-error/-/helper-api-error-1.11.1.tgz", - "integrity": "sha512-RlhS8CBCXfRUR/cwo2ho9bkheSXG0+NwooXcc3PAILALf2QLdFyj7KGsKRbVc95hZnhnERon4kW/D3SZpp6Tcg==", + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-api-error/-/helper-api-error-1.11.6.tgz", + "integrity": "sha512-o0YkoP4pVu4rN8aTJgAyj9hC2Sv5UlkzCHhxqWj8butaLvnpdc2jOwh4ewE6CX0txSfLn/UYaV/pheS2Txg//Q==", "dev": true }, "@webassemblyjs/helper-buffer": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-buffer/-/helper-buffer-1.11.1.tgz", - "integrity": "sha512-gwikF65aDNeeXa8JxXa2BAk+REjSyhrNC9ZwdT0f8jc4dQQeDQ7G4m0f2QCLPJiMTTO6wfDmRmj/pW0PsUvIcA==", + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-buffer/-/helper-buffer-1.11.6.tgz", + "integrity": "sha512-z3nFzdcp1mb8nEOFFk8DrYLpHvhKC3grJD2ardfKOzmbmJvEf/tPIqCY+sNcwZIY8ZD7IkB2l7/pqhUhqm7hLA==", "dev": true }, "@webassemblyjs/helper-numbers": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-numbers/-/helper-numbers-1.11.1.tgz", - "integrity": "sha512-vDkbxiB8zfnPdNK9Rajcey5C0w+QJugEglN0of+kmO8l7lDb77AnlKYQF7aarZuCrv+l0UvqL+68gSDr3k9LPQ==", + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-numbers/-/helper-numbers-1.11.6.tgz", + "integrity": "sha512-vUIhZ8LZoIWHBohiEObxVm6hwP034jwmc9kuq5GdHZH0wiLVLIPcMCdpJzG4C11cHoQ25TFIQj9kaVADVX7N3g==", "dev": true, "requires": { - "@webassemblyjs/floating-point-hex-parser": "1.11.1", - "@webassemblyjs/helper-api-error": "1.11.1", + "@webassemblyjs/floating-point-hex-parser": "1.11.6", + "@webassemblyjs/helper-api-error": "1.11.6", "@xtuc/long": "4.2.2" } }, "@webassemblyjs/helper-wasm-bytecode": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.11.1.tgz", - "integrity": "sha512-PvpoOGiJwXeTrSf/qfudJhwlvDQxFgelbMqtq52WWiXC6Xgg1IREdngmPN3bs4RoO83PnL/nFrxucXj1+BX62Q==", + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.11.6.tgz", + "integrity": "sha512-sFFHKwcmBprO9e7Icf0+gddyWYDViL8bpPjJJl0WHxCdETktXdmtWLGVzoHbqUcY4Be1LkNfwTmXOJUFZYSJdA==", "dev": true }, "@webassemblyjs/helper-wasm-section": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.11.1.tgz", - "integrity": "sha512-10P9No29rYX1j7F3EVPX3JvGPQPae+AomuSTPiF9eBQeChHI6iqjMIwR9JmOJXwpnn/oVGDk7I5IlskuMwU/pg==", + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.11.6.tgz", + "integrity": "sha512-LPpZbSOwTpEC2cgn4hTydySy1Ke+XEu+ETXuoyvuyezHO3Kjdu90KK95Sh9xTbmjrCsUwvWwCOQQNta37VrS9g==", "dev": true, "requires": { - "@webassemblyjs/ast": "1.11.1", - "@webassemblyjs/helper-buffer": "1.11.1", - "@webassemblyjs/helper-wasm-bytecode": "1.11.1", - "@webassemblyjs/wasm-gen": "1.11.1" + "@webassemblyjs/ast": "1.11.6", + "@webassemblyjs/helper-buffer": "1.11.6", + "@webassemblyjs/helper-wasm-bytecode": "1.11.6", + "@webassemblyjs/wasm-gen": "1.11.6" } }, "@webassemblyjs/ieee754": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/ieee754/-/ieee754-1.11.1.tgz", - "integrity": "sha512-hJ87QIPtAMKbFq6CGTkZYJivEwZDbQUgYd3qKSadTNOhVY7p+gfP6Sr0lLRVTaG1JjFj+r3YchoqRYxNH3M0GQ==", + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/ieee754/-/ieee754-1.11.6.tgz", + "integrity": "sha512-LM4p2csPNvbij6U1f19v6WR56QZ8JcHg3QIJTlSwzFcmx6WSORicYj6I63f9yU1kEUtrpG+kjkiIAkevHpDXrg==", "dev": true, "requires": { "@xtuc/ieee754": "^1.2.0" } }, "@webassemblyjs/leb128": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/leb128/-/leb128-1.11.1.tgz", - "integrity": "sha512-BJ2P0hNZ0u+Th1YZXJpzW6miwqQUGcIHT1G/sf72gLVD9DZ5AdYTqPNbHZh6K1M5VmKvFXwGSWZADz+qBWxeRw==", + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/leb128/-/leb128-1.11.6.tgz", + "integrity": "sha512-m7a0FhE67DQXgouf1tbN5XQcdWoNgaAuoULHIfGFIEVKA6tu/edls6XnIlkmS6FrXAquJRPni3ZZKjw6FSPjPQ==", "dev": true, "requires": { "@xtuc/long": "4.2.2" } }, "@webassemblyjs/utf8": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/utf8/-/utf8-1.11.1.tgz", - "integrity": "sha512-9kqcxAEdMhiwQkHpkNiorZzqpGrodQQ2IGrHHxCy+Ozng0ofyMA0lTqiLkVs1uzTRejX+/O0EOT7KxqVPuXosQ==", + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/utf8/-/utf8-1.11.6.tgz", + "integrity": "sha512-vtXf2wTQ3+up9Zsg8sa2yWiQpzSsMyXj0qViVP6xKGCUT8p8YJ6HqI7l5eCnWx1T/FYdsv07HQs2wTFbbof/RA==", "dev": true }, "@webassemblyjs/wasm-edit": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-edit/-/wasm-edit-1.11.1.tgz", - "integrity": "sha512-g+RsupUC1aTHfR8CDgnsVRVZFJqdkFHpsHMfJuWQzWU3tvnLC07UqHICfP+4XyL2tnr1amvl1Sdp06TnYCmVkA==", + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-edit/-/wasm-edit-1.11.6.tgz", + "integrity": "sha512-Ybn2I6fnfIGuCR+Faaz7YcvtBKxvoLV3Lebn1tM4o/IAJzmi9AWYIPWpyBfU8cC+JxAO57bk4+zdsTjJR+VTOw==", "dev": true, "requires": { - "@webassemblyjs/ast": "1.11.1", - "@webassemblyjs/helper-buffer": "1.11.1", - "@webassemblyjs/helper-wasm-bytecode": "1.11.1", - "@webassemblyjs/helper-wasm-section": "1.11.1", - "@webassemblyjs/wasm-gen": "1.11.1", - "@webassemblyjs/wasm-opt": "1.11.1", - "@webassemblyjs/wasm-parser": "1.11.1", - "@webassemblyjs/wast-printer": "1.11.1" + "@webassemblyjs/ast": "1.11.6", + "@webassemblyjs/helper-buffer": "1.11.6", + "@webassemblyjs/helper-wasm-bytecode": "1.11.6", + "@webassemblyjs/helper-wasm-section": "1.11.6", + "@webassemblyjs/wasm-gen": "1.11.6", + "@webassemblyjs/wasm-opt": "1.11.6", + "@webassemblyjs/wasm-parser": "1.11.6", + "@webassemblyjs/wast-printer": "1.11.6" } }, "@webassemblyjs/wasm-gen": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-gen/-/wasm-gen-1.11.1.tgz", - "integrity": "sha512-F7QqKXwwNlMmsulj6+O7r4mmtAlCWfO/0HdgOxSklZfQcDu0TpLiD1mRt/zF25Bk59FIjEuGAIyn5ei4yMfLhA==", + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-gen/-/wasm-gen-1.11.6.tgz", + "integrity": "sha512-3XOqkZP/y6B4F0PBAXvI1/bky7GryoogUtfwExeP/v7Nzwo1QLcq5oQmpKlftZLbT+ERUOAZVQjuNVak6UXjPA==", "dev": true, "requires": { - "@webassemblyjs/ast": "1.11.1", - "@webassemblyjs/helper-wasm-bytecode": "1.11.1", - "@webassemblyjs/ieee754": "1.11.1", - "@webassemblyjs/leb128": "1.11.1", - "@webassemblyjs/utf8": "1.11.1" + "@webassemblyjs/ast": "1.11.6", + "@webassemblyjs/helper-wasm-bytecode": "1.11.6", + "@webassemblyjs/ieee754": "1.11.6", + "@webassemblyjs/leb128": "1.11.6", + "@webassemblyjs/utf8": "1.11.6" } }, "@webassemblyjs/wasm-opt": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-opt/-/wasm-opt-1.11.1.tgz", - "integrity": "sha512-VqnkNqnZlU5EB64pp1l7hdm3hmQw7Vgqa0KF/KCNO9sIpI6Fk6brDEiX+iCOYrvMuBWDws0NkTOxYEb85XQHHw==", + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-opt/-/wasm-opt-1.11.6.tgz", + "integrity": "sha512-cOrKuLRE7PCe6AsOVl7WasYf3wbSo4CeOk6PkrjS7g57MFfVUF9u6ysQBBODX0LdgSvQqRiGz3CXvIDKcPNy4g==", "dev": true, "requires": { - "@webassemblyjs/ast": "1.11.1", - "@webassemblyjs/helper-buffer": "1.11.1", - "@webassemblyjs/wasm-gen": "1.11.1", - "@webassemblyjs/wasm-parser": "1.11.1" + "@webassemblyjs/ast": "1.11.6", + "@webassemblyjs/helper-buffer": "1.11.6", + "@webassemblyjs/wasm-gen": "1.11.6", + "@webassemblyjs/wasm-parser": "1.11.6" } }, "@webassemblyjs/wasm-parser": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-parser/-/wasm-parser-1.11.1.tgz", - "integrity": "sha512-rrBujw+dJu32gYB7/Lup6UhdkPx9S9SnobZzRVL7VcBH9Bt9bCBLEuX/YXOOtBsOZ4NQrRykKhffRWHvigQvOA==", + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-parser/-/wasm-parser-1.11.6.tgz", + "integrity": "sha512-6ZwPeGzMJM3Dqp3hCsLgESxBGtT/OeCvCZ4TA1JUPYgmhAx38tTPR9JaKy0S5H3evQpO/h2uWs2j6Yc/fjkpTQ==", "dev": true, "requires": { - "@webassemblyjs/ast": "1.11.1", - "@webassemblyjs/helper-api-error": "1.11.1", - "@webassemblyjs/helper-wasm-bytecode": "1.11.1", - "@webassemblyjs/ieee754": "1.11.1", - "@webassemblyjs/leb128": "1.11.1", - "@webassemblyjs/utf8": "1.11.1" + "@webassemblyjs/ast": "1.11.6", + "@webassemblyjs/helper-api-error": "1.11.6", + "@webassemblyjs/helper-wasm-bytecode": "1.11.6", + "@webassemblyjs/ieee754": "1.11.6", + "@webassemblyjs/leb128": "1.11.6", + "@webassemblyjs/utf8": "1.11.6" } }, "@webassemblyjs/wast-printer": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wast-printer/-/wast-printer-1.11.1.tgz", - "integrity": "sha512-IQboUWM4eKzWW+N/jij2sRatKMh99QEelo3Eb2q0qXkvPRISAj8Qxtmw5itwqK+TTkBuUIE45AxYPToqPtL5gg==", + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wast-printer/-/wast-printer-1.11.6.tgz", + "integrity": "sha512-JM7AhRcE+yW2GWYaKeHL5vt4xqee5N2WcezptmgyhNS+ScggqcT1OtXykhAb13Sn5Yas0j2uv9tHgrjwvzAP4A==", "dev": true, "requires": { - "@webassemblyjs/ast": "1.11.1", + "@webassemblyjs/ast": "1.11.6", "@xtuc/long": "4.2.2" } }, @@ -19161,15 +18893,6 @@ "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-7.2.0.tgz", "integrity": "sha512-OPdCF6GsMIP+Az+aWfAAOEt2/+iVDKE7oy6lJ098aoe59oAmK76qV6Gw60SbZ8jHuG2wH058GF4pLFbYamYrVA==" }, - "adler-32": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/adler-32/-/adler-32-1.2.0.tgz", - "integrity": "sha512-/vUqU/UY4MVeFsg+SsK6c+/05RZXIHZMGJA+PX5JyWI0ZRcBpupnRuPLU/NXXoFwMYCPCoxIfElM2eS+DUXCqQ==", - "requires": { - "exit-on-epipe": "~1.0.1", - "printj": "~1.1.0" - } - }, "agent-base": { "version": "6.0.2", "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz", @@ -19807,22 +19530,6 @@ "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001358.tgz", "integrity": "sha512-hvp8PSRymk85R20bsDra7ZTCpSVGN/PAz9pSAjPSjKC+rNmnUk5vCRgJwiTT/O4feQ/yu/drvZYpKxxhbFuChw==" }, - "cfb": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/cfb/-/cfb-1.2.2.tgz", - "integrity": "sha512-KfdUZsSOw19/ObEWasvBP/Ac4reZvAGauZhs6S/gqNhXhI7cKwvlH7ulj+dOEYnca4bm4SGo8C1bTAQvnTjgQA==", - "requires": { - "adler-32": "~1.3.0", - "crc-32": "~1.2.0" - }, - "dependencies": { - "adler-32": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/adler-32/-/adler-32-1.3.1.tgz", - "integrity": "sha512-ynZ4w/nUUv5rrsR8UUGoe1VC9hZj6V5hU9Qw1HlMDJGEJw5S7TfTErWTjMys6M7vr0YWcPqs3qAr4ss0nDfP+A==" - } - } - }, "chalk": { "version": "2.4.2", "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", @@ -19975,11 +19682,6 @@ "integrity": "sha512-QVb0dM5HvG+uaxitm8wONl7jltx8dqhfU33DcqtOZcLSVIKSDDLDi7+0LbAKiyI8hD9u42m2YxXSkMGWThaecQ==", "dev": true }, - "codepage": { - "version": "1.15.0", - "resolved": "https://registry.npmjs.org/codepage/-/codepage-1.15.0.tgz", - "integrity": "sha512-3g6NUTPd/YtuuGrhMnOMRjFc+LJw/bnMp3+0r/Wcz3IXUuCosKRJvMphm5+Q+bvTVGcJJuRvVLuYba+WojaFaA==" - }, "collect-v8-coverage": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/collect-v8-coverage/-/collect-v8-coverage-1.0.1.tgz", @@ -20146,11 +19848,6 @@ "serialize-javascript": "^5.0.1" } }, - "core-js": { - "version": "3.23.2", - "resolved": "https://registry.npmjs.org/core-js/-/core-js-3.23.2.tgz", - "integrity": "sha512-ELJOWxNrJfOH/WK4VJ3Qd+fOqZuOuDNDJz0xG6Bt4mGg2eO/UT9CljCrbqDGovjLKUrGajEEBcoTOc0w+yBYeQ==" - }, "core-js-pure": { "version": "3.23.2", "resolved": "https://registry.npmjs.org/core-js-pure/-/core-js-pure-3.23.2.tgz", @@ -20179,11 +19876,6 @@ "resolved": "https://registry.npmjs.org/country-flag-icons/-/country-flag-icons-1.5.7.tgz", "integrity": "sha512-AdvXhMcmSp7nBSkpGfW4qR/luAdRUutJqya9PuwRbsBzuoknThfultbv7Ib6fWsHXC43Es/4QJ8gzQQdBNm75A==" }, - "crc-32": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/crc-32/-/crc-32-1.2.2.tgz", - "integrity": "sha512-ROmzCKrTnOwybPcJApAA6WBWij23HVfGVNKqqrZpuyZOHqK2CwHSvpGuyt/UNNvaIjEd8X5IFGp4Mh+Ie1IHJQ==" - }, "create-require": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/create-require/-/create-require-1.1.1.tgz", @@ -20465,16 +20157,6 @@ "d3-array": "2.5.0 - 3" } }, - "d3-geo-projection": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/d3-geo-projection/-/d3-geo-projection-4.0.0.tgz", - "integrity": "sha512-p0bK60CEzph1iqmnxut7d/1kyTmm3UWtPlwdkM31AU+LW+BXazd5zJdoCn7VFxNCHXRngPHRnsNn5uGjLRGndg==", - "requires": { - "commander": "7", - "d3-array": "1 - 3", - "d3-geo": "1.12.0 - 3" - } - }, "d3-hierarchy": { "version": "3.1.2", "resolved": "https://registry.npmjs.org/d3-hierarchy/-/d3-hierarchy-3.1.2.tgz", @@ -21049,9 +20731,9 @@ } }, "es-module-lexer": { - "version": "0.9.3", - "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-0.9.3.tgz", - "integrity": "sha512-1HQ2M2sPtxwnvOvT1ZClHyQDiggdNjURWpY2we6aMKCQiUVxTmVs2UYPLIrD84sS+kMdUwfBSylbJPwNnBrnHQ==", + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-1.3.0.tgz", + "integrity": "sha512-vZK7T0N2CBmBOixhmjdqx2gWVbFZ4DXZ/NyRMZVlJXPa7CyFS+/a4QQsDGDQy9ZfEzxFuNEsMLeQJnKP2p5/JA==", "dev": true }, "es-shim-unscopables": { @@ -21593,11 +21275,6 @@ "integrity": "sha512-Zk/eNKV2zbjpKzrsQ+n1G6poVbErQxJ0LBOJXaKZ1EViLzH+hrLu9cdXI4zw9dBQJslwBEpbQ2P1oS7nDxs6jQ==", "dev": true }, - "exit-on-epipe": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/exit-on-epipe/-/exit-on-epipe-1.0.1.tgz", - "integrity": "sha512-h2z5mrROTxce56S+pnvAV890uu7ls7f1kEvVGJbw1OlFH3/mlJ5bkXu0KRyW94v37zzHPiUd55iLn3DA7TjWpw==" - }, "expect": { "version": "27.5.1", "resolved": "https://registry.npmjs.org/expect/-/expect-27.5.1.tgz", @@ -21870,11 +21547,6 @@ "integrity": "sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==", "dev": true }, - "frac": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/frac/-/frac-1.1.2.tgz", - "integrity": "sha512-w/XBfkibaTl3YDqASwfDUqkna4Z2p9cFSr1aHDt0WoMTECnRfBOv2WArlZILlqgWlmdIlALXGpM2AOhEk5W3IA==" - }, "fresh": { "version": "0.5.2", "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", @@ -24143,9 +23815,9 @@ "dev": true }, "json5": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.1.tgz", - "integrity": "sha512-1hqLFMSrGHRHxav9q9gNjJ5EXznIxGVO09xQRrwplcS8qs28pZ8s8hupZAmqDwZUmVZ2Qb2jnyPOWcDH8m8dlA==" + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz", + "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==" }, "jss": { "version": "10.9.2", @@ -24409,9 +24081,9 @@ "dev": true }, "loader-utils": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-2.0.2.tgz", - "integrity": "sha512-TM57VeHptv569d/GKh6TAYdzKblwDNiumOdkFnejjD0XwTH87K90w3O7AiJRqdQoXygvi1VQTJTLGhJl7WqA7A==", + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-2.0.4.tgz", + "integrity": "sha512-xXqpXoINfFhgua9xiqD8fPFHgkoq1mmmpE92WlDbm9rNRd/EbRb+Gqf908T2DMfuHjjJlksiK2RbHVOdD/MqSw==", "dev": true, "requires": { "big.js": "^5.2.2", @@ -24643,9 +24315,9 @@ } }, "markerjs2": { - "version": "2.21.4", - "resolved": "https://registry.npmjs.org/markerjs2/-/markerjs2-2.21.4.tgz", - "integrity": "sha512-KftstbdiYYF1zYM2N87Fb60RnT/TpZsZNBOwH7Kp+yENQbtsP4zvnabqqnPGDBMoojhGNOF55wwG0Hk4ho9sHA==" + "version": "2.29.4", + "resolved": "https://registry.npmjs.org/markerjs2/-/markerjs2-2.29.4.tgz", + "integrity": "sha512-Fvtay7a8lGjy8T+ns3fQdeHF8LnAnjg3TO5HUsgVJ2/xUUaIOCfeKbutvivcyrYyG4tnTaiPUMg+mhsZ+Fa9bQ==" }, "mdast-util-definitions": { "version": "4.0.0", @@ -25425,11 +25097,6 @@ } } }, - "printj": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/printj/-/printj-1.1.2.tgz", - "integrity": "sha512-zA2SmoLaxZyArQTOPj5LXecR+RagfPSU5Kw1qP+jkWeNlrq+eJZyY2oS68SU1Z/7/myXM4lo9716laOFAVStCQ==" - }, "process-nextick-args": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", @@ -25902,11 +25569,6 @@ "integrity": "sha512-V2hovdzFbOi77/WajaSMXk2OLm+xNIeQdMMuB7icj7bk6zi2F8GGAxigcnDFpJHbNyNcgyJDiP+8nOrY5cZGrA==", "dev": true }, - "rgbcolor": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/rgbcolor/-/rgbcolor-1.0.1.tgz", - "integrity": "sha512-9aZLIrhRaD97sgVhtJOW6ckOEh6/GnvQtdVNfdZ6s67+3/XwLS9lBcQYzEEhYVeUowN7pRzMLsyGhK2i/xvWbw==" - }, "rifm": { "version": "0.12.1", "resolved": "https://registry.npmjs.org/rifm/-/rifm-0.12.1.tgz", @@ -26014,9 +25676,9 @@ } }, "schema-utils": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.1.1.tgz", - "integrity": "sha512-Y5PQxS4ITlC+EahLuXaY86TXfR7Dc5lw294alXOq86JAHCihAIZfqv8nNCWvaEJvaC51uN9hbLGeV0cFBdH+Fw==", + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.2.0.tgz", + "integrity": "sha512-0zTyLGyDJYd/MBxG1AhJkKa6fpEBds4OQO2ut0w7OYG+ZGhGea09lijvzsqegYSik88zc7cUtIlnnO+/BvD6gQ==", "dev": true, "requires": { "@types/json-schema": "^7.0.8", @@ -26404,14 +26066,6 @@ "integrity": "sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==", "dev": true }, - "ssf": { - "version": "0.11.2", - "resolved": "https://registry.npmjs.org/ssf/-/ssf-0.11.2.tgz", - "integrity": "sha512-+idbmIXoYET47hH+d7dfm2epdOMUDjqcB4648sTZ+t2JwoyBFL/insLfB/racrDmsKB3diwsDA696pZMieAC5g==", - "requires": { - "frac": "~1.1.2" - } - }, "stack-utils": { "version": "2.0.5", "resolved": "https://registry.npmjs.org/stack-utils/-/stack-utils-2.0.5.tgz", @@ -26429,11 +26083,6 @@ } } }, - "stackblur-canvas": { - "version": "2.5.0", - "resolved": "https://registry.npmjs.org/stackblur-canvas/-/stackblur-canvas-2.5.0.tgz", - "integrity": "sha512-EeNzTVfj+1In7aSLPKDD03F/ly4RxEuF/EX0YcOG0cKoPXs+SLZxDawQbexQDBzwROs4VKLWTOaZQlZkGBFEIQ==" - }, "static-eval": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/static-eval/-/static-eval-2.1.0.tgz", @@ -26859,21 +26508,21 @@ } }, "terser": { - "version": "5.15.1", - "resolved": "https://registry.npmjs.org/terser/-/terser-5.15.1.tgz", - "integrity": "sha512-K1faMUvpm/FBxjBXud0LWVAGxmvoPbZbfTCYbSgaaYQaIXI3/TdI7a7ZGA73Zrou6Q8Zmz3oeUTsp/dj+ag2Xw==", + "version": "5.18.0", + "resolved": "https://registry.npmjs.org/terser/-/terser-5.18.0.tgz", + "integrity": "sha512-pdL757Ig5a0I+owA42l6tIuEycRuM7FPY4n62h44mRLRfnOxJkkOHd6i89dOpwZlpF6JXBwaAHF6yWzFrt+QyA==", "dev": true, "requires": { - "@jridgewell/source-map": "^0.3.2", - "acorn": "^8.5.0", + "@jridgewell/source-map": "^0.3.3", + "acorn": "^8.8.2", "commander": "^2.20.0", "source-map-support": "~0.5.20" }, "dependencies": { "acorn": { - "version": "8.7.1", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.7.1.tgz", - "integrity": "sha512-Xx54uLJQZ19lKygFXOWsscKUbsBZW0CPykPhVQdhIeIwrbPmJzqeASDInc8nKBnp/JT6igTs82qPXz069H8I/A==", + "version": "8.8.2", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.8.2.tgz", + "integrity": "sha512-xjIYgE8HBrkpd/sJqOGNspf8uHG+NOHGOw6a/Urj8taM2EXfdNAH2oFcPeIFfsv3+kz/mJrS5VuMqbNLjCa2vw==", "dev": true }, "commander": { @@ -26885,22 +26534,22 @@ } }, "terser-webpack-plugin": { - "version": "5.3.3", - "resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-5.3.3.tgz", - "integrity": "sha512-Fx60G5HNYknNTNQnzQ1VePRuu89ZVYWfjRAeT5rITuCY/1b08s49e5kSQwHDirKZWuoKOBRFS98EUUoZ9kLEwQ==", + "version": "5.3.9", + "resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-5.3.9.tgz", + "integrity": "sha512-ZuXsqE07EcggTWQjXUj+Aot/OMcD0bMKGgF63f7UxYcu5/AJF53aIpK1YoP5xR9l6s/Hy2b+t1AM0bLNPRuhwA==", "dev": true, "requires": { - "@jridgewell/trace-mapping": "^0.3.7", + "@jridgewell/trace-mapping": "^0.3.17", "jest-worker": "^27.4.5", "schema-utils": "^3.1.1", - "serialize-javascript": "^6.0.0", - "terser": "^5.7.2" + "serialize-javascript": "^6.0.1", + "terser": "^5.16.8" }, "dependencies": { "serialize-javascript": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-6.0.0.tgz", - "integrity": "sha512-Qr3TosvguFt8ePWqsvRfrKyQXIiW+nGbYpy8XK24NQHE83caxWt+mIymTT19DGFbNWNLfEwsrkSmN64lVWB9ag==", + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-6.0.1.tgz", + "integrity": "sha512-owoXEFjWRllis8/M1Q+Cw5k8ZH40e3zhp/ovX+Xr/vi1qj6QesbyXXViFbpNvWvPNAD62SutwEXavefrLJWj7w==", "dev": true, "requires": { "randombytes": "^2.1.0" @@ -27473,22 +27122,22 @@ "dev": true }, "webpack": { - "version": "5.76.0", - "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.76.0.tgz", - "integrity": "sha512-l5sOdYBDunyf72HW8dF23rFtWq/7Zgvt/9ftMof71E/yUb1YLOBmTgA2K4vQthB3kotMrSj609txVE0dnr2fjA==", + "version": "5.86.0", + "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.86.0.tgz", + "integrity": "sha512-3BOvworZ8SO/D4GVP+GoRC3fVeg5MO4vzmq8TJJEkdmopxyazGDxN8ClqN12uzrZW9Tv8EED8v5VSb6Sqyi0pg==", "dev": true, "requires": { "@types/eslint-scope": "^3.7.3", - "@types/estree": "^0.0.51", - "@webassemblyjs/ast": "1.11.1", - "@webassemblyjs/wasm-edit": "1.11.1", - "@webassemblyjs/wasm-parser": "1.11.1", + "@types/estree": "^1.0.0", + "@webassemblyjs/ast": "^1.11.5", + "@webassemblyjs/wasm-edit": "^1.11.5", + "@webassemblyjs/wasm-parser": "^1.11.5", "acorn": "^8.7.1", - "acorn-import-assertions": "^1.7.6", + "acorn-import-assertions": "^1.9.0", "browserslist": "^4.14.5", "chrome-trace-event": "^1.0.2", - "enhanced-resolve": "^5.10.0", - "es-module-lexer": "^0.9.0", + "enhanced-resolve": "^5.14.1", + "es-module-lexer": "^1.2.1", "eslint-scope": "5.1.1", "events": "^3.2.0", "glob-to-regexp": "^0.4.1", @@ -27497,30 +27146,30 @@ "loader-runner": "^4.2.0", "mime-types": "^2.1.27", "neo-async": "^2.6.2", - "schema-utils": "^3.1.0", + "schema-utils": "^3.1.2", "tapable": "^2.1.1", - "terser-webpack-plugin": "^5.1.3", + "terser-webpack-plugin": "^5.3.7", "watchpack": "^2.4.0", "webpack-sources": "^3.2.3" }, "dependencies": { "acorn": { - "version": "8.7.1", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.7.1.tgz", - "integrity": "sha512-Xx54uLJQZ19lKygFXOWsscKUbsBZW0CPykPhVQdhIeIwrbPmJzqeASDInc8nKBnp/JT6igTs82qPXz069H8I/A==", + "version": "8.8.2", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.8.2.tgz", + "integrity": "sha512-xjIYgE8HBrkpd/sJqOGNspf8uHG+NOHGOw6a/Urj8taM2EXfdNAH2oFcPeIFfsv3+kz/mJrS5VuMqbNLjCa2vw==", "dev": true }, "acorn-import-assertions": { - "version": "1.8.0", - "resolved": "https://registry.npmjs.org/acorn-import-assertions/-/acorn-import-assertions-1.8.0.tgz", - "integrity": "sha512-m7VZ3jwz4eK6A4Vtt8Ew1/mNbP24u0FhdyfA7fSvnJR6LMdfOYnmuIrrJAgrYfYJ10F/otaHTtrtrtmHdMNzEw==", + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/acorn-import-assertions/-/acorn-import-assertions-1.9.0.tgz", + "integrity": "sha512-cmMwop9x+8KFhxvKrKfPYmN6/pKTYYHBqLa0DfvVZcKMJWNyWLnaqND7dx/qn66R7ewM1UX5XMaDVP5wlVTaVA==", "dev": true, "requires": {} }, "enhanced-resolve": { - "version": "5.12.0", - "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.12.0.tgz", - "integrity": "sha512-QHTXI/sZQmko1cbDoNAa3mJ5qhWUUNAq3vR0/YiD379fWQrcfuoX1+HW2S0MTt7XmoPLapdaDKUtelUSPic7hQ==", + "version": "5.15.0", + "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.15.0.tgz", + "integrity": "sha512-LXYT42KJ7lpIKECr2mAXIaMldcNCh/7E0KBKOu4KSfkHmP+mZmSs+8V5gBAqisWBy0OO4W5Oyys0GO1Y8KtdKg==", "dev": true, "requires": { "graceful-fs": "^4.2.4", @@ -27786,16 +27435,6 @@ "integrity": "sha512-JcKqAHLPxcdb9KM49dufGXn2x3ssnfjbcaQdLlfZsL9rH9wgDQjUtDxbo8NE0F6SFvydeu1VhZe7hZuHsB2/pw==", "dev": true }, - "wmf": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/wmf/-/wmf-1.0.2.tgz", - "integrity": "sha512-/p9K7bEh0Dj6WbXg4JG0xvLQmIadrner1bi45VMJTfnbVHsc7yIajZyoSoK60/dtVBs12Fm6WkUI5/3WAVsNMw==" - }, - "word": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/word/-/word-0.3.0.tgz", - "integrity": "sha512-OELeY0Q61OXpdUfTp+oweA/vtLVg5VDOXh+3he3PNzLGG/y0oylSOC1xRVj0+l4vQ3tj/bB1HVHv1ocXkQceFA==" - }, "word-wrap": { "version": "1.2.3", "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.3.tgz", @@ -27863,20 +27502,6 @@ "dev": true, "requires": {} }, - "xlsx": { - "version": "0.17.5", - "resolved": "https://registry.npmjs.org/xlsx/-/xlsx-0.17.5.tgz", - "integrity": "sha512-lXNU0TuYsvElzvtI6O7WIVb9Zar1XYw7Xb3VAx2wn8N/n0whBYrCnHMxtFyIiUU1Wjf09WzmLALDfBO5PqTb1g==", - "requires": { - "adler-32": "~1.2.0", - "cfb": "^1.1.4", - "codepage": "~1.15.0", - "crc-32": "~1.2.0", - "ssf": "~0.11.2", - "wmf": "~1.0.1", - "word": "~0.3.0" - } - }, "xml": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/xml/-/xml-1.0.1.tgz", diff --git a/frontend/package.json b/frontend/package.json index a6f96224..c22f8863 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -69,8 +69,7 @@ "**/*": "prettier --write --ignore-unknown" }, "dependencies": { - "@amcharts/amcharts4": "^4.10.17", - "@amcharts/amcharts5": "^5.1.8", + "@amcharts/amcharts5": "^5.3.8", "@emotion/react": "^11.10.5", "@emotion/styled": "^11.10.5", "@mui/icons-material": "^5.10.9", diff --git a/frontend/public/locales/de/global.json5 b/frontend/public/locales/de/global.json5 index 2f38852f..8575f4df 100644 --- a/frontend/public/locales/de/global.json5 +++ b/frontend/public/locales/de/global.json5 @@ -1,5 +1,6 @@ { dateFormat: 'dd. MMM yyyy', + dayFormat: 'dd. MMM', topBar: { 'icon-alt': 'ESID Anwendungslogo', language: 'Sprache', @@ -51,6 +52,9 @@ }, chart: { caseData: 'Falldaten', + date: 'Datum', + percentileUp: '0,75-Quantil', + percentileDown: '0,25-Quantil', }, heatlegend: { edit: 'Farblegende bearbeiten', diff --git a/frontend/public/locales/en/global.json5 b/frontend/public/locales/en/global.json5 index 18265263..c769f224 100644 --- a/frontend/public/locales/en/global.json5 +++ b/frontend/public/locales/en/global.json5 @@ -1,5 +1,6 @@ { dateFormat: 'MMM dd. yyyy', + dayFormat: 'MMM dd.', topBar: { 'icon-alt': 'ESID application logo', language: 'Language', @@ -60,6 +61,9 @@ }, chart: { caseData: 'Case Data', + date: 'Date', + percentileUp: '75th percentile', + percentileDown: '25th percentile', }, heatlegend: { edit: 'Edit heatmap colors', diff --git a/frontend/src/components/SimulationChart.tsx b/frontend/src/components/SimulationChart.tsx index 201f6c02..8b4f3abf 100644 --- a/frontend/src/components/SimulationChart.tsx +++ b/frontend/src/components/SimulationChart.tsx @@ -1,14 +1,19 @@ import React, {useEffect, useRef} from 'react'; -import {create} from '@amcharts/amcharts4/.internal/core/utils/Instance'; -import {XYChart} from '@amcharts/amcharts4/.internal/charts/types/XYChart'; -import {DateAxis} from '@amcharts/amcharts4/.internal/charts/axes/DateAxis'; -import {ValueAxis} from '@amcharts/amcharts4/.internal/charts/axes/ValueAxis'; -import {XYCursor} from '@amcharts/amcharts4/.internal/charts/cursors/XYCursor'; -import {LineSeries} from '@amcharts/amcharts4/.internal/charts/series/LineSeries'; -import {Color, color} from '@amcharts/amcharts4/.internal/core/utils/Color'; -import {ExportMenu} from '@amcharts/amcharts4/.internal/core/export/ExportMenu'; -import am4lang_en_US from '@amcharts/amcharts4/lang/en_US'; -import am4lang_de_DE from '@amcharts/amcharts4/lang/de_DE'; +import {Root} from '@amcharts/amcharts5/.internal/core/Root'; +import {Tooltip} from '@amcharts/amcharts5/.internal/core/render/Tooltip'; +import {RoundedRectangle} from '@amcharts/amcharts5/.internal/core/render/RoundedRectangle'; +import {Color, color} from '@amcharts/amcharts5/.internal/core/util/Color'; +import {DataProcessor} from '@amcharts/amcharts5/.internal/core/util/DataProcessor'; +import {XYChart} from '@amcharts/amcharts5/.internal/charts/xy/XYChart'; +import {DateAxis} from '@amcharts/amcharts5/.internal/charts/xy/axes/DateAxis'; +import {AxisRendererX} from '@amcharts/amcharts5/.internal/charts/xy/axes/AxisRendererX'; +import {ValueAxis} from '@amcharts/amcharts5/.internal/charts/xy/axes/ValueAxis'; +import {AxisRendererY} from '@amcharts/amcharts5/.internal/charts/xy/axes/AxisRendererY'; +import {XYCursor} from '@amcharts/amcharts5/.internal/charts/xy/XYCursor'; +import {LineSeries} from '@amcharts/amcharts5/.internal/charts/xy/series/LineSeries'; +import am5locales_en_US from '@amcharts/amcharts5/locales/en_US'; +import am5locales_de_DE from '@amcharts/amcharts5/locales/de_DE'; +import {Exporting, ExportingMenu} from '@amcharts/amcharts5/plugins/exporting'; import {useAppDispatch, useAppSelector} from '../store/hooks'; import {useTheme} from '@mui/material/styles'; import Box from '@mui/material/Box'; @@ -25,12 +30,10 @@ import {NumberFormatter} from 'util/hooks'; import LoadingContainer from './shared/LoadingContainer'; import {useGetMultipleGroupFilterDataQuery} from 'store/services/groupApi'; import {GroupData} from 'types/group'; -/* This component displays the evolution of the pandemic for a specific compartment (hospitalized, dead, infected, etc.) regarding the different scenarios +/* + * This component displays the evolution of the pandemic over time for a specific infection state (hospitalized, dead, infected, etc.) regarding the different scenarios. */ -// deviations toggle (TODO) -const drawDeviations = false; - /** * React Component to render the Simulation Chart Section * @returns {JSX.Element} JSX Element to render the scenario chart container and the scenario graph within. @@ -39,6 +42,7 @@ export default function SimulationChart(): JSX.Element { const {t, i18n} = useTranslation(); const {t: tBackend} = useTranslation('backend'); const theme = useTheme(); + const scenarioList = useAppSelector((state) => state.scenarioList); const selectedDistrict = useAppSelector((state) => state.dataSelection.district.ags); const selectedCompartment = useAppSelector((state) => state.dataSelection.compartment); @@ -94,357 +98,612 @@ export default function SimulationChart(): JSX.Element { const {formatNumber} = NumberFormatter(i18n.language, 3, 8); + const rootRef = useRef(null); const chartRef = useRef(null); - useEffect(() => { - // Create chart instance (is called when props.scenarios changes) - const chart = create('chartdiv', XYChart); - - // Set localization - chart.language.locale = i18n.language === 'de' ? am4lang_de_DE : am4lang_en_US; - - // Create axes - const dateAxis = chart.xAxes.push(new DateAxis()); - const valueAxis = chart.yAxes.push(new ValueAxis()); - valueAxis.min = 0; - - // Add cursor - chart.cursor = new XYCursor(); - chart.cursor.xAxis = dateAxis; - - // Add series for case data - const caseDataSeries = chart.series.push(new LineSeries()); - caseDataSeries.dataFields.valueY = 'caseData'; - caseDataSeries.dataFields.dateX = 'date'; - caseDataSeries.id = 'caseData'; - caseDataSeries.strokeWidth = 2; - caseDataSeries.fill = color('black'); - caseDataSeries.stroke = color('black'); - caseDataSeries.name = t('chart.caseData'); - - const percentileSeries = chart.series.push(new LineSeries()); - percentileSeries.dataFields.valueY = 'percentileUp'; - percentileSeries.dataFields.openValueY = 'percentileDown'; - percentileSeries.dataFields.dateX = 'date'; - percentileSeries.id = 'percentiles'; - percentileSeries.strokeWidth = 0; - percentileSeries.fillOpacity = 0.3; - - // Add series for scenarios - Object.entries(scenarioList.scenarios).forEach(([scenarioId, scenario], i) => { - const series = chart.series.push(new LineSeries()); - series.dataFields.valueY = scenarioId; - series.dataFields.dateX = 'date'; - series.id = scenarioId; - series.strokeWidth = 2; - series.fill = color(theme.custom.scenarios[i % theme.custom.scenarios.length][0]); // loop around the color list if scenarios exceed color list - series.stroke = series.fill; - series.tooltipText = `[bold ${series.stroke.hex}]${tBackend( - `scenario-names.${scenario.label}` - )}:[/] {${scenarioId}}`; - series.name = tBackend(`scenario-names.${scenario.label}`); - - if (drawDeviations) { - const seriesSTD = chart.series.push(new LineSeries()); - seriesSTD.dataFields.valueY = `${scenarioId}STDup`; - seriesSTD.dataFields.openValueY = `${scenarioId}STDdown`; - seriesSTD.dataFields.dateX = 'date'; - seriesSTD.strokeWidth = 0; - seriesSTD.fillOpacity = 0.3; - series.fill = color(theme.custom.scenarios[i % theme.custom.scenarios.length][0]); // loop around the color list if scenarios exceed color list - series.stroke = series.fill; - // override tooltip - series.tooltipText = `${tBackend( - `scenario-names.${scenario.label}` - )}: [bold]{${scenarioId}STDdown} ~ {${scenarioId}STDup}[/]`; + // Effect to initialize root & chart + useEffect( + () => { + // Create root and chart + const root = Root.new('chartdiv'); + const chart = root.container.children.push( + XYChart.new(root, { + panX: false, + panY: false, + wheelX: 'panX', + wheelY: 'zoomX', + maxTooltipDistance: -1, + }) + ); + + // Set number formatter + root.numberFormatter.set('numberFormat', '#,###.'); + + // Create x-axis + const xAxis = chart.xAxes.push( + DateAxis.new(root, { + renderer: AxisRendererX.new(root, {}), + // Set base interval and aggregated intervals when the chart is zoomed out + baseInterval: {timeUnit: 'day', count: 1}, + gridIntervals: [ + {timeUnit: 'day', count: 1}, + {timeUnit: 'day', count: 3}, + {timeUnit: 'day', count: 7}, + {timeUnit: 'month', count: 1}, + {timeUnit: 'month', count: 3}, + {timeUnit: 'year', count: 1}, + ], + // Add tooltip instance so cursor can display value + tooltip: Tooltip.new(root, {}), + }) + ); + // Change axis renderer to have ticks/labels on day center + const xRenderer = xAxis.get('renderer'); + xRenderer.ticks.template.setAll({ + location: 0.5, + }); + + // Create y-axis + chart.yAxes.push( + ValueAxis.new(root, { + renderer: AxisRendererY.new(root, {}), + // Fix lower end to 0 + min: 0, + // Add tooltip instance so cursor can display value + tooltip: Tooltip.new(root, {}), + }) + ); + + // Add cursor + chart.set( + 'cursor', + XYCursor.new(root, { + // Only allow zooming along x-axis + behavior: 'zoomX', + // Snap cursor to xAxis ticks + xAxis: xAxis, + }) + ); + + // Add event on double click to select date + chart.events.on('click', (ev) => { + // Get date from axis position from cursor position + const date = xAxis.positionToDate( + xAxis.toAxisPosition(ev.target.get('cursor')?.getPrivate('positionX') as number) + ); + // Remove time information to only have a date + date.setHours(0, 0, 0, 0); + // Set date in store + dispatch(selectDate(dateToISOString(date))); + }); + + // Set refs to be used in other effects + rootRef.current = root; + chartRef.current = chart; + + // Clean-up before re-running this effect + return () => { + // Dispose old root and chart before creating a new instance + chartRef.current?.dispose(); + rootRef.current?.dispose(); + }; + }, + // This effect should only run once. dispatch should not change during runtime + [dispatch] + ); + + // Effect to change localization of chart if language changes + useEffect( + () => { + // Skip if root or chart is not initialized + if (!rootRef.current || !chartRef.current) { + return; } - }); - // To export this chart - chart.exporting.menu = new ExportMenu(); - chart.exporting.dataFields = { - date: 'Date', - rki: 'RKI', - '1': 'Scenario 1', - '2': 'Scenario 2', - percentileUp: 'PercentileUp', - percentileDown: 'PercentileDown', - }; - chart.exporting.filePrefix = 'Covid Simulation Data'; - - // Add series for groupFilter - if (groupFilterList && selectedScenario) { - const groupFilterStrokes = ['2,4', '8,4', '8,4,2,4']; - Object.values(groupFilterList) - .filter((groupFilter) => groupFilter.isVisible) - .forEach((groupFilter, i) => { - const series = chart.series.push(new LineSeries()); - series.dataFields.valueY = groupFilter.name; - series.dataFields.dateX = 'date'; - series.id = 'group-filter-' + groupFilter.name; - series.strokeWidth = 2; - series.fill = color(theme.custom.scenarios[(selectedScenario - 1) % theme.custom.scenarios.length][0]); - series.stroke = series.fill; - if (i < groupFilterStrokes.length) { - series.strokeDasharray = groupFilterStrokes[i]; - } - series.tooltipText = `[bold ${series.stroke.hex}]${groupFilter.name}:[/] {${i}}`; - series.name = groupFilter.name; + // Set localization + rootRef.current.locale = i18n.language === 'de' ? am5locales_de_DE : am5locales_en_US; + + // Change date formats for ticks & tooltip (use fallback object to suppress undefined object warnings as this cannot be undefined) + const xAxis: DateAxis = chartRef.current.xAxes.getIndex(0) as DateAxis; + xAxis.get('dateFormats', {day: ''})['day'] = t('dayFormat'); + xAxis.get('tooltipDateFormats', {day: ''})['day'] = t('dayFormat'); + // Fix first date of the month falling back to wrong format (also with fallback object) + xAxis.get('periodChangeDateFormats', {day: ''})['day'] = t('dayFormat'); + }, + // Re-run effect if language changes + [i18n.language, t] + ); + + // Effect to add series to chart + useEffect( + () => { + // Skip if root or chart not initialized + if (!rootRef.current || !chartRef.current) { + return; + } + + const chart: XYChart = chartRef.current; + const root: Root = rootRef.current; + const xAxis: DateAxis = chart.xAxes.getIndex(0) as DateAxis; + const yAxis: ValueAxis = chart.yAxes.getIndex(0) as ValueAxis; + + // Add series for case data + const caseDataSeries = chart.series.push( + LineSeries.new(root, { + xAxis: xAxis, + yAxis: yAxis, + id: 'caseData', + name: t('chart.caseData'), + valueXField: 'date', + valueYField: 'caseData', + // Prevent data points from connecting across gaps in the data + connect: false, + stroke: color('#000'), + }) + ); + caseDataSeries.strokes.template.setAll({ + strokeWidth: 2, + }); + + // Add series for percentile area + const percentileSeries = chart.series.push( + LineSeries.new(root, { + xAxis: xAxis, + yAxis: yAxis, + id: 'percentiles', + valueXField: 'date', + valueYField: 'percentileUp', + openValueYField: 'percentileDown', + connect: false, + // Add fill color according to selected scenario (if selected scenario is set) + fill: selectedScenario + ? color(theme.custom.scenarios[(selectedScenario - 1) % theme.custom.scenarios.length][0]) + : undefined, + }) + ); + percentileSeries.strokes.template.setAll({ + strokeWidth: 0, + }); + percentileSeries.fills.template.setAll({ + fillOpacity: 0.3, + visible: true, + }); + + // Add series for each scenario + Object.entries(scenarioList.scenarios).forEach(([scenarioId, scenario], i) => { + const series = chart.series.push( + LineSeries.new(root, { + xAxis: xAxis, + yAxis: yAxis, + id: scenarioId, + name: tBackend(`scenario-names.${scenario.label}`), + valueXField: 'date', + valueYField: scenarioId, + // Prevent data points from connecting across gaps in the data + connect: false, + // Fallback Tooltip (if HTML breaks for some reason) + // For text color: loop around the theme's scenario color list if scenario IDs exceed color list length, then pick first color of sub-palette which is the main color + tooltip: Tooltip.new(root, { + labelText: `[bold ${theme.custom.scenarios[i % theme.custom.scenarios.length][0]}]${tBackend( + `scenario-names.${scenario.label}` + )}:[/] {${scenarioId}}`, + }), + stroke: color(theme.custom.scenarios[i % theme.custom.scenarios.length][0]), + }) + ); + series.strokes.template.setAll({ + strokeWidth: 2, }); - } + }); - chart.events.on('hit', () => { - // Timezone shenanigans could get us the wrong day ... - const date = new Date(dateAxis.tooltipDate); - date.setUTCFullYear(date.getFullYear()); - date.setUTCMonth(date.getMonth()); - date.setUTCDate(date.getDate()); - dispatch(selectDate(dateToISOString(date))); - }); + // Add series for groupFilter (if there are any) + if (groupFilterList && selectedScenario) { + // Define line style variants for groups + const groupFilterStrokes = [ + [2, 4], // dotted + [8, 4], // dashed + [8, 4, 2, 4], // dash-dotted + [8, 4, 2, 4, 2, 4], // dash-dot-dotted + ]; + // Loop through visible group filters + Object.values(groupFilterList) + .filter((groupFilter) => groupFilter.isVisible) + .forEach((groupFilter, i) => { + // Add series for each group filter + const series = chart.series.push( + LineSeries.new(root, { + xAxis: xAxis, + yAxis: yAxis, + id: `group-filter-${groupFilter.name}`, + name: groupFilter.name, + valueXField: 'date', + valueYField: groupFilter.name, + connect: false, + // Fallback Tooltip (if HTML breaks for some reason) + // Use color of selected scenario (scenario ID is 1-based index, color list is 0-based index) loop if scenario ID exceeds length of color list; use first color of palette (main color) + tooltip: Tooltip.new(root, { + labelText: `[bold ${ + theme.custom.scenarios[(selectedScenario - 1) % theme.custom.scenarios.length][0] + }]${groupFilter.name}:[/] {${groupFilter.name}}`, + }), + stroke: color(theme.custom.scenarios[(selectedScenario - 1) % theme.custom.scenarios.length][0]), + }) + ); + series.strokes.template.setAll({ + strokeWidth: 2, + // Loop through stroke list if group filters exceeds list length + strokeDasharray: groupFilterStrokes[i % groupFilterStrokes.length], + }); + }); + } - chartRef.current = chart; - return () => { - chartRef.current?.dispose(); - }; - }, [scenarioList, groupFilterList, dispatch, i18n.language, t, theme, selectedScenario, tBackend]); + // Clean-up function + return () => { + // Remove all series + chart.series.clear(); + }; + }, + // Re-run if scenario, group filter, or selected scenario (percentile series) change. (t, tBackend, and theme do not change during runtime). + [scenarioList, groupFilterList, selectedScenario, t, tBackend, theme] + ); - //Effect to hide disabled scenarios (and show them again if not hidden anymore) - useEffect(() => { - const allSeries = chartRef.current?.series; - if (allSeries) { + // Effect to hide disabled scenarios (and show them again if not hidden anymore) + useEffect( + () => { + const allSeries = chartRef.current?.series; + // Skip effect if chart is not initialized (contains no series yet) + if (!allSeries) return; + + // Set visibility of each series allSeries.each((series) => { - if (scenarioList.scenarios[+series.id] && !activeScenarios?.includes(+series.id)) { - series.hide(); + // Everything but scenario series evaluate to NaN (because scenario series have their scenario id as series id while others have names) + const seriesID = Number(series.get('id')); + // Hide series if it is a scenario series (and in the scenario list) but not in the active scenarios list + if (!Number.isNaN(seriesID) && scenarioList.scenarios[seriesID] && !activeScenarios?.includes(seriesID)) { + void series.hide(); } else { - series.show(); + void series.show(); } }); - } - }, [scenarioList.scenarios, activeScenarios]); + }, + // Re-run effect when the active scenario list or the scenarios change + [scenarioList.scenarios, activeScenarios] + ); - //effect to hide deviations if no scenario is selected - useEffect(() => { - const allSeries = chartRef.current?.series; - if (allSeries) { - allSeries.each((series) => { - if (series.id == 'percentiles') { - if (selectedScenario) { - series.show(); - } else { - series.hide(); - } - } - }); - } - }, [selectedScenario]); + // Effect to hide deviations if no scenario is selected + useEffect( + () => { + // Skip effect if chart is not initialized (contains no series yet) + if (!chartRef.current) return; + + // Find percentile series and only show it if there is a selected scenario + chartRef.current?.series.values + .filter((series) => series.get('id') === 'percentiles') + .map((percentileSeries) => { + selectedScenario ? void percentileSeries.show() : void percentileSeries.hide(); + }); + }, + // Re-run effect when the selected scenario changes + [selectedScenario] + ); // Effect to add Guide when date selected - useEffect(() => { - if (chartRef.current && selectedDate) { - const dateAxis = chartRef.current.xAxes.getIndex(0) as DateAxis; - const range = dateAxis.axisRanges.create(); - range.date = new Date(selectedDate); - range.grid.above = true; - range.grid.stroke = color(theme.palette.primary.main); - range.grid.strokeWidth = 2; - range.grid.strokeOpacity = 1; - range.label.text = '{date}'; - range.label.language.locale = dateAxis.language.locale; - range.label.dateFormatter.dateFormat = t('dateFormat'); - range.label.fill = color('white'); - range.label.background.fill = range.grid.stroke; - } - - // remove old ranges before creating a new one - return () => { - try { - const ranges = chartRef.current?.xAxes.getIndex(0)?.axisRanges; - ranges?.values.forEach((range) => { - ranges.removeValue(range); - }); - } catch (e) { - console.error(e); + useEffect( + () => { + // Skip effect if chart (or root) is not initialized yet or no date is selected + if (!chartRef.current || !rootRef.current || !selectedDate) { + return; } - }; - }, [scenarioList, selectedDate, theme, t, i18n.language, groupFilterData]); - // Effect to update Simulation and case data - useEffect(() => { - if ( - chartRef.current && - simulationData && - simulationData.length > 1 && - selectedCompartment && - percentileData && - selectedScenario - ) { - // clear data - chartRef.current.data = []; - - // create map to match dates - const dataMap = new Map(); - - // cycle through scenarios - activeScenarios?.forEach((scenarioId) => { - if (simulationData[scenarioId]) { - simulationData[scenarioId].results.forEach(({day, compartments}) => { - dataMap.set(day, {...dataMap.get(day), [scenarioId]: compartments[selectedCompartment]}); - }); - } + // Get xAxis from chart + const xAxis = chartRef.current.xAxes.getIndex(0) as DateAxis; + + // Create data item for range + const rangeDataItem = xAxis.makeDataItem({ + // Make sure the time of the start date object is set to first second of day + value: new Date(selectedDate).setHours(0, 0, 0), + // Make sure the time of the end date object is set to last second of day + endValue: new Date(selectedDate).setHours(23, 59, 59), + // Line and label should drawn above the other elements + above: true, }); - // add case data values - caseData?.results.forEach((entry) => { - dataMap.set(entry.day, {...dataMap.get(entry.day), caseData: entry.compartments[selectedCompartment]}); + // Create the range with the data item + const range = xAxis.createAxisRange(rangeDataItem); + + // Set stroke of range (line with label) + range.get('grid')?.setAll({ + stroke: color(theme.palette.primary.main), + strokeOpacity: 1, + strokeWidth: 2, + location: 0.5, + visible: true, }); - //add 25th percentile data - percentileData[0].results?.forEach((entry: PercentileDataByDay) => { - dataMap.set(entry.day, {...dataMap.get(entry.day), percentileDown: entry.compartments[selectedCompartment]}); + // Set fill of range (rest of the day) + range.get('axisFill')?.setAll({ + fill: color(theme.palette.primary.main), + fillOpacity: 0.3, + visible: true, }); - //add 75th percentile data - percentileData[1].results?.forEach((entry: PercentileDataByDay) => { - dataMap.set(entry.day, {...dataMap.get(entry.day), percentileUp: entry.compartments[selectedCompartment]}); + // Set label for range + range.get('label')?.setAll({ + fill: color(theme.palette.primary.contrastText), + text: new Date(selectedDate).toLocaleDateString(i18n.language, { + year: 'numeric', + month: 'short', + day: '2-digit', + }), + location: 0.5, + background: RoundedRectangle.new(rootRef.current, { + fill: color(theme.palette.primary.main), + }), + // Put Label to the topmost layer to make sure it is drawn on top of the axis tick labels + layer: Number.MAX_VALUE, }); - // Add groupFilter data - if (groupFilterList && groupFilterData) { - Object.values(groupFilterList).forEach((groupFilter) => { - if (groupFilter && groupFilter.isVisible) { - if (groupFilterData[groupFilter.name]) { - groupFilterData[groupFilter.name].results.forEach((entry: GroupData) => { - dataMap.set(entry.day, { - ...dataMap.get(entry.day), - [groupFilter.name]: entry.compartments[selectedCompartment], - }); + return () => { + // Discard range before re-running this effect + xAxis.axisRanges.removeValue(range); + }; + }, + // Re-run effect when selection changes (date/scenario/compartment/district) or when the active scenarios/filters change (theme and translation do not change after initialization) + [ + selectedDate, + selectedScenario, + selectedCompartment, + selectedDistrict, + activeScenarios, + groupFilterList, + theme, + t, + i18n.language, + ] + ); + + // Effect to update Simulation and case data + useEffect(() => { + // Skip effect if chart is not initialized yet + if (!chartRef.current) return; + // Also skip if simulation data is not populated or no data was requested (no active scenarios) + if (!simulationData || !simulationData.length) return; + // Also skip if percentile data is not populated + if (!percentileData) return; + // Also skip if there is no scenario or compartment selected + if (!selectedScenario || !selectedCompartment) return; + + // Create empty map to match dates + const dataMap = new Map(); + + // Cycle through scenarios + activeScenarios?.forEach((scenarioId) => { + if (simulationData[scenarioId]) { + simulationData[scenarioId].results.forEach(({day, compartments}) => { + // Add scenario data to map (upsert date entry) + dataMap.set(day, {...dataMap.get(day), [scenarioId]: compartments[selectedCompartment]}); + }); + } + }); + + // Add case data values (upsert date entry) + caseData?.results.forEach((entry) => { + dataMap.set(entry.day, {...dataMap.get(entry.day), caseData: entry.compartments[selectedCompartment]}); + }); + + // Add 25th percentile data + percentileData[0].results?.forEach((entry: PercentileDataByDay) => { + dataMap.set(entry.day, {...dataMap.get(entry.day), percentileDown: entry.compartments[selectedCompartment]}); + }); + + // Add 75th percentile data + percentileData[1].results?.forEach((entry: PercentileDataByDay) => { + dataMap.set(entry.day, {...dataMap.get(entry.day), percentileUp: entry.compartments[selectedCompartment]}); + }); + + // Add groupFilter data of visible filters + if (groupFilterList && groupFilterData) { + Object.values(groupFilterList).forEach((groupFilter) => { + if (groupFilter && groupFilter.isVisible) { + // Check if data for filter is available (else report error) + if (groupFilterData[groupFilter.name]) { + groupFilterData[groupFilter.name].results.forEach((entry: GroupData) => { + dataMap.set(entry.day, { + ...dataMap.get(entry.day), + [groupFilter.name]: entry.compartments[selectedCompartment], }); - } + }); + } else { + console.error(`ERROR: missing data for "${groupFilter.name}" filter`); } + } + }); + } + + // Sort map by date + const dataMapSorted = new Map(Array.from(dataMap).sort(([a], [b]) => String(a).localeCompare(b))); + const data = Array.from(dataMapSorted).map(([day, data]) => { + return {date: day, ...data}; + }); + + // Put data into series + chartRef.current.series.each((series, i) => { + // Set-up data processors for first series (not needed for others since all use the same data) + if (i === 0) { + series.data.processor = DataProcessor.new(rootRef.current as Root, { + // Define date fields and their format (incoming format from API) + dateFields: ['date'], + dateFormat: 'yyyy-MM-dd', }); } + // Link each series to data + series.data.setAll(data); + }); - //change fill color of percentile series to selected scenario color - const percentileSeries = chartRef.current.map.getKey('percentiles') as LineSeries; - if ( - percentileSeries.fill !== - color(theme.custom.scenarios[(selectedScenario - 1) % theme.custom.scenarios.length][0]) - ) { - percentileSeries.fill = color( - theme.custom.scenarios[(selectedScenario - 1) % theme.custom.scenarios.length][0] - ); - } + // Set up HTML tooltip + const tooltipHTML = ` + ${'' /* Current Date and selected compartment name */} + {date.formatDate("${t('dateFormat')}")} (${tBackend( + `infection-states.${selectedCompartment}` + )}) + + ${ + // Table row for each series + chartRef.current.series.values + .map((series): string => { + /* Skip if series: + * - is hidden + * - is percentile series (which is added to the active scenario series) + * - is group filter series + */ + if ( + series.isHidden() || + series.get('id') === 'percentiles' || + series.get('id')?.startsWith('group-filter-') + ) { + return ''; + } + /* Skip with error if series does not have property: + * - id + * - name + * - valueYField + * - stroke + */ + if (!series.get('id') || !series.get('name') || !series.get('valueYField') || !series.get('stroke')) { + console.error( + 'ERROR: missing series property: ', + series.get('id'), + series.get('name'), + series.get('valueYField'), + series.get('stroke') + ); + return ''; + } + // Handle series normally + return ` + + + + ${ + // Add percentiles if this series is the selected scenario + series.get('id') !== selectedScenario.toString() + ? '' + : ` + + ` + } + + ${ + // Add group filters if this series is the selected scenario + series.get('id') !== selectedScenario.toString() + ? '' + : // Add table row for each active group filter + (chartRef.current as XYChart).series.values + .filter((s) => s.get('id')?.startsWith('group-filter-') && !s.isHidden()) + .map((groupFilterSeries) => { + return ` + + + + + `; + }) + .join('') + } + `; + }) + .join('') + } +
+ ${series.get('name') as string} + + {${series.get('valueYField') as string}} + + [{percentileDown} - {percentileUp}] +
+ ${groupFilterSeries.get('name') as string} + + {${groupFilterSeries.get('valueYField') as string}} +
+ `; + + // Attach tooltip to series + chartRef.current.series.each((series) => { + const tooltip = Tooltip.new(rootRef.current as Root, { + labelHTML: tooltipHTML, + getFillFromSprite: false, + autoTextColor: false, + pointerOrientation: 'horizontal', + }); - // sort map by date - const dataMapSorted = new Map(Array.from(dataMap).sort(([a], [b]) => String(a).localeCompare(b))); + // Set tooltip default text color to theme primary text color + tooltip.label.setAll({ + fill: color(theme.palette.text.primary), + }); - // push DataMap into chart data - dataMapSorted.forEach((values, day) => { - chartRef.current?.data.push({ - date: day, - ...values, - }); + // Set tooltip background to theme paper + tooltip.get('background')?.setAll({ + fill: color(theme.palette.background.paper), }); - // set up tooltip - // TODO: HTML Tooltip - chartRef.current.series.each((series) => { - series.adapter.add('tooltipHTML', (_, target) => { - const data = target.tooltipDataItem.dataContext; - const text = [ - `{date.formatDate("${t('dateFormat')}")} (${tBackend( - `infection-states.${selectedCompartment}` - )})`, - ]; - text.push(''); - chartRef.current?.series.each((s) => { - if ( - s.dataFields.valueY && - data && - (data as {[key: string]: number | string})[s.dataFields.valueY] && - s.id !== 'percentiles' && - !s.id.startsWith('group-filter-') - ) { - text.push(''); - text.push( - `` - ); - text.push( - `` - ); - if ( - s.id == scenarioList.scenarios[selectedScenario].id.toString() && - percentileSeries.dataFields.openValueY && - percentileSeries.dataFields.valueY - ) { - text.push( - `` - ); - chartRef.current?.series.each((groupFilterSeries) => { - if ( - groupFilterSeries.id.startsWith('group-filter-') && - groupFilterSeries.dataFields.valueY && - data && - (data as {[key: string]: number | string})[groupFilterSeries.dataFields.valueY] - ) { - text.push(''); - text.push( - `` - ); - text.push( - `` - ); - text.push(``); - } - }); - } else { - text.push(''); - } - } - }); - text.push('
- ${s.name} - ${formatNumber( - (data as {[key: string]: number})[s.dataFields.valueY] - )}[${formatNumber((data as {[key: string]: number})[percentileSeries.dataFields.openValueY])} - - ${formatNumber((data as {[key: string]: number})[percentileSeries.dataFields.valueY])}]
- ${groupFilterSeries.name} - ${formatNumber( - (data as {[key: string]: number})[groupFilterSeries.dataFields.valueY] - )}
'); - text.push('
'); - return text.join('\n'); - }); - // fix tooltip text & background color - if (series.tooltip) { - series.tooltip.label.fill = color(theme.palette.text.primary); - series.tooltip.getFillFromObject = false; - series.tooltip.background.fill = color(theme.palette.background.paper); + // Set tooltip + series.set('tooltip', tooltip); + }); + + // Collect data field names & order for data export + // Always export date and case data (and percentiles of selected scenario) + let dataFields = { + date: `${t('chart.date')}`, + caseData: `${t('chart.caseData')}`, + percentileUp: `${t('chart.percentileUp')}`, + percentileDown: `${t('chart.percentileDown')}`, + }; + // Always put date first, case data second + const dataFieldsOrder = ['date', 'caseData']; + // Loop through active scenarios (if there are any) + if (activeScenarios) { + activeScenarios.forEach((scenario_id) => { + // Add scenario label to export data field names + dataFields = { + ...dataFields, + [scenario_id]: scenarioList.scenarios[scenario_id].label, + }; + // Add scenario id to export data field order (for sorted export like csv) + dataFieldsOrder.push(`${scenario_id}`); + // If this is the selected scenario also add percentiles after it + if (scenario_id == selectedScenario) { + dataFieldsOrder.push('percentileDown', 'percentileUp'); } }); - // prevent multiple tooltips from showing - chartRef.current.cursor.maxTooltipDistance = 0; - - // invalidate/reload data - chartRef.current.invalidateData(); } + // Update export menu + Exporting.new(rootRef.current as Root, { + menu: ExportingMenu.new(rootRef.current as Root, {}), + filePrefix: 'Covid Simulation Data', + dataSource: data, + dateFields: ['date'], + dateFormat: `${t('dateFormat')}`, + dataFields: dataFields, + dataFieldsOrder: dataFieldsOrder, + }); + // Re-run this effect whenever the data itself changes (or any variable the effect uses) }, [ - activeScenarios, - selectedScenario, percentileData, simulationData, caseData, + groupFilterData, + activeScenarios, + selectedScenario, scenarioList, selectedCompartment, theme, groupFilterList, formatNumber, t, - groupFilterData, tBackend, ]); diff --git a/frontend/src/store/DataSelectionSlice.ts b/frontend/src/store/DataSelectionSlice.ts index 3dcc5c29..5f6f9f72 100644 --- a/frontend/src/store/DataSelectionSlice.ts +++ b/frontend/src/store/DataSelectionSlice.ts @@ -17,6 +17,7 @@ export type AGS = string; */ export interface DataSelection { district: {ags: AGS; name: string; type: string}; + /** The current date in the store. Must be an ISO 8601 date cutoff at time (YYYY-MM-DD) */ date: string | null; scenario: number | null; compartment: string | null;