From 3b2e01d52f674e186eaa10783a0a178c7b2b8a21 Mon Sep 17 00:00:00 2001 From: Victor Berchet Date: Thu, 11 Jul 2024 16:08:03 +0200 Subject: [PATCH 01/16] Update Nx --- package-lock.json | 724 ++++++++++++---------------------------------- package.json | 24 +- 2 files changed, 197 insertions(+), 551 deletions(-) diff --git a/package-lock.json b/package-lock.json index 9871a415..9c45380f 100644 --- a/package-lock.json +++ b/package-lock.json @@ -76,17 +76,17 @@ "@esri/arcgis-rest-geocoding": "^4.0.3", "@esri/arcgis-rest-request": "^4.2.3", "@nx-tools/nx-container": "^6.0.1", - "@nx/cypress": "19.4.1", - "@nx/eslint": "19.4.1", - "@nx/eslint-plugin": "19.4.1", - "@nx/express": "19.4.1", - "@nx/jest": "19.4.1", - "@nx/js": "19.4.1", - "@nx/node": "19.4.1", - "@nx/vite": "19.4.1", - "@nx/web": "19.4.1", - "@nx/webpack": "19.4.1", - "@nx/workspace": "19.4.1", + "@nx/cypress": "19.4.2", + "@nx/eslint": "19.4.2", + "@nx/eslint-plugin": "19.4.2", + "@nx/express": "19.4.2", + "@nx/jest": "19.4.2", + "@nx/js": "19.4.2", + "@nx/node": "19.4.2", + "@nx/vite": "19.4.2", + "@nx/web": "19.4.2", + "@nx/webpack": "19.4.2", + "@nx/workspace": "19.4.2", "@preact/preset-vite": "^2.8.3", "@protobuf-ts/plugin": "^2.9.4", "@sveltejs/vite-plugin-svelte": "^3.1.1", @@ -129,7 +129,7 @@ "jest-environment-node": "^29.4.1", "jsdom": "~22.1.0", "mailersend": "^2.2.0", - "nx": "19.4.1", + "nx": "19.4.2", "prettier": "^2.6.2", "rollup-plugin-minify-html-literals": "^1.2.6", "rollup-plugin-visualizer": "^5.12.0", @@ -4370,75 +4370,75 @@ } }, "node_modules/@nrwl/cypress": { - "version": "19.4.1", - "resolved": "https://registry.npmjs.org/@nrwl/cypress/-/cypress-19.4.1.tgz", - "integrity": "sha512-O/F8SHQTeAQ0jlUQjozJjxVf54ZYd9UkQvF3n5zQuxNV24me/h+U8kfqP8nka+uL0/+HZDCCGalRek01v+BsFg==", + "version": "19.4.2", + "resolved": "https://registry.npmjs.org/@nrwl/cypress/-/cypress-19.4.2.tgz", + "integrity": "sha512-Xse5MM7VMm6+CXeuPwz70sOkOTLBxK6rJBt9sfWN5xVXLy0kfvcYD6nk32eB5YUoNb589lORKGPpp78D1zT+fQ==", "dev": true, "dependencies": { - "@nx/cypress": "19.4.1" + "@nx/cypress": "19.4.2" } }, "node_modules/@nrwl/devkit": { - "version": "19.4.1", - "resolved": "https://registry.npmjs.org/@nrwl/devkit/-/devkit-19.4.1.tgz", - "integrity": "sha512-BVo735k+HgCQ78fHi/yDFN7n0kUbCujyASm+iu6BKLi0b2aPi9Dw+Igztiv38g/Gyjjapos0O39XLpbcoGnw3Q==", + "version": "19.4.2", + "resolved": "https://registry.npmjs.org/@nrwl/devkit/-/devkit-19.4.2.tgz", + "integrity": "sha512-uvJ2kjEUq2VAQHKgaDaumFzowagqOJJgAk9dL9mdB4ZwmDi2i3XroInp/X64phrlHRyJAcYEdRJyaaM/924KVQ==", "dev": true, "dependencies": { - "@nx/devkit": "19.4.1" + "@nx/devkit": "19.4.2" } }, "node_modules/@nrwl/eslint-plugin-nx": { - "version": "19.4.1", - "resolved": "https://registry.npmjs.org/@nrwl/eslint-plugin-nx/-/eslint-plugin-nx-19.4.1.tgz", - "integrity": "sha512-TMoSIz1vzezXMv2y/rveopWP5KdsXP5H1LkjZXvvQY6b7f1MrsvaxrUGa/kzX4WnOIKjRAtsnCu/NzwN2Y7v1g==", + "version": "19.4.2", + "resolved": "https://registry.npmjs.org/@nrwl/eslint-plugin-nx/-/eslint-plugin-nx-19.4.2.tgz", + "integrity": "sha512-Ux7YhXOWdIdNnbYoje1VyK/Ef96SHcklTWofGydYWfS71Qz9GZeIzLnjYsYwFv2Kjk7o0gbJDPYW178Id7hgjw==", "dev": true, "dependencies": { - "@nx/eslint-plugin": "19.4.1" + "@nx/eslint-plugin": "19.4.2" } }, "node_modules/@nrwl/express": { - "version": "19.4.1", - "resolved": "https://registry.npmjs.org/@nrwl/express/-/express-19.4.1.tgz", - "integrity": "sha512-wz6IOjImT23k4lI8DhFG/0mAVmVrnTAXtjm08ni7Ha1ecte9n2TbhRbYMLY3LtDVAS7Pl+o/m/4y9T2Cu+ZbXw==", + "version": "19.4.2", + "resolved": "https://registry.npmjs.org/@nrwl/express/-/express-19.4.2.tgz", + "integrity": "sha512-xo6gFkFxVlDZfNFx+OfBO5y/Me4OpJqaycExsHojCLBkH91TFA7rb/0bCtHtyBgYhH1d1l9wcJGxmrn1b5Prjw==", "dev": true, "dependencies": { - "@nx/express": "19.4.1" + "@nx/express": "19.4.2" } }, "node_modules/@nrwl/jest": { - "version": "19.4.1", - "resolved": "https://registry.npmjs.org/@nrwl/jest/-/jest-19.4.1.tgz", - "integrity": "sha512-mOzHX6wfiKRTq7BRXEdxfrvi/x/7fhOP+8qPuhvyNb3256fCVnrOqV2etd/Tvn+RmL8pIUzKnLTZyWuGjA0uCw==", + "version": "19.4.2", + "resolved": "https://registry.npmjs.org/@nrwl/jest/-/jest-19.4.2.tgz", + "integrity": "sha512-523Ecv0NWNex88t/xDls9dAqeA/r2gaDKXzVp03YeUf61Ue5PcdEXYLzgyPuctn6dhVPKGFb1yjaojtGOtRi7A==", "dev": true, "dependencies": { - "@nx/jest": "19.4.1" + "@nx/jest": "19.4.2" } }, "node_modules/@nrwl/js": { - "version": "19.4.1", - "resolved": "https://registry.npmjs.org/@nrwl/js/-/js-19.4.1.tgz", - "integrity": "sha512-yic2Verqq1N43sC7Y0jSIu2i2LaCA8hkpt6kfyhOy5Qru4BHUV+mvXp6E7/d/kpuJQoh8YmWkhXaFroPY8bT+w==", + "version": "19.4.2", + "resolved": "https://registry.npmjs.org/@nrwl/js/-/js-19.4.2.tgz", + "integrity": "sha512-jp1VuNEWhAIDe13rqtQPxq/aw1OF+GCBJe3RKQxElZSiphFnE8PNVqFRusEsowpPVkgt40qlnsqymEa+61eczw==", "dev": true, "dependencies": { - "@nx/js": "19.4.1" + "@nx/js": "19.4.2" } }, "node_modules/@nrwl/node": { - "version": "19.4.1", - "resolved": "https://registry.npmjs.org/@nrwl/node/-/node-19.4.1.tgz", - "integrity": "sha512-+xdd2FxwTs5IKo3cFVIXctyOO5Yz9hvXQZz/l4TlMjgzZwGRo0FeHIkVjOQswU/gDEzNQXwts1BMFgnJwJAg9w==", + "version": "19.4.2", + "resolved": "https://registry.npmjs.org/@nrwl/node/-/node-19.4.2.tgz", + "integrity": "sha512-rtrWvejMsMlqqRSBzpgZOz8MV2utU/nrJPZ0SqF026R7hPPG1k/+mCW0aR7pfQK9YVgrudlqBLrSAqh00Jr/Jg==", "dev": true, "dependencies": { - "@nx/node": "19.4.1" + "@nx/node": "19.4.2" } }, "node_modules/@nrwl/tao": { - "version": "19.4.1", - "resolved": "https://registry.npmjs.org/@nrwl/tao/-/tao-19.4.1.tgz", - "integrity": "sha512-4PHs6Ja8PkWkIrg8ViB47j+dR2fDn51vtQTWL33n4q5hqZ65rvsMHNch4UsC52XUSv55IZnJwcYlxhAx/vXk3g==", + "version": "19.4.2", + "resolved": "https://registry.npmjs.org/@nrwl/tao/-/tao-19.4.2.tgz", + "integrity": "sha512-bRCRWWqR86ckji7tK4xRl9czB2WSZG4qSGqvttQMmxCvQc+njnG/QhnoGXYueaz2xr5Z1z7RJWNEqTYEAILh5Q==", "dev": true, "dependencies": { - "nx": "19.4.1", + "nx": "19.4.2", "tslib": "^2.3.0" }, "bin": { @@ -4446,39 +4446,39 @@ } }, "node_modules/@nrwl/vite": { - "version": "19.4.1", - "resolved": "https://registry.npmjs.org/@nrwl/vite/-/vite-19.4.1.tgz", - "integrity": "sha512-EIbHKQGhw97nMtG+BilLeNXlJr6IdmQVGITPEEeUB9R9Q184OSzb6sYe3oqR6nkqYdOllpGTN+UAkzdBE5ObNA==", + "version": "19.4.2", + "resolved": "https://registry.npmjs.org/@nrwl/vite/-/vite-19.4.2.tgz", + "integrity": "sha512-DR0dR8VdNp8NOyhWaT++ZezE4lfOp0yAwSGj0WT6GNNDutcdAHZJw2n6cm/cyDIz7/0BjY0UTsK2V6pBI9fKSg==", "dev": true, "dependencies": { - "@nx/vite": "19.4.1" + "@nx/vite": "19.4.2" } }, "node_modules/@nrwl/web": { - "version": "19.4.1", - "resolved": "https://registry.npmjs.org/@nrwl/web/-/web-19.4.1.tgz", - "integrity": "sha512-vYSBALiCtr+MKxgQqvTlxz/1WBvINNBC2NgqIMVTU2Ky2GQGOtUqFaWRNfokVHpPm+VLFkiTtYuQjpdt5d9L7Q==", + "version": "19.4.2", + "resolved": "https://registry.npmjs.org/@nrwl/web/-/web-19.4.2.tgz", + "integrity": "sha512-zlKVeEOQeGpZqNgzakIDw+y6V6u/fpQp27GZVxBoeFKOtttEhbfK6n39REBP/XApw0IwGejtA1LDjXDPDWEpNw==", "dev": true, "dependencies": { - "@nx/web": "19.4.1" + "@nx/web": "19.4.2" } }, "node_modules/@nrwl/webpack": { - "version": "19.4.1", - "resolved": "https://registry.npmjs.org/@nrwl/webpack/-/webpack-19.4.1.tgz", - "integrity": "sha512-gv+1ci7MlAmSbBjKFIrgQHxFXkeQ5N3z4hI+mWnSxoLpNkq8KK4B69kYd9dtWFUPGvIUISmqF8MK2yy7dP9vCA==", + "version": "19.4.2", + "resolved": "https://registry.npmjs.org/@nrwl/webpack/-/webpack-19.4.2.tgz", + "integrity": "sha512-BF+8CMnxR3aFT4fMAX1zRrDKIdkEsblnk6DNw+2cfxYJBUHtJ4LwFRWAsuh+VxYg1VX9psoQP8WIDAFfPa7ZcA==", "dev": true, "dependencies": { - "@nx/webpack": "19.4.1" + "@nx/webpack": "19.4.2" } }, "node_modules/@nrwl/workspace": { - "version": "19.4.1", - "resolved": "https://registry.npmjs.org/@nrwl/workspace/-/workspace-19.4.1.tgz", - "integrity": "sha512-PUlxo7nIckj6PicrSHCI0JVLmspdyhQVHdcdh435Gub0bRd9Pw+iHZUPlyvnBRs/ktmfe2v9MmghLZvRE5WNxg==", + "version": "19.4.2", + "resolved": "https://registry.npmjs.org/@nrwl/workspace/-/workspace-19.4.2.tgz", + "integrity": "sha512-+u8Ok6WF0rfaR5wL/WDIZtQhclLBREHvUdnjoLYtL8RspTyqSoQuOXQXP07Ln++rwLWmTIoE2NaSNKF7K0hLRQ==", "dev": true, "dependencies": { - "@nx/workspace": "19.4.1" + "@nx/workspace": "19.4.2" } }, "node_modules/@nx-tools/ci-context": { @@ -4647,15 +4647,15 @@ } }, "node_modules/@nx/cypress": { - "version": "19.4.1", - "resolved": "https://registry.npmjs.org/@nx/cypress/-/cypress-19.4.1.tgz", - "integrity": "sha512-MgdDlwnHxQcPtBC0L9CsRgcbiO/ws2f3BRNWnkOHG2gcFVTYyfe/wOwIerhyBT6Yx6RWAFnAaPg9QDvWXIBHCg==", + "version": "19.4.2", + "resolved": "https://registry.npmjs.org/@nx/cypress/-/cypress-19.4.2.tgz", + "integrity": "sha512-b732py3ssBZJN2EJuQM3Ufo7IcqBk6XXNmMdqaXpi9MdpBHomRgZsMKG2IE87CI6nGWvZF7Bq/OhbZ8CJBtZLw==", "dev": true, "dependencies": { - "@nrwl/cypress": "19.4.1", - "@nx/devkit": "19.4.1", - "@nx/eslint": "19.4.1", - "@nx/js": "19.4.1", + "@nrwl/cypress": "19.4.2", + "@nx/devkit": "19.4.2", + "@nx/eslint": "19.4.2", + "@nx/js": "19.4.2", "@phenomnomnominal/tsquery": "~5.0.1", "detect-port": "^1.5.1", "tslib": "^2.3.0" @@ -4670,12 +4670,12 @@ } }, "node_modules/@nx/devkit": { - "version": "19.4.1", - "resolved": "https://registry.npmjs.org/@nx/devkit/-/devkit-19.4.1.tgz", - "integrity": "sha512-vOUes8e8guFmbcpUcppUlx120Y52ovY46ZnKogOjnw5q7LN12Fvn68A2wBF8SYmyiYmPd56YtUV7A6LuS8Wd3w==", + "version": "19.4.2", + "resolved": "https://registry.npmjs.org/@nx/devkit/-/devkit-19.4.2.tgz", + "integrity": "sha512-4Lp3E7TiIkdYDZCk3dlCPgeTDBIaLqqEis02kgi/vO16Jek7fHet7Irkg3zU9JcjJPuoPjUyyqEXvOv5IL31IA==", "dev": true, "dependencies": { - "@nrwl/devkit": "19.4.1", + "@nrwl/devkit": "19.4.2", "ejs": "^3.1.7", "enquirer": "~2.3.6", "ignore": "^5.0.4", @@ -4702,14 +4702,14 @@ } }, "node_modules/@nx/eslint": { - "version": "19.4.1", - "resolved": "https://registry.npmjs.org/@nx/eslint/-/eslint-19.4.1.tgz", - "integrity": "sha512-d8Glnz77j3NBckpFYod96ptlCndZHdzZtPVZ0QxCNqYtbjy75tMkynjDl5bEoe9MN/au4zrEnFUTy6r+Bdcl8Q==", + "version": "19.4.2", + "resolved": "https://registry.npmjs.org/@nx/eslint/-/eslint-19.4.2.tgz", + "integrity": "sha512-p27Sa0BidOz2Y9z+N8clbfh4+8WTRml0Ep2EJLPVBDIMNYtWnl9RCZdqM/85nkwjaRC3aWsvIcgVbYdLSiU6hw==", "dev": true, "dependencies": { - "@nx/devkit": "19.4.1", - "@nx/js": "19.4.1", - "@nx/linter": "19.4.1", + "@nx/devkit": "19.4.2", + "@nx/js": "19.4.2", + "@nx/linter": "19.4.2", "semver": "^7.5.3", "tslib": "^2.3.0", "typescript": "~5.4.2" @@ -4725,14 +4725,14 @@ } }, "node_modules/@nx/eslint-plugin": { - "version": "19.4.1", - "resolved": "https://registry.npmjs.org/@nx/eslint-plugin/-/eslint-plugin-19.4.1.tgz", - "integrity": "sha512-FpPfoZDSaPpF70ksR09tV4dk0/BXF8STULPc8xKoCnjXlYepeDUSFrA3Lx4M4gIi0Qao94kXLzW1eqgyHFj5HA==", + "version": "19.4.2", + "resolved": "https://registry.npmjs.org/@nx/eslint-plugin/-/eslint-plugin-19.4.2.tgz", + "integrity": "sha512-pIKERLqDsFG0KeV4m7o4ZhV2LY6FCOmcdjgg0QhoslQpQ9kEkJS4qTsHRqlEjNqnNnwEzwY/sFmY97nM/82cXA==", "dev": true, "dependencies": { - "@nrwl/eslint-plugin-nx": "19.4.1", - "@nx/devkit": "19.4.1", - "@nx/js": "19.4.1", + "@nrwl/eslint-plugin-nx": "19.4.2", + "@nx/devkit": "19.4.2", + "@nx/js": "19.4.2", "@typescript-eslint/type-utils": "^7.3.0", "@typescript-eslint/utils": "^7.3.0", "chalk": "^4.1.0", @@ -4859,14 +4859,14 @@ } }, "node_modules/@nx/express": { - "version": "19.4.1", - "resolved": "https://registry.npmjs.org/@nx/express/-/express-19.4.1.tgz", - "integrity": "sha512-KP8FaqrgWvhlzisCk7YXdhPuIlyvwU310o2HnVITgJmj1ycH0LKtUSwHtKgnuMY5604EyEVqOSPzQU7sXfqePg==", + "version": "19.4.2", + "resolved": "https://registry.npmjs.org/@nx/express/-/express-19.4.2.tgz", + "integrity": "sha512-Pddw8Uw+d8eXuygyzbPG7LruhtMKJI2ZLNKSpgC0M/SPeEUqSHxbVBo42FlYC3FLAx7YyHMq+DPWkDBrtuAFbg==", "dev": true, "dependencies": { - "@nrwl/express": "19.4.1", - "@nx/devkit": "19.4.1", - "@nx/node": "19.4.1", + "@nrwl/express": "19.4.2", + "@nx/devkit": "19.4.2", + "@nx/node": "19.4.2", "tslib": "^2.3.0" }, "peerDependencies": { @@ -4879,16 +4879,16 @@ } }, "node_modules/@nx/jest": { - "version": "19.4.1", - "resolved": "https://registry.npmjs.org/@nx/jest/-/jest-19.4.1.tgz", - "integrity": "sha512-HOL2pnf72oraVTORbJ/7hNYB3TyIP57updRIR+2I/ryJXggZuVRcn94wcfaax+s9dz8jf9KTGr0cN4hTO/E51w==", + "version": "19.4.2", + "resolved": "https://registry.npmjs.org/@nx/jest/-/jest-19.4.2.tgz", + "integrity": "sha512-OXpK68K853WIQZycQv+xE7lfE4CX51CDivuThIxED+aE5yYRH3M71tqM9/qkm5Jc/9Tj3qdXzU+KpPA3HBNxFg==", "dev": true, "dependencies": { "@jest/reporters": "^29.4.1", "@jest/test-result": "^29.4.1", - "@nrwl/jest": "19.4.1", - "@nx/devkit": "19.4.1", - "@nx/js": "19.4.1", + "@nrwl/jest": "19.4.2", + "@nx/devkit": "19.4.2", + "@nx/js": "19.4.2", "@phenomnomnominal/tsquery": "~5.0.1", "chalk": "^4.1.0", "identity-obj-proxy": "3.0.0", @@ -4972,9 +4972,9 @@ } }, "node_modules/@nx/js": { - "version": "19.4.1", - "resolved": "https://registry.npmjs.org/@nx/js/-/js-19.4.1.tgz", - "integrity": "sha512-X3GZ3hqYWUES/buunfc4F1pD1pnKOsSkOcj0kiZ2UPk5sl4v32D7lIARXaM99OiTXNbHzi1q/MWxFQAstiNZKQ==", + "version": "19.4.2", + "resolved": "https://registry.npmjs.org/@nx/js/-/js-19.4.2.tgz", + "integrity": "sha512-hY3Q+W/f9uwbaT1SFy5gkfaQebrtTu8putJrwii4o7b5LehuE6/UPwTj7DR7m6t2hYWgPcZaj5Z+HsfNolNYYg==", "dev": true, "dependencies": { "@babel/core": "^7.23.2", @@ -4984,9 +4984,9 @@ "@babel/preset-env": "^7.23.2", "@babel/preset-typescript": "^7.22.5", "@babel/runtime": "^7.22.6", - "@nrwl/js": "19.4.1", - "@nx/devkit": "19.4.1", - "@nx/workspace": "19.4.1", + "@nrwl/js": "19.4.2", + "@nx/devkit": "19.4.2", + "@nx/workspace": "19.4.2", "babel-plugin-const-enum": "^1.0.1", "babel-plugin-macros": "^2.8.0", "babel-plugin-transform-typescript-metadata": "^0.3.1", @@ -5142,32 +5142,32 @@ } }, "node_modules/@nx/linter": { - "version": "19.4.1", - "resolved": "https://registry.npmjs.org/@nx/linter/-/linter-19.4.1.tgz", - "integrity": "sha512-Tw+8WfiXg+URQHopDOXDFDvOVkFjFMQw5NJ0i/jJLFKkywhNK0oxSBzhbJIGtscHM+j6SdcSd6zCy48KCZ7M2Q==", + "version": "19.4.2", + "resolved": "https://registry.npmjs.org/@nx/linter/-/linter-19.4.2.tgz", + "integrity": "sha512-kPSsZOSQVVWwkjQL/s7CyLxf/uKlO6RINGum+NrqKzgnmvQAtFosa/zZ4Mm3JNAPOdrstP8uNOuoLaFCsue4ZA==", "dev": true, "dependencies": { - "@nx/eslint": "19.4.1" + "@nx/eslint": "19.4.2" } }, "node_modules/@nx/node": { - "version": "19.4.1", - "resolved": "https://registry.npmjs.org/@nx/node/-/node-19.4.1.tgz", - "integrity": "sha512-4Mr+jx8Th0v/3Qo26olKmYg8hyFMnn1UW7QSHEUFZ+yIC9QTJc8BOabhrAcgNgIOUdk76e5iAl+igvkS0v7wdQ==", + "version": "19.4.2", + "resolved": "https://registry.npmjs.org/@nx/node/-/node-19.4.2.tgz", + "integrity": "sha512-PTbxbcTaw3cZlzER0SrAC7ly8Uv17lWZBPZ9m5mJmkDS8A2UXEqgS7VC8jdgl8NhafpuYwyzMtP17jfJNT4f7Q==", "dev": true, "dependencies": { - "@nrwl/node": "19.4.1", - "@nx/devkit": "19.4.1", - "@nx/eslint": "19.4.1", - "@nx/jest": "19.4.1", - "@nx/js": "19.4.1", + "@nrwl/node": "19.4.2", + "@nx/devkit": "19.4.2", + "@nx/eslint": "19.4.2", + "@nx/jest": "19.4.2", + "@nx/js": "19.4.2", "tslib": "^2.3.0" } }, "node_modules/@nx/nx-darwin-arm64": { - "version": "19.4.1", - "resolved": "https://registry.npmjs.org/@nx/nx-darwin-arm64/-/nx-darwin-arm64-19.4.1.tgz", - "integrity": "sha512-WfNRFpMoBB5Ayzvwqfy+anEUgqOZLnLctGG1qwMhCOqczcPUtuTrAjRilMYZ7RrT0cvw0da8dTkpkAsAURS7Ig==", + "version": "19.4.2", + "resolved": "https://registry.npmjs.org/@nx/nx-darwin-arm64/-/nx-darwin-arm64-19.4.2.tgz", + "integrity": "sha512-yy0ik+MYli6lg9khgb0/NJIjMr2re2fpE7hl/MhaHWZmTH9PUmzz6vWpx74O3tnz93oT/9ENXFLBagQuj9hjww==", "cpu": [ "arm64" ], @@ -5181,9 +5181,9 @@ } }, "node_modules/@nx/nx-darwin-x64": { - "version": "19.4.1", - "resolved": "https://registry.npmjs.org/@nx/nx-darwin-x64/-/nx-darwin-x64-19.4.1.tgz", - "integrity": "sha512-p8/lJZLeqAFjCyINrQUvlUvG2GkWN0IlqRm7NknNFXisFDwzcT6u12GR96hPbl+6eVBOtldYhwlufF4tZQDJiw==", + "version": "19.4.2", + "resolved": "https://registry.npmjs.org/@nx/nx-darwin-x64/-/nx-darwin-x64-19.4.2.tgz", + "integrity": "sha512-UEZw7qzvWyOe0B5SvvrN4I2irq8FGlf1V6ut0ajL0vDbLR2IiiF6EYiM36ewpJmx5XspjhbLxEyQJn1TUMUm4w==", "cpu": [ "x64" ], @@ -5197,9 +5197,9 @@ } }, "node_modules/@nx/nx-freebsd-x64": { - "version": "19.4.1", - "resolved": "https://registry.npmjs.org/@nx/nx-freebsd-x64/-/nx-freebsd-x64-19.4.1.tgz", - "integrity": "sha512-qi/tRWKuFS6wpYbAD/s0SBqh/2pNXNg+ytxmon3czYPuUrIiMfmXGxtz922P6YUSOWtL2N6Q9UI6vqZwS+g9/A==", + "version": "19.4.2", + "resolved": "https://registry.npmjs.org/@nx/nx-freebsd-x64/-/nx-freebsd-x64-19.4.2.tgz", + "integrity": "sha512-kAB73FAe3Ae50XnZ+DrCFjbbqHJoTF2ZJVYiHdtRfAefEqsrFltM3Py2/qeeSp1Pxtri3sp4yeEui8WGV2ArWA==", "cpu": [ "x64" ], @@ -5213,9 +5213,9 @@ } }, "node_modules/@nx/nx-linux-arm-gnueabihf": { - "version": "19.4.1", - "resolved": "https://registry.npmjs.org/@nx/nx-linux-arm-gnueabihf/-/nx-linux-arm-gnueabihf-19.4.1.tgz", - "integrity": "sha512-AIowQrN14ucZnBr4Syo2oDGYLqjuJHSGgY/ur6mPoxH02ghGAd68Mc1swX8elGRgBcGc251s05H8MjyPQVsT3A==", + "version": "19.4.2", + "resolved": "https://registry.npmjs.org/@nx/nx-linux-arm-gnueabihf/-/nx-linux-arm-gnueabihf-19.4.2.tgz", + "integrity": "sha512-24cHzxYB/cxlvX8I/cYZIp88TNgCrl4srMeUzqV5bHuDKVYjA1BL/gzP/pRmsdOSq+ggAKxzXhgCG3nwStUvdw==", "cpu": [ "arm" ], @@ -5229,9 +5229,9 @@ } }, "node_modules/@nx/nx-linux-arm64-gnu": { - "version": "19.4.1", - "resolved": "https://registry.npmjs.org/@nx/nx-linux-arm64-gnu/-/nx-linux-arm64-gnu-19.4.1.tgz", - "integrity": "sha512-TG/GfX7olq8bINKLOfamikHJWchYapcJheHj7aUZo951X96s6jYpbeZjwGrVesTJ2fO6EYlS7T1sJIqMoSMxaw==", + "version": "19.4.2", + "resolved": "https://registry.npmjs.org/@nx/nx-linux-arm64-gnu/-/nx-linux-arm64-gnu-19.4.2.tgz", + "integrity": "sha512-6gbBak/bL4vEV2aoTFc7VaeWYF+ossJ0YOqx+hwLpv9SSt6e3yIJrqf7SiwdKq0lcoPeHq3DO06+bRzNLZxVTQ==", "cpu": [ "arm64" ], @@ -5245,9 +5245,9 @@ } }, "node_modules/@nx/nx-linux-arm64-musl": { - "version": "19.4.1", - "resolved": "https://registry.npmjs.org/@nx/nx-linux-arm64-musl/-/nx-linux-arm64-musl-19.4.1.tgz", - "integrity": "sha512-GBBKbERw0baa4JKTbQi8LAERI6C5n3Scrk76pmzCn0HW5GxaQygr61kg6H6C7Duy+w+3D7vwMxCk2wPbUOTuOA==", + "version": "19.4.2", + "resolved": "https://registry.npmjs.org/@nx/nx-linux-arm64-musl/-/nx-linux-arm64-musl-19.4.2.tgz", + "integrity": "sha512-JKc3Bw84jWbOhlqXGBIH9/qz3kzTwpKfsIqtar8K8Gd5/UFJS8GLEdy0mXsnoeFrA1DuYJJ0PWxoHkAa1MYLxg==", "cpu": [ "arm64" ], @@ -5261,9 +5261,9 @@ } }, "node_modules/@nx/nx-linux-x64-gnu": { - "version": "19.4.1", - "resolved": "https://registry.npmjs.org/@nx/nx-linux-x64-gnu/-/nx-linux-x64-gnu-19.4.1.tgz", - "integrity": "sha512-zaHHFM75hLVfMEBR8U7X8xiND1HNQJxybItuoBpnXHVRfKJwp1quByqArnaKKCzsvLvO5HdoXIA80ToJNmDkBQ==", + "version": "19.4.2", + "resolved": "https://registry.npmjs.org/@nx/nx-linux-x64-gnu/-/nx-linux-x64-gnu-19.4.2.tgz", + "integrity": "sha512-hyf0cDZ3rAM8WERZ/M82v1rnf6oO1X+xwYq363Qx04SufU+Knto7xHGndLNkx2i18+UtCoEr4ZhDYrIb8ZWHww==", "cpu": [ "x64" ], @@ -5277,9 +5277,9 @@ } }, "node_modules/@nx/nx-linux-x64-musl": { - "version": "19.4.1", - "resolved": "https://registry.npmjs.org/@nx/nx-linux-x64-musl/-/nx-linux-x64-musl-19.4.1.tgz", - "integrity": "sha512-ygfqznUMoXnrI23U12VwkxOqG4C7sV85YaF7fWDIMuszxYU7KtrVAQ5YG0LNW5KNa1JCgKkjL9YszEiNJxK47Q==", + "version": "19.4.2", + "resolved": "https://registry.npmjs.org/@nx/nx-linux-x64-musl/-/nx-linux-x64-musl-19.4.2.tgz", + "integrity": "sha512-XbKut3RTb04FNA0diDhO/OM8DgqaWaaXhyybRocfhITxH+mPQBZPUs/NM3xeQCrzlGjwrBYxt+Y9Ep8Ftgd/MA==", "cpu": [ "x64" ], @@ -5293,9 +5293,9 @@ } }, "node_modules/@nx/nx-win32-arm64-msvc": { - "version": "19.4.1", - "resolved": "https://registry.npmjs.org/@nx/nx-win32-arm64-msvc/-/nx-win32-arm64-msvc-19.4.1.tgz", - "integrity": "sha512-tOpjieJ7XqbhvgQX9xcKTu/nWvj+w9tL0j6NlpP5Gkq1LiGUuXG2EWvOEGS5CsyAtT/tncLo2OJUx//Ah+dEtw==", + "version": "19.4.2", + "resolved": "https://registry.npmjs.org/@nx/nx-win32-arm64-msvc/-/nx-win32-arm64-msvc-19.4.2.tgz", + "integrity": "sha512-VMOQ44KlndtAKE6JaXSQqrAdHBEqbJSJP4EKrBREn8HyVyr6LAfAG3Pj93ZPMvQC47uheisBcDwitxEY/Mhs1Q==", "cpu": [ "arm64" ], @@ -5309,9 +5309,9 @@ } }, "node_modules/@nx/nx-win32-x64-msvc": { - "version": "19.4.1", - "resolved": "https://registry.npmjs.org/@nx/nx-win32-x64-msvc/-/nx-win32-x64-msvc-19.4.1.tgz", - "integrity": "sha512-u9h7nrIplf79A6Yhzk1ZlNNlHrhuKrDaGMyhpTx3QaLEiRp0Kl3haMrnYmPlpRFNDwWXWDKzwiTWZtQoo2JoaA==", + "version": "19.4.2", + "resolved": "https://registry.npmjs.org/@nx/nx-win32-x64-msvc/-/nx-win32-x64-msvc-19.4.2.tgz", + "integrity": "sha512-FOK4XVanWZYM4cLS9uAx8Xg4BpPRdo0z/jt8gVto8BwgoBPIJuytGhnTVyDNgB+nRJf8K3fz7RFcZm5jup/krg==", "cpu": [ "x64" ], @@ -5325,14 +5325,14 @@ } }, "node_modules/@nx/vite": { - "version": "19.4.1", - "resolved": "https://registry.npmjs.org/@nx/vite/-/vite-19.4.1.tgz", - "integrity": "sha512-b1bWJBifTqWlN2GKhsm3j9t0A8L7Sz7ddNP9B7FnSicnahOmVUts/ENXdBCf10O9qxD2aFeSbgJlHJHXZzZYeA==", + "version": "19.4.2", + "resolved": "https://registry.npmjs.org/@nx/vite/-/vite-19.4.2.tgz", + "integrity": "sha512-FIGWtEP5UzFNkKHnYOmy1cWwPj1mlMak1rl5NYQz+CKI80VlWAaGuPxFBZ0sccgKc66vlBiOffXeXWuThB08Mw==", "dev": true, "dependencies": { - "@nrwl/vite": "19.4.1", - "@nx/devkit": "19.4.1", - "@nx/js": "19.4.1", + "@nrwl/vite": "19.4.2", + "@nx/devkit": "19.4.2", + "@nx/js": "19.4.2", "@phenomnomnominal/tsquery": "~5.0.1", "@swc/helpers": "~0.5.0", "enquirer": "~2.3.6", @@ -5344,14 +5344,14 @@ } }, "node_modules/@nx/web": { - "version": "19.4.1", - "resolved": "https://registry.npmjs.org/@nx/web/-/web-19.4.1.tgz", - "integrity": "sha512-h814gF8PDvIVjEfso/84mu/Ih9c4MZrZAdXRy6wwsjz7EUyxFhGy3xEwGVV2RGjm/9Er1kq9xn45g1BprvycFg==", + "version": "19.4.2", + "resolved": "https://registry.npmjs.org/@nx/web/-/web-19.4.2.tgz", + "integrity": "sha512-DsBvA90VBABYb0nJAowW6G+xBMwoglalaM1yCzndReQ280Px83ATgkgJb3yuuBmNBvj/ySTLExlePL5TC+cdUQ==", "dev": true, "dependencies": { - "@nrwl/web": "19.4.1", - "@nx/devkit": "19.4.1", - "@nx/js": "19.4.1", + "@nrwl/web": "19.4.2", + "@nx/devkit": "19.4.2", + "@nx/js": "19.4.2", "chalk": "^4.1.0", "detect-port": "^1.5.1", "http-server": "^14.1.0", @@ -5429,15 +5429,15 @@ } }, "node_modules/@nx/webpack": { - "version": "19.4.1", - "resolved": "https://registry.npmjs.org/@nx/webpack/-/webpack-19.4.1.tgz", - "integrity": "sha512-fpIvChnvY9apurxtz+Huvuy3R2OcvSo/Cczph3YMy5MzBFtMHpCkJNhAyXZLoUb4gO6VLn/oizou67IBuIIE0w==", + "version": "19.4.2", + "resolved": "https://registry.npmjs.org/@nx/webpack/-/webpack-19.4.2.tgz", + "integrity": "sha512-pfVJkd+KHhcqwLmyqe6hLDLYU63kkHjzNc1d9bMLZ0SoKuZa+zoTSOJda0pjZGo6oQgQDRt0zqtKSZuYYKwOeg==", "dev": true, "dependencies": { "@babel/core": "^7.23.2", - "@nrwl/webpack": "19.4.1", - "@nx/devkit": "19.4.1", - "@nx/js": "19.4.1", + "@nrwl/webpack": "19.4.2", + "@nx/devkit": "19.4.2", + "@nx/js": "19.4.2", "@phenomnomnominal/tsquery": "~5.0.1", "ajv": "^8.12.0", "autoprefixer": "^10.4.9", @@ -5545,16 +5545,16 @@ } }, "node_modules/@nx/workspace": { - "version": "19.4.1", - "resolved": "https://registry.npmjs.org/@nx/workspace/-/workspace-19.4.1.tgz", - "integrity": "sha512-2HhPdxe2+kOSc2T4kg2xKqCaQAGYBLfEf7XXGKKJFmZlr1RBp6+mutEzmWUw62BenKagPaIgPV6mfr2TSwzlYQ==", + "version": "19.4.2", + "resolved": "https://registry.npmjs.org/@nx/workspace/-/workspace-19.4.2.tgz", + "integrity": "sha512-wPRDN9jsqNzrrOjwrhEdju2tuEn2/wHW8G3kymGtQL24SHOY3+Ja1ZfZgfRqyjxHyUysVTH/xYfszDQ6qvdlhA==", "dev": true, "dependencies": { - "@nrwl/workspace": "19.4.1", - "@nx/devkit": "19.4.1", + "@nrwl/workspace": "19.4.2", + "@nx/devkit": "19.4.2", "chalk": "^4.1.0", "enquirer": "~2.3.6", - "nx": "19.4.1", + "nx": "19.4.2", "tslib": "^2.3.0", "yargs-parser": "21.1.1" } @@ -7164,20 +7164,11 @@ "version": "0.5.11", "resolved": "https://registry.npmjs.org/@swc/helpers/-/helpers-0.5.11.tgz", "integrity": "sha512-YNlnKRWF2sVojTpIyzwou9XoTNbzbzONwRhOoniEioF1AtaitTvVZblaQRrAzChWQ1bLYyYSWzM18y4WwgzJ+A==", - "devOptional": true, + "dev": true, "dependencies": { "tslib": "^2.4.0" } }, - "node_modules/@swc/types": { - "version": "0.1.9", - "resolved": "https://registry.npmjs.org/@swc/types/-/types-0.1.9.tgz", - "integrity": "sha512-qKnCno++jzcJ4lM4NTfYifm1EFSCeIfKiAHAfkENZAV5Kl9PjJIyd2yeeVv6c/2CckuLyv2NmRC5pv6pm2WQBg==", - "peer": true, - "dependencies": { - "@swc/counter": "^0.1.3" - } - }, "node_modules/@terraformer/arcgis": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/@terraformer/arcgis/-/arcgis-2.1.2.tgz", @@ -7742,7 +7733,8 @@ "node_modules/@types/geojson": { "version": "7946.0.14", "resolved": "https://registry.npmjs.org/@types/geojson/-/geojson-7946.0.14.tgz", - "integrity": "sha512-WCfD5Ht3ZesJUsONdhvm84dmzWOiOzOAqOncN0++w0lBw1o8OuDNJF2McvvCef/yBqb/HYRahp1BYtODFQ8bRg==" + "integrity": "sha512-WCfD5Ht3ZesJUsONdhvm84dmzWOiOzOAqOncN0++w0lBw1o8OuDNJF2McvvCef/yBqb/HYRahp1BYtODFQ8bRg==", + "dev": true }, "node_modules/@types/google.maps": { "version": "3.55.11", @@ -9227,18 +9219,6 @@ "url": "https://opencollective.com/typescript-eslint" } }, - "node_modules/@windycom/plugin-devtools/node_modules/brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", - "dev": true, - "optional": true, - "peer": true, - "dependencies": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, "node_modules/@windycom/plugin-devtools/node_modules/eslint-config-standard-with-typescript": { "version": "43.0.1", "resolved": "https://registry.npmjs.org/eslint-config-standard-with-typescript/-/eslint-config-standard-with-typescript-43.0.1.tgz", @@ -9258,43 +9238,6 @@ "typescript": "*" } }, - "node_modules/@windycom/plugin-devtools/node_modules/glob": { - "version": "7.2.3", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", - "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", - "deprecated": "Glob versions prior to v9 are no longer supported", - "dev": true, - "optional": true, - "peer": true, - "dependencies": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.1.1", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - }, - "engines": { - "node": "*" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/@windycom/plugin-devtools/node_modules/glob/node_modules/minimatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", - "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", - "dev": true, - "optional": true, - "peer": true, - "dependencies": { - "brace-expansion": "^1.1.7" - }, - "engines": { - "node": "*" - } - }, "node_modules/@windycom/plugin-devtools/node_modules/less": { "version": "4.2.0", "resolved": "https://registry.npmjs.org/less/-/less-4.2.0.tgz", @@ -9368,28 +9311,6 @@ "node": ">=4" } }, - "node_modules/@windycom/plugin-devtools/node_modules/mkdirp": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz", - "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==", - "dev": true, - "optional": true, - "peer": true, - "bin": { - "mkdirp": "bin/cmd.js" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/@windycom/plugin-devtools/node_modules/ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", - "dev": true, - "optional": true, - "peer": true - }, "node_modules/@windycom/plugin-devtools/node_modules/pify": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/pify/-/pify-4.0.1.tgz", @@ -9460,14 +9381,6 @@ "fsevents": "~2.3.2" } }, - "node_modules/@windycom/plugin-devtools/node_modules/sax": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/sax/-/sax-1.2.4.tgz", - "integrity": "sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw==", - "dev": true, - "optional": true, - "peer": true - }, "node_modules/@windycom/plugin-devtools/node_modules/semver": { "version": "7.6.2", "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.2.tgz", @@ -9480,52 +9393,6 @@ "node": ">=10" } }, - "node_modules/@windycom/plugin-devtools/node_modules/stylus": { - "version": "0.55.0", - "resolved": "https://registry.npmjs.org/stylus/-/stylus-0.55.0.tgz", - "integrity": "sha512-MuzIIVRSbc8XxHH7FjkvWqkIcr1BvoMZoR/oFuAJDlh7VSaNJzrB4uJ38GRQa+mWjLXODAMzeDe0xi9GYbGwnw==", - "dev": true, - "optional": true, - "peer": true, - "dependencies": { - "css": "^3.0.0", - "debug": "~3.1.0", - "glob": "^7.1.6", - "mkdirp": "~1.0.4", - "safer-buffer": "^2.1.2", - "sax": "~1.2.4", - "semver": "^6.3.0", - "source-map": "^0.7.3" - }, - "bin": { - "stylus": "bin/stylus" - }, - "engines": { - "node": "*" - } - }, - "node_modules/@windycom/plugin-devtools/node_modules/stylus/node_modules/debug": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", - "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", - "dev": true, - "optional": true, - "peer": true, - "dependencies": { - "ms": "2.0.0" - } - }, - "node_modules/@windycom/plugin-devtools/node_modules/stylus/node_modules/semver": { - "version": "6.3.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", - "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", - "dev": true, - "optional": true, - "peer": true, - "bin": { - "semver": "bin/semver.js" - } - }, "node_modules/@windycom/plugin-devtools/node_modules/svelte-preprocess": { "version": "5.1.4", "resolved": "https://registry.npmjs.org/svelte-preprocess/-/svelte-preprocess-5.1.4.tgz", @@ -10168,20 +10035,6 @@ "node": ">= 4.0.0" } }, - "node_modules/atob": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/atob/-/atob-2.1.2.tgz", - "integrity": "sha512-Wm6ukoaOGJi/73p/cl2GvLjTI5JM1k/O14isD73YML8StrH/7/lRFgmg8nICZgD3bZZvjwCGxtMOD3wWNAu8cg==", - "dev": true, - "optional": true, - "peer": true, - "bin": { - "atob": "bin/atob.js" - }, - "engines": { - "node": ">= 4.5.0" - } - }, "node_modules/autoprefixer": { "version": "10.4.19", "resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-10.4.19.tgz", @@ -12016,19 +11869,6 @@ "node": ">=8" } }, - "node_modules/css": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/css/-/css-3.0.0.tgz", - "integrity": "sha512-DG9pFfwOrzc+hawpmqX/dHYHJG+Bsdb0klhyi1sDneOgGOXy9wQIC8hzyVp1e4NRYDBdxcylvywPkkXCHAzTyQ==", - "dev": true, - "optional": true, - "peer": true, - "dependencies": { - "inherits": "^2.0.4", - "source-map": "^0.6.1", - "source-map-resolve": "^0.6.0" - } - }, "node_modules/css-declaration-sorter": { "version": "7.2.0", "resolved": "https://registry.npmjs.org/css-declaration-sorter/-/css-declaration-sorter-7.2.0.tgz", @@ -12173,17 +12013,6 @@ "url": "https://github.com/sponsors/fb55" } }, - "node_modules/css/node_modules/source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "dev": true, - "optional": true, - "peer": true, - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/cssesc": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/cssesc/-/cssesc-3.0.0.tgz", @@ -13098,17 +12927,6 @@ "node": ">=8.6" } }, - "node_modules/decode-uri-component": { - "version": "0.2.2", - "resolved": "https://registry.npmjs.org/decode-uri-component/-/decode-uri-component-0.2.2.tgz", - "integrity": "sha512-FqUYQ+8o158GyGTrMFJms9qh3CqTKvAqgqsTnkLI8sKu0028orqBhxNMFkFen0zGyg6epACD32pjVk58ngIErQ==", - "dev": true, - "optional": true, - "peer": true, - "engines": { - "node": ">=0.10" - } - }, "node_modules/decompress-response": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-6.0.0.tgz", @@ -18447,23 +18265,6 @@ "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, - "node_modules/jest-circus/node_modules/babel-plugin-macros": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/babel-plugin-macros/-/babel-plugin-macros-3.1.0.tgz", - "integrity": "sha512-Cg7TFGpIr01vOQNODXOOaGz2NpCU5gl8x1qJFbb6hbZxR7XrcE2vtbAsTAbJ7/xwJtUuJEw8K8Zr/AE0LHlesg==", - "dev": true, - "optional": true, - "peer": true, - "dependencies": { - "@babel/runtime": "^7.12.5", - "cosmiconfig": "^7.0.0", - "resolve": "^1.19.0" - }, - "engines": { - "node": ">=10", - "npm": ">=6" - } - }, "node_modules/jest-circus/node_modules/chalk": { "version": "4.1.2", "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", @@ -18498,24 +18299,6 @@ "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", "dev": true }, - "node_modules/jest-circus/node_modules/cosmiconfig": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-7.1.0.tgz", - "integrity": "sha512-AdmX6xUzdNASswsFtmwSt7Vj8po9IuqXm0UXz7QKPuEUmPB4XyjGfaAr2PSuELMwkRMVH1EpIkX5bTZGRB3eCA==", - "dev": true, - "optional": true, - "peer": true, - "dependencies": { - "@types/parse-json": "^4.0.0", - "import-fresh": "^3.2.1", - "parse-json": "^5.0.0", - "path-type": "^4.0.0", - "yaml": "^1.10.0" - }, - "engines": { - "node": ">=10" - } - }, "node_modules/jest-circus/node_modules/dedent": { "version": "1.5.3", "resolved": "https://registry.npmjs.org/dedent/-/dedent-1.5.3.tgz", @@ -22187,13 +21970,13 @@ "dev": true }, "node_modules/nx": { - "version": "19.4.1", - "resolved": "https://registry.npmjs.org/nx/-/nx-19.4.1.tgz", - "integrity": "sha512-II+Ix/z6i1E2/3DinwnYKWlM0g3bO/1bcQkwhpaPee5GwHejBYdxlQ2B9uxwqRMYgpF5tFJr/0Q8WsBQybuSJw==", + "version": "19.4.2", + "resolved": "https://registry.npmjs.org/nx/-/nx-19.4.2.tgz", + "integrity": "sha512-h4NMoy9uvSHuM+kyioZXb5G4hfBZ7E4a5dswG2RPe3g/GcY9wdpkUMd/EJJ0cHQwv36kRZOMCflhounYCd7OeA==", "dev": true, "hasInstallScript": true, "dependencies": { - "@nrwl/tao": "19.4.1", + "@nrwl/tao": "19.4.2", "@yarnpkg/lockfile": "^1.1.0", "@yarnpkg/parsers": "3.0.0-rc.46", "@zkochan/js-yaml": "0.0.7", @@ -22233,16 +22016,16 @@ "nx-cloud": "bin/nx-cloud.js" }, "optionalDependencies": { - "@nx/nx-darwin-arm64": "19.4.1", - "@nx/nx-darwin-x64": "19.4.1", - "@nx/nx-freebsd-x64": "19.4.1", - "@nx/nx-linux-arm-gnueabihf": "19.4.1", - "@nx/nx-linux-arm64-gnu": "19.4.1", - "@nx/nx-linux-arm64-musl": "19.4.1", - "@nx/nx-linux-x64-gnu": "19.4.1", - "@nx/nx-linux-x64-musl": "19.4.1", - "@nx/nx-win32-arm64-msvc": "19.4.1", - "@nx/nx-win32-x64-msvc": "19.4.1" + "@nx/nx-darwin-arm64": "19.4.2", + "@nx/nx-darwin-x64": "19.4.2", + "@nx/nx-freebsd-x64": "19.4.2", + "@nx/nx-linux-arm-gnueabihf": "19.4.2", + "@nx/nx-linux-arm64-gnu": "19.4.2", + "@nx/nx-linux-arm64-musl": "19.4.2", + "@nx/nx-linux-x64-gnu": "19.4.2", + "@nx/nx-linux-x64-musl": "19.4.2", + "@nx/nx-win32-arm64-msvc": "19.4.2", + "@nx/nx-win32-x64-msvc": "19.4.2" }, "peerDependencies": { "@swc-node/register": "^1.8.0", @@ -23838,17 +23621,6 @@ "integrity": "sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==", "dev": true }, - "node_modules/preact": { - "version": "10.22.1", - "resolved": "https://registry.npmjs.org/preact/-/preact-10.22.1.tgz", - "integrity": "sha512-jRYbDDgMpIb5LHq3hkI0bbl+l/TQ9UnkdQ0ww+lp+4MMOdqaUYdFc5qeyP+IV8FAd/2Em7drVPeKdQxsiWCf/A==", - "dev": true, - "peer": true, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/preact" - } - }, "node_modules/prebuild-install": { "version": "7.1.2", "resolved": "https://registry.npmjs.org/prebuild-install/-/prebuild-install-7.1.2.tgz", @@ -25901,19 +25673,6 @@ "webpack": "^5.72.1" } }, - "node_modules/source-map-resolve": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/source-map-resolve/-/source-map-resolve-0.6.0.tgz", - "integrity": "sha512-KXBr9d/fO/bWo97NXsPIAW1bFSBOuCnjbNTBMO7N59hsv5i9yzRDfcYwwt0l04+VqnKC+EwzvJZIP/qkuMgR/w==", - "deprecated": "See https://github.com/lydell/source-map-resolve#deprecated", - "dev": true, - "optional": true, - "peer": true, - "dependencies": { - "atob": "^2.1.2", - "decode-uri-component": "^0.2.0" - } - }, "node_modules/source-map-support": { "version": "0.5.19", "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.19.tgz", @@ -26632,120 +26391,6 @@ "svelte": "^3.55.0 || ^4.0.0-next.0 || ^4.0.0 || ^5.0.0-next.0" } }, - "node_modules/svelte-check/node_modules/brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", - "dev": true, - "optional": true, - "peer": true, - "dependencies": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, - "node_modules/svelte-check/node_modules/debug": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", - "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", - "dev": true, - "optional": true, - "peer": true, - "dependencies": { - "ms": "2.0.0" - } - }, - "node_modules/svelte-check/node_modules/glob": { - "version": "7.2.3", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", - "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", - "deprecated": "Glob versions prior to v9 are no longer supported", - "dev": true, - "optional": true, - "peer": true, - "dependencies": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.1.1", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - }, - "engines": { - "node": "*" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/svelte-check/node_modules/minimatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", - "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", - "dev": true, - "optional": true, - "peer": true, - "dependencies": { - "brace-expansion": "^1.1.7" - }, - "engines": { - "node": "*" - } - }, - "node_modules/svelte-check/node_modules/mkdirp": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz", - "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==", - "dev": true, - "optional": true, - "peer": true, - "bin": { - "mkdirp": "bin/cmd.js" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/svelte-check/node_modules/ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", - "dev": true, - "optional": true, - "peer": true - }, - "node_modules/svelte-check/node_modules/sax": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/sax/-/sax-1.2.4.tgz", - "integrity": "sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw==", - "dev": true, - "optional": true, - "peer": true - }, - "node_modules/svelte-check/node_modules/stylus": { - "version": "0.55.0", - "resolved": "https://registry.npmjs.org/stylus/-/stylus-0.55.0.tgz", - "integrity": "sha512-MuzIIVRSbc8XxHH7FjkvWqkIcr1BvoMZoR/oFuAJDlh7VSaNJzrB4uJ38GRQa+mWjLXODAMzeDe0xi9GYbGwnw==", - "dev": true, - "optional": true, - "peer": true, - "dependencies": { - "css": "^3.0.0", - "debug": "~3.1.0", - "glob": "^7.1.6", - "mkdirp": "~1.0.4", - "safer-buffer": "^2.1.2", - "sax": "~1.2.4", - "semver": "^6.3.0", - "source-map": "^0.7.3" - }, - "bin": { - "stylus": "bin/stylus" - }, - "engines": { - "node": "*" - } - }, "node_modules/svelte-check/node_modules/svelte-preprocess": { "version": "5.1.4", "resolved": "https://registry.npmjs.org/svelte-preprocess/-/svelte-preprocess-5.1.4.tgz", @@ -28002,6 +27647,7 @@ "version": "5.5.3", "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.5.3.tgz", "integrity": "sha512-/hreyEujaB0w76zKo6717l3L0o/qEUtRgdvUBvlkhoWeOVMjMuHNHk0BRBzikzuGDqNmPQbg5ifMEqsHLiIUcQ==", + "dev": true, "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" diff --git a/package.json b/package.json index b43de87d..b83105ac 100644 --- a/package.json +++ b/package.json @@ -19,17 +19,17 @@ "@esri/arcgis-rest-geocoding": "^4.0.3", "@esri/arcgis-rest-request": "^4.2.3", "@nx-tools/nx-container": "^6.0.1", - "@nx/cypress": "19.4.1", - "@nx/eslint": "19.4.1", - "@nx/eslint-plugin": "19.4.1", - "@nx/express": "19.4.1", - "@nx/jest": "19.4.1", - "@nx/js": "19.4.1", - "@nx/node": "19.4.1", - "@nx/vite": "19.4.1", - "@nx/web": "19.4.1", - "@nx/webpack": "19.4.1", - "@nx/workspace": "19.4.1", + "@nx/cypress": "19.4.2", + "@nx/eslint": "19.4.2", + "@nx/eslint-plugin": "19.4.2", + "@nx/express": "19.4.2", + "@nx/jest": "19.4.2", + "@nx/js": "19.4.2", + "@nx/node": "19.4.2", + "@nx/vite": "19.4.2", + "@nx/web": "19.4.2", + "@nx/webpack": "19.4.2", + "@nx/workspace": "19.4.2", "@preact/preset-vite": "^2.8.3", "@protobuf-ts/plugin": "^2.9.4", "@sveltejs/vite-plugin-svelte": "^3.1.1", @@ -72,7 +72,7 @@ "jest-environment-node": "^29.4.1", "jsdom": "~22.1.0", "mailersend": "^2.2.0", - "nx": "19.4.1", + "nx": "19.4.2", "prettier": "^2.6.2", "rollup-plugin-minify-html-literals": "^1.2.6", "rollup-plugin-visualizer": "^5.12.0", From 7121bd899f02cb86deffceab58e4d7f294d4a407 Mon Sep 17 00:00:00 2001 From: Victor Berchet Date: Thu, 11 Jul 2024 18:18:31 +0200 Subject: [PATCH 02/16] Split the state in multiple slices --- libs/secrets/package.json | 2 +- libs/windy-sounding/CHANGELOG.md | 4 + libs/windy-sounding/package-lock.json | 14 +- libs/windy-sounding/package.json | 2 +- .../src/containers/containers.tsx | 123 +- .../src/redux/forecast-slice.ts | 530 +++++++++ libs/windy-sounding/src/redux/meta.ts | 15 +- libs/windy-sounding/src/redux/plugin-slice.ts | 570 +-------- libs/windy-sounding/src/redux/store.ts | 4 + libs/windy-sounding/src/redux/units-slice.ts | 63 + libs/windy-sounding/src/sounding.tsx | 4 +- package-lock.json | 1060 ++++++++--------- package.json | 1 + 13 files changed, 1189 insertions(+), 1203 deletions(-) create mode 100644 libs/windy-sounding/src/redux/forecast-slice.ts create mode 100644 libs/windy-sounding/src/redux/units-slice.ts diff --git a/libs/secrets/package.json b/libs/secrets/package.json index ed0f632d..eacafb01 100644 --- a/libs/secrets/package.json +++ b/libs/secrets/package.json @@ -3,7 +3,7 @@ "version": "0.0.1", "private": true, "dependencies": { - "@nx/webpack": "19.4.1", + "@nx/webpack": "19.4.2", "dotenv-webpack": "^8.1.0" } } diff --git a/libs/windy-sounding/CHANGELOG.md b/libs/windy-sounding/CHANGELOG.md index d9e9674e..eb8c63fb 100644 --- a/libs/windy-sounding/CHANGELOG.md +++ b/libs/windy-sounding/CHANGELOG.md @@ -1,5 +1,9 @@ # Release history +## 4.0.0-alpha.3 + +- Split the state into multiple slices + ## 4.0.0-alpha.2 - July 10, 2024 - Fix elevation steps in ft (3000ft) diff --git a/libs/windy-sounding/package-lock.json b/libs/windy-sounding/package-lock.json index bed3ca8f..650c4e5e 100644 --- a/libs/windy-sounding/package-lock.json +++ b/libs/windy-sounding/package-lock.json @@ -1,19 +1,19 @@ { "name": "windy-plugin-sounding", - "version": "4.0.0-alpha.1", + "version": "4.0.0-alpha.2", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "windy-plugin-sounding", - "version": "4.0.0-alpha.1", + "version": "4.0.0-alpha.2", "license": "MIT", "dependencies": { "@reduxjs/toolkit": "^2.2.6", "@sveltejs/vite-plugin-svelte": "^3.1.1", "date-fns": "^3.6.0", "geojson": "^0.5.0", - "preact": "10.22.1", + "preact": "^10.22.1", "react-redux": "^9.1.2", "svelte": "^4.2.18" } @@ -1167,9 +1167,9 @@ } }, "node_modules/postcss": { - "version": "8.4.38", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.38.tgz", - "integrity": "sha512-Wglpdk03BSfXkHoQa3b/oulrotAkwrlLDRSOb9D0bN86FdRyE9lppSp33aHNPgBa0JKCoB+drFLZkQoRRYae5A==", + "version": "8.4.39", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.39.tgz", + "integrity": "sha512-0vzE+lAiG7hZl1/9I8yzKLx3aR9Xbof3fBHKunvMfOCYAtMhrsnccJY2iTURb9EZd5+pLuiNV9/c/GZJOHsgIw==", "funding": [ { "type": "opencollective", @@ -1187,7 +1187,7 @@ "peer": true, "dependencies": { "nanoid": "^3.3.7", - "picocolors": "^1.0.0", + "picocolors": "^1.0.1", "source-map-js": "^1.2.0" }, "engines": { diff --git a/libs/windy-sounding/package.json b/libs/windy-sounding/package.json index d011eadc..125140d5 100644 --- a/libs/windy-sounding/package.json +++ b/libs/windy-sounding/package.json @@ -16,7 +16,7 @@ "@sveltejs/vite-plugin-svelte": "^3.1.1", "date-fns": "^3.6.0", "geojson": "^0.5.0", - "preact": "10.22.1", + "preact": "^10.22.1", "react-redux": "^9.1.2", "svelte": "^4.2.18" } diff --git a/libs/windy-sounding/src/containers/containers.tsx b/libs/windy-sounding/src/containers/containers.tsx index 170d5008..261d3431 100644 --- a/libs/windy-sounding/src/containers/containers.tsx +++ b/libs/windy-sounding/src/containers/containers.tsx @@ -9,28 +9,36 @@ import { SkewT, type SkewTProps } from '../components/skewt.js'; import { WindProfile, type WindProfileProps } from '../components/wind-profile.jsx'; import { pluginConfig } from '../config'; import flyxcIcon from '../img/jumoplane.svg'; +import * as forecastSlice from '../redux/forecast-slice'; import { centerMap, changeLocation } from '../redux/meta'; import * as pluginSlice from '../redux/plugin-slice'; import { type RootState } from '../redux/store'; +import * as unitsSlice from '../redux/units-slice'; import { formatTimestamp } from '../util/utils.js'; function stateToSkewTProp(state: RootState, ownProps: SkewTProps) { - const S = pluginSlice.selectors; + const pluginSel = pluginSlice.slice.selectors; + const unitsSel = unitsSlice.slice.selectors; + const forecastSel = forecastSlice.slice.selectors; - if (S.selWindyDataIsLoading(state)) { + const modelName = pluginSel.selModelName(state); + const location = pluginSel.selLocation(state); + const timeMs = pluginSel.selTimeMs(state); + + if (forecastSel.selWindyDataIsLoading(state, modelName, location)) { return { isLoading: true }; } const { width, height, yPointer, minPressure, maxPressure } = ownProps as SkewTProps & { isLoading: false }; - const periodValues = S.selPeriodValues(state); - const timeValues = S.selValuesAtCurrentTime(state); - const isZoomedIn = S.selIsZoomedIn(state); + const periodValues = forecastSel.selPeriodValues(state, modelName, location); + const timeValues = forecastSel.selValuesAt(state, modelName, location, timeMs); + const isZoomedIn = pluginSel.selIsZoomedIn(state); - const periodMaxTemp = S.selMaxPeriodTemp(state); + const periodMaxTemp = forecastSel.selMaxPeriodTemp(state, modelName, location); const maxTemp = periodMaxTemp + 8; const minTemp = periodMaxTemp - 60; - const formatTemp = S.selTempFormatter(state); + const formatTemp = unitsSel.selTempFormatter(state); return { width, @@ -45,30 +53,38 @@ function stateToSkewTProp(state: RootState, ownProps: SkewTProps) { seaLevelPressure: timeValues.seaLevelPressure, minTemp, maxTemp, - surfaceElevation: S.selElevation(state), - parcel: S.selDisplayParcel(state) ? S.selParcel(state) : undefined, - formatAltitude: S.selAltitudeFormatter(state), + surfaceElevation: forecastSel.selElevation(state, modelName, location), + parcel: forecastSel.selDisplayParcel(state, modelName, location, timeMs) + ? forecastSel.selParcel(state, modelName, location, timeMs) + : undefined, + formatAltitude: unitsSel.selAltitudeFormatter(state), formatTemp, - tempUnit: S.selTempUnit(state), - tempAxisStep: S.selTempUnit(state) === '°C' ? 10 : 20, - ghUnit: S.selAltitudeUnit(state), - ghAxisStep: S.selAltitudeUnit(state) === 'm' ? 1000 : 3000, + tempUnit: unitsSel.selTempUnit(state), + tempAxisStep: unitsSel.selTempUnit(state) === '°C' ? 10 : 20, + ghUnit: unitsSel.selAltitudeUnit(state), + ghAxisStep: unitsSel.selAltitudeUnit(state) === 'm' ? 1000 : 3000, showUpperClouds: isZoomedIn, - cloudCover: S.selGetCloudCoverGenerator(state), + cloudCover: forecastSel.selGetCloudCoverGenerator(state, modelName, location, timeMs), }; } const ConnectedSkewT = connect(stateToSkewTProp)(SkewT); const stateToWindProp = (state: RootState, ownProps: WindProfileProps): WindProfileProps => { - const S = pluginSlice.selectors; + const pluginSel = pluginSlice.slice.selectors; + const unitsSel = unitsSlice.slice.selectors; + const forecastSel = forecastSlice.slice.selectors; + + const modelName = pluginSel.selModelName(state); + const location = pluginSel.selLocation(state); + const timeMs = pluginSel.selTimeMs(state); - if (S.selWindyDataIsLoading(state)) { + if (forecastSel.selWindyDataIsLoading(state, modelName, location)) { return { isLoading: true }; } - const periodValues = S.selPeriodValues(state); - const timeValues = S.selValuesAtCurrentTime(state); + const periodValues = forecastSel.selPeriodValues(state, modelName, location); + const timeValues = forecastSel.selValuesAt(state, modelName, location, timeMs); const { width, height, minPressure, maxPressure, yPointer } = ownProps as WindProfileProps & { isLoading: false }; return { @@ -79,11 +95,11 @@ const stateToWindProp = (state: RootState, ownProps: WindProfileProps): WindProf seaLevelPressure: timeValues.seaLevelPressure, levels: periodValues.levels, ghs: timeValues.gh, - windByLevel: S.selWindDetailsByLevel(state), - format: S.selWindSpeedFormatter(state), - unit: S.selWindSpeedUnit(state), - surfaceElevation: S.selElevation(state), - isFixedRange: S.selIsZoomedIn(state), + windByLevel: forecastSel.selWindDetailsByLevel(state, modelName, location, timeMs), + format: unitsSel.selWindSpeedFormatter(state), + unit: unitsSel.selWindSpeedUnit(state), + surfaceElevation: forecastSel.selElevation(state, modelName, location), + isFixedRange: pluginSel.selIsZoomedIn(state), yPointer, }; }; @@ -91,7 +107,7 @@ const stateToWindProp = (state: RootState, ownProps: WindProfileProps): WindProf const ConnectedWind = connect(stateToWindProp)(WindProfile); const stateToFavProp = (state: RootState) => { - const S = pluginSlice.selectors; + const S = pluginSlice.slice.selectors; return { favorites: S.selFavorites(state), location: S.selLocation(state), @@ -133,10 +149,15 @@ type GraphProps = { ); function stateToGraphProps(state: RootState, ownProps: GraphProps) { - const S = pluginSlice.selectors; + const pluginSel = pluginSlice.slice.selectors; + const forecastSel = forecastSlice.slice.selectors; + + const width = pluginSel.selWidth(state); + const height = pluginSel.selHeight(state); - const width = S.selWidth(state); - const height = S.selHeight(state); + const modelName = pluginSel.selModelName(state); + const location = pluginSel.selLocation(state); + const timeMs = pluginSel.selTimeMs(state); const props = { status: AppStatus.Loading, @@ -146,30 +167,30 @@ function stateToGraphProps(state: RootState, ownProps: GraphProps) { onWheel: (e: WheelEvent) => e.preventDefault(), }; - if (S.selWindyDataIsLoading(state)) { + if (forecastSel.selWindyDataIsLoading(state, modelName, location)) { return props; } - props.onWheel = S.selWheelEventHandler(state); + props.onWheel = forecastSel.selWheelEventHandler(state, modelName, location); - if (S.selIsOutOfModelBounds(state)) { + if (forecastSel.selIsOutOfModelBounds(state, modelName, location)) { return { ...props, status: AppStatus.OutOfBounds, }; } - if (!S.selAreValuesAvailableAtCurrentTime(state)) { + if (!forecastSel.selAreValuesAvailableAt(state, modelName, location, timeMs)) { return { ...props, status: AppStatus.DataNotAvailable, }; } - const elevation = S.selElevation(state); - const minModelPressure = S.selMinModelPressure(state); - const pressureToGhScale = S.selPressureToGhScale(state); - const minPressure = S.selIsZoomedIn(state) + const elevation = forecastSel.selElevation(state, modelName, location); + const minModelPressure = forecastSel.selMinModelPressure(state, modelName, location); + const pressureToGhScale = forecastSel.selPressureToGhScale(state, modelName, location, timeMs); + const minPressure = pluginSel.selIsZoomedIn(state) ? Math.round(Math.max(pressureToGhScale.invert(6500 + (elevation * 2) / 5), minModelPressure)) : minModelPressure; const maxPressure = Math.min(1000, Math.round(pressureToGhScale.invert((elevation * 4) / 5))); @@ -179,7 +200,7 @@ function stateToGraphProps(state: RootState, ownProps: GraphProps) { status: AppStatus.Ready, minPressure, maxPressure, - isZoomedIn: S.selIsZoomedIn(state), + isZoomedIn: pluginSel.selIsZoomedIn(state), }; } @@ -339,13 +360,18 @@ export const Graph = connect( }); const stateToDetailsProps = (state: RootState) => { - const S = pluginSlice.selectors; + const pluginSel = pluginSlice.slice.selectors; + const forecastSel = forecastSlice.slice.selectors; + + const modelName = pluginSel.selModelName(state); + const location = pluginSel.selLocation(state); + const timeMs = pluginSel.selTimeMs(state); return { - modelName: S.selModelName(state), - updateMs: S.selModelUpdateTimeMs(state), - nextUpdateMs: S.selModelNextUpdateTimeMs(state), - timeMs: S.selTimeMs(state), + modelName: pluginSel.selModelName(state), + updateMs: forecastSel.selModelUpdateTimeMs(state, modelName, location), + nextUpdateMs: forecastSel.selModelNextUpdateTimeMs(state, modelName, location), + timeMs, }; }; @@ -385,12 +411,17 @@ type WatermarkProps = { }; const stateToWatermarkProps = (state: RootState) => { - const S = pluginSlice.selectors; + const pluginSel = pluginSlice.slice.selectors; + const forecastSel = forecastSlice.slice.selectors; + + const modelName = pluginSel.selModelName(state); + const location = pluginSel.selLocation(state); + const timeMs = pluginSel.selTimeMs(state); return { - updateMs: S.selModelUpdateTimeMs(state), - nextUpdateMs: S.selModelNextUpdateTimeMs(state), - timeMs: S.selTimeMs(state), + updateMs: forecastSel.selModelUpdateTimeMs(state, modelName, location), + nextUpdateMs: forecastSel.selModelNextUpdateTimeMs(state, modelName, location), + timeMs, }; }; diff --git a/libs/windy-sounding/src/redux/forecast-slice.ts b/libs/windy-sounding/src/redux/forecast-slice.ts new file mode 100644 index 00000000..ecc637e4 --- /dev/null +++ b/libs/windy-sounding/src/redux/forecast-slice.ts @@ -0,0 +1,530 @@ +import { createAsyncThunk, createSlice } from '@reduxjs/toolkit'; +import type { DataHash, LatLon, MeteogramDataPayload, WeatherDataPayload } from '@windy/interfaces'; +import type { MeteogramLayers } from '@windy/types'; + +import * as atm from '../util/atmosphere'; +import { + type CloudCoverGenerator, + computePeriodClouds, + DEBUG_CLOUDS, + debugCloudCanvas, + debugCloudTimeCursor, + getCloudCoverGenerator, + type PeriodCloud, +} from '../util/clouds'; +import { sampleAt, type Scale, scaleLog } from '../util/math'; +import type { AppThunkAPI, RootState } from './store'; + +const windyStore = W.store; +const windyUtils = W.utils; +const windyFetch = W.fetch; +const windySubscription = W.subscription; +const windyProducts = W.products; + +// Cache stale windy data for 10 minutes. +// Data are stale when an update is expected. +const STALE_WINDY_DATA_CACHE_MIN = 10; + +export enum FetchStatus { + Idle = 'idle', + Loading = 'loading', + Loaded = 'loaded', + Error = 'error', + ErrorOutOfBounds = 'errorOutOfBounds', +} + +// Those properties varies with the altitude level. +const levelProps = ['temp', 'dewpoint', 'gh', 'windU', 'windV', 'rh'] as const; +type LevelProp = (typeof levelProps)[number]; +type LevelPropByTime = `${LevelProp}ByTime`; + +// Those properties do not vary with altitude. +const sfcProps = ['rainMm', 'seaLevelPressure'] as const; +type SfcProps = (typeof sfcProps)[number]; +type SfcPropsByTime = `${SfcProps}ByTime`; + +type TimeValue = Record & Record; + +export type PeriodValue = { + maxTemp: number; + minTemp: number; + maxSeaLevelPressure: number; + levels: number[]; + timesMs: number[]; +} & Record & // By time then by level + // By time only + Record; + +export type Forecast = + | { + forecastKey: string; + modelName: string; + location: LatLon; + loadedMs: number; + } & ( + | { + fetchStatus: FetchStatus.Loading | FetchStatus.Error | FetchStatus.Idle | FetchStatus.ErrorOutOfBounds; + } + | { + fetchStatus: FetchStatus.Loaded; + meteogram: MeteogramDataPayload; + weather: WeatherDataPayload; + nextUpdateMs: number; + updateMs: number; + } + ); + +export type ModelAndLocation = { + modelName: string; + location: LatLon; +}; + +type ForecastState = { + // Windy data by forecast key. + data: Record; +}; + +const initialState: ForecastState = { + data: {}, +}; + +export const slice = createSlice({ + name: 'forecast', + initialState, + reducers: {}, + extraReducers: (builder) => { + builder.addCase(fetchForecast.pending, (state: ForecastState, action) => { + const { modelName, location } = action.meta.arg; + const key = windyDataKey(modelName, location); + state.data[key] = { + forecastKey: key, + modelName, + location, + fetchStatus: FetchStatus.Loading, + loadedMs: Date.now(), + }; + }); + + builder.addCase(fetchForecast.fulfilled, (state: ForecastState, action) => { + const { modelName, location } = action.meta.arg; + const key = windyDataKey(modelName, location); + state.data[key] = { ...state.data[key], ...action.payload }; + }); + + builder.addCase(fetchForecast.rejected, (state: ForecastState, action) => { + const { modelName, location } = action.meta.arg; + const key = windyDataKey(modelName, location); + state.data[key] = { + forecastKey: key, + modelName, + location, + fetchStatus: action.error.name === 'OutOfBoundsError' ? FetchStatus.ErrorOutOfBounds : FetchStatus.Error, + loadedMs: Date.now(), + }; + }); + }, + selectors: { + // Computed + selWindyDataUnsafe: (state: ForecastState, modelName: string, location: LatLon): Forecast | undefined => { + const key = windyDataKey(modelName, location); + return isDataCached(state, key) ? (state.data[key] as Forecast & { fetchStatus: FetchStatus.Loaded }) : undefined; + }, + selIsOutOfModelBounds: (state: ForecastState, modelName: string, location: LatLon): boolean => { + const windyData = slice.getSelectors().selWindyDataUnsafe(state, modelName, location); + return windyData?.fetchStatus === FetchStatus.ErrorOutOfBounds; + }, + + selWindyDataIsLoading: (state: ForecastState, modelName: string, location: LatLon): boolean => { + const windyData = slice.getSelectors().selWindyDataUnsafe(state, modelName, location); + return ( + windyData === undefined || + windyData.fetchStatus === FetchStatus.Loading || + windyData.fetchStatus === FetchStatus.Idle + ); + }, + selWindyDataIsLoaded(state: ForecastState, modelName: string, location: LatLon): boolean { + const windyData = slice.getSelectors().selWindyDataUnsafe(state, modelName, location); + return windyData !== undefined && windyData.fetchStatus === FetchStatus.Loaded; + }, + selModelUpdateTimeMs(state: ForecastState, modelName: string, location: LatLon): number { + const windyData = getWindyDataOrThrow(state, modelName, location); + return windyData.updateMs; + }, + selModelNextUpdateTimeMs(state: ForecastState, modelName: string, location: LatLon): number { + const windyData = getWindyDataOrThrow(state, modelName, location); + return windyData.nextUpdateMs; + }, + selTzOffsetH(state: ForecastState, modelName: string, location: LatLon): number { + const windyData = getWindyDataOrThrow(state, modelName, location); + return windyData.weather.celestial.TZoffset; + }, + selSunriseMs(state: ForecastState, modelName: string, location: LatLon): number { + const windyData = getWindyDataOrThrow(state, modelName, location); + return windyData.weather.celestial.sunriseTs; + }, + selSunsetMs(state: ForecastState, modelName: string, location: LatLon): number { + const windyData = getWindyDataOrThrow(state, modelName, location); + return windyData.weather.celestial.sunsetTs; + }, + // Levels in descending order + selLevels: (state: ForecastState, modelName: string, location: LatLon): number[] => { + const windyData = getWindyDataOrThrow(state, modelName, location); + return Object.keys(windyData.meteogram.data) + .filter((key: string) => key.startsWith('temp-') && key.endsWith('h')) + .map((key: string) => parseInt(key.slice(5, -1))) + .sort((a: number, b: number) => b - a); + }, + selMaxModelPressure: (state: ForecastState, modelName: string, location: LatLon): number => { + getWindyDataOrThrow(state, modelName, location); + const levels = slice.getSelectors().selLevels(state, modelName, location); + return Math.max(...levels); + }, + selMinModelPressure: (state: ForecastState, modelName: string, location: LatLon): number => { + getWindyDataOrThrow(state, modelName, location); + const levels = slice.getSelectors().selLevels(state, modelName, location); + return Math.min(...levels); + }, + selPeriodValues(state: ForecastState, modelName: string, location: LatLon): PeriodValue { + const windyData = getWindyDataOrThrow(state, modelName, location); + const levels = slice.getSelectors().selLevels(state, modelName, location); + return computePeriodValues(windyData, levels); + }, + selMaxPeriodTemp(state: ForecastState, modelName: string, location: LatLon): number { + getWindyDataOrThrow(state, modelName, location); + const periodValues = slice.getSelectors().selPeriodValues(state, modelName, location); + return periodValues.maxTemp; + }, + selMinPeriodTemp(state: ForecastState, modelName: string, location: LatLon): number { + getWindyDataOrThrow(state, modelName, location); + const periodValues = slice.getSelectors().selPeriodValues(state, modelName, location); + return periodValues.minTemp; + }, + selPeriodClouds(state: ForecastState, modelName: string, location: LatLon): PeriodCloud { + const windyData = getWindyDataOrThrow(state, modelName, location); + return computePeriodClouds(windyData.meteogram.data); + }, + selGetCloudCoverGenerator(state: ForecastState, modelName: string, location: LatLon, timeMs): CloudCoverGenerator { + const windyData = getWindyDataOrThrow(state, modelName, location); + const timesMs = windyData.meteogram.data.hours; + const { width, height, clouds } = slice.getSelectors().selPeriodClouds(state, modelName, location); + const timesIndex = Math.max( + 1, + timesMs.findIndex((ms) => ms > timeMs), + ); + const startMs = timesMs[timesIndex - 1]; + const endMs = timesMs[timesIndex]; + const timeRatio = Math.max(0, Math.min(1, (endMs - timeMs) / (endMs - startMs))); + const indexRatio = (timesIndex - timeRatio) / timesMs.length; + const x = Math.round(Math.round((width - 1) * indexRatio)); + if (DEBUG_CLOUDS && debugCloudCanvas && debugCloudTimeCursor) { + debugCloudTimeCursor.style.width = `${Math.round(debugCloudCanvas.width * indexRatio)}px`; + } + const cloudSliceAtMs: number[] = []; + for (let y = height - 1; y >= 0; y--) { + cloudSliceAtMs.push(clouds[x + y * width]); + } + return getCloudCoverGenerator(cloudSliceAtMs); + }, + selMaxSeaLevelPressure(state: ForecastState, modelName: string, location: LatLon): number { + getWindyDataOrThrow(state, modelName, location); + const periodValues = slice.getSelectors().selPeriodValues(state, modelName, location); + return periodValues.maxSeaLevelPressure; + }, + selAreValuesAvailableAt(state: ForecastState, modelName: string, location: LatLon, timeMs: number): boolean { + const windyData = getWindyDataOrThrow(state, modelName, location); + const maxTimeMs = Math.min( + ...[windyData.meteogram.data.hours.at(-1), windyData.weather.data.ts.at(-1)].filter((v) => v !== undefined), + ); + return timeMs <= maxTimeMs; + }, + selValuesAt(state: ForecastState, modelName: string, location: LatLon, timeMs: number): TimeValue { + const windyData = getWindyDataOrThrow(state, modelName, location); + const periodValues = slice.getSelectors().selPeriodValues(state, modelName, location); + const { timesMs } = periodValues; + timeMs = Math.max(timeMs, windyData.meteogram.data.hours[0], windyData.weather.data.ts[0]); + return { + temp: sampleAt(timesMs, periodValues.tempByTime, timeMs), + dewpoint: sampleAt(timesMs, periodValues.dewpointByTime, timeMs), + gh: sampleAt(timesMs, periodValues.ghByTime, timeMs), + rh: sampleAt(timesMs, periodValues.rhByTime, timeMs), + windU: sampleAt(timesMs, periodValues.windUByTime, timeMs), + windV: sampleAt(timesMs, periodValues.windVByTime, timeMs), + rainMm: sampleAt(timesMs, periodValues.rainMmByTime, timeMs), + seaLevelPressure: sampleAt(timesMs, periodValues.seaLevelPressureByTime, timeMs), + }; + }, + selWindDetailsByLevel( + state, + modelName: string, + location: LatLon, + timeMs: number, + ): { speed: number; direction: number }[] { + getWindyDataOrThrow(state, modelName, location); + const { windU, windV } = slice.getSelectors().selValuesAt(state, modelName, location, timeMs); + const details = []; + for (let i = 0; i < windU.length; i++) { + const { wind: speed, dir: direction } = windyUtils.wind2obj([windU[i], windV[i]]); + details.push({ speed, direction }); + } + return details; + }, + selElevation(state: ForecastState, modelName: string, location: LatLon): number { + const windyData = getWindyDataOrThrow(state, modelName, location); + const { weather, meteogram } = windyData; + return meteogram.header.elevation ?? weather.header.elevation ?? meteogram.header.modelElevation; + }, + selPressureToGhScale(state: ForecastState, modelName: string, location: LatLon, timeMs: number): Scale { + getWindyDataOrThrow(state, modelName, location); + const levels = slice.getSelectors().selLevels(state, modelName, location); + const { gh, seaLevelPressure } = slice.getSelectors().selValuesAt(state, modelName, location, timeMs); + return atm.getPressureToGhScale(levels, gh, seaLevelPressure); + }, + selDisplayParcel(state: ForecastState, modelName: string, location: LatLon, timeMs: number): boolean { + const startMs = slice.getSelectors().selSunriseMs(state, modelName, location) + 2 * 3600 * 1000; + const endMs = slice.getSelectors().selSunsetMs(state, modelName, location) - 3600 * 1000; + const durationMs = endMs - startMs; + return timeMs > startMs && (timeMs - startMs) % (24 * 3600 * 1000) < durationMs; + }, + selParcel(state: ForecastState, modelName: string, location: LatLon, timeMs: number): atm.ParcelData { + const timeValues = slice.getSelectors().selValuesAt(state, modelName, location, timeMs); + const periodValues = slice.getSelectors().selPeriodValues(state, modelName, location); + const pressureToGhScale = slice.getSelectors().selPressureToGhScale(state, modelName, location, timeMs); + const elevation = slice.getSelectors().selElevation(state, modelName, location); + const pressureToDewpointScale = scaleLog(periodValues.levels, timeValues.dewpoint); + + return atm.parcelTrajectory( + periodValues.levels, + timeValues.gh, + timeValues.temp, + 3, + elevation, + pressureToDewpointScale(pressureToGhScale.invert(elevation)), + 40, + ); + }, + selUpdateTime( + state, + modelName: string, + location: LatLon, + ): ({ direction, stepIsDay }: { direction: number; stepIsDay: boolean }) => void { + const tzOffset = slice.getSelectors().selTzOffsetH(state, modelName, location); + return ({ direction, stepIsDay }: { direction: number; stepIsDay: boolean }) => { + let timeMs = windyStore.get('timestamp'); + if (stepIsDay) { + const date = new Date(timeMs); + const utcHours = date.getUTCHours(); + date.setUTCMinutes(0); + timeMs = date.getTime(); + // Jump to previous/next day at 13h. + const refTime = (13 - tzOffset + 24) % 24; + const deltaHours = (refTime - utcHours) * direction; + if (deltaHours <= 0) { + timeMs += direction * (24 + deltaHours) * 3600 * 1000; + } else { + timeMs += direction * deltaHours * 3600 * 1000; + } + } else { + timeMs += direction * 3600 * 1000; + } + + windyStore.set('timestamp', timeMs); + }; + }, + selWheelEventHandler(state: ForecastState, modelName: string, location: LatLon): (e: WheelEvent) => void { + let nextWheelMove = 0; + return (e: WheelEvent) => { + const updateTime = slice.getSelectors().selUpdateTime(state, modelName, location); + if (Date.now() > nextWheelMove) { + const stepIsDay: boolean = e.shiftKey || e.ctrlKey; + const direction: number = Math.sign(e.deltaY); + updateTime({ direction, stepIsDay }); + nextWheelMove = Date.now() + (stepIsDay ? 800 : 20); + } + e.stopImmediatePropagation(); + e.preventDefault(); + }; + }, + }, +}); + +/** + * Throws when accessing data that are not loaded yet. + * + * @param state + */ +function getWindyDataOrThrow( + state: ForecastState, + modelName: string, + location: LatLon, +): Forecast & { fetchStatus: FetchStatus.Loaded } { + const windyData = slice.getSelectors().selWindyDataUnsafe(state, modelName, location); + if (windyData === undefined || windyData.fetchStatus !== FetchStatus.Loaded) { + throw new Error('Data not loaded'); + } + return windyData; +} + +class OutOfBoundsError extends Error { + constructor(message: string) { + super(message); + this.name = 'OutOfBoundsError'; + } +} + +export const fetchForecast = createAsyncThunk( + 'plugin/fetchForecast', + async (modelAndLocation: ModelAndLocation, api: { getState: () => RootState }) => { + const { modelName, location } = modelAndLocation; + const key = windyDataKey(modelName, location); + + if (isDataCached(slice.selectSlice(api.getState()), key)) { + return slice.selectSlice(api.getState()).data[key]; + } + + const [meteogram, forecast] = await Promise.allSettled([ + // extended is required to get fulml length forecast for pro windy users + windyFetch.getMeteogramForecastData(modelName, { ...location, step: 1 }, { extended: 'true' }), + windyFetch.getPointForecastData(modelName, { ...location }), + ]); + + if (meteogram.status === 'rejected') { + if ( + meteogram.reason.status == 400 && + JSON.parse(meteogram.reason.responseText).message === 'Out of model bounds' + ) { + throw new OutOfBoundsError(meteogram.reason.message); + } + throw new Error('Failed to fetch meteogram data'); + } + + if (forecast.status === 'rejected') { + if (forecast.reason.status == 400 && JSON.parse(forecast.reason.responseText).message === 'Out of mode bounds') { + throw new OutOfBoundsError(forecast.reason.message); + } + throw new Error('Failed to fetch forecast data'); + } + + const updateMs = forecast.value.data.header.updateTs; + const product = windyProducts[modelName]; + const updateIntervalMin = windySubscription.hasAny() + ? product.intervalPremium ?? product.interval + : product.interval; + + return { + forecastKey: key, + modelName, + location, + loadedMs: Date.now(), + updateMs, + nextUpdateMs: updateMs + updateIntervalMin * 60 * 1000, + fetchStatus: FetchStatus.Loaded, + meteogram: meteogram.value.data, + weather: forecast.value.data, + }; + }, + { + condition: (modelAndLocation, api: AppThunkAPI) => { + // Prevent fetching again while loading. + const key = windyDataKey(modelAndLocation.modelName, modelAndLocation.location); + const data = slice.selectSlice(api.getState()).data[key]; + return data?.fetchStatus != FetchStatus.Loading; + }, + }, +); + +function windyDataKey(modelName: string, location: LatLon): string { + return `${modelName}-${windyUtils.latLon2str(location)}`; +} + +function isDataCached(state: ForecastState, key: string) { + const nowMs = Date.now(); + const forecast = state.data[key]; + if (forecast == null) { + return false; + } + + if (forecast.fetchStatus === FetchStatus.ErrorOutOfBounds) { + return true; + } + + if (forecast.fetchStatus === FetchStatus.Loaded) { + const requestMs = forecast.loadedMs; + const dataAgeMin = (nowMs - requestMs) / (60 * 1000); + return nowMs < forecast.nextUpdateMs || dataAgeMin < STALE_WINDY_DATA_CACHE_MIN; + } + + return false; +} + +function extractMeteogramParamByLevel( + meteogram: MeteogramDataPayload, + paramName: MeteogramLayers, + levels: number[], + tsIndex: number, +): number[] { + return levels.map((level: number): number => { + const valueByTs: number[] = (meteogram.data as Record)[`${paramName}-${level}h`]; + const value = Array.isArray(valueByTs) ? valueByTs[tsIndex] : null; + if (value == null) { + if (paramName === 'gh') { + // Approximate gh when not provided by the model + return Math.round(atm.getElevation(level)); + } + throw new Error('Unexpected null value'); + } + return value; + }); +} + +function computePeriodValues( + windyData: Forecast & { + fetchStatus: FetchStatus.Loaded; + }, + levels: number[], +): PeriodValue { + const timesMeteogramMs: number[] = windyData.meteogram.data.hours; + const timeWeatherMs: number[] = windyData.weather.data.ts; + + let maxTemp: number = Number.MIN_VALUE; + let minTemp: number = Number.MAX_VALUE; + let maxSeaLevelPressure: number = Number.MIN_VALUE; + + const values: Record & Record = { + dewpointByTime: [], + ghByTime: [], + rhByTime: [], + tempByTime: [], + windUByTime: [], + windVByTime: [], + rainMmByTime: [], + seaLevelPressureByTime: [], + }; + + for (let tsIndex = 0; tsIndex < timesMeteogramMs.length; tsIndex++) { + const timeMs = timesMeteogramMs[tsIndex]; + const tempByLevel = extractMeteogramParamByLevel(windyData.meteogram, 'temp', levels, tsIndex); + maxTemp = Math.max(maxTemp, ...tempByLevel); + minTemp = Math.min(minTemp, ...tempByLevel); + const seaLevelPressure = sampleAt(timeWeatherMs, windyData.weather.data.pressure, timeMs) / 100; + maxSeaLevelPressure = Math.max(maxSeaLevelPressure, seaLevelPressure); + values.tempByTime.push(tempByLevel); + values.dewpointByTime.push(extractMeteogramParamByLevel(windyData.meteogram, 'dewpoint', levels, tsIndex)); + values.ghByTime.push(extractMeteogramParamByLevel(windyData.meteogram, 'gh', levels, tsIndex)); + values.rhByTime.push(extractMeteogramParamByLevel(windyData.meteogram, 'rh', levels, tsIndex)); + values.windUByTime.push(extractMeteogramParamByLevel(windyData.meteogram, 'wind_u', levels, tsIndex)); + values.windVByTime.push(extractMeteogramParamByLevel(windyData.meteogram, 'wind_v', levels, tsIndex)); + values.rainMmByTime.push(sampleAt(timeWeatherMs, windyData.weather.data.mm, timeMs)); + values.seaLevelPressureByTime.push(Math.round(seaLevelPressure)); + } + + return { + timesMs: timesMeteogramMs, + levels, + maxTemp, + minTemp, + maxSeaLevelPressure, + ...values, + }; +} + +export const { reducer } = slice; diff --git a/libs/windy-sounding/src/redux/meta.ts b/libs/windy-sounding/src/redux/meta.ts index 8437d51d..a706010e 100644 --- a/libs/windy-sounding/src/redux/meta.ts +++ b/libs/windy-sounding/src/redux/meta.ts @@ -1,12 +1,15 @@ import type { LatLon } from '@windy/interfaces'; import { pluginConfig } from '../config'; +import * as forecastSlice from './forecast-slice'; import * as pluginSlice from './plugin-slice'; import type { AppDispatch, RootState } from './store'; const { map: windyMap, markers } = W.map; const windyRootScope = W.rootScope; +// Subscription + type Subscription = () => void; const subscriptions: Subscription[] = []; @@ -30,9 +33,9 @@ export function cancelAllSubscriptions() { * - Fetch the forecast */ export const changeLocation = (location: LatLon) => (dispatch: AppDispatch, getState: () => RootState) => { - const modelName = pluginSlice.selectors.selModelName(getState()); + const modelName = pluginSlice.slice.selectors.selModelName(getState()); dispatch(pluginSlice.setLocation(location)); - dispatch(pluginSlice.fetchForecast({ modelName, location })); + dispatch(forecastSlice.fetchForecast({ modelName, location })); changeMarkerLocation(location); @@ -40,15 +43,15 @@ export const changeLocation = (location: LatLon) => (dispatch: AppDispatch, getS }; export const changeModel = (modelName: string) => (dispatch: AppDispatch, getState: () => RootState) => { - const location = pluginSlice.selectors.selLocation(getState()); + const location = pluginSlice.slice.selectors.selLocation(getState()); dispatch(pluginSlice.setModelName(modelName)); - dispatch(pluginSlice.fetchForecast({ modelName, location })); + dispatch(forecastSlice.fetchForecast({ modelName, location })); updateUrl(getState()); }; function updateUrl(state: RootState) { - const location = pluginSlice.selectors.selLocation(state); - const modelName = pluginSlice.selectors.selModelName(state); + const location = pluginSlice.slice.selectors.selLocation(state); + const modelName = pluginSlice.slice.selectors.selModelName(state); W.location.setUrl(pluginConfig.name, { modelName, ...location }); } diff --git a/libs/windy-sounding/src/redux/plugin-slice.ts b/libs/windy-sounding/src/redux/plugin-slice.ts index ff52764c..19be3eeb 100644 --- a/libs/windy-sounding/src/redux/plugin-slice.ts +++ b/libs/windy-sounding/src/redux/plugin-slice.ts @@ -1,95 +1,14 @@ -import { createAsyncThunk, createSlice } from '@reduxjs/toolkit'; -import type { DataHash, Fav, LatLon, MeteogramDataPayload, WeatherDataPayload } from '@windy/interfaces'; -import type { MeteogramLayers } from '@windy/types'; +import { createSlice } from '@reduxjs/toolkit'; +import type { Fav, LatLon } from '@windy/interfaces'; -import * as atm from '../util/atmosphere'; -import { - type CloudCoverGenerator, - computePeriodClouds, - DEBUG_CLOUDS, - debugCloudCanvas, - debugCloudTimeCursor, - getCloudCoverGenerator, - type PeriodCloud, -} from '../util/clouds'; -import { sampleAt, type Scale, scaleLog } from '../util/math'; import { getFavLabel } from '../util/utils'; -import type { AppThunkAPI, RootState } from './store'; const windyStore = W.store; -const windyUtils = W.utils; -const windyFetch = W.fetch; -const windySubscription = W.subscription; -const windyProducts = W.products; -const windyMetrics = W.metrics; - -// Cache stale windy data for 10 minutes. -// Data are stale when an update is expected. -const STALE_WINDY_DATA_CACHE_MIN = 10; // Some models do not have the required parameters for soundings (i.e. surface only) export const SUPPORTED_MODEL_PREFIXES = ['ecmwf', 'gfs', 'nam', 'icon', 'hrrr', 'ukv', 'arome']; const DEFAULT_MODEL = 'ecmwf'; -export type TempUnit = 'K' | '°C' | '°F'; -export type AltitudeUnit = 'm' | 'ft'; -export type SpeedUnit = 'km/h' | 'mph' | 'kt' | 'bft'; -export type PressureUnit = 'mmHg' | 'inHg' | 'hPa'; - -export enum FetchStatus { - Idle = 'idle', - Loading = 'loading', - Loaded = 'loaded', - Error = 'error', - ErrorOutOfBounds = 'errorOutOfBounds', -} - -// Those properties varies with the altitude level. -const levelProps = ['temp', 'dewpoint', 'gh', 'windU', 'windV', 'rh'] as const; -type LevelProp = (typeof levelProps)[number]; -type LevelPropByTime = `${LevelProp}ByTime`; - -// Those properties do not vary with altitude. -const sfcProps = ['rainMm', 'seaLevelPressure'] as const; -type SfcProps = (typeof sfcProps)[number]; -type SfcPropsByTime = `${SfcProps}ByTime`; - -type TimeValue = Record & Record; - -export type PeriodValue = { - maxTemp: number; - minTemp: number; - maxSeaLevelPressure: number; - levels: number[]; - timesMs: number[]; -} & Record & // By time then by level - // By time only - Record; - -export type Forecast = - | { - forecastKey: string; - modelName: string; - location: LatLon; - loadedMs: number; - } & ( - | { - fetchStatus: FetchStatus.Loading | FetchStatus.Error | FetchStatus.Idle | FetchStatus.ErrorOutOfBounds; - } - | { - fetchStatus: FetchStatus.Loaded; - meteogram: MeteogramDataPayload; - weather: WeatherDataPayload; - nextUpdateMs: number; - updateMs: number; - } - ); - -export type ModelAndLocation = { - modelName: string; - location: LatLon; -}; - type PluginState = { favorites: Fav[]; // Default to true, i.e. PG mode, zoomed out mode is SkewT @@ -99,14 +18,6 @@ type PluginState = { width: number; height: number; location: LatLon; - // The key is based on the model and location. - windyDataKey: string; - // Windy data by forecast key. - windyDataCache: Record; - tempUnit: TempUnit; - altitudeUnit: AltitudeUnit; - windSpeedUnit: SpeedUnit; - pressureUnit: PressureUnit; }; const initialState: PluginState = { @@ -115,14 +26,8 @@ const initialState: PluginState = { width: 0, height: 0, location: { lat: 0, lon: 0 }, - windyDataKey: '', - windyDataCache: {}, modelName: windyStore.get('product'), timeMs: windyStore.get('timestamp'), - tempUnit: windyStore.get('metric_temp'), - altitudeUnit: windyStore.get('metric_altitude'), - windSpeedUnit: windyStore.get('metric_wind'), - pressureUnit: windyStore.get('metric_pressure'), }; export const slice = createSlice({ @@ -154,50 +59,6 @@ export const slice = createSlice({ setLocation: (state, action: { payload: LatLon }) => { state.location = action.payload; }, - setTempUnit: (state, action: { payload: TempUnit }) => { - state.tempUnit = action.payload; - }, - setAltitudeUnit: (state, action: { payload: AltitudeUnit }) => { - state.altitudeUnit = action.payload; - }, - setWindSpeedUnit: (state, action: { payload: SpeedUnit }) => { - state.windSpeedUnit = action.payload; - }, - setPressureUnit: (state, action: { payload: PressureUnit }) => { - state.pressureUnit = action.payload; - }, - }, - extraReducers: (builder) => { - builder.addCase(fetchForecast.pending, (state, action) => { - const key = windyDataKey(action.meta.arg); - const { modelName, location } = action.meta.arg; - state.windyDataCache[key] = { - forecastKey: key, - modelName, - location, - fetchStatus: FetchStatus.Loading, - loadedMs: Date.now(), - }; - }); - - builder.addCase(fetchForecast.fulfilled, (state, action) => { - const key = windyDataKey(action.meta.arg); - state.windyDataKey = key; - state.windyDataCache[key] = { ...state.windyDataCache[key], ...action.payload }; - }); - - builder.addCase(fetchForecast.rejected, (state, action) => { - const key = windyDataKey(action.meta.arg); - const { modelName, location } = action.meta.arg; - state.windyDataKey = key; - state.windyDataCache[key] = { - forecastKey: key, - modelName, - location, - fetchStatus: action.error.name === 'OutOfBoundsError' ? FetchStatus.ErrorOutOfBounds : FetchStatus.Error, - loadedMs: Date.now(), - }; - }); }, selectors: { // Values @@ -208,434 +69,9 @@ export const slice = createSlice({ selIsZoomedIn: (state): boolean => state.isZoomedIn, selLocation: (state): LatLon => state.location, selFavorites: (state): Fav[] => state.favorites, - selTempUnit: (state): TempUnit => state.tempUnit, - selAltitudeUnit: (state): AltitudeUnit => state.altitudeUnit, - selWindSpeedUnit: (state): SpeedUnit => state.windSpeedUnit, - selPressureUnit: (state): PressureUnit => state.pressureUnit, - - // Computed - selWindyDataUnsafe: (state): Forecast | undefined => { - const key = state.windyDataKey; - return isDataCached(state, key) - ? (state.windyDataCache[key] as Forecast & { fetchStatus: FetchStatus.Loaded }) - : undefined; - }, - selIsOutOfModelBounds: (state): boolean => { - const windyData = slice.getSelectors().selWindyDataUnsafe(state); - return windyData?.fetchStatus === FetchStatus.ErrorOutOfBounds; - }, - - selWindyDataIsLoading: (state): boolean => { - const windyData = slice.getSelectors().selWindyDataUnsafe(state); - return ( - windyData === undefined || - windyData.fetchStatus === FetchStatus.Loading || - windyData.fetchStatus === FetchStatus.Idle - ); - }, - selWindyDataIsLoaded(state): boolean { - const windyData = slice.getSelectors().selWindyDataUnsafe(state); - return windyData !== undefined && windyData.fetchStatus === FetchStatus.Loaded; - }, - selModelUpdateTimeMs(state): number { - const windyData = selWindyData(state); - return windyData.updateMs; - }, - selModelNextUpdateTimeMs(state): number { - const windyData = selWindyData(state); - return windyData.nextUpdateMs; - }, - selTzOffsetH(state): number { - const windyData = selWindyData(state); - return windyData.weather.celestial.TZoffset; - }, - selSunriseMs(state): number { - const windyData = selWindyData(state); - return windyData.weather.celestial.sunriseTs; - }, - selSunsetMs(state): number { - const windyData = selWindyData(state); - return windyData.weather.celestial.sunsetTs; - }, - selDisplayParcel(state): boolean { - const timeMs = slice.getSelectors().selTimeMs(state); - const startMs = slice.getSelectors().selSunriseMs(state) + 2 * 3600 * 1000; - const endMs = slice.getSelectors().selSunsetMs(state) - 3600 * 1000; - const durationMs = endMs - startMs; - return timeMs > startMs && (timeMs - startMs) % (24 * 3600 * 1000) < durationMs; - }, - - // Formatters - selTempFormatter: - (state): ((temp: number) => number) => - (temp: number) => - Math.round(windyMetrics.temp.conv[slice.getSelectors().selTempUnit(state)].conversion(temp)), - selAltitudeFormatter: - (state): ((altitude: number) => number) => - (altitude: number) => - Math.round( - windyMetrics.altitude.conv[slice.getSelectors().selAltitudeUnit(state)].conversion( - Math.round(altitude / 100) * 100, - ), - ), - selPressureFormatter: - (state): ((pressure: number) => number) => - (pressure: number) => - Math.round(windyMetrics.pressure.conv[slice.getSelectors().selPressureUnit(state)].conversion(pressure)), - selWindSpeedFormatter: - (state): ((windSpeed: number) => number) => - (windSpeed: number) => - Math.round(windyMetrics.wind.conv[slice.getSelectors().selWindSpeedUnit(state)].conversion(windSpeed)), - // Levels in descending order - selLevels: (state): number[] => { - const windyData = selWindyData(state); - return Object.keys(windyData.meteogram.data) - .filter((key: string) => key.startsWith('temp-') && key.endsWith('h')) - .map((key: string) => parseInt(key.slice(5, -1))) - .sort((a: number, b: number) => b - a); - }, - selMaxModelPressure: (state): number => { - selWindyData(state); - const levels = slice.getSelectors().selLevels(state); - return Math.max(...levels); - }, - selMinModelPressure: (state): number => { - selWindyData(state); - const levels = slice.getSelectors().selLevels(state); - return Math.min(...levels); - }, - selMinGraphPressure: (state): number => { - selWindyData(state); - const minPressure = slice.getSelectors().selMinModelPressure(state); - const isZoomedIn = slice.getSelectors().selIsZoomedIn(state); - return isZoomedIn ? 150 : minPressure; - }, - selPeriodValues(state): PeriodValue { - selWindyData(state); - return computePeriodValues(state); - }, - selMaxPeriodTemp(state): number { - selWindyData(state); - const periodValues = slice.getSelectors().selPeriodValues(state); - return periodValues.maxTemp; - }, - selMinPeriodTemp(state): number { - selWindyData(state); - const periodValues = slice.getSelectors().selPeriodValues(state); - return periodValues.minTemp; - }, - selPeriodClouds(state): PeriodCloud { - const windyData = selWindyData(state); - return computePeriodClouds(windyData.meteogram.data); - }, - selGetCloudCoverGenerator(state): CloudCoverGenerator { - const windyData = selWindyData(state); - const timesMs = windyData.meteogram.data.hours; - const timeMs = slice.getSelectors().selTimeMs(state); - const { width, height, clouds } = slice.getSelectors().selPeriodClouds(state); - const timesIndex = Math.max( - 1, - timesMs.findIndex((ms) => ms > timeMs), - ); - const startMs = timesMs[timesIndex - 1]; - const endMs = timesMs[timesIndex]; - const timeRatio = Math.max(0, Math.min(1, (endMs - timeMs) / (endMs - startMs))); - const indexRatio = (timesIndex - timeRatio) / timesMs.length; - const x = Math.round(Math.round((width - 1) * indexRatio)); - if (DEBUG_CLOUDS && debugCloudCanvas && debugCloudTimeCursor) { - debugCloudTimeCursor.style.width = `${Math.round(debugCloudCanvas.width * indexRatio)}px`; - } - const cloudSliceAtMs: number[] = []; - for (let y = height - 1; y >= 0; y--) { - cloudSliceAtMs.push(clouds[x + y * width]); - } - return getCloudCoverGenerator(cloudSliceAtMs); - }, - selMaxSeaLevelPressure(state): number { - selWindyData(state); - const periodValues = slice.getSelectors().selPeriodValues(state); - return periodValues.maxSeaLevelPressure; - }, - selAreValuesAvailableAtCurrentTime(state): boolean { - const windyData = selWindyData(state); - const maxTimeMs = Math.min( - ...[windyData.meteogram.data.hours.at(-1), windyData.weather.data.ts.at(-1)].filter((v) => v !== undefined), - ); - return slice.getSelectors().selTimeMs(state) <= maxTimeMs; - }, - selValuesAtCurrentTime(state): TimeValue { - const windyData = selWindyData(state); - const periodValues = slice.getSelectors().selPeriodValues(state); - const { timesMs } = periodValues; - const timeMs = Math.max( - slice.getSelectors().selTimeMs(state), - windyData.meteogram.data.hours[0], - windyData.weather.data.ts[0], - ); - return { - temp: sampleAt(timesMs, periodValues.tempByTime, timeMs), - dewpoint: sampleAt(timesMs, periodValues.dewpointByTime, timeMs), - gh: sampleAt(timesMs, periodValues.ghByTime, timeMs), - rh: sampleAt(timesMs, periodValues.rhByTime, timeMs), - windU: sampleAt(timesMs, periodValues.windUByTime, timeMs), - windV: sampleAt(timesMs, periodValues.windVByTime, timeMs), - rainMm: sampleAt(timesMs, periodValues.rainMmByTime, timeMs), - seaLevelPressure: sampleAt(timesMs, periodValues.seaLevelPressureByTime, timeMs), - }; - }, - selWindDetailsByLevel(state): { speed: number; direction: number }[] { - selWindyData(state); - const { windU, windV } = slice.getSelectors().selValuesAtCurrentTime(state); - const details = []; - for (let i = 0; i < windU.length; i++) { - const { wind: speed, dir: direction } = windyUtils.wind2obj([windU[i], windV[i]]); - details.push({ speed, direction }); - } - return details; - }, - selElevation(state): number { - const windyData = selWindyData(state); - const { weather, meteogram } = windyData; - return meteogram.header.elevation ?? weather.header.elevation ?? meteogram.header.modelElevation; - }, - selPressureToGhScale(state): Scale { - selWindyData(state); - const levels = slice.getSelectors().selLevels(state); - const { gh, seaLevelPressure } = slice.getSelectors().selValuesAtCurrentTime(state); - return atm.getPressureToGhScale(levels, gh, seaLevelPressure); - }, - selParcel(state): atm.ParcelData { - const timeValues = slice.getSelectors().selValuesAtCurrentTime(state); - const periodValues = slice.getSelectors().selPeriodValues(state); - const pressureToGhScale = slice.getSelectors().selPressureToGhScale(state); - const elevation = slice.getSelectors().selElevation(state); - const pressureToDewpointScale = scaleLog(periodValues.levels, timeValues.dewpoint); - - return atm.parcelTrajectory( - periodValues.levels, - timeValues.gh, - timeValues.temp, - 3, - elevation, - pressureToDewpointScale(pressureToGhScale.invert(elevation)), - 40, - ); - }, - selUpdateTime(state): ({ direction, stepIsDay }: { direction: number; stepIsDay: boolean }) => void { - const tzOffset = slice.getSelectors().selTzOffsetH(state); - return ({ direction, stepIsDay }: { direction: number; stepIsDay: boolean }) => { - let timeMs = windyStore.get('timestamp'); - if (stepIsDay) { - const date = new Date(timeMs); - const utcHours = date.getUTCHours(); - date.setUTCMinutes(0); - timeMs = date.getTime(); - // Jump to previous/next day at 13h. - const refTime = (13 - tzOffset + 24) % 24; - const deltaHours = (refTime - utcHours) * direction; - if (deltaHours <= 0) { - timeMs += direction * (24 + deltaHours) * 3600 * 1000; - } else { - timeMs += direction * deltaHours * 3600 * 1000; - } - } else { - timeMs += direction * 3600 * 1000; - } - - windyStore.set('timestamp', timeMs); - }; - }, - selWheelEventHandler(state): (e: WheelEvent) => void { - let nextWheelMove = 0; - return (e: WheelEvent) => { - const updateTime = slice.getSelectors().selUpdateTime(state); - if (Date.now() > nextWheelMove) { - const stepIsDay: boolean = e.shiftKey || e.ctrlKey; - const direction: number = Math.sign(e.deltaY); - updateTime({ direction, stepIsDay }); - nextWheelMove = Date.now() + (stepIsDay ? 800 : 20); - } - e.stopImmediatePropagation(); - e.preventDefault(); - }; - }, }, }); -/** - * Throws when accessing data that are not loaded yet. - * - * @param state - */ -function selWindyData(state: PluginState): Forecast & { fetchStatus: FetchStatus.Loaded } { - const windyData = slice.getSelectors().selWindyDataUnsafe(state); - if (windyData === undefined || windyData.fetchStatus !== FetchStatus.Loaded) { - throw new Error('Data not loaded'); - } - return windyData; -} - -class OutOfBoundsError extends Error { - constructor(message: string) { - super(message); - this.name = 'OutOfBoundsError'; - } -} - -export const fetchForecast = createAsyncThunk( - 'plugin/fetchForecast', - async (modelAndLocation: ModelAndLocation, api: { getState: () => RootState }) => { - const key = windyDataKey(modelAndLocation); - - if (isDataCached(slice.selectSlice(api.getState()), key)) { - return slice.selectSlice(api.getState()).windyDataCache[key]; - } - - const { modelName, location } = modelAndLocation; - const [meteogram, forecast] = await Promise.allSettled([ - // extended is required to get fulml length forecast for pro windy users - windyFetch.getMeteogramForecastData(modelName, { ...location, step: 1 }, { extended: 'true' }), - windyFetch.getPointForecastData(modelName, { ...location }), - ]); - - if (meteogram.status === 'rejected') { - if ( - meteogram.reason.status == 400 && - JSON.parse(meteogram.reason.responseText).message === 'Out of model bounds' - ) { - throw new OutOfBoundsError(meteogram.reason.message); - } - throw new Error('Failed to fetch meteogram data'); - } - - if (forecast.status === 'rejected') { - if (forecast.reason.status == 400 && JSON.parse(forecast.reason.responseText).message === 'Out of mode bounds') { - throw new OutOfBoundsError(forecast.reason.message); - } - throw new Error('Failed to fetch forecast data'); - } - - const updateMs = forecast.value.data.header.updateTs; - const product = windyProducts[modelName]; - const updateIntervalMin = windySubscription.hasAny() - ? product.intervalPremium ?? product.interval - : product.interval; - - return { - forecastKey: key, - modelName, - location, - loadedMs: Date.now(), - updateMs, - nextUpdateMs: updateMs + updateIntervalMin * 60 * 1000, - fetchStatus: FetchStatus.Loaded, - meteogram: meteogram.value.data, - weather: forecast.value.data, - }; - }, - { - condition: (modelAndLocation, api: AppThunkAPI) => { - // Prevent fetching again while loading. - const key = windyDataKey(modelAndLocation); - const data = slice.selectSlice(api.getState()).windyDataCache[key]; - return data?.fetchStatus != FetchStatus.Loading; - }, - }, -); - -function windyDataKey(modelAndLocation: ModelAndLocation): string { - return `${modelAndLocation.modelName}-${windyUtils.latLon2str(modelAndLocation.location)}`; -} - -function isDataCached(state: PluginState, key: string) { - const nowMs = Date.now(); - const forecast = state.windyDataCache[key]; - if (forecast == null) { - return false; - } - - if (forecast.fetchStatus === FetchStatus.ErrorOutOfBounds) { - return true; - } - - if (forecast.fetchStatus === FetchStatus.Loaded) { - const requestMs = forecast.loadedMs; - const dataAgeMin = (nowMs - requestMs) / (60 * 1000); - return nowMs < forecast.nextUpdateMs || dataAgeMin < STALE_WINDY_DATA_CACHE_MIN; - } - - return false; -} - -function extractMeteogramParamByLevel( - meteogram: MeteogramDataPayload, - paramName: MeteogramLayers, - levels: number[], - tsIndex: number, -): number[] { - return levels.map((level: number): number => { - const valueByTs: number[] = (meteogram.data as Record)[`${paramName}-${level}h`]; - const value = Array.isArray(valueByTs) ? valueByTs[tsIndex] : null; - if (value == null) { - if (paramName === 'gh') { - // Approximate gh when not provided by the model - return Math.round(atm.getElevation(level)); - } - throw new Error('Unexpected null value'); - } - return value; - }); -} - -function computePeriodValues(state: PluginState): PeriodValue { - const windyData = selWindyData(state); - const levels: number[] = slice.getSelectors().selLevels(state); - - const timesMeteogramMs: number[] = windyData.meteogram.data.hours; - const timeWeatherMs: number[] = windyData.weather.data.ts; - - let maxTemp: number = Number.MIN_VALUE; - let minTemp: number = Number.MAX_VALUE; - let maxSeaLevelPressure: number = Number.MIN_VALUE; - - const values: Record & Record = { - dewpointByTime: [], - ghByTime: [], - rhByTime: [], - tempByTime: [], - windUByTime: [], - windVByTime: [], - rainMmByTime: [], - seaLevelPressureByTime: [], - }; - - for (let tsIndex = 0; tsIndex < timesMeteogramMs.length; tsIndex++) { - const timeMs = timesMeteogramMs[tsIndex]; - const tempByLevel = extractMeteogramParamByLevel(windyData.meteogram, 'temp', levels, tsIndex); - maxTemp = Math.max(maxTemp, ...tempByLevel); - minTemp = Math.min(minTemp, ...tempByLevel); - const seaLevelPressure = sampleAt(timeWeatherMs, windyData.weather.data.pressure, timeMs) / 100; - maxSeaLevelPressure = Math.max(maxSeaLevelPressure, seaLevelPressure); - values.tempByTime.push(tempByLevel); - values.dewpointByTime.push(extractMeteogramParamByLevel(windyData.meteogram, 'dewpoint', levels, tsIndex)); - values.ghByTime.push(extractMeteogramParamByLevel(windyData.meteogram, 'gh', levels, tsIndex)); - values.rhByTime.push(extractMeteogramParamByLevel(windyData.meteogram, 'rh', levels, tsIndex)); - values.windUByTime.push(extractMeteogramParamByLevel(windyData.meteogram, 'wind_u', levels, tsIndex)); - values.windVByTime.push(extractMeteogramParamByLevel(windyData.meteogram, 'wind_v', levels, tsIndex)); - values.rainMmByTime.push(sampleAt(timeWeatherMs, windyData.weather.data.mm, timeMs)); - values.seaLevelPressureByTime.push(Math.round(seaLevelPressure)); - } - - return { - timesMs: timesMeteogramMs, - levels, - maxTemp, - minTemp, - maxSeaLevelPressure, - ...values, - }; -} - export const { setIsZoomedIn: setIsZoomedIn, setFavorites, @@ -647,5 +83,3 @@ export const { } = slice.actions; export const { reducer } = slice; - -export const selectors = slice.getSelectors((state: RootState) => state.plugin); diff --git a/libs/windy-sounding/src/redux/store.ts b/libs/windy-sounding/src/redux/store.ts index 27f359fb..df7040d9 100644 --- a/libs/windy-sounding/src/redux/store.ts +++ b/libs/windy-sounding/src/redux/store.ts @@ -1,7 +1,9 @@ import type { DevToolsEnhancerOptions, GetThunkAPI } from '@reduxjs/toolkit'; import { combineReducers, configureStore } from '@reduxjs/toolkit'; +import * as forecastSlice from '../redux/forecast-slice'; import * as pluginSlice from '../redux/plugin-slice'; +import * as unitsSlice from '../redux/units-slice'; export type AppGetState = typeof store.getState; export type AppDispatch = typeof store.dispatch; @@ -19,6 +21,8 @@ const devTools: DevToolsEnhancerOptions | boolean = export const store = configureStore({ reducer: combineReducers({ [pluginSlice.slice.name]: pluginSlice.reducer, + [unitsSlice.slice.name]: unitsSlice.reducer, + [forecastSlice.slice.name]: forecastSlice.reducer, }), middleware: (getDefaultMiddleware) => getDefaultMiddleware({ diff --git a/libs/windy-sounding/src/redux/units-slice.ts b/libs/windy-sounding/src/redux/units-slice.ts new file mode 100644 index 00000000..db9ad69a --- /dev/null +++ b/libs/windy-sounding/src/redux/units-slice.ts @@ -0,0 +1,63 @@ +import { createSlice } from '@reduxjs/toolkit'; + +import type { RootState } from './store'; + +const windyStore = W.store; +const windyMetrics = W.metrics; + +export type TempUnit = 'K' | '°C' | '°F'; +export type AltitudeUnit = 'm' | 'ft'; +export type SpeedUnit = 'km/h' | 'mph' | 'kt' | 'bft'; +export type PressureUnit = 'mmHg' | 'inHg' | 'hPa'; + +type UnitsState = { + tempUnit: TempUnit; + altitudeUnit: AltitudeUnit; + windSpeedUnit: SpeedUnit; + pressureUnit: PressureUnit; +}; + +const initialState: UnitsState = { + tempUnit: windyStore.get('metric_temp'), + altitudeUnit: windyStore.get('metric_altitude'), + windSpeedUnit: windyStore.get('metric_wind'), + pressureUnit: windyStore.get('metric_pressure'), +}; + +export const slice = createSlice({ + name: 'units', + initialState, + reducers: {}, + selectors: { + // Values + selTempUnit: (state): TempUnit => state.tempUnit, + selAltitudeUnit: (state): AltitudeUnit => state.altitudeUnit, + selWindSpeedUnit: (state): SpeedUnit => state.windSpeedUnit, + selPressureUnit: (state): PressureUnit => state.pressureUnit, + // Formatters + selTempFormatter: + (state): ((temp: number) => number) => + (temp: number) => + Math.round(windyMetrics.temp.conv[slice.getSelectors().selTempUnit(state)].conversion(temp)), + selAltitudeFormatter: + (state): ((altitude: number) => number) => + (altitude: number) => + Math.round( + windyMetrics.altitude.conv[slice.getSelectors().selAltitudeUnit(state)].conversion( + Math.round(altitude / 100) * 100, + ), + ), + selPressureFormatter: + (state): ((pressure: number) => number) => + (pressure: number) => + Math.round(windyMetrics.pressure.conv[slice.getSelectors().selPressureUnit(state)].conversion(pressure)), + selWindSpeedFormatter: + (state): ((windSpeed: number) => number) => + (windSpeed: number) => + Math.round(windyMetrics.wind.conv[slice.getSelectors().selWindSpeedUnit(state)].conversion(windSpeed)), + }, +}); + +export const { reducer } = slice; + +export const selectors = slice.getSelectors((state: RootState) => state.units); diff --git a/libs/windy-sounding/src/sounding.tsx b/libs/windy-sounding/src/sounding.tsx index 3cba7420..463a784e 100644 --- a/libs/windy-sounding/src/sounding.tsx +++ b/libs/windy-sounding/src/sounding.tsx @@ -54,7 +54,7 @@ export const mountPlugin = (container: HTMLElement) => { (e: CustomEvent) => { const { right, left } = e.detail.directions; const direction = left ? -1 : right ? 1 : 0; - pluginSlice.selectors.selUpdateTime(store.getState())({ direction, stepIsDay: true }); + pluginSlice.slice.selectors.selUpdateTime(store.getState())({ direction, stepIsDay: true }); }, { signal: controller.signal }, ); @@ -68,7 +68,7 @@ export const mountPlugin = (container: HTMLElement) => { setSizeFrom(appContainer); }); resizeObserver.observe(container); - addSubscription(() => resizeObserver.unobserve(container)); + addSubscription(() => resizeObserver?.unobserve(container)); } } diff --git a/package-lock.json b/package-lock.json index 9c45380f..0669dcf8 100644 --- a/package-lock.json +++ b/package-lock.json @@ -28,6 +28,7 @@ "@tmcw/togeojson": "^5.8.1", "@types/mapbox__sphericalmercator": "^1.2.3", "@vivaxy/png": "^1.3.0", + "@windycom/plugin-devtools": "^2.0.0", "@xmldom/xmldom": "^0.8.10", "axios": "1.7.2", "commander": "^12.1.0", @@ -113,7 +114,6 @@ "@vitejs/plugin-react": "^4.2.0", "@vitest/coverage-v8": "^1.0.4", "@vitest/ui": "^1.3.1", - "@windycom/plugin-devtools": "^2.0.0", "cypress": "13.13.0", "dotenv-webpack": "^8.1.0", "eslint": "~8.57.0", @@ -241,7 +241,6 @@ "version": "2.3.0", "resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.3.0.tgz", "integrity": "sha512-30iZtAPgz+LTIYoeivqYo853f02jBYSd5uGnGpkFV0M3xOt9aN73erkgYAmZU43x4VfqcnLxW9Kpg3R5LC4YYw==", - "dev": true, "dependencies": { "@jridgewell/gen-mapping": "^0.3.5", "@jridgewell/trace-mapping": "^0.3.24" @@ -295,7 +294,7 @@ "version": "7.24.7", "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.24.7.tgz", "integrity": "sha512-BcYH1CVJBO9tvyIZ2jVeXgSIMvGZ2FDRvDdOIVQyuklNKSsx+eppDEBq/g47Ayw+RqNFE+URvOShmf+f/qwAlA==", - "dev": true, + "devOptional": true, "dependencies": { "@babel/highlight": "^7.24.7", "picocolors": "^1.0.0" @@ -308,7 +307,7 @@ "version": "7.24.7", "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.24.7.tgz", "integrity": "sha512-qJzAIcv03PyaWqxRgO4mSU3lihncDT296vnyuE2O8uA4w3UHWI4S3hgeZd1L8W1Bft40w9JxJ2b412iDUFFRhw==", - "dev": true, + "devOptional": true, "engines": { "node": ">=6.9.0" } @@ -317,7 +316,7 @@ "version": "7.24.7", "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.24.7.tgz", "integrity": "sha512-nykK+LEK86ahTkX/3TgauT0ikKoNCfKHEaZYTUVupJdTLzGNvrblu4u6fa7DhZONAltdf8e662t/abY8idrd/g==", - "dev": true, + "devOptional": true, "dependencies": { "@ampproject/remapping": "^2.2.0", "@babel/code-frame": "^7.24.7", @@ -347,7 +346,7 @@ "version": "7.24.7", "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.24.7.tgz", "integrity": "sha512-oipXieGC3i45Y1A41t4tAqpnEZWgB/lC6Ehh6+rOviR5XWpTtMmLN+fGjz9vOiNRt0p6RtO6DtD0pdU3vpqdSA==", - "dev": true, + "devOptional": true, "dependencies": { "@babel/types": "^7.24.7", "@jridgewell/gen-mapping": "^0.3.5", @@ -387,7 +386,7 @@ "version": "7.24.7", "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.24.7.tgz", "integrity": "sha512-ctSdRHBi20qWOfy27RUb4Fhp07KSJ3sXcuSvTrXrc4aG8NSYDo1ici3Vhg9bg69y5bj0Mr1lh0aeEgTvc12rMg==", - "dev": true, + "devOptional": true, "dependencies": { "@babel/compat-data": "^7.24.7", "@babel/helper-validator-option": "^7.24.7", @@ -459,7 +458,7 @@ "version": "7.24.7", "resolved": "https://registry.npmjs.org/@babel/helper-environment-visitor/-/helper-environment-visitor-7.24.7.tgz", "integrity": "sha512-DoiN84+4Gnd0ncbBOM9AZENV4a5ZiL39HYMyZJGZ/AZEykHYdJw0wW3kdcsh9/Kn+BRXHLkkklZ51ecPKmI1CQ==", - "dev": true, + "devOptional": true, "dependencies": { "@babel/types": "^7.24.7" }, @@ -471,7 +470,7 @@ "version": "7.24.7", "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.24.7.tgz", "integrity": "sha512-FyoJTsj/PEUWu1/TYRiXTIHc8lbw+TDYkZuoE43opPS5TrI7MyONBE1oNvfguEXAD9yhQRrVBnXdXzSLQl9XnA==", - "dev": true, + "devOptional": true, "dependencies": { "@babel/template": "^7.24.7", "@babel/types": "^7.24.7" @@ -484,7 +483,7 @@ "version": "7.24.7", "resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.24.7.tgz", "integrity": "sha512-MJJwhkoGy5c4ehfoRyrJ/owKeMl19U54h27YYftT0o2teQ3FJ3nQUf/I3LlJsX4l3qlw7WRXUmiyajvHXoTubQ==", - "dev": true, + "devOptional": true, "dependencies": { "@babel/types": "^7.24.7" }, @@ -509,7 +508,7 @@ "version": "7.24.7", "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.24.7.tgz", "integrity": "sha512-8AyH3C+74cgCVVXow/myrynrAGv+nTVg5vKu2nZph9x7RcRwzmh0VFallJuFTZ9mx6u4eSdXZfcOzSqTUm0HCA==", - "dev": true, + "devOptional": true, "dependencies": { "@babel/traverse": "^7.24.7", "@babel/types": "^7.24.7" @@ -522,7 +521,7 @@ "version": "7.24.7", "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.24.7.tgz", "integrity": "sha512-1fuJEwIrp+97rM4RWdO+qrRsZlAeL1lQJoPqtCYWv0NL115XM93hIH4CSRln2w52SqvmY5hqdtauB6QFCDiZNQ==", - "dev": true, + "devOptional": true, "dependencies": { "@babel/helper-environment-visitor": "^7.24.7", "@babel/helper-module-imports": "^7.24.7", @@ -596,7 +595,7 @@ "version": "7.24.7", "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.24.7.tgz", "integrity": "sha512-zBAIvbCMh5Ts+b86r/CjU+4XGYIs+R1j951gxI3KmmxBMhCg4oQMsv6ZXQ64XOm/cvzfU1FmoCyt6+owc5QMYg==", - "dev": true, + "devOptional": true, "dependencies": { "@babel/traverse": "^7.24.7", "@babel/types": "^7.24.7" @@ -622,7 +621,7 @@ "version": "7.24.7", "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.24.7.tgz", "integrity": "sha512-oy5V7pD+UvfkEATUKvIjvIAH/xCzfsFVw7ygW2SI6NClZzquT+mwdTfgfdbUiceh6iQO0CHtCPsyze/MZ2YbAA==", - "dev": true, + "devOptional": true, "dependencies": { "@babel/types": "^7.24.7" }, @@ -634,7 +633,7 @@ "version": "7.24.7", "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.24.7.tgz", "integrity": "sha512-7MbVt6xrwFQbunH2DNQsAP5sTGxfqQtErvBIvIMi6EQnbgUOuVYanvREcmFrOPhoXBrTtjhhP+lW+o5UfK+tDg==", - "dev": true, + "devOptional": true, "engines": { "node": ">=6.9.0" } @@ -643,7 +642,7 @@ "version": "7.24.7", "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.24.7.tgz", "integrity": "sha512-rR+PBcQ1SMQDDyF6X0wxtG8QyLCgUB0eRAGguqRLfkCA87l7yAP7ehq8SNj96OOGTO8OBV70KhuFYcIkHXOg0w==", - "dev": true, + "devOptional": true, "engines": { "node": ">=6.9.0" } @@ -652,7 +651,7 @@ "version": "7.24.7", "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.24.7.tgz", "integrity": "sha512-yy1/KvjhV/ZCL+SM7hBrvnZJ3ZuT9OuZgIJAGpPEToANvc3iM6iDvBnRjtElWibHU6n8/LPR/EjX9EtIEYO3pw==", - "dev": true, + "devOptional": true, "engines": { "node": ">=6.9.0" } @@ -676,7 +675,7 @@ "version": "7.24.7", "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.24.7.tgz", "integrity": "sha512-NlmJJtvcw72yRJRcnCmGvSi+3jDEg8qFu3z0AFoymmzLx5ERVWyzd9kVXr7Th9/8yIJi2Zc6av4Tqz3wFs8QWg==", - "dev": true, + "devOptional": true, "dependencies": { "@babel/template": "^7.24.7", "@babel/types": "^7.24.7" @@ -689,7 +688,7 @@ "version": "7.24.7", "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.24.7.tgz", "integrity": "sha512-EStJpq4OuY8xYfhGVXngigBJRWxftKX9ksiGDnmlY3o7B/V7KIAc9X4oiK87uPJSc/vs5L869bem5fhZa8caZw==", - "dev": true, + "devOptional": true, "dependencies": { "@babel/helper-validator-identifier": "^7.24.7", "chalk": "^2.4.2", @@ -704,7 +703,7 @@ "version": "7.24.7", "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.24.7.tgz", "integrity": "sha512-9uUYRm6OqQrCqQdG1iCBwBPZgN8ciDBro2nIOFaiRz1/BCxaI7CNvQbDHvsArAC7Tw9Hda/B3U+6ui9u4HWXPw==", - "dev": true, + "devOptional": true, "bin": { "parser": "bin/babel-parser.js" }, @@ -2132,7 +2131,7 @@ "version": "7.24.7", "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.24.7.tgz", "integrity": "sha512-jYqfPrU9JTF0PmPy1tLYHW4Mp4KlgxJD9l2nP9fD6yT/ICi554DmrWBAEYpIelzjHf1msDP3PxJIRt/nFNfBig==", - "dev": true, + "devOptional": true, "dependencies": { "@babel/code-frame": "^7.24.7", "@babel/parser": "^7.24.7", @@ -2146,7 +2145,7 @@ "version": "7.24.7", "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.24.7.tgz", "integrity": "sha512-yb65Ed5S/QAcewNPh0nZczy9JdYXkkAbIsEo+P7BE7yO3txAY30Y/oPa3QkQ5It3xVG2kpKMg9MsdxZaO31uKA==", - "dev": true, + "devOptional": true, "dependencies": { "@babel/code-frame": "^7.24.7", "@babel/generator": "^7.24.7", @@ -2167,7 +2166,7 @@ "version": "7.24.7", "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.24.7.tgz", "integrity": "sha512-XEFXSlxiG5td2EJRe8vOmRbaXVgfcBlszKujvVmWIK/UpywWljQCfzAv3RQCGujWQ1RD4YYWEAqDXfuJiy8f5Q==", - "dev": true, + "devOptional": true, "dependencies": { "@babel/helper-string-parser": "^7.24.7", "@babel/helper-validator-identifier": "^7.24.7", @@ -2294,7 +2293,7 @@ "version": "0.8.1", "resolved": "https://registry.npmjs.org/@cspotcode/source-map-support/-/source-map-support-0.8.1.tgz", "integrity": "sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==", - "dev": true, + "devOptional": true, "dependencies": { "@jridgewell/trace-mapping": "0.3.9" }, @@ -2306,7 +2305,7 @@ "version": "0.3.9", "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.9.tgz", "integrity": "sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ==", - "dev": true, + "devOptional": true, "dependencies": { "@jridgewell/resolve-uri": "^3.0.3", "@jridgewell/sourcemap-codec": "^1.4.10" @@ -2796,7 +2795,6 @@ "version": "4.4.0", "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.4.0.tgz", "integrity": "sha512-1/sA4dwrzBAyeUoQ6oxahHKmrZvsnLCg4RfxW3ZFGGmQkSNQPFNLV9CUEFQP1x9EYXHTo5p6xdhZM1Ne9p/AfA==", - "dev": true, "dependencies": { "eslint-visitor-keys": "^3.3.0" }, @@ -2811,7 +2809,6 @@ "version": "4.11.0", "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.11.0.tgz", "integrity": "sha512-G/M/tIiMrTAxEWRfLfQJMmGNX28IxBg4PBz8XqQhqUHLFI6TL2htpIB1iQCj144V5ee/JaKyT9/WZ0MGZWfA7A==", - "dev": true, "engines": { "node": "^12.0.0 || ^14.0.0 || >=16.0.0" } @@ -2820,7 +2817,6 @@ "version": "2.1.4", "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-2.1.4.tgz", "integrity": "sha512-269Z39MS6wVJtsoUl10L60WdkhJVdPG24Q4eZTH3nnF6lpvSShEK3wQjDX9JRWAUPvPh7COouPpU9IrqaZFvtQ==", - "dev": true, "dependencies": { "ajv": "^6.12.4", "debug": "^4.3.2", @@ -2843,7 +2839,6 @@ "version": "6.12.6", "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", - "dev": true, "dependencies": { "fast-deep-equal": "^3.1.1", "fast-json-stable-stringify": "^2.0.0", @@ -2858,14 +2853,12 @@ "node_modules/@eslint/eslintrc/node_modules/argparse": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", - "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", - "dev": true + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==" }, "node_modules/@eslint/eslintrc/node_modules/brace-expansion": { "version": "1.1.11", "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", - "dev": true, "dependencies": { "balanced-match": "^1.0.0", "concat-map": "0.0.1" @@ -2875,7 +2868,6 @@ "version": "13.24.0", "resolved": "https://registry.npmjs.org/globals/-/globals-13.24.0.tgz", "integrity": "sha512-AhO5QUcj8llrbG09iWhPU2B204J1xnPeL8kQmVorSsy+Sjj1sk8gIyh6cUocGmH4L0UuhAJy+hJMRA4mgA4mFQ==", - "dev": true, "dependencies": { "type-fest": "^0.20.2" }, @@ -2890,7 +2882,6 @@ "version": "4.1.0", "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", - "dev": true, "dependencies": { "argparse": "^2.0.1" }, @@ -2901,14 +2892,12 @@ "node_modules/@eslint/eslintrc/node_modules/json-schema-traverse": { "version": "0.4.1", "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", - "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", - "dev": true + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==" }, "node_modules/@eslint/eslintrc/node_modules/minimatch": { "version": "3.1.2", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", - "dev": true, "dependencies": { "brace-expansion": "^1.1.7" }, @@ -2920,7 +2909,6 @@ "version": "0.20.2", "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", - "dev": true, "engines": { "node": ">=10" }, @@ -2932,7 +2920,6 @@ "version": "8.57.0", "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.57.0.tgz", "integrity": "sha512-Ys+3g2TaW7gADOJzPt83SJtCDhMjndcDMFVQ/Tj9iA1BfJzFKD9mAUXT3OenpuPHbI6P/myECxRJrofUsDx/5g==", - "dev": true, "engines": { "node": "^12.22.0 || ^14.17.0 || >=16.0.0" } @@ -3050,8 +3037,7 @@ "node_modules/@fastify/deepmerge": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/@fastify/deepmerge/-/deepmerge-1.3.0.tgz", - "integrity": "sha512-J8TOSBq3SoZbDhM9+R/u77hP93gz/rajSA+K2kGyijPpORPWUXHUpTaleoj+92As0S9uPRP7Oi8IqMf0u+ro6A==", - "dev": true + "integrity": "sha512-J8TOSBq3SoZbDhM9+R/u77hP93gz/rajSA+K2kGyijPpORPWUXHUpTaleoj+92As0S9uPRP7Oi8IqMf0u+ro6A==" }, "node_modules/@floating-ui/core": { "version": "1.6.4", @@ -3232,7 +3218,6 @@ "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.14.tgz", "integrity": "sha512-3T8LkOmg45BV5FICb15QQMsyUSWrQ8AygVfC7ZG32zOalnqrilm018ZVCw0eapXux8FtA33q8PSRSstjee3jSg==", "deprecated": "Use @eslint/config-array instead", - "dev": true, "dependencies": { "@humanwhocodes/object-schema": "^2.0.2", "debug": "^4.3.1", @@ -3246,7 +3231,6 @@ "version": "1.1.11", "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", - "dev": true, "dependencies": { "balanced-match": "^1.0.0", "concat-map": "0.0.1" @@ -3256,7 +3240,6 @@ "version": "3.1.2", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", - "dev": true, "dependencies": { "brace-expansion": "^1.1.7" }, @@ -3268,7 +3251,6 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz", "integrity": "sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==", - "dev": true, "engines": { "node": ">=12.22" }, @@ -3281,8 +3263,7 @@ "version": "2.0.3", "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-2.0.3.tgz", "integrity": "sha512-93zYdMES/c1D69yZiKDBj0V24vqNzB/koF26KPaagAfd3P/4gUlh3Dys5ogAK+Exi9QyzlD8x/08Zt7wIKcDcA==", - "deprecated": "Use @eslint/object-schema instead", - "dev": true + "deprecated": "Use @eslint/object-schema instead" }, "node_modules/@ionic/core": { "version": "8.2.5", @@ -4076,7 +4057,6 @@ "version": "0.3.5", "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.5.tgz", "integrity": "sha512-IzL8ZoEDIBRWEzlCcRhOaCupYyN5gdIK+Q6fbFdPDg6HqX6jpkItn7DFIpW9LQzXG6Df9sA7+OKnq0qlz/GaQg==", - "dev": true, "dependencies": { "@jridgewell/set-array": "^1.2.1", "@jridgewell/sourcemap-codec": "^1.4.10", @@ -4090,7 +4070,6 @@ "version": "3.1.2", "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz", "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==", - "dev": true, "engines": { "node": ">=6.0.0" } @@ -4099,7 +4078,6 @@ "version": "1.2.1", "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.2.1.tgz", "integrity": "sha512-R8gLRTZeyp03ymzP/6Lil/28tGeGEzhx1q2k703KGWRAI1VdvPIXdG70VJc2pAMw3NA6JKL5hhFu1sJX0Mnn/A==", - "dev": true, "engines": { "node": ">=6.0.0" } @@ -4108,7 +4086,6 @@ "version": "0.3.6", "resolved": "https://registry.npmjs.org/@jridgewell/source-map/-/source-map-0.3.6.tgz", "integrity": "sha512-1ZJTZebgqllO79ue2bm3rIGud/bOe0pP5BjSRCRxxYkEZS8STV7zN84UBbiYu7jy+eCKSnVIUgoWWE/tt+shMQ==", - "dev": true, "dependencies": { "@jridgewell/gen-mapping": "^0.3.5", "@jridgewell/trace-mapping": "^0.3.25" @@ -4117,14 +4094,12 @@ "node_modules/@jridgewell/sourcemap-codec": { "version": "1.4.15", "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz", - "integrity": "sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==", - "dev": true + "integrity": "sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==" }, "node_modules/@jridgewell/trace-mapping": { "version": "0.3.25", "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.25.tgz", "integrity": "sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==", - "dev": true, "dependencies": { "@jridgewell/resolve-uri": "^3.1.0", "@jridgewell/sourcemap-codec": "^1.4.14" @@ -4338,7 +4313,6 @@ "version": "2.1.5", "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", - "dev": true, "dependencies": { "@nodelib/fs.stat": "2.0.5", "run-parallel": "^1.1.9" @@ -4351,7 +4325,6 @@ "version": "2.0.5", "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", - "dev": true, "engines": { "node": ">= 8" } @@ -4360,7 +4333,6 @@ "version": "1.2.8", "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", - "dev": true, "dependencies": { "@nodelib/fs.scandir": "2.1.5", "fastq": "^1.6.0" @@ -6177,7 +6149,6 @@ "version": "25.0.8", "resolved": "https://registry.npmjs.org/@rollup/plugin-commonjs/-/plugin-commonjs-25.0.8.tgz", "integrity": "sha512-ZEZWTK5n6Qde0to4vS9Mr5x/0UZoqCxPVR9KRUjU4kA2sO7GEUn1fop0DAwpO6z0Nw/kJON9bDmSxdWxO/TT1A==", - "dev": true, "dependencies": { "@rollup/pluginutils": "^5.0.1", "commondir": "^1.0.1", @@ -6202,7 +6173,6 @@ "version": "5.1.0", "resolved": "https://registry.npmjs.org/@rollup/pluginutils/-/pluginutils-5.1.0.tgz", "integrity": "sha512-XTIWOPPcpvyKI6L1NHo0lFlCyznUEyPmPY1mc3KpPVDYulHSTvyeLNVW00QTLIAFNhR3kYnJTQHeGqU4M3n09g==", - "dev": true, "dependencies": { "@types/estree": "^1.0.0", "estree-walker": "^2.0.2", @@ -6225,7 +6195,6 @@ "resolved": "https://registry.npmjs.org/glob/-/glob-8.1.0.tgz", "integrity": "sha512-r8hpEjiQEYlF2QU0df3dS+nxxSIreXQS1qRhMJM0Q5NDdR386C7jb7Hwwod8Fgiuex+k0GFjgft18yvxm5XoCQ==", "deprecated": "Glob versions prior to v9 are no longer supported", - "dev": true, "dependencies": { "fs.realpath": "^1.0.0", "inflight": "^1.0.4", @@ -6244,7 +6213,6 @@ "version": "5.1.6", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.1.6.tgz", "integrity": "sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g==", - "dev": true, "dependencies": { "brace-expansion": "^2.0.1" }, @@ -6256,7 +6224,6 @@ "version": "15.2.3", "resolved": "https://registry.npmjs.org/@rollup/plugin-node-resolve/-/plugin-node-resolve-15.2.3.tgz", "integrity": "sha512-j/lym8nf5E21LwBT4Df1VD6hRO2L2iwUeUmP7litikRsVp1H6NWx20NEp0Y7su+7XGc476GnXXc4kFeZNGmaSQ==", - "dev": true, "dependencies": { "@rollup/pluginutils": "^5.0.1", "@types/resolve": "1.20.2", @@ -6281,7 +6248,6 @@ "version": "5.1.0", "resolved": "https://registry.npmjs.org/@rollup/pluginutils/-/pluginutils-5.1.0.tgz", "integrity": "sha512-XTIWOPPcpvyKI6L1NHo0lFlCyznUEyPmPY1mc3KpPVDYulHSTvyeLNVW00QTLIAFNhR3kYnJTQHeGqU4M3n09g==", - "dev": true, "dependencies": { "@types/estree": "^1.0.0", "estree-walker": "^2.0.2", @@ -6354,7 +6320,6 @@ "version": "0.4.4", "resolved": "https://registry.npmjs.org/@rollup/plugin-terser/-/plugin-terser-0.4.4.tgz", "integrity": "sha512-XHeJC5Bgvs8LfukDwWZp7yeqin6ns8RTl2B9avbejt6tZqsqvVoWI7ZTQrcNsfKEDWBTnTxM8nMDkO2IFFbd0A==", - "dev": true, "dependencies": { "serialize-javascript": "^6.0.1", "smob": "^1.0.0", @@ -6376,7 +6341,6 @@ "version": "11.1.6", "resolved": "https://registry.npmjs.org/@rollup/plugin-typescript/-/plugin-typescript-11.1.6.tgz", "integrity": "sha512-R92yOmIACgYdJ7dJ97p4K69I8gg6IEHt8M7dUBxN3W6nrO8uUxX5ixl0yU/N3aZTi8WhPuICvOHXQvF6FaykAA==", - "dev": true, "dependencies": { "@rollup/pluginutils": "^5.1.0", "resolve": "^1.22.1" @@ -6402,7 +6366,6 @@ "version": "5.1.0", "resolved": "https://registry.npmjs.org/@rollup/pluginutils/-/pluginutils-5.1.0.tgz", "integrity": "sha512-XTIWOPPcpvyKI6L1NHo0lFlCyznUEyPmPY1mc3KpPVDYulHSTvyeLNVW00QTLIAFNhR3kYnJTQHeGqU4M3n09g==", - "dev": true, "dependencies": { "@types/estree": "^1.0.0", "estree-walker": "^2.0.2", @@ -6424,7 +6387,6 @@ "version": "4.2.1", "resolved": "https://registry.npmjs.org/@rollup/pluginutils/-/pluginutils-4.2.1.tgz", "integrity": "sha512-iKnFXr7NkdZAIHiIWE+BX5ULi/ucVFYWD6TbAV+rZctiRTY2PL6tsIKhoIOaoskiWAkgu+VsbXgUVDNLHf+InQ==", - "dev": true, "dependencies": { "estree-walker": "^2.0.1", "picomatch": "^2.2.2" @@ -6440,7 +6402,6 @@ "cpu": [ "arm" ], - "dev": true, "optional": true, "os": [ "android" @@ -6453,7 +6414,6 @@ "cpu": [ "arm64" ], - "dev": true, "optional": true, "os": [ "android" @@ -6466,7 +6426,6 @@ "cpu": [ "arm64" ], - "dev": true, "optional": true, "os": [ "darwin" @@ -6479,7 +6438,6 @@ "cpu": [ "x64" ], - "dev": true, "optional": true, "os": [ "darwin" @@ -6492,7 +6450,6 @@ "cpu": [ "arm" ], - "dev": true, "optional": true, "os": [ "linux" @@ -6505,7 +6462,6 @@ "cpu": [ "arm" ], - "dev": true, "optional": true, "os": [ "linux" @@ -6518,7 +6474,6 @@ "cpu": [ "arm64" ], - "dev": true, "optional": true, "os": [ "linux" @@ -6531,7 +6486,6 @@ "cpu": [ "arm64" ], - "dev": true, "optional": true, "os": [ "linux" @@ -6544,7 +6498,6 @@ "cpu": [ "ppc64" ], - "dev": true, "optional": true, "os": [ "linux" @@ -6557,7 +6510,6 @@ "cpu": [ "riscv64" ], - "dev": true, "optional": true, "os": [ "linux" @@ -6570,7 +6522,6 @@ "cpu": [ "s390x" ], - "dev": true, "optional": true, "os": [ "linux" @@ -6583,7 +6534,6 @@ "cpu": [ "x64" ], - "dev": true, "optional": true, "os": [ "linux" @@ -6596,7 +6546,6 @@ "cpu": [ "x64" ], - "dev": true, "optional": true, "os": [ "linux" @@ -6609,7 +6558,6 @@ "cpu": [ "arm64" ], - "dev": true, "optional": true, "os": [ "win32" @@ -6622,7 +6570,6 @@ "cpu": [ "ia32" ], - "dev": true, "optional": true, "os": [ "win32" @@ -6635,7 +6582,6 @@ "cpu": [ "x64" ], - "dev": true, "optional": true, "os": [ "win32" @@ -7164,11 +7110,20 @@ "version": "0.5.11", "resolved": "https://registry.npmjs.org/@swc/helpers/-/helpers-0.5.11.tgz", "integrity": "sha512-YNlnKRWF2sVojTpIyzwou9XoTNbzbzONwRhOoniEioF1AtaitTvVZblaQRrAzChWQ1bLYyYSWzM18y4WwgzJ+A==", - "dev": true, + "devOptional": true, "dependencies": { "tslib": "^2.4.0" } }, + "node_modules/@swc/types": { + "version": "0.1.9", + "resolved": "https://registry.npmjs.org/@swc/types/-/types-0.1.9.tgz", + "integrity": "sha512-qKnCno++jzcJ4lM4NTfYifm1EFSCeIfKiAHAfkENZAV5Kl9PjJIyd2yeeVv6c/2CckuLyv2NmRC5pv6pm2WQBg==", + "peer": true, + "dependencies": { + "@swc/counter": "^0.1.3" + } + }, "node_modules/@terraformer/arcgis": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/@terraformer/arcgis/-/arcgis-2.1.2.tgz", @@ -7216,25 +7171,25 @@ "version": "1.0.11", "resolved": "https://registry.npmjs.org/@tsconfig/node10/-/node10-1.0.11.tgz", "integrity": "sha512-DcRjDCujK/kCk/cUe8Xz8ZSpm8mS3mNNpta+jGCA6USEDfktlNvm1+IuZ9eTcDbNk41BHwpHHeW+N1lKCz4zOw==", - "dev": true + "devOptional": true }, "node_modules/@tsconfig/node12": { "version": "1.0.11", "resolved": "https://registry.npmjs.org/@tsconfig/node12/-/node12-1.0.11.tgz", "integrity": "sha512-cqefuRsh12pWyGsIoBKJA9luFu3mRxCA+ORZvA4ktLSzIuCUtWVxGIuXigEwO5/ywWFMZ2QEGKWvkZG1zDMTag==", - "dev": true + "devOptional": true }, "node_modules/@tsconfig/node14": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/@tsconfig/node14/-/node14-1.0.3.tgz", "integrity": "sha512-ysT8mhdixWK6Hw3i1V2AeRqZ5WfXg1G43mqoYlM2nc6388Fq5jcXyr5mRsqViLx/GJYdoL0bfXD8nmF+Zn/Iow==", - "dev": true + "devOptional": true }, "node_modules/@tsconfig/node16": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/@tsconfig/node16/-/node16-1.0.4.tgz", "integrity": "sha512-vxhUy4J8lyeyinH7Azl1pdd43GJhZH/tP2weN8TntQblOY+A0XbT8DJk1/oCPuOOyg/Ja757rG0CgHcWC8OfMA==", - "dev": true + "devOptional": true }, "node_modules/@types/arcgis-rest-api": { "version": "10.4.8", @@ -7412,7 +7367,6 @@ "version": "7.4.3", "resolved": "https://registry.npmjs.org/@types/d3/-/d3-7.4.3.tgz", "integrity": "sha512-lZXZ9ckh5R8uiFVt8ogUNf+pIrK4EsWrx2Np75WvF/eTpJ0FMHNhjXk8CKEx/+gpHbNQyJWehbFaTvqmHWB3ww==", - "dev": true, "dependencies": { "@types/d3-array": "*", "@types/d3-axis": "*", @@ -7449,14 +7403,12 @@ "node_modules/@types/d3-array": { "version": "3.2.1", "resolved": "https://registry.npmjs.org/@types/d3-array/-/d3-array-3.2.1.tgz", - "integrity": "sha512-Y2Jn2idRrLzUfAKV2LyRImR+y4oa2AntrgID95SHJxuMUrkNXmanDSed71sRNZysveJVt1hLLemQZIady0FpEg==", - "dev": true + "integrity": "sha512-Y2Jn2idRrLzUfAKV2LyRImR+y4oa2AntrgID95SHJxuMUrkNXmanDSed71sRNZysveJVt1hLLemQZIady0FpEg==" }, "node_modules/@types/d3-axis": { "version": "3.0.6", "resolved": "https://registry.npmjs.org/@types/d3-axis/-/d3-axis-3.0.6.tgz", "integrity": "sha512-pYeijfZuBd87T0hGn0FO1vQ/cgLk6E1ALJjfkC0oJ8cbwkZl3TpgS8bVBLZN+2jjGgg38epgxb2zmoGtSfvgMw==", - "dev": true, "dependencies": { "@types/d3-selection": "*" } @@ -7465,7 +7417,6 @@ "version": "3.0.6", "resolved": "https://registry.npmjs.org/@types/d3-brush/-/d3-brush-3.0.6.tgz", "integrity": "sha512-nH60IZNNxEcrh6L1ZSMNA28rj27ut/2ZmI3r96Zd+1jrZD++zD3LsMIjWlvg4AYrHn/Pqz4CF3veCxGjtbqt7A==", - "dev": true, "dependencies": { "@types/d3-selection": "*" } @@ -7473,20 +7424,17 @@ "node_modules/@types/d3-chord": { "version": "3.0.6", "resolved": "https://registry.npmjs.org/@types/d3-chord/-/d3-chord-3.0.6.tgz", - "integrity": "sha512-LFYWWd8nwfwEmTZG9PfQxd17HbNPksHBiJHaKuY1XeqscXacsS2tyoo6OdRsjf+NQYeB6XrNL3a25E3gH69lcg==", - "dev": true + "integrity": "sha512-LFYWWd8nwfwEmTZG9PfQxd17HbNPksHBiJHaKuY1XeqscXacsS2tyoo6OdRsjf+NQYeB6XrNL3a25E3gH69lcg==" }, "node_modules/@types/d3-color": { "version": "3.1.3", "resolved": "https://registry.npmjs.org/@types/d3-color/-/d3-color-3.1.3.tgz", - "integrity": "sha512-iO90scth9WAbmgv7ogoq57O9YpKmFBbmoEoCHDB2xMBY0+/KVrqAaCDyCE16dUspeOvIxFFRI+0sEtqDqy2b4A==", - "dev": true + "integrity": "sha512-iO90scth9WAbmgv7ogoq57O9YpKmFBbmoEoCHDB2xMBY0+/KVrqAaCDyCE16dUspeOvIxFFRI+0sEtqDqy2b4A==" }, "node_modules/@types/d3-contour": { "version": "3.0.6", "resolved": "https://registry.npmjs.org/@types/d3-contour/-/d3-contour-3.0.6.tgz", "integrity": "sha512-BjzLgXGnCWjUSYGfH1cpdo41/hgdWETu4YxpezoztawmqsvCeep+8QGfiY6YbDvfgHz/DkjeIkkZVJavB4a3rg==", - "dev": true, "dependencies": { "@types/d3-array": "*", "@types/geojson": "*" @@ -7495,20 +7443,17 @@ "node_modules/@types/d3-delaunay": { "version": "6.0.4", "resolved": "https://registry.npmjs.org/@types/d3-delaunay/-/d3-delaunay-6.0.4.tgz", - "integrity": "sha512-ZMaSKu4THYCU6sV64Lhg6qjf1orxBthaC161plr5KuPHo3CNm8DTHiLw/5Eq2b6TsNP0W0iJrUOFscY6Q450Hw==", - "dev": true + "integrity": "sha512-ZMaSKu4THYCU6sV64Lhg6qjf1orxBthaC161plr5KuPHo3CNm8DTHiLw/5Eq2b6TsNP0W0iJrUOFscY6Q450Hw==" }, "node_modules/@types/d3-dispatch": { "version": "3.0.6", "resolved": "https://registry.npmjs.org/@types/d3-dispatch/-/d3-dispatch-3.0.6.tgz", - "integrity": "sha512-4fvZhzMeeuBJYZXRXrRIQnvUYfyXwYmLsdiN7XXmVNQKKw1cM8a5WdID0g1hVFZDqT9ZqZEY5pD44p24VS7iZQ==", - "dev": true + "integrity": "sha512-4fvZhzMeeuBJYZXRXrRIQnvUYfyXwYmLsdiN7XXmVNQKKw1cM8a5WdID0g1hVFZDqT9ZqZEY5pD44p24VS7iZQ==" }, "node_modules/@types/d3-drag": { "version": "3.0.7", "resolved": "https://registry.npmjs.org/@types/d3-drag/-/d3-drag-3.0.7.tgz", "integrity": "sha512-HE3jVKlzU9AaMazNufooRJ5ZpWmLIoc90A37WU2JMmeq28w1FQqCZswHZ3xR+SuxYftzHq6WU6KJHvqxKzTxxQ==", - "dev": true, "dependencies": { "@types/d3-selection": "*" } @@ -7516,20 +7461,17 @@ "node_modules/@types/d3-dsv": { "version": "3.0.7", "resolved": "https://registry.npmjs.org/@types/d3-dsv/-/d3-dsv-3.0.7.tgz", - "integrity": "sha512-n6QBF9/+XASqcKK6waudgL0pf/S5XHPPI8APyMLLUHd8NqouBGLsU8MgtO7NINGtPBtk9Kko/W4ea0oAspwh9g==", - "dev": true + "integrity": "sha512-n6QBF9/+XASqcKK6waudgL0pf/S5XHPPI8APyMLLUHd8NqouBGLsU8MgtO7NINGtPBtk9Kko/W4ea0oAspwh9g==" }, "node_modules/@types/d3-ease": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/@types/d3-ease/-/d3-ease-3.0.2.tgz", - "integrity": "sha512-NcV1JjO5oDzoK26oMzbILE6HW7uVXOHLQvHshBUW4UMdZGfiY6v5BeQwh9a9tCzv+CeefZQHJt5SRgK154RtiA==", - "dev": true + "integrity": "sha512-NcV1JjO5oDzoK26oMzbILE6HW7uVXOHLQvHshBUW4UMdZGfiY6v5BeQwh9a9tCzv+CeefZQHJt5SRgK154RtiA==" }, "node_modules/@types/d3-fetch": { "version": "3.0.7", "resolved": "https://registry.npmjs.org/@types/d3-fetch/-/d3-fetch-3.0.7.tgz", "integrity": "sha512-fTAfNmxSb9SOWNB9IoG5c8Hg6R+AzUHDRlsXsDZsNp6sxAEOP0tkP3gKkNSO/qmHPoBFTxNrjDprVHDQDvo5aA==", - "dev": true, "dependencies": { "@types/d3-dsv": "*" } @@ -7537,20 +7479,17 @@ "node_modules/@types/d3-force": { "version": "3.0.10", "resolved": "https://registry.npmjs.org/@types/d3-force/-/d3-force-3.0.10.tgz", - "integrity": "sha512-ZYeSaCF3p73RdOKcjj+swRlZfnYpK1EbaDiYICEEp5Q6sUiqFaFQ9qgoshp5CzIyyb/yD09kD9o2zEltCexlgw==", - "dev": true + "integrity": "sha512-ZYeSaCF3p73RdOKcjj+swRlZfnYpK1EbaDiYICEEp5Q6sUiqFaFQ9qgoshp5CzIyyb/yD09kD9o2zEltCexlgw==" }, "node_modules/@types/d3-format": { "version": "3.0.4", "resolved": "https://registry.npmjs.org/@types/d3-format/-/d3-format-3.0.4.tgz", - "integrity": "sha512-fALi2aI6shfg7vM5KiR1wNJnZ7r6UuggVqtDA+xiEdPZQwy/trcQaHnwShLuLdta2rTymCNpxYTiMZX/e09F4g==", - "dev": true + "integrity": "sha512-fALi2aI6shfg7vM5KiR1wNJnZ7r6UuggVqtDA+xiEdPZQwy/trcQaHnwShLuLdta2rTymCNpxYTiMZX/e09F4g==" }, "node_modules/@types/d3-geo": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/@types/d3-geo/-/d3-geo-3.1.0.tgz", "integrity": "sha512-856sckF0oP/diXtS4jNsiQw/UuK5fQG8l/a9VVLeSouf1/PPbBE1i1W852zVwKwYCBkFJJB7nCFTbk6UMEXBOQ==", - "dev": true, "dependencies": { "@types/geojson": "*" } @@ -7558,14 +7497,12 @@ "node_modules/@types/d3-hierarchy": { "version": "3.1.7", "resolved": "https://registry.npmjs.org/@types/d3-hierarchy/-/d3-hierarchy-3.1.7.tgz", - "integrity": "sha512-tJFtNoYBtRtkNysX1Xq4sxtjK8YgoWUNpIiUee0/jHGRwqvzYxkq0hGVbbOGSz+JgFxxRu4K8nb3YpG3CMARtg==", - "dev": true + "integrity": "sha512-tJFtNoYBtRtkNysX1Xq4sxtjK8YgoWUNpIiUee0/jHGRwqvzYxkq0hGVbbOGSz+JgFxxRu4K8nb3YpG3CMARtg==" }, "node_modules/@types/d3-interpolate": { "version": "3.0.4", "resolved": "https://registry.npmjs.org/@types/d3-interpolate/-/d3-interpolate-3.0.4.tgz", "integrity": "sha512-mgLPETlrpVV1YRJIglr4Ez47g7Yxjl1lj7YKsiMCb27VJH9W8NVM6Bb9d8kkpG/uAQS5AmbA48q2IAolKKo1MA==", - "dev": true, "dependencies": { "@types/d3-color": "*" } @@ -7573,32 +7510,27 @@ "node_modules/@types/d3-path": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/@types/d3-path/-/d3-path-3.1.0.tgz", - "integrity": "sha512-P2dlU/q51fkOc/Gfl3Ul9kicV7l+ra934qBFXCFhrZMOL6du1TM0pm1ThYvENukyOn5h9v+yMJ9Fn5JK4QozrQ==", - "dev": true + "integrity": "sha512-P2dlU/q51fkOc/Gfl3Ul9kicV7l+ra934qBFXCFhrZMOL6du1TM0pm1ThYvENukyOn5h9v+yMJ9Fn5JK4QozrQ==" }, "node_modules/@types/d3-polygon": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/@types/d3-polygon/-/d3-polygon-3.0.2.tgz", - "integrity": "sha512-ZuWOtMaHCkN9xoeEMr1ubW2nGWsp4nIql+OPQRstu4ypeZ+zk3YKqQT0CXVe/PYqrKpZAi+J9mTs05TKwjXSRA==", - "dev": true + "integrity": "sha512-ZuWOtMaHCkN9xoeEMr1ubW2nGWsp4nIql+OPQRstu4ypeZ+zk3YKqQT0CXVe/PYqrKpZAi+J9mTs05TKwjXSRA==" }, "node_modules/@types/d3-quadtree": { "version": "3.0.6", "resolved": "https://registry.npmjs.org/@types/d3-quadtree/-/d3-quadtree-3.0.6.tgz", - "integrity": "sha512-oUzyO1/Zm6rsxKRHA1vH0NEDG58HrT5icx/azi9MF1TWdtttWl0UIUsjEQBBh+SIkrpd21ZjEv7ptxWys1ncsg==", - "dev": true + "integrity": "sha512-oUzyO1/Zm6rsxKRHA1vH0NEDG58HrT5icx/azi9MF1TWdtttWl0UIUsjEQBBh+SIkrpd21ZjEv7ptxWys1ncsg==" }, "node_modules/@types/d3-random": { "version": "3.0.3", "resolved": "https://registry.npmjs.org/@types/d3-random/-/d3-random-3.0.3.tgz", - "integrity": "sha512-Imagg1vJ3y76Y2ea0871wpabqp613+8/r0mCLEBfdtqC7xMSfj9idOnmBYyMoULfHePJyxMAw3nWhJxzc+LFwQ==", - "dev": true + "integrity": "sha512-Imagg1vJ3y76Y2ea0871wpabqp613+8/r0mCLEBfdtqC7xMSfj9idOnmBYyMoULfHePJyxMAw3nWhJxzc+LFwQ==" }, "node_modules/@types/d3-scale": { "version": "4.0.8", "resolved": "https://registry.npmjs.org/@types/d3-scale/-/d3-scale-4.0.8.tgz", "integrity": "sha512-gkK1VVTr5iNiYJ7vWDI+yUFFlszhNMtVeneJ6lUTKPjprsvLLI9/tgEGiXJOnlINJA8FyA88gfnQsHbybVZrYQ==", - "dev": true, "dependencies": { "@types/d3-time": "*" } @@ -7606,20 +7538,17 @@ "node_modules/@types/d3-scale-chromatic": { "version": "3.0.3", "resolved": "https://registry.npmjs.org/@types/d3-scale-chromatic/-/d3-scale-chromatic-3.0.3.tgz", - "integrity": "sha512-laXM4+1o5ImZv3RpFAsTRn3TEkzqkytiOY0Dz0sq5cnd1dtNlk6sHLon4OvqaiJb28T0S/TdsBI3Sjsy+keJrw==", - "dev": true + "integrity": "sha512-laXM4+1o5ImZv3RpFAsTRn3TEkzqkytiOY0Dz0sq5cnd1dtNlk6sHLon4OvqaiJb28T0S/TdsBI3Sjsy+keJrw==" }, "node_modules/@types/d3-selection": { "version": "3.0.10", "resolved": "https://registry.npmjs.org/@types/d3-selection/-/d3-selection-3.0.10.tgz", - "integrity": "sha512-cuHoUgS/V3hLdjJOLTT691+G2QoqAjCVLmr4kJXR4ha56w1Zdu8UUQ5TxLRqudgNjwXeQxKMq4j+lyf9sWuslg==", - "dev": true + "integrity": "sha512-cuHoUgS/V3hLdjJOLTT691+G2QoqAjCVLmr4kJXR4ha56w1Zdu8UUQ5TxLRqudgNjwXeQxKMq4j+lyf9sWuslg==" }, "node_modules/@types/d3-shape": { "version": "3.1.6", "resolved": "https://registry.npmjs.org/@types/d3-shape/-/d3-shape-3.1.6.tgz", "integrity": "sha512-5KKk5aKGu2I+O6SONMYSNflgiP0WfZIQvVUMan50wHsLG1G94JlxEVnCpQARfTtzytuY0p/9PXXZb3I7giofIA==", - "dev": true, "dependencies": { "@types/d3-path": "*" } @@ -7627,26 +7556,22 @@ "node_modules/@types/d3-time": { "version": "3.0.3", "resolved": "https://registry.npmjs.org/@types/d3-time/-/d3-time-3.0.3.tgz", - "integrity": "sha512-2p6olUZ4w3s+07q3Tm2dbiMZy5pCDfYwtLXXHUnVzXgQlZ/OyPtUz6OL382BkOuGlLXqfT+wqv8Fw2v8/0geBw==", - "dev": true + "integrity": "sha512-2p6olUZ4w3s+07q3Tm2dbiMZy5pCDfYwtLXXHUnVzXgQlZ/OyPtUz6OL382BkOuGlLXqfT+wqv8Fw2v8/0geBw==" }, "node_modules/@types/d3-time-format": { "version": "4.0.3", "resolved": "https://registry.npmjs.org/@types/d3-time-format/-/d3-time-format-4.0.3.tgz", - "integrity": "sha512-5xg9rC+wWL8kdDj153qZcsJ0FWiFt0J5RB6LYUNZjwSnesfblqrI/bJ1wBdJ8OQfncgbJG5+2F+qfqnqyzYxyg==", - "dev": true + "integrity": "sha512-5xg9rC+wWL8kdDj153qZcsJ0FWiFt0J5RB6LYUNZjwSnesfblqrI/bJ1wBdJ8OQfncgbJG5+2F+qfqnqyzYxyg==" }, "node_modules/@types/d3-timer": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/@types/d3-timer/-/d3-timer-3.0.2.tgz", - "integrity": "sha512-Ps3T8E8dZDam6fUyNiMkekK3XUsaUEik+idO9/YjPtfj2qruF8tFBXS7XhtE4iIXBLxhmLjP3SXpLhVf21I9Lw==", - "dev": true + "integrity": "sha512-Ps3T8E8dZDam6fUyNiMkekK3XUsaUEik+idO9/YjPtfj2qruF8tFBXS7XhtE4iIXBLxhmLjP3SXpLhVf21I9Lw==" }, "node_modules/@types/d3-transition": { "version": "3.0.8", "resolved": "https://registry.npmjs.org/@types/d3-transition/-/d3-transition-3.0.8.tgz", "integrity": "sha512-ew63aJfQ/ms7QQ4X7pk5NxQ9fZH/z+i24ZfJ6tJSfqxJMrYLiK01EAs2/Rtw/JreGUsS3pLPNV644qXFGnoZNQ==", - "dev": true, "dependencies": { "@types/d3-selection": "*" } @@ -7655,7 +7580,6 @@ "version": "3.0.8", "resolved": "https://registry.npmjs.org/@types/d3-zoom/-/d3-zoom-3.0.8.tgz", "integrity": "sha512-iqMC4/YlFCSlO8+2Ii1GGGliCAY4XdeG748w5vQUbevlbDu0zSjH/+jojorQVBK/se0j6DUFNPBGSqD3YWYnDw==", - "dev": true, "dependencies": { "@types/d3-interpolate": "*", "@types/d3-selection": "*" @@ -7684,8 +7608,7 @@ "node_modules/@types/estree": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.5.tgz", - "integrity": "sha512-/kYRxGDLWzHOB7q+wtSUQlFrtcdUccpfy+X+9iMBpHK8QLLhx2wIPYuS5DYtR9Wa/YlZAbIovy7qVdB1Aq6Lyw==", - "dev": true + "integrity": "sha512-/kYRxGDLWzHOB7q+wtSUQlFrtcdUccpfy+X+9iMBpHK8QLLhx2wIPYuS5DYtR9Wa/YlZAbIovy7qVdB1Aq6Lyw==" }, "node_modules/@types/express": { "version": "4.17.21", @@ -7733,8 +7656,7 @@ "node_modules/@types/geojson": { "version": "7946.0.14", "resolved": "https://registry.npmjs.org/@types/geojson/-/geojson-7946.0.14.tgz", - "integrity": "sha512-WCfD5Ht3ZesJUsONdhvm84dmzWOiOzOAqOncN0++w0lBw1o8OuDNJF2McvvCef/yBqb/HYRahp1BYtODFQ8bRg==", - "dev": true + "integrity": "sha512-WCfD5Ht3ZesJUsONdhvm84dmzWOiOzOAqOncN0++w0lBw1o8OuDNJF2McvvCef/yBqb/HYRahp1BYtODFQ8bRg==" }, "node_modules/@types/google.maps": { "version": "3.55.11", @@ -7852,14 +7774,12 @@ "node_modules/@types/json-schema": { "version": "7.0.15", "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.15.tgz", - "integrity": "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==", - "dev": true + "integrity": "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==" }, "node_modules/@types/json5": { "version": "0.0.29", "resolved": "https://registry.npmjs.org/@types/json5/-/json5-0.0.29.tgz", - "integrity": "sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ==", - "dev": true + "integrity": "sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ==" }, "node_modules/@types/long": { "version": "4.0.2", @@ -7915,8 +7835,7 @@ "node_modules/@types/pug": { "version": "2.0.10", "resolved": "https://registry.npmjs.org/@types/pug/-/pug-2.0.10.tgz", - "integrity": "sha512-Sk/uYFOBAB7mb74XcpizmH0KOR2Pv3D2Hmrh1Dmy5BmK3MpdSa5kqZcg6EKBdklU0bFXX9gCfzvpnyUehrPIuA==", - "dev": true + "integrity": "sha512-Sk/uYFOBAB7mb74XcpizmH0KOR2Pv3D2Hmrh1Dmy5BmK3MpdSa5kqZcg6EKBdklU0bFXX9gCfzvpnyUehrPIuA==" }, "node_modules/@types/qs": { "version": "6.9.15", @@ -7963,8 +7882,7 @@ "node_modules/@types/resolve": { "version": "1.20.2", "resolved": "https://registry.npmjs.org/@types/resolve/-/resolve-1.20.2.tgz", - "integrity": "sha512-60BCwRFOZCQhDncwQdxxeOEEkbc5dIMccYLwbxsS4TUNeVECQ/pBJ0j09mrHOl/JJvpRPGwO9SvE4nR2Nb/a4Q==", - "dev": true + "integrity": "sha512-60BCwRFOZCQhDncwQdxxeOEEkbc5dIMccYLwbxsS4TUNeVECQ/pBJ0j09mrHOl/JJvpRPGwO9SvE4nR2Nb/a4Q==" }, "node_modules/@types/retry": { "version": "0.12.0", @@ -7977,7 +7895,6 @@ "resolved": "https://registry.npmjs.org/@types/rollup/-/rollup-0.54.0.tgz", "integrity": "sha512-oeYztLHhQ98jnr+u2cs1c3tHOGtpzrm9DJlIdEjznwoXWidUbrI+X6ib7zCkPIbB7eJ7VbbKNQ5n/bPnSg6Naw==", "deprecated": "This is a stub types definition for rollup (https://github.com/rollup/rollup). rollup provides its own type definitions, so you don't need @types/rollup installed!", - "dev": true, "dependencies": { "rollup": "*" } @@ -7985,8 +7902,7 @@ "node_modules/@types/semver": { "version": "7.5.8", "resolved": "https://registry.npmjs.org/@types/semver/-/semver-7.5.8.tgz", - "integrity": "sha512-I8EUhyrgfLrcTkzV3TSsGyl1tSuPrEDzr0yd5m90UgNxQkyDXULk3b6MlQqTCpZpNtWe1K0hzclnZkTcLBe2UQ==", - "dev": true + "integrity": "sha512-I8EUhyrgfLrcTkzV3TSsGyl1tSuPrEDzr0yd5m90UgNxQkyDXULk3b6MlQqTCpZpNtWe1K0hzclnZkTcLBe2UQ==" }, "node_modules/@types/send": { "version": "0.17.4", @@ -8344,8 +8260,7 @@ "node_modules/@ungap/structured-clone": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/@ungap/structured-clone/-/structured-clone-1.2.0.tgz", - "integrity": "sha512-zuVdFrMJiuCDQUMCzQaD6KL28MjnqqN8XnAqiEq9PNm/hCPTSGfrXCOfwj1ow4LFb/tNymJPwsNbVePc1xFqrQ==", - "dev": true + "integrity": "sha512-zuVdFrMJiuCDQUMCzQaD6KL28MjnqqN8XnAqiEq9PNm/hCPTSGfrXCOfwj1ow4LFb/tNymJPwsNbVePc1xFqrQ==" }, "node_modules/@vaadin/a11y-base": { "version": "24.3.15", @@ -8995,7 +8910,6 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/@windycom/plugin-devtools/-/plugin-devtools-2.0.0.tgz", "integrity": "sha512-S+67Xrkav0+pL/tk6OzwjGN40oiHjDiZpibO5KkskoNGSc6z4g8R++xQIV+Uw3FEMx7fi7JFqBSuZQz8zeM2eg==", - "dev": true, "dependencies": { "@rollup/plugin-commonjs": "^25.0.7", "@rollup/plugin-node-resolve": "^15.2.3", @@ -9033,7 +8947,6 @@ "version": "6.21.0", "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-6.21.0.tgz", "integrity": "sha512-oy9+hTPCUFpngkEZUSzbf9MxI65wbKFoQYsgPdILTfbUldp5ovUuphZVe4i30emU9M/kP+T64Di0mxl7dSw3MA==", - "dev": true, "dependencies": { "@eslint-community/regexpp": "^4.5.1", "@typescript-eslint/scope-manager": "6.21.0", @@ -9068,7 +8981,6 @@ "version": "6.21.0", "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-6.21.0.tgz", "integrity": "sha512-tbsV1jPne5CkFQCgPBcDOt30ItF7aJoZL997JSF7MhGQqOeT3svWRYxiqlfA5RUdlHN6Fi+EI9bxqbdyAUZjYQ==", - "dev": true, "dependencies": { "@typescript-eslint/scope-manager": "6.21.0", "@typescript-eslint/types": "6.21.0", @@ -9096,7 +9008,6 @@ "version": "6.21.0", "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-6.21.0.tgz", "integrity": "sha512-OwLUIWZJry80O99zvqXVEioyniJMa+d2GrqpUTqi5/v5D5rOrppJVBPa0yKCblcigC0/aYAzxxqQ1B+DS2RYsg==", - "dev": true, "dependencies": { "@typescript-eslint/types": "6.21.0", "@typescript-eslint/visitor-keys": "6.21.0" @@ -9113,7 +9024,6 @@ "version": "6.21.0", "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-6.21.0.tgz", "integrity": "sha512-rZQI7wHfao8qMX3Rd3xqeYSMCL3SoiSQLBATSiVKARdFGCYSRvmViieZjqc58jKgs8Y8i9YvVVhRbHSTA4VBag==", - "dev": true, "dependencies": { "@typescript-eslint/typescript-estree": "6.21.0", "@typescript-eslint/utils": "6.21.0", @@ -9140,7 +9050,6 @@ "version": "6.21.0", "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-6.21.0.tgz", "integrity": "sha512-1kFmZ1rOm5epu9NZEZm1kckCDGj5UJEf7P1kliH4LKu/RkwpsfqqGmY2OOcUs18lSlQBKLDYBOGxRVtrMN5lpg==", - "dev": true, "engines": { "node": "^16.0.0 || >=18.0.0" }, @@ -9153,7 +9062,6 @@ "version": "6.21.0", "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-6.21.0.tgz", "integrity": "sha512-6npJTkZcO+y2/kr+z0hc4HwNfrrP4kNYh57ek7yCNlrBjWQ1Y0OS7jiZTkgumrvkX5HkEKXFZkkdFNkaW2wmUQ==", - "dev": true, "dependencies": { "@typescript-eslint/types": "6.21.0", "@typescript-eslint/visitor-keys": "6.21.0", @@ -9181,7 +9089,6 @@ "version": "6.21.0", "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-6.21.0.tgz", "integrity": "sha512-NfWVaC8HP9T8cbKQxHcsJBY5YE1O33+jpMwN45qzWWaPDZgLIbo12toGMWnmhvCpd3sIxkpDw3Wv1B3dYrbDQQ==", - "dev": true, "dependencies": { "@eslint-community/eslint-utils": "^4.4.0", "@types/json-schema": "^7.0.12", @@ -9206,7 +9113,6 @@ "version": "6.21.0", "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-6.21.0.tgz", "integrity": "sha512-JJtkDduxLi9bivAB+cYOVMtbkqdPOhZ+ZI5LC47MIRrDV4Yn2o+ZnW10Nkmr28xRpSpdJ6Sm42Hjf2+REYXm0A==", - "dev": true, "dependencies": { "@typescript-eslint/types": "6.21.0", "eslint-visitor-keys": "^3.4.1" @@ -9219,12 +9125,22 @@ "url": "https://opencollective.com/typescript-eslint" } }, + "node_modules/@windycom/plugin-devtools/node_modules/brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "optional": true, + "peer": true, + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, "node_modules/@windycom/plugin-devtools/node_modules/eslint-config-standard-with-typescript": { "version": "43.0.1", "resolved": "https://registry.npmjs.org/eslint-config-standard-with-typescript/-/eslint-config-standard-with-typescript-43.0.1.tgz", "integrity": "sha512-WfZ986+qzIzX6dcr4yGUyVb/l9N3Z8wPXCc5z/70fljs3UbWhhV+WxrfgsqMToRzuuyX9MqZ974pq2UPhDTOcA==", "deprecated": "Please use eslint-config-love, instead.", - "dev": true, "dependencies": { "@typescript-eslint/parser": "^6.4.0", "eslint-config-standard": "17.1.0" @@ -9238,11 +9154,45 @@ "typescript": "*" } }, + "node_modules/@windycom/plugin-devtools/node_modules/glob": { + "version": "7.2.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", + "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", + "deprecated": "Glob versions prior to v9 are no longer supported", + "optional": true, + "peer": true, + "dependencies": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.1.1", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + }, + "engines": { + "node": "*" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/@windycom/plugin-devtools/node_modules/glob/node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "optional": true, + "peer": true, + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, "node_modules/@windycom/plugin-devtools/node_modules/less": { "version": "4.2.0", "resolved": "https://registry.npmjs.org/less/-/less-4.2.0.tgz", "integrity": "sha512-P3b3HJDBtSzsXUl0im2L7gTO5Ubg8mEN6G8qoTS77iXxXX4Hvu4Qj540PZDvQ8V6DmX6iXo98k7Md0Cm1PrLaA==", - "dev": true, "dependencies": { "copy-anything": "^2.0.1", "parse-node-version": "^1.0.1", @@ -9268,7 +9218,6 @@ "version": "0.6.1", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "dev": true, "optional": true, "engines": { "node": ">=0.10.0" @@ -9278,7 +9227,6 @@ "version": "2.1.0", "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-2.1.0.tgz", "integrity": "sha512-LS9X+dc8KLxXCb8dni79fLIIUA5VyZoyjSMCwTluaXA0o27cCK0bhXkpgw+sTXVpPy/lSO57ilRixqk0vDmtRA==", - "dev": true, "optional": true, "dependencies": { "pify": "^4.0.1", @@ -9292,7 +9240,6 @@ "version": "5.7.2", "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz", "integrity": "sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==", - "dev": true, "optional": true, "bin": { "semver": "bin/semver" @@ -9302,7 +9249,6 @@ "version": "1.6.0", "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==", - "dev": true, "optional": true, "bin": { "mime": "cli.js" @@ -9311,11 +9257,30 @@ "node": ">=4" } }, + "node_modules/@windycom/plugin-devtools/node_modules/mkdirp": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz", + "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==", + "optional": true, + "peer": true, + "bin": { + "mkdirp": "bin/cmd.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/@windycom/plugin-devtools/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", + "optional": true, + "peer": true + }, "node_modules/@windycom/plugin-devtools/node_modules/pify": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/pify/-/pify-4.0.1.tgz", "integrity": "sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==", - "dev": true, "optional": true, "engines": { "node": ">=6" @@ -9325,7 +9290,6 @@ "version": "3.3.2", "resolved": "https://registry.npmjs.org/prettier/-/prettier-3.3.2.tgz", "integrity": "sha512-rAVeHYMcv8ATV5d508CFdn+8/pHPpXeIid1DdrPwXnaAdH7cqjVbpJaT5eq4yRAFU/lsbwYwSF/n5iNrdJHPQA==", - "dev": true, "bin": { "prettier": "bin/prettier.cjs" }, @@ -9340,7 +9304,6 @@ "version": "3.2.5", "resolved": "https://registry.npmjs.org/prettier-plugin-svelte/-/prettier-plugin-svelte-3.2.5.tgz", "integrity": "sha512-vP/M/Goc8z4iVIvrwXwbrYVjJgA0Hf8PO1G4LBh/ocSt6vUP6sLvyu9F3ABEGr+dbKyxZjEKLkeFsWy/yYl0HQ==", - "dev": true, "peerDependencies": { "prettier": "^3.0.0", "svelte": "^3.2.0 || ^4.0.0-next.0 || ^5.0.0-next.0" @@ -9350,7 +9313,6 @@ "version": "4.18.1", "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.18.1.tgz", "integrity": "sha512-Elx2UT8lzxxOXMpy5HWQGZqkrQOtrVDDa/bm9l10+U4rQnVzbL/LgZ4NOM1MPIDyHk69W4InuYDF5dzRh4Kw1A==", - "dev": true, "dependencies": { "@types/estree": "1.0.5" }, @@ -9381,11 +9343,17 @@ "fsevents": "~2.3.2" } }, + "node_modules/@windycom/plugin-devtools/node_modules/sax": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/sax/-/sax-1.2.4.tgz", + "integrity": "sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw==", + "optional": true, + "peer": true + }, "node_modules/@windycom/plugin-devtools/node_modules/semver": { "version": "7.6.2", "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.2.tgz", "integrity": "sha512-FNAIBWCx9qcRhoHcgcJ0gvU7SN1lYU2ZXuSfl04bSC5OpvDHFyJCjdNHomPXxjQlCBU67YW64PzY7/VIEH7F2w==", - "dev": true, "bin": { "semver": "bin/semver.js" }, @@ -9393,11 +9361,53 @@ "node": ">=10" } }, + "node_modules/@windycom/plugin-devtools/node_modules/stylus": { + "version": "0.55.0", + "resolved": "https://registry.npmjs.org/stylus/-/stylus-0.55.0.tgz", + "integrity": "sha512-MuzIIVRSbc8XxHH7FjkvWqkIcr1BvoMZoR/oFuAJDlh7VSaNJzrB4uJ38GRQa+mWjLXODAMzeDe0xi9GYbGwnw==", + "optional": true, + "peer": true, + "dependencies": { + "css": "^3.0.0", + "debug": "~3.1.0", + "glob": "^7.1.6", + "mkdirp": "~1.0.4", + "safer-buffer": "^2.1.2", + "sax": "~1.2.4", + "semver": "^6.3.0", + "source-map": "^0.7.3" + }, + "bin": { + "stylus": "bin/stylus" + }, + "engines": { + "node": "*" + } + }, + "node_modules/@windycom/plugin-devtools/node_modules/stylus/node_modules/debug": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", + "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", + "optional": true, + "peer": true, + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/@windycom/plugin-devtools/node_modules/stylus/node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "optional": true, + "peer": true, + "bin": { + "semver": "bin/semver.js" + } + }, "node_modules/@windycom/plugin-devtools/node_modules/svelte-preprocess": { "version": "5.1.4", "resolved": "https://registry.npmjs.org/svelte-preprocess/-/svelte-preprocess-5.1.4.tgz", "integrity": "sha512-IvnbQ6D6Ao3Gg6ftiM5tdbR6aAETwjhHV+UKGf5bHGYR69RQvF1ho0JKPcbUON4vy4R7zom13jPjgdOWCQ5hDA==", - "dev": true, "hasInstallScript": true, "dependencies": { "@types/pug": "^2.0.6", @@ -9556,7 +9566,6 @@ "version": "8.12.1", "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.12.1.tgz", "integrity": "sha512-tcpGyI9zbizT9JbV6oYE477V6mTlXvvi0T0G3SNIYE2apm/G5huBa1+K89VGeovbg+jycCrfhl3ADxErOuO6Jg==", - "dev": true, "bin": { "acorn": "bin/acorn" }, @@ -9587,7 +9596,6 @@ "version": "5.3.2", "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz", "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==", - "dev": true, "peerDependencies": { "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" } @@ -9596,7 +9604,7 @@ "version": "8.3.3", "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.3.3.tgz", "integrity": "sha512-MxXdReSRhGO7VlFe1bRG/oI7/mdLV9B9JJT0N8vZOhF7gFRR5l3M8W9G8JxmKV+JC5mGqJ0QvqfSOLsCPa4nUw==", - "dev": true, + "devOptional": true, "dependencies": { "acorn": "^8.11.0" }, @@ -9742,7 +9750,7 @@ "version": "3.2.1", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "dev": true, + "devOptional": true, "dependencies": { "color-convert": "^1.9.0" }, @@ -9754,7 +9762,7 @@ "version": "3.1.3", "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz", "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==", - "dev": true, + "devOptional": true, "dependencies": { "normalize-path": "^3.0.0", "picomatch": "^2.0.4" @@ -9787,7 +9795,7 @@ "version": "4.1.3", "resolved": "https://registry.npmjs.org/arg/-/arg-4.1.3.tgz", "integrity": "sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==", - "dev": true + "devOptional": true }, "node_modules/argparse": { "version": "1.0.10", @@ -9801,7 +9809,6 @@ "version": "5.3.0", "resolved": "https://registry.npmjs.org/aria-query/-/aria-query-5.3.0.tgz", "integrity": "sha512-b0P0sZPKtyu8HkeRAfCq0IfURZK+SuwMjY1UXGBU27wpAiTwQAIlq56IbIO+ytk/JjS1fMR14ee5WBBfKi5J6A==", - "dev": true, "dependencies": { "dequal": "^2.0.3" } @@ -9810,7 +9817,6 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/array-buffer-byte-length/-/array-buffer-byte-length-1.0.1.tgz", "integrity": "sha512-ahC5W1xgou+KTXix4sAO8Ki12Q+jf4i0+tmk3sC+zgcynshkHxzpXdImBehiUYKKKDwvfFiJl1tZt6ewscS1Mg==", - "dev": true, "dependencies": { "call-bind": "^1.0.5", "is-array-buffer": "^3.0.4" @@ -9831,7 +9837,6 @@ "version": "3.1.8", "resolved": "https://registry.npmjs.org/array-includes/-/array-includes-3.1.8.tgz", "integrity": "sha512-itaWrbYbqpGXkGhZPGUulwnhVf5Hpy1xiCFsGqyIGglbBxmG5vSjxQen3/WGOjPpNEv1RtBLKxbmVXm8HpJStQ==", - "dev": true, "dependencies": { "call-bind": "^1.0.7", "define-properties": "^1.2.1", @@ -9851,7 +9856,6 @@ "version": "2.1.0", "resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz", "integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==", - "dev": true, "engines": { "node": ">=8" } @@ -9860,7 +9864,6 @@ "version": "1.2.5", "resolved": "https://registry.npmjs.org/array.prototype.findlastindex/-/array.prototype.findlastindex-1.2.5.tgz", "integrity": "sha512-zfETvRFA8o7EiNn++N5f/kaCw221hrpGsDmcpndVupkPzEc1Wuf3VgC0qby1BbHs7f5DVYjgtEU2LLh5bqeGfQ==", - "dev": true, "dependencies": { "call-bind": "^1.0.7", "define-properties": "^1.2.1", @@ -9880,7 +9883,6 @@ "version": "1.3.2", "resolved": "https://registry.npmjs.org/array.prototype.flat/-/array.prototype.flat-1.3.2.tgz", "integrity": "sha512-djYB+Zx2vLewY8RWlNCUdHjDXs2XOgm602S9E7P/UpHgfeHL00cRiIF+IN/G/aUJ7kGPb6yO/ErDI5V2s8iycA==", - "dev": true, "dependencies": { "call-bind": "^1.0.2", "define-properties": "^1.2.0", @@ -9898,7 +9900,6 @@ "version": "1.3.2", "resolved": "https://registry.npmjs.org/array.prototype.flatmap/-/array.prototype.flatmap-1.3.2.tgz", "integrity": "sha512-Ewyx0c9PmpcsByhSW4r+9zDU7sGjFc86qf/kKtuSCRdhfbk0SNLLkaT5qvcHnRGgc5NP/ly/y+qkXkqONX54CQ==", - "dev": true, "dependencies": { "call-bind": "^1.0.2", "define-properties": "^1.2.0", @@ -9916,7 +9917,6 @@ "version": "1.0.3", "resolved": "https://registry.npmjs.org/arraybuffer.prototype.slice/-/arraybuffer.prototype.slice-1.0.3.tgz", "integrity": "sha512-bMxMKAjg13EBSVscxTaYA4mRc5t1UAXa2kXiGTNfZ079HIWXEkKmkgFrh/nJqamaLSrXO5H4WFFkPEaLJWbs3A==", - "dev": true, "dependencies": { "array-buffer-byte-length": "^1.0.1", "call-bind": "^1.0.5", @@ -10035,6 +10035,19 @@ "node": ">= 4.0.0" } }, + "node_modules/atob": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/atob/-/atob-2.1.2.tgz", + "integrity": "sha512-Wm6ukoaOGJi/73p/cl2GvLjTI5JM1k/O14isD73YML8StrH/7/lRFgmg8nICZgD3bZZvjwCGxtMOD3wWNAu8cg==", + "optional": true, + "peer": true, + "bin": { + "atob": "bin/atob.js" + }, + "engines": { + "node": ">= 4.5.0" + } + }, "node_modules/autoprefixer": { "version": "10.4.19", "resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-10.4.19.tgz", @@ -10076,7 +10089,6 @@ "version": "1.0.7", "resolved": "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.7.tgz", "integrity": "sha512-wvUjBtSGN7+7SjNpq/9M2Tg350UZD3q62IFZLbRAR1bSMlCo1ZaeW+BJ+D090e4hIIZLBcTDWe4Mh4jvUDajzQ==", - "dev": true, "dependencies": { "possible-typed-array-names": "^1.0.0" }, @@ -10116,7 +10128,6 @@ "version": "4.0.0", "resolved": "https://registry.npmjs.org/axobject-query/-/axobject-query-4.0.0.tgz", "integrity": "sha512-+60uv1hiVFhHZeO+Lz0RYzsVHy5Wr1ayX0mwda9KPDVLNJgZ1T9Ny7VmFbLDzxsH0D87I86vgj3gFrjTJUYznw==", - "dev": true, "dependencies": { "dequal": "^2.0.3" } @@ -10544,7 +10555,7 @@ "version": "2.3.0", "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.3.0.tgz", "integrity": "sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==", - "dev": true, + "devOptional": true, "engines": { "node": ">=8" }, @@ -10684,7 +10695,6 @@ "version": "3.0.3", "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz", "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==", - "dev": true, "dependencies": { "fill-range": "^7.1.1" }, @@ -10702,7 +10712,6 @@ "version": "4.23.1", "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.23.1.tgz", "integrity": "sha512-TUfofFo/KsK/bWZ9TWQ5O26tsWW4Uhmt8IYklbnUa70udB6P2wA7w7o4PY4muaEPBQaAX+CEnmmIA41NVHtPVw==", - "dev": true, "funding": [ { "type": "opencollective", @@ -10798,7 +10807,6 @@ "version": "3.3.0", "resolved": "https://registry.npmjs.org/builtin-modules/-/builtin-modules-3.3.0.tgz", "integrity": "sha512-zhaCDicdLuWN5UbN5IMnFqNMhNfo919sH85y2/ea+5Yg9TsTkeZxpL+JLbp6cgYFS4sRLp3YV4S6yDuqVWHYOw==", - "dev": true, "engines": { "node": ">=6" }, @@ -10810,7 +10818,6 @@ "version": "5.1.0", "resolved": "https://registry.npmjs.org/builtins/-/builtins-5.1.0.tgz", "integrity": "sha512-SW9lzGTLvWTP1AY8xeAMZimqDrIaSdLQUcVr9DMef51niJ022Ri87SwRRKYm4A6iHfkPaiVUu/Duw2Wc4J7kKg==", - "dev": true, "dependencies": { "semver": "^7.0.0" } @@ -10819,7 +10826,6 @@ "version": "7.6.2", "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.2.tgz", "integrity": "sha512-FNAIBWCx9qcRhoHcgcJ0gvU7SN1lYU2ZXuSfl04bSC5OpvDHFyJCjdNHomPXxjQlCBU67YW64PzY7/VIEH7F2w==", - "dev": true, "bin": { "semver": "bin/semver.js" }, @@ -10886,7 +10892,6 @@ "version": "3.1.0", "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", - "dev": true, "engines": { "node": ">=6" } @@ -10925,7 +10930,6 @@ "version": "1.0.30001640", "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001640.tgz", "integrity": "sha512-lA4VMpW0PSUrFnkmVuEKBUovSWKhj7puyCg8StBChgu298N1AtuF1sKWEvfDuimSEDbhlb/KqPKC3fs1HbuQUA==", - "dev": true, "funding": [ { "type": "opencollective", @@ -10979,7 +10983,7 @@ "version": "2.4.2", "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", - "dev": true, + "devOptional": true, "dependencies": { "ansi-styles": "^3.2.1", "escape-string-regexp": "^1.0.5", @@ -11023,7 +11027,7 @@ "version": "3.6.0", "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.6.0.tgz", "integrity": "sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==", - "dev": true, + "devOptional": true, "dependencies": { "anymatch": "~3.1.2", "braces": "~3.0.2", @@ -11047,7 +11051,7 @@ "version": "5.1.2", "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", - "dev": true, + "devOptional": true, "dependencies": { "is-glob": "^4.0.1" }, @@ -11266,7 +11270,6 @@ "version": "1.0.4", "resolved": "https://registry.npmjs.org/code-red/-/code-red-1.0.4.tgz", "integrity": "sha512-7qJWqItLA8/VPVlKJlFXU+NBlo/qyfs39aJcuMT/2ere32ZqvF5OSxgdM5xOfJJ7O429gg2HM47y8v9P+9wrNw==", - "dev": true, "dependencies": { "@jridgewell/sourcemap-codec": "^1.4.15", "@types/estree": "^1.0.1", @@ -11279,7 +11282,6 @@ "version": "3.0.3", "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-3.0.3.tgz", "integrity": "sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g==", - "dev": true, "dependencies": { "@types/estree": "^1.0.0" } @@ -11314,7 +11316,7 @@ "version": "1.9.3", "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", - "dev": true, + "devOptional": true, "dependencies": { "color-name": "1.1.3" } @@ -11419,8 +11421,7 @@ "node_modules/commondir": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/commondir/-/commondir-1.0.1.tgz", - "integrity": "sha512-W9pAhw0ja1Edb5GVdIF1mjZw/ASI0AlShXM83UUGe2DVr5TdAPEA1OA8m/g8zWp9x6On7gqufY+FatDbC3MDQg==", - "dev": true + "integrity": "sha512-W9pAhw0ja1Edb5GVdIF1mjZw/ASI0AlShXM83UUGe2DVr5TdAPEA1OA8m/g8zWp9x6On7gqufY+FatDbC3MDQg==" }, "node_modules/composed-offset-position": { "version": "0.0.4", @@ -11576,7 +11577,7 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz", "integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==", - "dev": true + "devOptional": true }, "node_modules/cookie": { "version": "0.5.0", @@ -11598,7 +11599,6 @@ "version": "2.0.6", "resolved": "https://registry.npmjs.org/copy-anything/-/copy-anything-2.0.6.tgz", "integrity": "sha512-1j20GZTsvKNkc4BY3NpMOM8tt///wY3FpIzozTOFO2ffuZcV61nojHXVKIy3WM+7ADCy5FVhdZYHYDdgTU0yJw==", - "dev": true, "dependencies": { "is-what": "^3.14.1" }, @@ -11845,7 +11845,7 @@ "version": "1.1.1", "resolved": "https://registry.npmjs.org/create-require/-/create-require-1.1.1.tgz", "integrity": "sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==", - "dev": true + "devOptional": true }, "node_modules/cross-spawn": { "version": "7.0.3", @@ -11869,6 +11869,18 @@ "node": ">=8" } }, + "node_modules/css": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/css/-/css-3.0.0.tgz", + "integrity": "sha512-DG9pFfwOrzc+hawpmqX/dHYHJG+Bsdb0klhyi1sDneOgGOXy9wQIC8hzyVp1e4NRYDBdxcylvywPkkXCHAzTyQ==", + "optional": true, + "peer": true, + "dependencies": { + "inherits": "^2.0.4", + "source-map": "^0.6.1", + "source-map-resolve": "^0.6.0" + } + }, "node_modules/css-declaration-sorter": { "version": "7.2.0", "resolved": "https://registry.npmjs.org/css-declaration-sorter/-/css-declaration-sorter-7.2.0.tgz", @@ -11992,7 +12004,6 @@ "version": "2.3.1", "resolved": "https://registry.npmjs.org/css-tree/-/css-tree-2.3.1.tgz", "integrity": "sha512-6Fv1DV/TYw//QF5IzQdqsNDjx/wc8TrMBZsqjL9eW01tWb7R7k/mq+/VXfJCl7SoD5emsJop9cOByJZfs8hYIw==", - "dev": true, "dependencies": { "mdn-data": "2.0.30", "source-map-js": "^1.0.1" @@ -12013,11 +12024,20 @@ "url": "https://github.com/sponsors/fb55" } }, + "node_modules/css/node_modules/source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "optional": true, + "peer": true, + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/cssesc": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/cssesc/-/cssesc-3.0.0.tgz", "integrity": "sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==", - "dev": true, "bin": { "cssesc": "bin/cssesc" }, @@ -12351,7 +12371,6 @@ "version": "7.9.0", "resolved": "https://registry.npmjs.org/d3/-/d3-7.9.0.tgz", "integrity": "sha512-e1U46jVP+w7Iut8Jt8ri1YsPOvFpg46k+K8TpCb0P+zjCkjkPnV7WzfDJzMHy1LnA+wj5pLT1wjO901gLXeEhA==", - "dev": true, "dependencies": { "d3-array": "3", "d3-axis": "3", @@ -12403,7 +12422,6 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/d3-axis/-/d3-axis-3.0.0.tgz", "integrity": "sha512-IH5tgjV4jE/GhHkRV0HiVYPDtvfjHQlQfJHs0usq7M30XcSBvOotpmH1IgkcXsO/5gEQZD43B//fc7SRT5S+xw==", - "dev": true, "engines": { "node": ">=12" } @@ -12412,7 +12430,6 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/d3-brush/-/d3-brush-3.0.0.tgz", "integrity": "sha512-ALnjWlVYkXsVIGlOsuWH1+3udkYFI48Ljihfnh8FZPF2QS9o+PzGLBslO0PjzVoHLZ2KCVgAM8NVkXPJB2aNnQ==", - "dev": true, "dependencies": { "d3-dispatch": "1 - 3", "d3-drag": "2 - 3", @@ -12428,7 +12445,6 @@ "version": "3.0.1", "resolved": "https://registry.npmjs.org/d3-chord/-/d3-chord-3.0.1.tgz", "integrity": "sha512-VE5S6TNa+j8msksl7HwjxMHDM2yNK3XCkusIlpX5kwauBfXuyLAtNg9jCp/iHH61tgI4sb6R/EIMWCqEIdjT/g==", - "dev": true, "dependencies": { "d3-path": "1 - 3" }, @@ -12440,7 +12456,6 @@ "version": "3.1.0", "resolved": "https://registry.npmjs.org/d3-color/-/d3-color-3.1.0.tgz", "integrity": "sha512-zg/chbXyeBtMQ1LbD/WSoW2DpC3I0mpmPdW+ynRTj/x2DAWYrIY7qeZIHidozwV24m4iavr15lNwIwLxRmOxhA==", - "dev": true, "engines": { "node": ">=12" } @@ -12449,7 +12464,6 @@ "version": "4.0.2", "resolved": "https://registry.npmjs.org/d3-contour/-/d3-contour-4.0.2.tgz", "integrity": "sha512-4EzFTRIikzs47RGmdxbeUvLWtGedDUNkTcmzoeyg4sP/dvCexO47AaQL7VKy/gul85TOxw+IBgA8US2xwbToNA==", - "dev": true, "dependencies": { "d3-array": "^3.2.0" }, @@ -12461,7 +12475,6 @@ "version": "6.0.4", "resolved": "https://registry.npmjs.org/d3-delaunay/-/d3-delaunay-6.0.4.tgz", "integrity": "sha512-mdjtIZ1XLAM8bm/hx3WwjfHt6Sggek7qH043O8KEjDXN40xi3vx/6pYSVTwLjEgiXQTbvaouWKynLBiUZ6SK6A==", - "dev": true, "dependencies": { "delaunator": "5" }, @@ -12473,7 +12486,6 @@ "version": "3.0.1", "resolved": "https://registry.npmjs.org/d3-dispatch/-/d3-dispatch-3.0.1.tgz", "integrity": "sha512-rzUyPU/S7rwUflMyLc1ETDeBj0NRuHKKAcvukozwhshr6g6c5d8zh4c2gQjY2bZ0dXeGLWc1PF174P2tVvKhfg==", - "dev": true, "engines": { "node": ">=12" } @@ -12482,7 +12494,6 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/d3-drag/-/d3-drag-3.0.0.tgz", "integrity": "sha512-pWbUJLdETVA8lQNJecMxoXfH6x+mO2UQo8rSmZ+QqxcbyA3hfeprFgIT//HW2nlHChWeIIMwS2Fq+gEARkhTkg==", - "dev": true, "dependencies": { "d3-dispatch": "1 - 3", "d3-selection": "3" @@ -12495,7 +12506,6 @@ "version": "3.0.1", "resolved": "https://registry.npmjs.org/d3-dsv/-/d3-dsv-3.0.1.tgz", "integrity": "sha512-UG6OvdI5afDIFP9w4G0mNq50dSOsXHJaRE8arAS5o9ApWnIElp8GZw1Dun8vP8OyHOZ/QJUKUJwxiiCCnUwm+Q==", - "dev": true, "dependencies": { "commander": "7", "iconv-lite": "0.6", @@ -12520,7 +12530,6 @@ "version": "7.2.0", "resolved": "https://registry.npmjs.org/commander/-/commander-7.2.0.tgz", "integrity": "sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw==", - "dev": true, "engines": { "node": ">= 10" } @@ -12529,7 +12538,6 @@ "version": "3.0.1", "resolved": "https://registry.npmjs.org/d3-ease/-/d3-ease-3.0.1.tgz", "integrity": "sha512-wR/XK3D3XcLIZwpbvQwQ5fK+8Ykds1ip7A2Txe0yxncXSdq1L9skcG7blcedkOX+ZcgxGAmLX1FrRGbADwzi0w==", - "dev": true, "engines": { "node": ">=12" } @@ -12538,7 +12546,6 @@ "version": "3.0.1", "resolved": "https://registry.npmjs.org/d3-fetch/-/d3-fetch-3.0.1.tgz", "integrity": "sha512-kpkQIM20n3oLVBKGg6oHrUchHM3xODkTzjMoj7aWQFq5QEM+R6E4WkzT5+tojDY7yjez8KgCBRoj4aEr99Fdqw==", - "dev": true, "dependencies": { "d3-dsv": "1 - 3" }, @@ -12550,7 +12557,6 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/d3-force/-/d3-force-3.0.0.tgz", "integrity": "sha512-zxV/SsA+U4yte8051P4ECydjD/S+qeYtnaIyAs9tgHCqfguma/aAQDjo85A9Z6EKhBirHRJHXIgJUlffT4wdLg==", - "dev": true, "dependencies": { "d3-dispatch": "1 - 3", "d3-quadtree": "1 - 3", @@ -12564,7 +12570,6 @@ "version": "3.1.0", "resolved": "https://registry.npmjs.org/d3-format/-/d3-format-3.1.0.tgz", "integrity": "sha512-YyUI6AEuY/Wpt8KWLgZHsIU86atmikuoOmCfommt0LYHiQSPjvX2AcFc38PX0CBpr2RCyZhjex+NS/LPOv6YqA==", - "dev": true, "engines": { "node": ">=12" } @@ -12573,7 +12578,6 @@ "version": "3.1.1", "resolved": "https://registry.npmjs.org/d3-geo/-/d3-geo-3.1.1.tgz", "integrity": "sha512-637ln3gXKXOwhalDzinUgY83KzNWZRKbYubaG+fGVuc/dxO64RRljtCTnf5ecMyE1RIdtqpkVcq0IbtU2S8j2Q==", - "dev": true, "dependencies": { "d3-array": "2.5.0 - 3" }, @@ -12585,7 +12589,6 @@ "version": "3.1.2", "resolved": "https://registry.npmjs.org/d3-hierarchy/-/d3-hierarchy-3.1.2.tgz", "integrity": "sha512-FX/9frcub54beBdugHjDCdikxThEqjnR93Qt7PvQTOHxyiNCAlvMrHhclk3cD5VeAaq9fxmfRp+CnWw9rEMBuA==", - "dev": true, "engines": { "node": ">=12" } @@ -12594,7 +12597,6 @@ "version": "3.0.1", "resolved": "https://registry.npmjs.org/d3-interpolate/-/d3-interpolate-3.0.1.tgz", "integrity": "sha512-3bYs1rOD33uo8aqJfKP3JWPAibgw8Zm2+L9vBKEHJ2Rg+viTR7o5Mmv5mZcieN+FRYaAOWX5SJATX6k1PWz72g==", - "dev": true, "dependencies": { "d3-color": "1 - 3" }, @@ -12606,7 +12608,6 @@ "version": "3.1.0", "resolved": "https://registry.npmjs.org/d3-path/-/d3-path-3.1.0.tgz", "integrity": "sha512-p3KP5HCf/bvjBSSKuXid6Zqijx7wIfNW+J/maPs+iwR35at5JCbLUT0LzF1cnjbCHWhqzQTIN2Jpe8pRebIEFQ==", - "dev": true, "engines": { "node": ">=12" } @@ -12615,7 +12616,6 @@ "version": "3.0.1", "resolved": "https://registry.npmjs.org/d3-polygon/-/d3-polygon-3.0.1.tgz", "integrity": "sha512-3vbA7vXYwfe1SYhED++fPUQlWSYTTGmFmQiany/gdbiWgU/iEyQzyymwL9SkJjFFuCS4902BSzewVGsHHmHtXg==", - "dev": true, "engines": { "node": ">=12" } @@ -12624,7 +12624,6 @@ "version": "3.0.1", "resolved": "https://registry.npmjs.org/d3-quadtree/-/d3-quadtree-3.0.1.tgz", "integrity": "sha512-04xDrxQTDTCFwP5H6hRhsRcb9xxv2RzkcsygFzmkSIOJy3PeRJP7sNk3VRIbKXcog561P9oU0/rVH6vDROAgUw==", - "dev": true, "engines": { "node": ">=12" } @@ -12633,7 +12632,6 @@ "version": "3.0.1", "resolved": "https://registry.npmjs.org/d3-random/-/d3-random-3.0.1.tgz", "integrity": "sha512-FXMe9GfxTxqd5D6jFsQ+DJ8BJS4E/fT5mqqdjovykEB2oFbTMDVdg1MGFxfQW+FBOGoB++k8swBrgwSHT1cUXQ==", - "dev": true, "engines": { "node": ">=12" } @@ -12642,7 +12640,6 @@ "version": "4.0.2", "resolved": "https://registry.npmjs.org/d3-scale/-/d3-scale-4.0.2.tgz", "integrity": "sha512-GZW464g1SH7ag3Y7hXjf8RoUuAFIqklOAq3MRl4OaWabTFJY9PN/E1YklhXLh+OQ3fM9yS2nOkCoS+WLZ6kvxQ==", - "dev": true, "dependencies": { "d3-array": "2.10.0 - 3", "d3-format": "1 - 3", @@ -12658,7 +12655,6 @@ "version": "3.1.0", "resolved": "https://registry.npmjs.org/d3-scale-chromatic/-/d3-scale-chromatic-3.1.0.tgz", "integrity": "sha512-A3s5PWiZ9YCXFye1o246KoscMWqf8BsD9eRiJ3He7C9OBaxKhAd5TFCdEx/7VbKtxxTsu//1mMJFrEt572cEyQ==", - "dev": true, "dependencies": { "d3-color": "1 - 3", "d3-interpolate": "1 - 3" @@ -12671,7 +12667,6 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/d3-selection/-/d3-selection-3.0.0.tgz", "integrity": "sha512-fmTRWbNMmsmWq6xJV8D19U/gw/bwrHfNXxrIN+HfZgnzqTHp9jOmKMhsTUjXOJnZOdZY9Q28y4yebKzqDKlxlQ==", - "dev": true, "engines": { "node": ">=12" } @@ -12680,7 +12675,6 @@ "version": "3.2.0", "resolved": "https://registry.npmjs.org/d3-shape/-/d3-shape-3.2.0.tgz", "integrity": "sha512-SaLBuwGm3MOViRq2ABk3eLoxwZELpH6zhl3FbAoJ7Vm1gofKx6El1Ib5z23NUEhF9AsGl7y+dzLe5Cw2AArGTA==", - "dev": true, "dependencies": { "d3-path": "^3.1.0" }, @@ -12692,7 +12686,6 @@ "version": "3.1.0", "resolved": "https://registry.npmjs.org/d3-time/-/d3-time-3.1.0.tgz", "integrity": "sha512-VqKjzBLejbSMT4IgbmVgDjpkYrNWUYJnbCGo874u7MMKIWsILRX+OpX/gTk8MqjpT1A/c6HY2dCA77ZN0lkQ2Q==", - "dev": true, "dependencies": { "d3-array": "2 - 3" }, @@ -12704,7 +12697,6 @@ "version": "4.1.0", "resolved": "https://registry.npmjs.org/d3-time-format/-/d3-time-format-4.1.0.tgz", "integrity": "sha512-dJxPBlzC7NugB2PDLwo9Q8JiTR3M3e4/XANkreKSUxF8vvXKqm1Yfq4Q5dl8budlunRVlUUaDUgFt7eA8D6NLg==", - "dev": true, "dependencies": { "d3-time": "1 - 3" }, @@ -12716,7 +12708,6 @@ "version": "3.0.1", "resolved": "https://registry.npmjs.org/d3-timer/-/d3-timer-3.0.1.tgz", "integrity": "sha512-ndfJ/JxxMd3nw31uyKoY2naivF+r29V+Lc0svZxe1JvvIRmi8hUsrMvdOwgS1o6uBHmiz91geQ0ylPP0aj1VUA==", - "dev": true, "engines": { "node": ">=12" } @@ -12725,7 +12716,6 @@ "version": "3.0.1", "resolved": "https://registry.npmjs.org/d3-transition/-/d3-transition-3.0.1.tgz", "integrity": "sha512-ApKvfjsSR6tg06xrL434C0WydLr7JewBB3V+/39RMHsaXTOG0zmt/OAXeng5M5LBm0ojmxJrpomQVZ1aPvBL4w==", - "dev": true, "dependencies": { "d3-color": "1 - 3", "d3-dispatch": "1 - 3", @@ -12744,7 +12734,6 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/d3-zoom/-/d3-zoom-3.0.0.tgz", "integrity": "sha512-b8AmV3kfQaqWAuacbPuNbL6vahnOJflOhexLzMMNLga62+/nh0JzvJ0aO/5a5MVgUFGS7Hu1P9P03o3fJkDCyw==", - "dev": true, "dependencies": { "d3-dispatch": "1 - 3", "d3-drag": "2 - 3", @@ -12795,7 +12784,6 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/data-view-buffer/-/data-view-buffer-1.0.1.tgz", "integrity": "sha512-0lht7OugA5x3iJLOWFhWK/5ehONdprk0ISXqVFn/NFrDu+cuc8iADFrGQz5BnRK7LLU3JmkbXSxaqX+/mXYtUA==", - "dev": true, "dependencies": { "call-bind": "^1.0.6", "es-errors": "^1.3.0", @@ -12812,7 +12800,6 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/data-view-byte-length/-/data-view-byte-length-1.0.1.tgz", "integrity": "sha512-4J7wRJD3ABAzr8wP+OcIcqq2dlUKp4DVflx++hs5h5ZKydWMI6/D/fAot+yh6g2tHh8fLFTvNOaVN357NvSrOQ==", - "dev": true, "dependencies": { "call-bind": "^1.0.7", "es-errors": "^1.3.0", @@ -12829,7 +12816,6 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/data-view-byte-offset/-/data-view-byte-offset-1.0.0.tgz", "integrity": "sha512-t/Ygsytq+R995EJ5PZlD4Cu56sWa8InXySaViRzw9apusqsOO2bQP+SbYzAhR0pFKoB+43lYy8rWban9JSuXnA==", - "dev": true, "dependencies": { "call-bind": "^1.0.6", "es-errors": "^1.3.0", @@ -12927,6 +12913,16 @@ "node": ">=8.6" } }, + "node_modules/decode-uri-component": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/decode-uri-component/-/decode-uri-component-0.2.2.tgz", + "integrity": "sha512-FqUYQ+8o158GyGTrMFJms9qh3CqTKvAqgqsTnkLI8sKu0028orqBhxNMFkFen0zGyg6epACD32pjVk58ngIErQ==", + "optional": true, + "peer": true, + "engines": { + "node": ">=0.10" + } + }, "node_modules/decompress-response": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-6.0.0.tgz", @@ -12966,14 +12962,12 @@ "node_modules/deep-is": { "version": "0.1.4", "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz", - "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==", - "dev": true + "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==" }, "node_modules/deepmerge": { "version": "4.3.1", "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.3.1.tgz", "integrity": "sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A==", - "dev": true, "engines": { "node": ">=0.10.0" } @@ -13075,7 +13069,6 @@ "version": "1.2.1", "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.2.1.tgz", "integrity": "sha512-8QmQKqEASLd5nx0U1B1okLElbUuuttJ/AnYmRXbbbGDWh6uS208EjD4Xqq/I9wK7u0v6O08XhTWnt5XtEbR6Dg==", - "dev": true, "dependencies": { "define-data-property": "^1.0.1", "has-property-descriptors": "^1.0.0", @@ -13098,7 +13091,6 @@ "version": "5.0.1", "resolved": "https://registry.npmjs.org/delaunator/-/delaunator-5.0.1.tgz", "integrity": "sha512-8nvh+XBe96aCESrGOqMp/84b13H9cdKbG5P2ejQCh4d4sK9RL4371qou9drQjMhvnPmhWl5hnmqbEE0fXr9Xnw==", - "dev": true, "dependencies": { "robust-predicates": "^3.0.2" } @@ -13137,7 +13129,6 @@ "version": "2.0.3", "resolved": "https://registry.npmjs.org/dequal/-/dequal-2.0.3.tgz", "integrity": "sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA==", - "dev": true, "engines": { "node": ">=6" } @@ -13155,7 +13146,6 @@ "version": "6.1.0", "resolved": "https://registry.npmjs.org/detect-indent/-/detect-indent-6.1.0.tgz", "integrity": "sha512-reYkTUJAZb9gUuZ2RvVCNhVHdg62RHnJ7WJl8ftMi4diZ6NWlciOzQN88pUhSELEwflJht4oQDv0F0BMlwaYtA==", - "dev": true, "engines": { "node": ">=8" } @@ -13205,7 +13195,7 @@ "version": "4.0.2", "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz", "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==", - "dev": true, + "devOptional": true, "engines": { "node": ">=0.3.1" } @@ -13228,7 +13218,6 @@ "version": "3.0.1", "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz", "integrity": "sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==", - "dev": true, "dependencies": { "path-type": "^4.0.0" }, @@ -13252,7 +13241,6 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz", "integrity": "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==", - "dev": true, "dependencies": { "esutils": "^2.0.2" }, @@ -13486,8 +13474,7 @@ "node_modules/electron-to-chromium": { "version": "1.4.818", "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.818.tgz", - "integrity": "sha512-eGvIk2V0dGImV9gWLq8fDfTTsCAeMDwZqEPMr+jMInxZdnp9Us8UpovYpRCf9NQ7VOFgrN2doNSgvISbsbNpxA==", - "dev": true + "integrity": "sha512-eGvIk2V0dGImV9gWLq8fDfTTsCAeMDwZqEPMr+jMInxZdnp9Us8UpovYpRCf9NQ7VOFgrN2doNSgvISbsbNpxA==" }, "node_modules/elliptic": { "version": "6.5.5", @@ -13555,7 +13542,6 @@ "version": "5.17.0", "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.17.0.tgz", "integrity": "sha512-dwDPwZL0dmye8Txp2gzFmA6sxALaSvdRDjPH0viLcKrtlOL3tw62nWWweVD1SdILDTJrbrL6tdWVN58Wo6U3eA==", - "dev": true, "dependencies": { "graceful-fs": "^4.2.4", "tapable": "^2.2.0" @@ -13592,7 +13578,6 @@ "version": "0.1.8", "resolved": "https://registry.npmjs.org/errno/-/errno-0.1.8.tgz", "integrity": "sha512-dJ6oBr5SQ1VSd9qkk7ByRgb/1SH4JZjCHSW/mr63/QcXO9zLVxvJ6Oy13nio03rxpSnVDDjFor75SjVeZWPW/A==", - "dev": true, "optional": true, "dependencies": { "prr": "~1.0.1" @@ -13614,7 +13599,6 @@ "version": "1.23.3", "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.23.3.tgz", "integrity": "sha512-e+HfNH61Bj1X9/jLc5v1owaLYuHdeHHSQlkhCBiTK8rBvKaULl/beGMxwrMXjpYrv4pz22BlY570vVePA2ho4A==", - "dev": true, "dependencies": { "array-buffer-byte-length": "^1.0.1", "arraybuffer.prototype.slice": "^1.0.3", @@ -13699,7 +13683,6 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.0.0.tgz", "integrity": "sha512-MZ4iQ6JwHOBQjahnjwaC1ZtIBH+2ohjamzAO3oaHcXYup7qxjF2fixyH+Q71voWHeOkI2q/TnJao/KfXYIZWbw==", - "dev": true, "dependencies": { "es-errors": "^1.3.0" }, @@ -13711,7 +13694,6 @@ "version": "2.0.3", "resolved": "https://registry.npmjs.org/es-set-tostringtag/-/es-set-tostringtag-2.0.3.tgz", "integrity": "sha512-3T8uNMC3OQTHkFUsFq8r/BwAXLHvU/9O9mE0fBc/MY5iq/8H7ncvO947LmYA6ldWw9Uh8Yhf25zu6n7nML5QWQ==", - "dev": true, "dependencies": { "get-intrinsic": "^1.2.4", "has-tostringtag": "^1.0.2", @@ -13725,7 +13707,6 @@ "version": "1.0.2", "resolved": "https://registry.npmjs.org/es-shim-unscopables/-/es-shim-unscopables-1.0.2.tgz", "integrity": "sha512-J3yBRXCzDu4ULnQwxyToo/OjdMx6akgVC7K6few0a7F/0wLtmKKN7I73AH5T2836UuXRqN7Qg+IIUw/+YJksRw==", - "dev": true, "dependencies": { "hasown": "^2.0.0" } @@ -13734,7 +13715,6 @@ "version": "1.2.1", "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.1.tgz", "integrity": "sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==", - "dev": true, "dependencies": { "is-callable": "^1.1.4", "is-date-object": "^1.0.1", @@ -13750,8 +13730,7 @@ "node_modules/es6-promise": { "version": "3.3.1", "resolved": "https://registry.npmjs.org/es6-promise/-/es6-promise-3.3.1.tgz", - "integrity": "sha512-SOp9Phqvqn7jtEUxPWdWfWoLmyt2VaJ6MpvP9Comy1MceMXqE6bxvaTu4iaxpYYPzhny28Lc+M87/c2cPK6lDg==", - "dev": true + "integrity": "sha512-SOp9Phqvqn7jtEUxPWdWfWoLmyt2VaJ6MpvP9Comy1MceMXqE6bxvaTu4iaxpYYPzhny28Lc+M87/c2cPK6lDg==" }, "node_modules/esbuild": { "version": "0.21.5", @@ -13808,7 +13787,7 @@ "version": "1.0.5", "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", - "dev": true, + "devOptional": true, "engines": { "node": ">=0.8.0" } @@ -13848,7 +13827,6 @@ "version": "8.57.0", "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.57.0.tgz", "integrity": "sha512-dZ6+mexnaTIbSBZWgou51U6OmzIhYM2VcNdtiTtI7qPNZm35Akpr0f6vtw3w1Kmn5PYo+tZVfh13WrhpS6oLqQ==", - "dev": true, "dependencies": { "@eslint-community/eslint-utils": "^4.2.0", "@eslint-community/regexpp": "^4.6.1", @@ -13903,7 +13881,6 @@ "version": "0.5.1", "resolved": "https://registry.npmjs.org/eslint-compat-utils/-/eslint-compat-utils-0.5.1.tgz", "integrity": "sha512-3z3vFexKIEnjHE3zCMRo6fn/e44U7T1khUjg+Hp0ZQMCigh28rALD0nPFBcGZuiLC5rLZa2ubQHDRln09JfU2Q==", - "dev": true, "dependencies": { "semver": "^7.5.4" }, @@ -13918,7 +13895,6 @@ "version": "7.6.2", "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.2.tgz", "integrity": "sha512-FNAIBWCx9qcRhoHcgcJ0gvU7SN1lYU2ZXuSfl04bSC5OpvDHFyJCjdNHomPXxjQlCBU67YW64PzY7/VIEH7F2w==", - "dev": true, "bin": { "semver": "bin/semver.js" }, @@ -13942,7 +13918,6 @@ "version": "17.1.0", "resolved": "https://registry.npmjs.org/eslint-config-standard/-/eslint-config-standard-17.1.0.tgz", "integrity": "sha512-IwHwmaBNtDK4zDHQukFDW5u/aTb8+meQWZvNFWkiGmbWjD6bqyuSSBxxXKkCftCUzc1zwCH2m/baCNDLGmuO5Q==", - "dev": true, "funding": [ { "type": "github", @@ -13971,7 +13946,6 @@ "version": "0.3.9", "resolved": "https://registry.npmjs.org/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.9.tgz", "integrity": "sha512-WFj2isz22JahUv+B788TlO3N6zL3nNJGU8CcZbPZvVEkBPaJdCV4vy5wyghty5ROFbCRnm132v8BScu5/1BQ8g==", - "dev": true, "dependencies": { "debug": "^3.2.7", "is-core-module": "^2.13.0", @@ -13982,7 +13956,6 @@ "version": "3.2.7", "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", - "dev": true, "dependencies": { "ms": "^2.1.1" } @@ -13991,7 +13964,6 @@ "version": "3.6.1", "resolved": "https://registry.npmjs.org/eslint-import-resolver-typescript/-/eslint-import-resolver-typescript-3.6.1.tgz", "integrity": "sha512-xgdptdoi5W3niYeuQxKmzVDTATvLYqhpwmykwsh7f6HIOStGWEIL9iqZgQDF9u9OEzrRwR8no5q2VT+bjAujTg==", - "dev": true, "dependencies": { "debug": "^4.3.4", "enhanced-resolve": "^5.12.0", @@ -14016,7 +13988,6 @@ "version": "3.3.2", "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.2.tgz", "integrity": "sha512-oX2ruAFQwf/Orj8m737Y5adxDQO0LAB7/S5MnxCdTNDd4p6BsyIVsv9JQsATbTSq8KHRpLwIHbVlUNatxd+1Ow==", - "dev": true, "dependencies": { "@nodelib/fs.stat": "^2.0.2", "@nodelib/fs.walk": "^1.2.3", @@ -14032,7 +14003,6 @@ "version": "5.1.2", "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", - "dev": true, "dependencies": { "is-glob": "^4.0.1" }, @@ -14044,7 +14014,6 @@ "version": "2.8.1", "resolved": "https://registry.npmjs.org/eslint-module-utils/-/eslint-module-utils-2.8.1.tgz", "integrity": "sha512-rXDXR3h7cs7dy9RNpUlQf80nX31XWJEyGq1tRMo+6GsO5VmTe4UTwtmonAD4ZkAsrfMVDA2wlGJ3790Ys+D49Q==", - "dev": true, "dependencies": { "debug": "^3.2.7" }, @@ -14061,7 +14030,6 @@ "version": "3.2.7", "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", - "dev": true, "dependencies": { "ms": "^2.1.1" } @@ -14070,7 +14038,6 @@ "version": "7.8.0", "resolved": "https://registry.npmjs.org/eslint-plugin-es-x/-/eslint-plugin-es-x-7.8.0.tgz", "integrity": "sha512-7Ds8+wAAoV3T+LAKeu39Y5BzXCrGKrcISfgKEqTS4BDN8SFEDQd0S43jiQ8vIa3wUKD07qitZdfzlenSi8/0qQ==", - "dev": true, "funding": [ "https://github.com/sponsors/ota-meshi", "https://opencollective.com/eslint" @@ -14091,7 +14058,6 @@ "version": "2.29.1", "resolved": "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.29.1.tgz", "integrity": "sha512-BbPC0cuExzhiMo4Ff1BTVwHpjjv28C5R+btTOGaCRC7UEz801up0JadwkeSk5Ued6TG34uaczuVuH6qyy5YUxw==", - "dev": true, "dependencies": { "array-includes": "^3.1.7", "array.prototype.findlastindex": "^1.2.3", @@ -14122,7 +14088,6 @@ "version": "1.1.11", "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", - "dev": true, "dependencies": { "balanced-match": "^1.0.0", "concat-map": "0.0.1" @@ -14132,7 +14097,6 @@ "version": "3.2.7", "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", - "dev": true, "dependencies": { "ms": "^2.1.1" } @@ -14141,7 +14105,6 @@ "version": "2.1.0", "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-2.1.0.tgz", "integrity": "sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==", - "dev": true, "dependencies": { "esutils": "^2.0.2" }, @@ -14153,7 +14116,6 @@ "version": "1.0.2", "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.2.tgz", "integrity": "sha512-g1MWMLBiz8FKi1e4w0UyVL3w+iJceWAFBAaBnnGKOpNa5f8TLktkbre1+s6oICydWAm+HRUGTmI+//xv2hvXYA==", - "dev": true, "dependencies": { "minimist": "^1.2.0" }, @@ -14165,7 +14127,6 @@ "version": "3.1.2", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", - "dev": true, "dependencies": { "brace-expansion": "^1.1.7" }, @@ -14177,7 +14138,6 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", "integrity": "sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==", - "dev": true, "engines": { "node": ">=4" } @@ -14186,7 +14146,6 @@ "version": "3.15.0", "resolved": "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-3.15.0.tgz", "integrity": "sha512-2Ac2RgzDe/cn48GvOe3M+o82pEFewD3UPbyoUHHdKasHwJKjds4fLXWf/Ux5kATBKN20oaFGu+jbElp1pos0mg==", - "dev": true, "dependencies": { "@types/json5": "^0.0.29", "json5": "^1.0.2", @@ -14221,7 +14180,6 @@ "version": "16.6.2", "resolved": "https://registry.npmjs.org/eslint-plugin-n/-/eslint-plugin-n-16.6.2.tgz", "integrity": "sha512-6TyDmZ1HXoFQXnhCTUjVFULReoBPOAjpuiKELMkeP40yffI/1ZRO+d9ug/VC6fqISo2WkuIBk3cvuRPALaWlOQ==", - "dev": true, "dependencies": { "@eslint-community/eslint-utils": "^4.4.0", "builtins": "^5.0.1", @@ -14249,7 +14207,6 @@ "version": "1.1.11", "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", - "dev": true, "dependencies": { "balanced-match": "^1.0.0", "concat-map": "0.0.1" @@ -14259,7 +14216,6 @@ "version": "13.24.0", "resolved": "https://registry.npmjs.org/globals/-/globals-13.24.0.tgz", "integrity": "sha512-AhO5QUcj8llrbG09iWhPU2B204J1xnPeL8kQmVorSsy+Sjj1sk8gIyh6cUocGmH4L0UuhAJy+hJMRA4mgA4mFQ==", - "dev": true, "dependencies": { "type-fest": "^0.20.2" }, @@ -14274,7 +14230,6 @@ "version": "3.1.2", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", - "dev": true, "dependencies": { "brace-expansion": "^1.1.7" }, @@ -14286,7 +14241,6 @@ "version": "7.6.2", "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.2.tgz", "integrity": "sha512-FNAIBWCx9qcRhoHcgcJ0gvU7SN1lYU2ZXuSfl04bSC5OpvDHFyJCjdNHomPXxjQlCBU67YW64PzY7/VIEH7F2w==", - "dev": true, "bin": { "semver": "bin/semver.js" }, @@ -14298,7 +14252,6 @@ "version": "0.20.2", "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", - "dev": true, "engines": { "node": ">=10" }, @@ -14310,7 +14263,6 @@ "version": "6.4.0", "resolved": "https://registry.npmjs.org/eslint-plugin-promise/-/eslint-plugin-promise-6.4.0.tgz", "integrity": "sha512-/KWWRaD3fGkVCZsdR0RU53PSthFmoHVhZl+y9+6DqeDLSikLdlUVpVEAmI6iCRR5QyOjBYBqHZV/bdv4DJ4Gtw==", - "dev": true, "engines": { "node": "^12.22.0 || ^14.17.0 || >=16.0.0" }, @@ -14343,10 +14295,9 @@ } }, "node_modules/eslint-plugin-svelte": { - "version": "2.41.0", - "resolved": "https://registry.npmjs.org/eslint-plugin-svelte/-/eslint-plugin-svelte-2.41.0.tgz", - "integrity": "sha512-gjU9Q/psxbWG1VNwYbEb0Q6U4W5PBGaDpYmO2zlQ+zlAMVS3Qt0luAK0ACi/tMSwRK6JENiySvMyJbO0YWmXSg==", - "dev": true, + "version": "2.42.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-svelte/-/eslint-plugin-svelte-2.42.0.tgz", + "integrity": "sha512-mHP6z0DWq97KZvoQcApZHdF9m9epcDV/ICKufeEH18Vh+8vl7S+gwt8WdUohEqKNVMuXRkbvy1suMcVvUDiOGw==", "dependencies": { "@eslint-community/eslint-utils": "^4.4.0", "@jridgewell/sourcemap-codec": "^1.4.15", @@ -14358,7 +14309,7 @@ "postcss-safe-parser": "^6.0.0", "postcss-selector-parser": "^6.1.0", "semver": "^7.6.2", - "svelte-eslint-parser": "^0.39.2" + "svelte-eslint-parser": "^0.40.0" }, "engines": { "node": "^14.17.0 || >=16.0.0" @@ -14368,7 +14319,7 @@ }, "peerDependencies": { "eslint": "^7.0.0 || ^8.0.0-0 || ^9.0.0-0", - "svelte": "^3.37.0 || ^4.0.0 || ^5.0.0-next.155" + "svelte": "^3.37.0 || ^4.0.0 || ^5.0.0-next.181" }, "peerDependenciesMeta": { "svelte": { @@ -14380,7 +14331,6 @@ "version": "7.6.2", "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.2.tgz", "integrity": "sha512-FNAIBWCx9qcRhoHcgcJ0gvU7SN1lYU2ZXuSfl04bSC5OpvDHFyJCjdNHomPXxjQlCBU67YW64PzY7/VIEH7F2w==", - "dev": true, "bin": { "semver": "bin/semver.js" }, @@ -14405,7 +14355,6 @@ "version": "7.2.2", "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.2.2.tgz", "integrity": "sha512-dOt21O7lTMhDM+X9mB4GX+DZrZtCUJPL/wlcTqxyrx5IvO0IYtILdtrQGQp+8n5S0gwSVmOf9NQrjMOgfQZlIg==", - "dev": true, "dependencies": { "esrecurse": "^4.3.0", "estraverse": "^5.2.0" @@ -14421,7 +14370,6 @@ "version": "3.4.3", "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz", "integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==", - "dev": true, "engines": { "node": "^12.22.0 || ^14.17.0 || >=16.0.0" }, @@ -14433,7 +14381,6 @@ "version": "6.12.6", "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", - "dev": true, "dependencies": { "fast-deep-equal": "^3.1.1", "fast-json-stable-stringify": "^2.0.0", @@ -14449,7 +14396,6 @@ "version": "4.3.0", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dev": true, "dependencies": { "color-convert": "^2.0.1" }, @@ -14463,14 +14409,12 @@ "node_modules/eslint/node_modules/argparse": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", - "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", - "dev": true + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==" }, "node_modules/eslint/node_modules/brace-expansion": { "version": "1.1.11", "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", - "dev": true, "dependencies": { "balanced-match": "^1.0.0", "concat-map": "0.0.1" @@ -14480,7 +14424,6 @@ "version": "4.1.2", "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "dev": true, "dependencies": { "ansi-styles": "^4.1.0", "supports-color": "^7.1.0" @@ -14496,7 +14439,6 @@ "version": "2.0.1", "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dev": true, "dependencies": { "color-name": "~1.1.4" }, @@ -14507,14 +14449,12 @@ "node_modules/eslint/node_modules/color-name": { "version": "1.1.4", "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "dev": true + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" }, "node_modules/eslint/node_modules/escape-string-regexp": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", - "dev": true, "engines": { "node": ">=10" }, @@ -14526,7 +14466,6 @@ "version": "5.0.0", "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", - "dev": true, "dependencies": { "locate-path": "^6.0.0", "path-exists": "^4.0.0" @@ -14542,7 +14481,6 @@ "version": "13.24.0", "resolved": "https://registry.npmjs.org/globals/-/globals-13.24.0.tgz", "integrity": "sha512-AhO5QUcj8llrbG09iWhPU2B204J1xnPeL8kQmVorSsy+Sjj1sk8gIyh6cUocGmH4L0UuhAJy+hJMRA4mgA4mFQ==", - "dev": true, "dependencies": { "type-fest": "^0.20.2" }, @@ -14557,7 +14495,6 @@ "version": "4.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "dev": true, "engines": { "node": ">=8" } @@ -14566,7 +14503,6 @@ "version": "4.1.0", "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", - "dev": true, "dependencies": { "argparse": "^2.0.1" }, @@ -14577,14 +14513,12 @@ "node_modules/eslint/node_modules/json-schema-traverse": { "version": "0.4.1", "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", - "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", - "dev": true + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==" }, "node_modules/eslint/node_modules/locate-path": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", - "dev": true, "dependencies": { "p-locate": "^5.0.0" }, @@ -14599,7 +14533,6 @@ "version": "3.1.2", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", - "dev": true, "dependencies": { "brace-expansion": "^1.1.7" }, @@ -14611,7 +14544,6 @@ "version": "5.0.0", "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", - "dev": true, "dependencies": { "p-limit": "^3.0.2" }, @@ -14626,7 +14558,6 @@ "version": "7.2.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "dev": true, "dependencies": { "has-flag": "^4.0.0" }, @@ -14638,7 +14569,6 @@ "version": "0.20.2", "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", - "dev": true, "engines": { "node": ">=10" }, @@ -14650,7 +14580,6 @@ "version": "9.6.1", "resolved": "https://registry.npmjs.org/espree/-/espree-9.6.1.tgz", "integrity": "sha512-oruZaFkjorTpF32kDSI5/75ViwGeZginGGy2NoOSg3Q9bnwlnmDm4HLnkl0RE3n+njDXR037aY1+x58Z/zFdwQ==", - "dev": true, "dependencies": { "acorn": "^8.9.0", "acorn-jsx": "^5.3.2", @@ -14679,7 +14608,6 @@ "version": "1.6.0", "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.6.0.tgz", "integrity": "sha512-ca9pw9fomFcKPvFLXhBKUK90ZvGibiGOvRJNbjljY7s7uq/5YO4BOzcYtJqExdx99rF6aAcnRxHmcUHcz6sQsg==", - "dev": true, "dependencies": { "estraverse": "^5.1.0" }, @@ -14691,7 +14619,6 @@ "version": "4.3.0", "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", - "dev": true, "dependencies": { "estraverse": "^5.2.0" }, @@ -14703,7 +14630,6 @@ "version": "5.3.0", "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", - "dev": true, "engines": { "node": ">=4.0" } @@ -14711,14 +14637,12 @@ "node_modules/estree-walker": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-2.0.2.tgz", - "integrity": "sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==", - "dev": true + "integrity": "sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==" }, "node_modules/esutils": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", - "dev": true, "engines": { "node": ">=0.10.0" } @@ -15099,14 +15023,12 @@ "node_modules/fast-json-stable-stringify": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", - "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", - "dev": true + "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==" }, "node_modules/fast-levenshtein": { "version": "2.0.6", "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", - "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==", - "dev": true + "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==" }, "node_modules/fast-xml-parser": { "version": "4.4.0", @@ -15133,7 +15055,6 @@ "version": "1.17.1", "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.17.1.tgz", "integrity": "sha512-sRVD3lWVIXWg6By68ZN7vho9a1pQcN/WBFaAAsDDFzlJjvoGx0P8z7V1t72grFJfJhu3YPZBuu25f7Kaw2jN1w==", - "dev": true, "dependencies": { "reusify": "^1.0.4" } @@ -15225,7 +15146,6 @@ "version": "6.0.1", "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz", "integrity": "sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==", - "dev": true, "dependencies": { "flat-cache": "^3.0.4" }, @@ -15258,7 +15178,6 @@ "version": "7.1.1", "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz", "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==", - "dev": true, "dependencies": { "to-regex-range": "^5.0.1" }, @@ -15337,7 +15256,6 @@ "version": "3.2.0", "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-3.2.0.tgz", "integrity": "sha512-CYcENa+FtcUKLmhhqyctpclsq7QF38pKjZHsGNiSQF5r4FtoKDWabFDl3hzaEQMvT1LHEysw5twgLvpYYb4vbw==", - "dev": true, "dependencies": { "flatted": "^3.2.9", "keyv": "^4.5.3", @@ -15366,8 +15284,7 @@ "node_modules/flatted": { "version": "3.3.1", "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.3.1.tgz", - "integrity": "sha512-X8cqMLLie7KsNUDSdzeN8FYK9rEt4Dt67OsG/DNGnYTSDBG4uFAJFBnUeiV+zCVAvwFy56IjM9sH51jVaEhNxw==", - "dev": true + "integrity": "sha512-X8cqMLLie7KsNUDSdzeN8FYK9rEt4Dt67OsG/DNGnYTSDBG4uFAJFBnUeiV+zCVAvwFy56IjM9sH51jVaEhNxw==" }, "node_modules/flight-recorder-manufacturers": { "version": "2.0.0", @@ -15408,7 +15325,6 @@ "version": "0.3.3", "resolved": "https://registry.npmjs.org/for-each/-/for-each-0.3.3.tgz", "integrity": "sha512-jqYfLp7mo9vIyQf8ykW2v7A+2N4QjeCeI5+Dz9XraiO1ign81wjiH7Fb9vSOWvQfNtmSa4H2RoQTrrXivdUZmw==", - "dev": true, "dependencies": { "is-callable": "^1.1.3" } @@ -15776,7 +15692,6 @@ "version": "2.3.3", "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", - "dev": true, "hasInstallScript": true, "optional": true, "os": [ @@ -15865,7 +15780,6 @@ "version": "1.1.6", "resolved": "https://registry.npmjs.org/function.prototype.name/-/function.prototype.name-1.1.6.tgz", "integrity": "sha512-Z5kx79swU5P27WEayXM1tBi5Ze/lbIyiNgU3qyXUOf9b2rgXYyF9Dy9Cx+IQv/Lc8WCG6L82zwUPpSS9hGehIg==", - "dev": true, "dependencies": { "call-bind": "^1.0.2", "define-properties": "^1.2.0", @@ -15883,7 +15797,6 @@ "version": "1.2.3", "resolved": "https://registry.npmjs.org/functions-have-names/-/functions-have-names-1.2.3.tgz", "integrity": "sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ==", - "dev": true, "funding": { "url": "https://github.com/sponsors/ljharb" } @@ -15969,7 +15882,7 @@ "version": "1.0.0-beta.2", "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz", "integrity": "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==", - "dev": true, + "devOptional": true, "engines": { "node": ">=6.9.0" } @@ -16081,7 +15994,6 @@ "version": "1.0.2", "resolved": "https://registry.npmjs.org/get-symbol-description/-/get-symbol-description-1.0.2.tgz", "integrity": "sha512-g0QYk1dZBxGwk+Ngc+ltRH2IBp2f7zBkBMBJZCDerh6EhlhSR6+9irMCuT/09zD6qkarHUSn529sK/yL4S27mg==", - "dev": true, "dependencies": { "call-bind": "^1.0.5", "es-errors": "^1.3.0", @@ -16098,7 +16010,6 @@ "version": "4.7.5", "resolved": "https://registry.npmjs.org/get-tsconfig/-/get-tsconfig-4.7.5.tgz", "integrity": "sha512-ZCuZCnlqNzjb4QprAzXKdpp/gh6KTxSJuw3IBsPnV/7fV4NxC9ckB+vPTt8w7fJA0TaSD7c55BR47JD6MEDyDw==", - "dev": true, "dependencies": { "resolve-pkg-maps": "^1.0.0" }, @@ -16156,7 +16067,6 @@ "version": "6.0.2", "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==", - "dev": true, "dependencies": { "is-glob": "^4.0.3" }, @@ -16203,7 +16113,7 @@ "version": "11.12.0", "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==", - "dev": true, + "devOptional": true, "engines": { "node": ">=4" } @@ -16212,7 +16122,6 @@ "version": "1.0.4", "resolved": "https://registry.npmjs.org/globalthis/-/globalthis-1.0.4.tgz", "integrity": "sha512-DpLKbNU4WylpxJykQujfCcwYWiV/Jhm50Goo0wrVILAv5jOr9d+H+UR3PhSCD2rCCEIg0uc+G+muBTwD54JhDQ==", - "dev": true, "dependencies": { "define-properties": "^1.2.1", "gopd": "^1.0.1" @@ -16228,7 +16137,6 @@ "version": "11.1.0", "resolved": "https://registry.npmjs.org/globby/-/globby-11.1.0.tgz", "integrity": "sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==", - "dev": true, "dependencies": { "array-union": "^2.1.0", "dir-glob": "^3.0.1", @@ -16248,7 +16156,6 @@ "version": "3.3.2", "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.2.tgz", "integrity": "sha512-oX2ruAFQwf/Orj8m737Y5adxDQO0LAB7/S5MnxCdTNDd4p6BsyIVsv9JQsATbTSq8KHRpLwIHbVlUNatxd+1Ow==", - "dev": true, "dependencies": { "@nodelib/fs.stat": "^2.0.2", "@nodelib/fs.walk": "^1.2.3", @@ -16264,7 +16171,6 @@ "version": "5.1.2", "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", - "dev": true, "dependencies": { "is-glob": "^4.0.1" }, @@ -16426,8 +16332,7 @@ "node_modules/graphemer": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/graphemer/-/graphemer-1.4.0.tgz", - "integrity": "sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==", - "dev": true + "integrity": "sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==" }, "node_modules/gtoken": { "version": "7.1.0", @@ -16487,7 +16392,6 @@ "version": "1.0.2", "resolved": "https://registry.npmjs.org/has-bigints/-/has-bigints-1.0.2.tgz", "integrity": "sha512-tSvCKtBr9lkF0Ex0aQiP9N+OpV4zi2r/Nee5VkRDbaqv35RLYMzbwQfFSZZH0kR+Rd6302UJZ2p/bJCEoR3VoQ==", - "dev": true, "funding": { "url": "https://github.com/sponsors/ljharb" } @@ -16496,7 +16400,7 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", - "dev": true, + "devOptional": true, "engines": { "node": ">=4" } @@ -16538,7 +16442,6 @@ "version": "1.0.2", "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.2.tgz", "integrity": "sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==", - "dev": true, "dependencies": { "has-symbols": "^1.0.3" }, @@ -16964,7 +16867,6 @@ "version": "0.6.3", "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz", "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==", - "dev": true, "dependencies": { "safer-buffer": ">= 2.1.2 < 3.0.0" }, @@ -17051,7 +16953,6 @@ "version": "5.3.1", "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.1.tgz", "integrity": "sha512-5Fytz/IraMjqpwfd34ke28PTVMjZjJG2MPn5t7OE4eUCUNf8BAa7b5WUS9/Qvr6mwOQS7Mk6vdsMno5he+T8Xw==", - "dev": true, "engines": { "node": ">= 4" } @@ -17060,7 +16961,6 @@ "version": "0.5.5", "resolved": "https://registry.npmjs.org/image-size/-/image-size-0.5.5.tgz", "integrity": "sha512-6TDAlDPZxUFCv+fuOkIoXT/V/f3Qbq8e37p+YOiYrUv3v9cc3/6x78VdfPgFVaB9dZYeLUfKgHRebpkm/oP2VQ==", - "dev": true, "optional": true, "bin": { "image-size": "bin/image-size.js" @@ -17082,13 +16982,12 @@ "version": "4.3.6", "resolved": "https://registry.npmjs.org/immutable/-/immutable-4.3.6.tgz", "integrity": "sha512-Ju0+lEMyzMVZarkTn/gqRpdqd5dOPaz1mCZ0SH3JV6iFw81PldE/PEB1hWVEA288HPt4WXW8O7AWxB10M+03QQ==", - "dev": true + "devOptional": true }, "node_modules/import-fresh": { "version": "3.3.0", "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz", "integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==", - "dev": true, "dependencies": { "parent-module": "^1.0.0", "resolve-from": "^4.0.0" @@ -17104,7 +17003,6 @@ "version": "4.0.0", "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", - "dev": true, "engines": { "node": ">=4" } @@ -17153,7 +17051,6 @@ "version": "0.1.4", "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==", - "dev": true, "engines": { "node": ">=0.8.19" } @@ -17195,7 +17092,6 @@ "version": "1.0.7", "resolved": "https://registry.npmjs.org/internal-slot/-/internal-slot-1.0.7.tgz", "integrity": "sha512-NGnrKwXzSms2qUUih/ILZ5JBqNTSa1+ZmP6flaIp6KmSElgE9qdndzS3cqjrDovwFdmwsGsLdeFgB6suw+1e9g==", - "dev": true, "dependencies": { "es-errors": "^1.3.0", "hasown": "^2.0.0", @@ -17264,7 +17160,6 @@ "version": "3.0.4", "resolved": "https://registry.npmjs.org/is-array-buffer/-/is-array-buffer-3.0.4.tgz", "integrity": "sha512-wcjaerHw0ydZwfhiKbXJWLDY8A7yV7KhjQOpb83hGgGfId/aQa4TOvwyzn2PuswW2gPCYEL/nEAiSVpdOj1lXw==", - "dev": true, "dependencies": { "call-bind": "^1.0.2", "get-intrinsic": "^1.2.1" @@ -17286,7 +17181,6 @@ "version": "1.0.4", "resolved": "https://registry.npmjs.org/is-bigint/-/is-bigint-1.0.4.tgz", "integrity": "sha512-zB9CruMamjym81i2JZ3UMn54PKGsQzsJeo6xvN3HJJ4CAsQNB6iRutp2To77OfCNuoxspsIhzaPoO1zyCEhFOg==", - "dev": true, "dependencies": { "has-bigints": "^1.0.1" }, @@ -17298,7 +17192,7 @@ "version": "2.1.0", "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", - "dev": true, + "devOptional": true, "dependencies": { "binary-extensions": "^2.0.0" }, @@ -17310,7 +17204,6 @@ "version": "1.1.2", "resolved": "https://registry.npmjs.org/is-boolean-object/-/is-boolean-object-1.1.2.tgz", "integrity": "sha512-gDYaKHJmnj4aWxyj6YHyXVpdQawtVLHU5cb+eztPGczf6cjuTdwve5ZIEfgXqH4e57An1D1AKf8CZ3kYrQRqYA==", - "dev": true, "dependencies": { "call-bind": "^1.0.2", "has-tostringtag": "^1.0.0" @@ -17326,7 +17219,6 @@ "version": "3.2.1", "resolved": "https://registry.npmjs.org/is-builtin-module/-/is-builtin-module-3.2.1.tgz", "integrity": "sha512-BSLE3HnV2syZ0FK0iMA/yUGplUeMmNz4AW5fnTunbCIqZi4vG3WjJT9FHMy5D69xmAYBHXQhJdALdpwVxV501A==", - "dev": true, "dependencies": { "builtin-modules": "^3.3.0" }, @@ -17341,7 +17233,6 @@ "version": "1.2.7", "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.7.tgz", "integrity": "sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA==", - "dev": true, "engines": { "node": ">= 0.4" }, @@ -17380,7 +17271,6 @@ "version": "2.14.0", "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.14.0.tgz", "integrity": "sha512-a5dFJih5ZLYlRtDc0dZWP7RiKr6xIKzmn/oAYCDvdLThadVgyJwlaoQPmRtMSpz+rk0OGAgIu+TcM9HUF0fk1A==", - "dev": true, "dependencies": { "hasown": "^2.0.2" }, @@ -17395,7 +17285,6 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/is-data-view/-/is-data-view-1.0.1.tgz", "integrity": "sha512-AHkaJrsUVW6wq6JS8y3JnM/GJF/9cf+k20+iDzlSaJrinEo5+7vRiteOSwBhHRiAyQATN1AmY4hwzxJKPmYf+w==", - "dev": true, "dependencies": { "is-typed-array": "^1.1.13" }, @@ -17410,7 +17299,6 @@ "version": "1.0.5", "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.5.tgz", "integrity": "sha512-9YQaSxsAiSwcvS33MBk3wTCVnWK+HhF8VZR2jRxehM16QcVOdHqPn4VPHmRK4lSr38n9JriurInLcP90xsYNfQ==", - "dev": true, "dependencies": { "has-tostringtag": "^1.0.0" }, @@ -17440,7 +17328,6 @@ "version": "2.1.1", "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", - "dev": true, "engines": { "node": ">=0.10.0" } @@ -17466,7 +17353,6 @@ "version": "4.0.3", "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", - "dev": true, "dependencies": { "is-extglob": "^2.1.1" }, @@ -17502,14 +17388,12 @@ "node_modules/is-module": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/is-module/-/is-module-1.0.0.tgz", - "integrity": "sha512-51ypPSPCoTEIN9dy5Oy+h4pShgJmPCygKfyRCISBI+JoWT/2oJvK8QPxmwv7b/p239jXrm9M1mlQbyKJ5A152g==", - "dev": true + "integrity": "sha512-51ypPSPCoTEIN9dy5Oy+h4pShgJmPCygKfyRCISBI+JoWT/2oJvK8QPxmwv7b/p239jXrm9M1mlQbyKJ5A152g==" }, "node_modules/is-negative-zero": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.3.tgz", "integrity": "sha512-5KoIu2Ngpyek75jXodFvnafB6DJgr3u8uuK0LEZJjrU19DrMD3EVERaR8sjz8CCGgpZvxPl9SuE1GMVPFHx1mw==", - "dev": true, "engines": { "node": ">= 0.4" }, @@ -17521,7 +17405,6 @@ "version": "7.0.0", "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", - "dev": true, "engines": { "node": ">=0.12.0" } @@ -17530,7 +17413,6 @@ "version": "1.0.7", "resolved": "https://registry.npmjs.org/is-number-object/-/is-number-object-1.0.7.tgz", "integrity": "sha512-k1U0IRzLMo7ZlYIfzRu23Oh6MiIFasgpb9X76eqfFZAqwH44UI4KTBvBYIZ1dSL9ZzChTB9ShHfLkR4pdW5krQ==", - "dev": true, "dependencies": { "has-tostringtag": "^1.0.0" }, @@ -17554,7 +17436,6 @@ "version": "3.0.3", "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-3.0.3.tgz", "integrity": "sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==", - "dev": true, "engines": { "node": ">=8" } @@ -17581,7 +17462,6 @@ "version": "1.2.1", "resolved": "https://registry.npmjs.org/is-reference/-/is-reference-1.2.1.tgz", "integrity": "sha512-U82MsXXiFIrjCK4otLT+o2NA2Cd2g5MLoOVXUZjIOhLurrRxpEXzI8O0KZHr3IjLvlAH1kTPYSuqer5T9ZVBKQ==", - "dev": true, "dependencies": { "@types/estree": "*" } @@ -17590,7 +17470,6 @@ "version": "1.1.4", "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.4.tgz", "integrity": "sha512-kvRdxDsxZjhzUX07ZnLydzS1TU/TJlTUHHY4YLL87e37oUA49DfkLqgy+VjFocowy29cKvcSiu+kIv728jTTVg==", - "dev": true, "dependencies": { "call-bind": "^1.0.2", "has-tostringtag": "^1.0.0" @@ -17615,7 +17494,6 @@ "version": "1.0.3", "resolved": "https://registry.npmjs.org/is-shared-array-buffer/-/is-shared-array-buffer-1.0.3.tgz", "integrity": "sha512-nA2hv5XIhLR3uVzDDfCIknerhx8XUKnstuOERPNNIinXG7v9u+ohXF67vxm4TPTEPU6lm61ZkwP3c9PCB97rhg==", - "dev": true, "dependencies": { "call-bind": "^1.0.7" }, @@ -17646,7 +17524,6 @@ "version": "1.0.7", "resolved": "https://registry.npmjs.org/is-string/-/is-string-1.0.7.tgz", "integrity": "sha512-tE2UXzivje6ofPW7l23cjDOMa09gb7xlAqG6jG5ej6uPV32TlWP3NKPigtaGeHNu9fohccRYvIiZMfOOnOYUtg==", - "dev": true, "dependencies": { "has-tostringtag": "^1.0.0" }, @@ -17661,7 +17538,6 @@ "version": "1.0.4", "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.4.tgz", "integrity": "sha512-C/CPBqKWnvdcxqIARxyOh4v1UUEOCHpgDa0WYgpKDFMszcrPcffg5uhwSgPCLD2WWxmq6isisz87tzT01tuGhg==", - "dev": true, "dependencies": { "has-symbols": "^1.0.2" }, @@ -17676,7 +17552,6 @@ "version": "1.1.13", "resolved": "https://registry.npmjs.org/is-typed-array/-/is-typed-array-1.1.13.tgz", "integrity": "sha512-uZ25/bUAlUY5fR4OKT4rZQEBrzQWYV9ZJYGGsUmEJ6thodVJ1HX64ePQ6Z0qPWP+m+Uq6e9UugrE38jeYsDSMw==", - "dev": true, "dependencies": { "which-typed-array": "^1.1.14" }, @@ -17718,7 +17593,6 @@ "version": "1.0.2", "resolved": "https://registry.npmjs.org/is-weakref/-/is-weakref-1.0.2.tgz", "integrity": "sha512-qctsuLZmIQ0+vSSMfoVvyFe2+GSEvnmZ2ezTup1SBse9+twCCeial6EEi3Nc2KFcf6+qz2FBPnjXsk8xhKSaPQ==", - "dev": true, "dependencies": { "call-bind": "^1.0.2" }, @@ -17729,8 +17603,7 @@ "node_modules/is-what": { "version": "3.14.1", "resolved": "https://registry.npmjs.org/is-what/-/is-what-3.14.1.tgz", - "integrity": "sha512-sNxgpk9793nzSs7bA6JQJGeIuRBQhAaNGG77kzYQgMkrID+lS6SlK07K5LaptscDlSaIgH+GPFzf+d75FVxozA==", - "dev": true + "integrity": "sha512-sNxgpk9793nzSs7bA6JQJGeIuRBQhAaNGG77kzYQgMkrID+lS6SlK07K5LaptscDlSaIgH+GPFzf+d75FVxozA==" }, "node_modules/is-wsl": { "version": "2.2.0", @@ -17747,8 +17620,7 @@ "node_modules/isarray": { "version": "2.0.5", "resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.5.tgz", - "integrity": "sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==", - "dev": true + "integrity": "sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==" }, "node_modules/isexe": { "version": "2.0.0", @@ -18265,6 +18137,23 @@ "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, + "node_modules/jest-circus/node_modules/babel-plugin-macros": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/babel-plugin-macros/-/babel-plugin-macros-3.1.0.tgz", + "integrity": "sha512-Cg7TFGpIr01vOQNODXOOaGz2NpCU5gl8x1qJFbb6hbZxR7XrcE2vtbAsTAbJ7/xwJtUuJEw8K8Zr/AE0LHlesg==", + "dev": true, + "optional": true, + "peer": true, + "dependencies": { + "@babel/runtime": "^7.12.5", + "cosmiconfig": "^7.0.0", + "resolve": "^1.19.0" + }, + "engines": { + "node": ">=10", + "npm": ">=6" + } + }, "node_modules/jest-circus/node_modules/chalk": { "version": "4.1.2", "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", @@ -18290,15 +18179,33 @@ "color-name": "~1.1.4" }, "engines": { - "node": ">=7.0.0" + "node": ">=7.0.0" + } + }, + "node_modules/jest-circus/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "node_modules/jest-circus/node_modules/cosmiconfig": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-7.1.0.tgz", + "integrity": "sha512-AdmX6xUzdNASswsFtmwSt7Vj8po9IuqXm0UXz7QKPuEUmPB4XyjGfaAr2PSuELMwkRMVH1EpIkX5bTZGRB3eCA==", + "dev": true, + "optional": true, + "peer": true, + "dependencies": { + "@types/parse-json": "^4.0.0", + "import-fresh": "^3.2.1", + "parse-json": "^5.0.0", + "path-type": "^4.0.0", + "yaml": "^1.10.0" + }, + "engines": { + "node": ">=10" } }, - "node_modules/jest-circus/node_modules/color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "dev": true - }, "node_modules/jest-circus/node_modules/dedent": { "version": "1.5.3", "resolved": "https://registry.npmjs.org/dedent/-/dedent-1.5.3.tgz", @@ -20078,7 +19985,6 @@ "version": "1.2.0", "resolved": "https://registry.npmjs.org/js-cleanup/-/js-cleanup-1.2.0.tgz", "integrity": "sha512-JeDD0yiiSt80fXzAVa/crrS0JDPQljyBG/RpOtaSbyDq03VHa9szJWMaWOYU/bcTn412uMN2MxApXq8v79cUiQ==", - "dev": true, "dependencies": { "magic-string": "^0.25.7", "perf-regexes": "^1.0.1", @@ -20092,7 +19998,6 @@ "version": "0.25.9", "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.25.9.tgz", "integrity": "sha512-RmF0AsMzgt25qzqqLc1+MbHmhdx0ojF2Fvs4XnOqz2ZOBXzzkEwc/dJQZCYHAn7v1jbVOjAZfK8msRn4BxO4VQ==", - "dev": true, "dependencies": { "sourcemap-codec": "^1.4.8" } @@ -20107,7 +20012,7 @@ "version": "4.0.0", "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", - "dev": true + "devOptional": true }, "node_modules/js-yaml": { "version": "3.14.1", @@ -20210,7 +20115,7 @@ "version": "2.5.2", "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz", "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==", - "dev": true, + "devOptional": true, "bin": { "jsesc": "bin/jsesc" }, @@ -20229,8 +20134,7 @@ "node_modules/json-buffer": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.1.tgz", - "integrity": "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==", - "dev": true + "integrity": "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==" }, "node_modules/json-parse-even-better-errors": { "version": "2.3.1", @@ -20253,8 +20157,7 @@ "node_modules/json-stable-stringify-without-jsonify": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", - "integrity": "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==", - "dev": true + "integrity": "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==" }, "node_modules/json-stringify-safe": { "version": "5.0.1", @@ -20379,7 +20282,6 @@ "version": "4.5.4", "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.4.tgz", "integrity": "sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==", - "dev": true, "dependencies": { "json-buffer": "3.0.1" } @@ -20405,8 +20307,7 @@ "node_modules/known-css-properties": { "version": "0.34.0", "resolved": "https://registry.npmjs.org/known-css-properties/-/known-css-properties-0.34.0.tgz", - "integrity": "sha512-tBECoUqNFbyAY4RrbqsBQqDFpGXAEbdD5QKr8kACx3+rnArmuuR22nKQWKazvp07N9yjTyDZaw/20UIH8tL9DQ==", - "dev": true + "integrity": "sha512-tBECoUqNFbyAY4RrbqsBQqDFpGXAEbdD5QKr8kACx3+rnArmuuR22nKQWKazvp07N9yjTyDZaw/20UIH8tL9DQ==" }, "node_modules/kolorist": { "version": "1.8.0", @@ -20483,7 +20384,6 @@ "version": "2.1.0", "resolved": "https://registry.npmjs.org/less-plugin-autoprefixer/-/less-plugin-autoprefixer-2.1.0.tgz", "integrity": "sha512-W7rOH0tgl+h9r1Uek6ozK8U8Hzw7MQi9DjY4D2nOHQfzVAOxgD6oitXzAl/Jfg5OKM/NnPpYvUeE/95EXBLdig==", - "dev": true, "dependencies": { "autoprefixer": "^9.5.1", "postcss": "^7.0.16" @@ -20496,7 +20396,6 @@ "version": "9.8.8", "resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-9.8.8.tgz", "integrity": "sha512-eM9d/swFopRt5gdJ7jrpCwgvEMIayITpojhkkSMRsFHYuH5bkSQ4p/9qTEHtmNudUZh22Tehu7I6CxAW0IXTKA==", - "dev": true, "dependencies": { "browserslist": "^4.12.0", "caniuse-lite": "^1.0.30001109", @@ -20517,14 +20416,12 @@ "node_modules/less-plugin-autoprefixer/node_modules/picocolors": { "version": "0.2.1", "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-0.2.1.tgz", - "integrity": "sha512-cMlDqaLEqfSaW8Z7N5Jw+lyIW869EzT73/F5lhtY9cLGoVxSXznfgfXMO0Z5K0o0Q2TkTXq+0KFsdnSe3jDViA==", - "dev": true + "integrity": "sha512-cMlDqaLEqfSaW8Z7N5Jw+lyIW869EzT73/F5lhtY9cLGoVxSXznfgfXMO0Z5K0o0Q2TkTXq+0KFsdnSe3jDViA==" }, "node_modules/less-plugin-autoprefixer/node_modules/postcss": { "version": "7.0.39", "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.39.tgz", "integrity": "sha512-yioayjNbHn6z1/Bywyb2Y4s3yvDAeXGOyxqD+LnVOinq6Mdmd++SW2wUNVzavyyHxd6+DxzWGIuosg6P1Rj8uA==", - "dev": true, "dependencies": { "picocolors": "^0.2.1", "source-map": "^0.6.1" @@ -20541,7 +20438,6 @@ "version": "0.6.1", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "dev": true, "engines": { "node": ">=0.10.0" } @@ -20616,7 +20512,6 @@ "version": "0.4.1", "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==", - "dev": true, "dependencies": { "prelude-ls": "^1.2.1", "type-check": "~0.4.0" @@ -20810,8 +20705,7 @@ "node_modules/locate-character": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/locate-character/-/locate-character-3.0.0.tgz", - "integrity": "sha512-SW13ws7BjaeJ6p7Q6CO2nchbYEc3X3J6WrmTTDto7yMPqVSZTUyY5Tjbid+Ab8gLnATtygYtiDIJGQRRn2ZOiA==", - "dev": true + "integrity": "sha512-SW13ws7BjaeJ6p7Q6CO2nchbYEc3X3J6WrmTTDto7yMPqVSZTUyY5Tjbid+Ab8gLnATtygYtiDIJGQRRn2ZOiA==" }, "node_modules/locate-path": { "version": "5.0.0", @@ -20877,8 +20771,7 @@ "node_modules/lodash.merge": { "version": "4.6.2", "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", - "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==", - "dev": true + "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==" }, "node_modules/lodash.once": { "version": "4.1.1", @@ -21107,7 +21000,7 @@ "version": "5.1.1", "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz", "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==", - "dev": true, + "devOptional": true, "dependencies": { "yallist": "^3.0.2" } @@ -21124,7 +21017,6 @@ "version": "0.30.5", "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.5.tgz", "integrity": "sha512-7xlpfBaQaP/T6Vh8MO/EqXSW5En6INHEvEXQiuff7Gku0PWjU3uf6w/j9o7O+SpB5fOAkrI5HeoNgwjEO0pFsA==", - "dev": true, "dependencies": { "@jridgewell/sourcemap-codec": "^1.4.15" }, @@ -21282,7 +21174,7 @@ "version": "1.3.6", "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz", "integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==", - "dev": true + "devOptional": true }, "node_modules/makeerror": { "version": "1.0.12", @@ -21323,8 +21215,7 @@ "node_modules/mdn-data": { "version": "2.0.30", "resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.0.30.tgz", - "integrity": "sha512-GaqWWShW4kv/G9IEucWScBx9G1/vsFZZJUO+tD26M8J8z3Kw5RDQjaoZe03YAClgeS/SWPOcb4nkFBTEi5DUEA==", - "dev": true + "integrity": "sha512-GaqWWShW4kv/G9IEucWScBx9G1/vsFZZJUO+tD26M8J8z3Kw5RDQjaoZe03YAClgeS/SWPOcb4nkFBTEi5DUEA==" }, "node_modules/media-typer": { "version": "0.3.0", @@ -21361,7 +21252,6 @@ "version": "1.4.1", "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", - "dev": true, "engines": { "node": ">= 8" } @@ -21387,7 +21277,6 @@ "version": "4.0.7", "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.7.tgz", "integrity": "sha512-LPP/3KorzCwBxfeUuZmaR6bG2kdeHSbe0P2tY3FLRU4vYrjYz5hI4QZwV0njUx3jeuKe67YukQ1LSPZBKDqO/Q==", - "dev": true, "dependencies": { "braces": "^3.0.3", "picomatch": "^2.3.1" @@ -21451,7 +21340,6 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/min-indent/-/min-indent-1.0.1.tgz", "integrity": "sha512-I9jwMn07Sy/IwOj3zVkVik2JTvgpaykDZEigL6Rx6N9LbMywwUSMtxET+7lVoDLLd3O3IXwJwvuuns8UB/HeAg==", - "dev": true, "engines": { "node": ">=4" } @@ -21539,7 +21427,6 @@ "version": "9.0.3", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.3.tgz", "integrity": "sha512-RHiac9mvaRw0x3AYRgDC1CxAP7HTcNrrECeA8YYJeWnpo+2Q5CegtZjaotWTWxDG3UeGA1coE05iH1mPjT/2mg==", - "dev": true, "dependencies": { "brace-expansion": "^2.0.1" }, @@ -21682,7 +21569,6 @@ "version": "3.3.7", "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.7.tgz", "integrity": "sha512-eSRppjcPIatRIMC1U6UngP8XFcz8MQWGQdt1MTBQ7NaAmvXDfvNxbvWV3x2y6CdEUciCSsDHDQZbhYaB8QEo2g==", - "dev": true, "funding": [ { "type": "github", @@ -21705,8 +21591,7 @@ "node_modules/natural-compare": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", - "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==", - "dev": true + "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==" }, "node_modules/ndjson": { "version": "2.0.0", @@ -21731,7 +21616,6 @@ "version": "3.3.1", "resolved": "https://registry.npmjs.org/needle/-/needle-3.3.1.tgz", "integrity": "sha512-6k0YULvhpw+RoLNiQCRKOl09Rv1dPLr8hHnVjHqdolKwDrdNyk+Hmrthi4lIGPPz3r39dLx0hsF5s40sZ3Us4Q==", - "dev": true, "optional": true, "dependencies": { "iconv-lite": "^0.6.3", @@ -21885,14 +21769,13 @@ "node_modules/node-releases": { "version": "2.0.14", "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.14.tgz", - "integrity": "sha512-y10wOWt8yZpqXmOgRo77WaHEmhYQYGNA6y421PKsKYWEK8aW+cqAphborZDhqfyKrbZEN92CN1X2KbafY2s7Yw==", - "dev": true + "integrity": "sha512-y10wOWt8yZpqXmOgRo77WaHEmhYQYGNA6y421PKsKYWEK8aW+cqAphborZDhqfyKrbZEN92CN1X2KbafY2s7Yw==" }, "node_modules/normalize-path": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", - "dev": true, + "devOptional": true, "engines": { "node": ">=0.10.0" } @@ -21901,7 +21784,6 @@ "version": "0.1.2", "resolved": "https://registry.npmjs.org/normalize-range/-/normalize-range-0.1.2.tgz", "integrity": "sha512-bdok/XvKII3nUpklnV6P2hxtMNrCboOjAcyBuQnWEhO665FwrSNRxU+AqpsyvO6LgGYPspN+lu5CLtw4jPRKNA==", - "dev": true, "engines": { "node": ">=0.10.0" } @@ -21960,8 +21842,7 @@ "node_modules/num2fraction": { "version": "1.2.2", "resolved": "https://registry.npmjs.org/num2fraction/-/num2fraction-1.2.2.tgz", - "integrity": "sha512-Y1wZESM7VUThYY+4W+X4ySH2maqcA+p7UR+w8VWNWVAd6lwuXXWz/w/Cz43J/dI2I+PS6wD5N+bJUF+gjWvIqg==", - "dev": true + "integrity": "sha512-Y1wZESM7VUThYY+4W+X4ySH2maqcA+p7UR+w8VWNWVAd6lwuXXWz/w/Cz43J/dI2I+PS6wD5N+bJUF+gjWvIqg==" }, "node_modules/nwsapi": { "version": "2.2.10", @@ -22161,7 +22042,6 @@ "version": "1.1.1", "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==", - "dev": true, "engines": { "node": ">= 0.4" } @@ -22175,7 +22055,6 @@ "version": "4.1.5", "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.5.tgz", "integrity": "sha512-byy+U7gp+FVwmyzKPYhW2h5l3crpmGsxl7X2s8y43IgxvG4g3QZ6CffDtsNQy1WsmZpQbO+ybo0AlW7TY6DcBQ==", - "dev": true, "dependencies": { "call-bind": "^1.0.5", "define-properties": "^1.2.1", @@ -22193,7 +22072,6 @@ "version": "2.0.8", "resolved": "https://registry.npmjs.org/object.fromentries/-/object.fromentries-2.0.8.tgz", "integrity": "sha512-k6E21FzySsSK5a21KRADBd/NGneRegFO5pLHfdQLpRDETUNJueLXs3WCzyQ3tFRDYgbq3KHGXfTbi2bs8WQ6rQ==", - "dev": true, "dependencies": { "call-bind": "^1.0.7", "define-properties": "^1.2.1", @@ -22211,7 +22089,6 @@ "version": "1.0.3", "resolved": "https://registry.npmjs.org/object.groupby/-/object.groupby-1.0.3.tgz", "integrity": "sha512-+Lhy3TQTuzXI5hevh8sBGqbmurHbbIjAi0Z4S63nthVLmLxfbj4T54a4CfZrXIrt9iP4mVAPYMo/v99taj3wjQ==", - "dev": true, "dependencies": { "call-bind": "^1.0.7", "define-properties": "^1.2.1", @@ -22225,7 +22102,6 @@ "version": "1.2.0", "resolved": "https://registry.npmjs.org/object.values/-/object.values-1.2.0.tgz", "integrity": "sha512-yBYjY9QX2hnRmZHAjG/f13MzmBzxzYgQhFrke06TTyKY5zSTEqkOeukBzIdVA3j3ulu8Qa3MbVFShV7T2RmGtQ==", - "dev": true, "dependencies": { "call-bind": "^1.0.7", "define-properties": "^1.2.1", @@ -22307,7 +22183,6 @@ "version": "1.5.2", "resolved": "https://registry.npmjs.org/opener/-/opener-1.5.2.tgz", "integrity": "sha512-ur5UIdyw5Y7yEj9wLzhqXiy6GZ3Mwx0yGI+5sMn2r0N0v3cKJvUmFH5yPP+WXh9e0xfyzyJX95D8l088DNFj7A==", - "dev": true, "bin": { "opener": "bin/opener-bin.js" } @@ -22316,7 +22191,6 @@ "version": "0.9.4", "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.4.tgz", "integrity": "sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g==", - "dev": true, "dependencies": { "deep-is": "^0.1.3", "fast-levenshtein": "^2.0.6", @@ -22533,7 +22407,6 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", - "dev": true, "dependencies": { "callsites": "^3.0.0" }, @@ -22591,7 +22464,6 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/parse-node-version/-/parse-node-version-1.0.1.tgz", "integrity": "sha512-3YHlOa/JgH6Mnpr05jP9eDG254US9ek25LyIxZlDItp2iJtwyaXQb57lBYLdT3MowkUFYEV2XXNAYIPlESvJlA==", - "dev": true, "engines": { "node": ">= 0.10" } @@ -22658,8 +22530,7 @@ "node_modules/path-parse": { "version": "1.0.7", "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", - "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", - "dev": true + "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==" }, "node_modules/path-scurry": { "version": "1.11.1", @@ -22693,7 +22564,6 @@ "version": "4.0.0", "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==", - "dev": true, "engines": { "node": ">=8" } @@ -22723,7 +22593,6 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/perf-regexes/-/perf-regexes-1.0.1.tgz", "integrity": "sha512-L7MXxUDtqr4PUaLFCDCXBfGV/6KLIuSEccizDI7JxT+c9x1G1v04BQ4+4oag84SHaCdrBgQAIs/Cqn+flwFPng==", - "dev": true, "engines": { "node": ">=6.14" } @@ -22738,7 +22607,6 @@ "version": "3.1.0", "resolved": "https://registry.npmjs.org/periscopic/-/periscopic-3.1.0.tgz", "integrity": "sha512-vKiQ8RRtkl9P+r/+oefh25C3fhybptkHKCZSPlcXiJux2tJF55GnEj3BVn4A5gKfq9NWWXXrxkHBwVPUfH0opw==", - "dev": true, "dependencies": { "@types/estree": "^1.0.0", "estree-walker": "^3.0.0", @@ -22749,7 +22617,6 @@ "version": "3.0.3", "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-3.0.3.tgz", "integrity": "sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g==", - "dev": true, "dependencies": { "@types/estree": "^1.0.0" } @@ -22758,7 +22625,6 @@ "version": "3.0.2", "resolved": "https://registry.npmjs.org/is-reference/-/is-reference-3.0.2.tgz", "integrity": "sha512-v3rht/LgVcsdZa3O2Nqs+NMowLOxeOm7Ay9+/ARQ2F+qEoANRcqrjAZKGN0v8ymUetZGgkp26LTnGT7H0Qo9Pg==", - "dev": true, "dependencies": { "@types/estree": "*" } @@ -22766,14 +22632,12 @@ "node_modules/picocolors": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.1.tgz", - "integrity": "sha512-anP1Z8qwhkbmu7MFP5iTt+wQKXgwzf7zTyGlcdzabySa9vd0Xt392U0rVmz9poOaBj0uHJKyyo9/upk0HrEQew==", - "dev": true + "integrity": "sha512-anP1Z8qwhkbmu7MFP5iTt+wQKXgwzf7zTyGlcdzabySa9vd0Xt392U0rVmz9poOaBj0uHJKyyo9/upk0HrEQew==" }, "node_modules/picomatch": { "version": "2.3.1", "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", - "dev": true, "engines": { "node": ">=8.6" }, @@ -22956,7 +22820,6 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/possible-typed-array-names/-/possible-typed-array-names-1.0.0.tgz", "integrity": "sha512-d7Uw+eZoloe0EHDIYoe+bQ5WXnGMOpmiZFTuMWCwpjzzkL2nTjcKiAk4hh8TjnGye2TwWOk3UXucZ+3rbmBa8Q==", - "dev": true, "engines": { "node": ">= 0.4" } @@ -22965,7 +22828,6 @@ "version": "8.4.39", "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.39.tgz", "integrity": "sha512-0vzE+lAiG7hZl1/9I8yzKLx3aR9Xbof3fBHKunvMfOCYAtMhrsnccJY2iTURb9EZd5+pLuiNV9/c/GZJOHsgIw==", - "dev": true, "funding": [ { "type": "opencollective", @@ -23108,7 +22970,6 @@ "version": "3.1.4", "resolved": "https://registry.npmjs.org/postcss-load-config/-/postcss-load-config-3.1.4.tgz", "integrity": "sha512-6DiM4E7v4coTE4uzA8U//WhtPwyhiim3eyjEMFCnUpzbrkK9wJHgKDT2mR+HbtSrd/NubVaYTOpSpjUl8NQeRg==", - "dev": true, "dependencies": { "lilconfig": "^2.0.5", "yaml": "^1.10.2" @@ -23137,7 +22998,6 @@ "version": "2.1.0", "resolved": "https://registry.npmjs.org/lilconfig/-/lilconfig-2.1.0.tgz", "integrity": "sha512-utWOt/GHzuUxnLKxB6dk81RoOeoNeHgbrXiuGk4yyF5qlRz+iIVWu56E2fqGHFrXz0QNUhLB/8nKqvRH66JKGQ==", - "dev": true, "engines": { "node": ">=10" } @@ -23533,7 +23393,6 @@ "version": "6.0.0", "resolved": "https://registry.npmjs.org/postcss-safe-parser/-/postcss-safe-parser-6.0.0.tgz", "integrity": "sha512-FARHN8pwH+WiS2OPCxJI8FuRJpTVnn6ZNFiqAM2aeW2LwTHWWmWgIyKC6cUo0L8aeKiF/14MNvnpls6R2PBeMQ==", - "dev": true, "engines": { "node": ">=12.0" }, @@ -23549,7 +23408,6 @@ "version": "4.0.9", "resolved": "https://registry.npmjs.org/postcss-scss/-/postcss-scss-4.0.9.tgz", "integrity": "sha512-AjKOeiwAitL/MXxQW2DliT28EKukvvbEWx3LBmJIRN8KfBGZbRTxNYW0kSqi1COiTZ57nZ9NW06S6ux//N1c9A==", - "dev": true, "funding": [ { "type": "opencollective", @@ -23575,7 +23433,6 @@ "version": "6.1.0", "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.1.0.tgz", "integrity": "sha512-UMz42UD0UY0EApS0ZL9o1XnLhSTtvvvLe5Dc2H2O56fvRZi+KulDyf5ctDhhtYJBGKStV2FL1fy6253cmLgqVQ==", - "dev": true, "dependencies": { "cssesc": "^3.0.0", "util-deprecate": "^1.0.2" @@ -23618,8 +23475,18 @@ "node_modules/postcss-value-parser": { "version": "4.2.0", "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-4.2.0.tgz", - "integrity": "sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==", - "dev": true + "integrity": "sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==" + }, + "node_modules/preact": { + "version": "10.22.1", + "resolved": "https://registry.npmjs.org/preact/-/preact-10.22.1.tgz", + "integrity": "sha512-jRYbDDgMpIb5LHq3hkI0bbl+l/TQ9UnkdQ0ww+lp+4MMOdqaUYdFc5qeyP+IV8FAd/2Em7drVPeKdQxsiWCf/A==", + "dev": true, + "peer": true, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/preact" + } }, "node_modules/prebuild-install": { "version": "7.1.2", @@ -23663,7 +23530,6 @@ "version": "1.2.1", "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==", - "dev": true, "engines": { "node": ">= 0.8.0" } @@ -23844,7 +23710,6 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/prr/-/prr-1.0.1.tgz", "integrity": "sha512-yPw4Sng1gWghHQWj0B3ZggWUm4qVbPwPFcRG8KyxiU7J2OHFSoEHKS+EZ3fv5l1t9CyCiop6l/ZYeWbrgoQejw==", - "dev": true, "optional": true }, "node_modules/psl": { @@ -23867,7 +23732,6 @@ "version": "2.3.1", "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==", - "dev": true, "engines": { "node": ">=6" } @@ -24033,7 +23897,6 @@ "version": "1.2.3", "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", - "dev": true, "funding": [ { "type": "github", @@ -24072,7 +23935,6 @@ "version": "2.1.0", "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==", - "dev": true, "dependencies": { "safe-buffer": "^5.1.0" } @@ -24197,7 +24059,7 @@ "version": "3.6.0", "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", - "dev": true, + "devOptional": true, "dependencies": { "picomatch": "^2.2.1" }, @@ -24273,7 +24135,6 @@ "version": "1.5.2", "resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.5.2.tgz", "integrity": "sha512-NcDiDkTLuPR+++OCKB0nWafEmhg/Da8aUPLPMQbK+bxKKCm1/S5he+AqYa4PlMCVBalb4/yxIRub6qkEx5yJbw==", - "dev": true, "dependencies": { "call-bind": "^1.0.6", "define-properties": "^1.2.1", @@ -24410,7 +24271,6 @@ "version": "1.22.8", "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.8.tgz", "integrity": "sha512-oKWePCxqpd6FlLvGV1VU0x7bkPmmCNolxzjMf4NczoDnQcIWrAF+cPtZn5i6n+RfD2d9i0tzpKnG6Yk168yIyw==", - "dev": true, "dependencies": { "is-core-module": "^2.13.0", "path-parse": "^1.0.7", @@ -24448,7 +24308,6 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/resolve-pkg-maps/-/resolve-pkg-maps-1.0.0.tgz", "integrity": "sha512-seS2Tj26TBVOC2NIc2rOe2y2ZO7efxITtLZcGSOnHHNOQ7CkiUBfw0Iw2ck6xkIhPwLhKNLS8BO+hEpngQlqzw==", - "dev": true, "funding": { "url": "https://github.com/privatenumber/resolve-pkg-maps?sponsor=1" } @@ -24500,7 +24359,6 @@ "version": "1.0.4", "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==", - "dev": true, "engines": { "iojs": ">=1.0.0", "node": ">=0.10.0" @@ -24517,7 +24375,6 @@ "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", "deprecated": "Rimraf versions prior to v4 are no longer supported", - "dev": true, "dependencies": { "glob": "^7.1.3" }, @@ -24532,7 +24389,6 @@ "version": "1.1.11", "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", - "dev": true, "dependencies": { "balanced-match": "^1.0.0", "concat-map": "0.0.1" @@ -24543,7 +24399,6 @@ "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", "deprecated": "Glob versions prior to v9 are no longer supported", - "dev": true, "dependencies": { "fs.realpath": "^1.0.0", "inflight": "^1.0.4", @@ -24563,7 +24418,6 @@ "version": "3.1.2", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", - "dev": true, "dependencies": { "brace-expansion": "^1.1.7" }, @@ -24579,14 +24433,12 @@ "node_modules/robust-predicates": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/robust-predicates/-/robust-predicates-3.0.2.tgz", - "integrity": "sha512-IXgzBWvWQwE6PrDI05OvmXUIruQTcoMDzRsOd5CDvHCVLcLHMTSYvOK5Cm46kWqlV3yAbuSpBZdJ5oP5OUoStg==", - "dev": true + "integrity": "sha512-IXgzBWvWQwE6PrDI05OvmXUIruQTcoMDzRsOd5CDvHCVLcLHMTSYvOK5Cm46kWqlV3yAbuSpBZdJ5oP5OUoStg==" }, "node_modules/rollup": { "version": "2.79.1", "resolved": "https://registry.npmjs.org/rollup/-/rollup-2.79.1.tgz", "integrity": "sha512-uKxbd0IhMZOhjAiD5oAFp7BqvkA4Dv47qpOCtaNvng4HBwdbWtdOh8f5nZNuk2rp51PMGk3bzfWu5oayNEuYnw==", - "dev": true, "bin": { "rollup": "dist/bin/rollup" }, @@ -24601,7 +24453,6 @@ "version": "3.2.1", "resolved": "https://registry.npmjs.org/rollup-plugin-cleanup/-/rollup-plugin-cleanup-3.2.1.tgz", "integrity": "sha512-zuv8EhoO3TpnrU8MX8W7YxSbO4gmOR0ny06Lm3nkFfq0IVKdBUtHwhVzY1OAJyNCIAdLiyPnOrU0KnO0Fri1GQ==", - "dev": true, "dependencies": { "js-cleanup": "^1.2.0", "rollup-pluginutils": "^2.8.2" @@ -24666,7 +24517,6 @@ "version": "1.1.1", "resolved": "https://registry.npmjs.org/rollup-plugin-serve/-/rollup-plugin-serve-1.1.1.tgz", "integrity": "sha512-H0VarZRtFR0lfiiC9/P8jzCDvtFf1liOX4oSdIeeYqUCKrmFA7vNiQ0rg2D+TuoP7leaa/LBR8XBts5viF6lnw==", - "dev": true, "dependencies": { "mime": "^2", "opener": "1" @@ -24676,7 +24526,6 @@ "version": "2.6.0", "resolved": "https://registry.npmjs.org/mime/-/mime-2.6.0.tgz", "integrity": "sha512-USPkMeET31rOMiarsBNIHZKLGgvKc/LrjofAnBlOttf5ajRvqiRA8QsenbcooctK6d6Ts6aqZXBA+XbkKthiQg==", - "dev": true, "bin": { "mime": "cli.js" }, @@ -24688,7 +24537,6 @@ "version": "7.2.2", "resolved": "https://registry.npmjs.org/rollup-plugin-svelte/-/rollup-plugin-svelte-7.2.2.tgz", "integrity": "sha512-hgnIblTRewaBEVQD6N0Q43o+y6q1TmDRhBjaEzQCi50bs8TXqjc+d1zFZyE8tsfgcfNHZQzclh4RxlFUB85H8Q==", - "dev": true, "dependencies": { "@rollup/pluginutils": "^4.1.0", "resolve.exports": "^2.0.0" @@ -24705,7 +24553,6 @@ "version": "2.0.2", "resolved": "https://registry.npmjs.org/resolve.exports/-/resolve.exports-2.0.2.tgz", "integrity": "sha512-X2UW6Nw3n/aMgDVy+0rSqgHlv39WZAlZrXCdnbyEiKm17DSqHX4MmQMaST3FbeWR5FTuRcUwYAziZajji0Y7mg==", - "dev": true, "engines": { "node": ">=10" } @@ -24714,7 +24561,6 @@ "version": "0.11.2", "resolved": "https://registry.npmjs.org/rollup-plugin-swc3/-/rollup-plugin-swc3-0.11.2.tgz", "integrity": "sha512-o1ih9B806fV2wBSNk46T0cYfTF2eiiKmYXRpWw3K4j/Cp3tCAt10UCVsTqvUhGP58pcB3/GZcAVl5e7TCSKN6Q==", - "dev": true, "dependencies": { "@fastify/deepmerge": "^1.3.0", "@rollup/pluginutils": "^5.1.0", @@ -24733,7 +24579,6 @@ "version": "5.1.0", "resolved": "https://registry.npmjs.org/@rollup/pluginutils/-/pluginutils-5.1.0.tgz", "integrity": "sha512-XTIWOPPcpvyKI6L1NHo0lFlCyznUEyPmPY1mc3KpPVDYulHSTvyeLNVW00QTLIAFNhR3kYnJTQHeGqU4M3n09g==", - "dev": true, "dependencies": { "@types/estree": "^1.0.0", "estree-walker": "^2.0.2", @@ -24781,7 +24626,6 @@ "version": "2.8.2", "resolved": "https://registry.npmjs.org/rollup-pluginutils/-/rollup-pluginutils-2.8.2.tgz", "integrity": "sha512-EEp9NhnUkwY8aif6bxgovPHMoMoNr2FulJziTndpt5H9RdwC47GSGuII9XxpSdzVGM0GWrNPHV6ie1LTNJPaLQ==", - "dev": true, "dependencies": { "estree-walker": "^0.6.1" } @@ -24789,14 +24633,12 @@ "node_modules/rollup-pluginutils/node_modules/estree-walker": { "version": "0.6.1", "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-0.6.1.tgz", - "integrity": "sha512-SqmZANLWS0mnatqbSfRP5g8OXZC12Fgg1IwNtLsyHDzJizORW4khDfjPqJZsemPWBB2uqykUah5YpQ6epsqC/w==", - "dev": true + "integrity": "sha512-SqmZANLWS0mnatqbSfRP5g8OXZC12Fgg1IwNtLsyHDzJizORW4khDfjPqJZsemPWBB2uqykUah5YpQ6epsqC/w==" }, "node_modules/rollup-preserve-directives": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/rollup-preserve-directives/-/rollup-preserve-directives-1.1.1.tgz", "integrity": "sha512-+eQafbuEfDPfxQ9hQPlwaROfin4yiVRxap8hnrvvvcSGoukv1tTiYpAW9mvm3uR8J+fe4xd8FdVd5rz9q7jZ+Q==", - "dev": true, "dependencies": { "magic-string": "^0.30.5" }, @@ -24814,7 +24656,6 @@ "version": "1.2.0", "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==", - "dev": true, "funding": [ { "type": "github", @@ -24836,8 +24677,7 @@ "node_modules/rw": { "version": "1.3.3", "resolved": "https://registry.npmjs.org/rw/-/rw-1.3.3.tgz", - "integrity": "sha512-PdhdWy89SiZogBLaw42zdeqtRJ//zFd2PgQavcICDUgJT5oW10QCRKbJ6bg4r0/UY2M6BWd5tkxuGFRvCkgfHQ==", - "dev": true + "integrity": "sha512-PdhdWy89SiZogBLaw42zdeqtRJ//zFd2PgQavcICDUgJT5oW10QCRKbJ6bg4r0/UY2M6BWd5tkxuGFRvCkgfHQ==" }, "node_modules/rxjs": { "version": "7.8.1", @@ -24864,7 +24704,6 @@ "version": "1.1.2", "resolved": "https://registry.npmjs.org/safe-array-concat/-/safe-array-concat-1.1.2.tgz", "integrity": "sha512-vj6RsCsWBCf19jIeHEfkRMw8DPiBb+DMXklQ/1SGDHOMlHdPUkZXFQ2YdplS23zESTijAcurb1aSgJA3AgMu1Q==", - "dev": true, "dependencies": { "call-bind": "^1.0.7", "get-intrinsic": "^1.2.4", @@ -24887,7 +24726,6 @@ "version": "1.0.3", "resolved": "https://registry.npmjs.org/safe-regex-test/-/safe-regex-test-1.0.3.tgz", "integrity": "sha512-CdASjNJPvRa7roO6Ra/gLYBTzYzzPyyBXxIMdGW3USQLyjWEls2RgW5UBTXaQVp+OrpeCK3bLem8smtmheoRuw==", - "dev": true, "dependencies": { "call-bind": "^1.0.6", "es-errors": "^1.3.0", @@ -24909,7 +24747,6 @@ "version": "0.5.1", "resolved": "https://registry.npmjs.org/sander/-/sander-0.5.1.tgz", "integrity": "sha512-3lVqBir7WuKDHGrKRDn/1Ye3kwpXaDOMsiRP1wd6wpZW56gJhsbp5RqQpA6JG/P+pkXizygnr1dKR8vzWaVsfA==", - "dev": true, "dependencies": { "es6-promise": "^3.1.2", "graceful-fs": "^4.1.3", @@ -24921,7 +24758,6 @@ "version": "1.1.11", "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", - "dev": true, "dependencies": { "balanced-match": "^1.0.0", "concat-map": "0.0.1" @@ -24932,7 +24768,6 @@ "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", "deprecated": "Glob versions prior to v9 are no longer supported", - "dev": true, "dependencies": { "fs.realpath": "^1.0.0", "inflight": "^1.0.4", @@ -24952,7 +24787,6 @@ "version": "3.1.2", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", - "dev": true, "dependencies": { "brace-expansion": "^1.1.7" }, @@ -24965,7 +24799,6 @@ "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz", "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==", "deprecated": "Rimraf versions prior to v4 are no longer supported", - "dev": true, "dependencies": { "glob": "^7.1.3" }, @@ -24977,7 +24810,7 @@ "version": "1.77.6", "resolved": "https://registry.npmjs.org/sass/-/sass-1.77.6.tgz", "integrity": "sha512-ByXE1oLD79GVq9Ht1PeHWCPMPB8XHpBuz1r85oByKHjZY6qV6rWnQovQzXJXuQ/XyE1Oj3iPk3lo28uzaRA2/Q==", - "dev": true, + "devOptional": true, "dependencies": { "chokidar": ">=3.0.0 <4.0.0", "immutable": "^4.0.0", @@ -25093,7 +24926,6 @@ "version": "6.3.1", "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", - "dev": true, "bin": { "semver": "bin/semver.js" } @@ -25154,7 +24986,6 @@ "version": "6.0.2", "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-6.0.2.tgz", "integrity": "sha512-Saa1xPByTTq2gdeFZYLLo+RFE35NHZkAbqZeWNd3BpzppeVisAqpDjcp8dyf6uIvEqJRd46jemmyA4iFIeVk8g==", - "dev": true, "dependencies": { "randombytes": "^2.1.0" } @@ -25322,7 +25153,6 @@ "version": "2.0.2", "resolved": "https://registry.npmjs.org/set-function-name/-/set-function-name-2.0.2.tgz", "integrity": "sha512-7PGFlmtwsEADb0WYyvCMa1t+yke6daIG4Wirafur5kcf+MhUnPms1UeR0CKQdTZD81yESwMHbtn+TR+dMviakQ==", - "dev": true, "dependencies": { "define-data-property": "^1.1.4", "es-errors": "^1.3.0", @@ -25528,7 +25358,6 @@ "version": "1.0.2", "resolved": "https://registry.npmjs.org/skip-regex/-/skip-regex-1.0.2.tgz", "integrity": "sha512-pEjMUbwJ5Pl/6Vn6FsamXHXItJXSRftcibixDmNCWbWhic0hzHrwkMZo0IZ7fMRH9KxcWDFSkzhccB4285PutA==", - "dev": true, "engines": { "node": ">=4.2" } @@ -25537,7 +25366,6 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", - "dev": true, "engines": { "node": ">=8" } @@ -25592,8 +25420,7 @@ "node_modules/smob": { "version": "1.5.0", "resolved": "https://registry.npmjs.org/smob/-/smob-1.5.0.tgz", - "integrity": "sha512-g6T+p7QO8npa+/hNx9ohv1E5pVCmWrVCUzUXJyLdMmftX6ER0oiWY/w9knEonLpnOp6b6FenKnMfR8gqwWdwig==", - "dev": true + "integrity": "sha512-g6T+p7QO8npa+/hNx9ohv1E5pVCmWrVCUzUXJyLdMmftX6ER0oiWY/w9knEonLpnOp6b6FenKnMfR8gqwWdwig==" }, "node_modules/sockjs": { "version": "0.3.24", @@ -25610,7 +25437,6 @@ "version": "0.11.1", "resolved": "https://registry.npmjs.org/sorcery/-/sorcery-0.11.1.tgz", "integrity": "sha512-o7npfeJE6wi6J9l0/5LKshFzZ2rMatRiCDwYeDQaOzqdzRJwALhX7mk/A/ecg6wjMu7wdZbmXfD2S/vpOg0bdQ==", - "dev": true, "dependencies": { "@jridgewell/sourcemap-codec": "^1.4.14", "buffer-crc32": "^1.0.0", @@ -25625,7 +25451,6 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/buffer-crc32/-/buffer-crc32-1.0.0.tgz", "integrity": "sha512-Db1SbgBS/fg/392AblrMJk97KggmvYhr4pB5ZIMTWtaivCPMWLkmb7m21cJvpvgK+J3nsU2CmmixNBZx4vFj/w==", - "dev": true, "engines": { "node": ">=8.0.0" } @@ -25639,7 +25464,7 @@ "version": "0.7.4", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.4.tgz", "integrity": "sha512-l3BikUxvPOcn5E74dZiq5BGsTb5yEwhaTSzccU6t4sDOH8NWJCstKO5QT2CvtFoK6F0saL7p9xHAqHOlCPJygA==", - "dev": true, + "devOptional": true, "engines": { "node": ">= 8" } @@ -25648,7 +25473,6 @@ "version": "1.2.0", "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.0.tgz", "integrity": "sha512-itJW8lvSA0TXEphiRoawsCksnlf8SyvmFzIhltqAHluXd88pkCd+cXJVHTDwdCr0IzwptSm035IHQktUu1QUMg==", - "dev": true, "engines": { "node": ">=0.10.0" } @@ -25673,6 +25497,18 @@ "webpack": "^5.72.1" } }, + "node_modules/source-map-resolve": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/source-map-resolve/-/source-map-resolve-0.6.0.tgz", + "integrity": "sha512-KXBr9d/fO/bWo97NXsPIAW1bFSBOuCnjbNTBMO7N59hsv5i9yzRDfcYwwt0l04+VqnKC+EwzvJZIP/qkuMgR/w==", + "deprecated": "See https://github.com/lydell/source-map-resolve#deprecated", + "optional": true, + "peer": true, + "dependencies": { + "atob": "^2.1.2", + "decode-uri-component": "^0.2.0" + } + }, "node_modules/source-map-support": { "version": "0.5.19", "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.19.tgz", @@ -25696,8 +25532,7 @@ "version": "1.4.8", "resolved": "https://registry.npmjs.org/sourcemap-codec/-/sourcemap-codec-1.4.8.tgz", "integrity": "sha512-9NykojV5Uih4lgo5So5dtw+f0JgJX30KCNI8gwhz2J9A15wD0Ml6tjHKwf6fTSa6fAdVBdZeNOs9eJ71qCk8vA==", - "deprecated": "Please use @jridgewell/sourcemap-codec instead", - "dev": true + "deprecated": "Please use @jridgewell/sourcemap-codec instead" }, "node_modules/spdy": { "version": "4.0.2", @@ -25992,7 +25827,6 @@ "version": "1.2.9", "resolved": "https://registry.npmjs.org/string.prototype.trim/-/string.prototype.trim-1.2.9.tgz", "integrity": "sha512-klHuCNxiMZ8MlsOihJhJEBJAiMVqU3Z2nEXWfWnIqjN0gEFS9J9+IxKozWWtQGcgoa1WUZzLjKPTr4ZHNFTFxw==", - "dev": true, "dependencies": { "call-bind": "^1.0.7", "define-properties": "^1.2.1", @@ -26010,7 +25844,6 @@ "version": "1.0.8", "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.8.tgz", "integrity": "sha512-p73uL5VCHCO2BZZ6krwwQE3kCzM7NKmis8S//xEC6fQonchbum4eP6kR4DLEjQFO3Wnj3Fuo8NM0kOSjVdHjZQ==", - "dev": true, "dependencies": { "call-bind": "^1.0.7", "define-properties": "^1.2.1", @@ -26024,7 +25857,6 @@ "version": "1.0.8", "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.8.tgz", "integrity": "sha512-UXSH262CSZY1tfu3G3Secr6uGLCFVPMhIqHjlgCUtCCcgihYc/xKs9djMTMUOb2j1mVSeU8EU6NWc/iQKU6Gfg==", - "dev": true, "dependencies": { "call-bind": "^1.0.7", "define-properties": "^1.2.1", @@ -26105,7 +25937,6 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/strip-indent/-/strip-indent-3.0.0.tgz", "integrity": "sha512-laJTa3Jb+VQpaC6DseHhF7dXVqHTfJPCRDaEbid/drOhgitgYku/letMUqOXFoWV0zIIUbjpdH2t+tYj4bQMRQ==", - "dev": true, "dependencies": { "min-indent": "^1.0.0" }, @@ -26117,7 +25948,6 @@ "version": "3.1.1", "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", - "dev": true, "engines": { "node": ">=8" }, @@ -26326,7 +26156,7 @@ "version": "5.5.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", - "dev": true, + "devOptional": true, "dependencies": { "has-flag": "^3.0.0" }, @@ -26338,7 +26168,6 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==", - "dev": true, "engines": { "node": ">= 0.4" }, @@ -26350,7 +26179,6 @@ "version": "4.2.18", "resolved": "https://registry.npmjs.org/svelte/-/svelte-4.2.18.tgz", "integrity": "sha512-d0FdzYIiAePqRJEb90WlJDkjUEx42xhivxN8muUBmfZnP+tzUgz12DJ2hRJi8sIHCME7jeK1PTMgKPSfTd8JrA==", - "dev": true, "dependencies": { "@ampproject/remapping": "^2.2.1", "@jridgewell/sourcemap-codec": "^1.4.15", @@ -26391,6 +26219,120 @@ "svelte": "^3.55.0 || ^4.0.0-next.0 || ^4.0.0 || ^5.0.0-next.0" } }, + "node_modules/svelte-check/node_modules/brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dev": true, + "optional": true, + "peer": true, + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/svelte-check/node_modules/debug": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", + "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", + "dev": true, + "optional": true, + "peer": true, + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/svelte-check/node_modules/glob": { + "version": "7.2.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", + "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", + "deprecated": "Glob versions prior to v9 are no longer supported", + "dev": true, + "optional": true, + "peer": true, + "dependencies": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.1.1", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + }, + "engines": { + "node": "*" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/svelte-check/node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, + "optional": true, + "peer": true, + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/svelte-check/node_modules/mkdirp": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz", + "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==", + "dev": true, + "optional": true, + "peer": true, + "bin": { + "mkdirp": "bin/cmd.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/svelte-check/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", + "dev": true, + "optional": true, + "peer": true + }, + "node_modules/svelte-check/node_modules/sax": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/sax/-/sax-1.2.4.tgz", + "integrity": "sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw==", + "dev": true, + "optional": true, + "peer": true + }, + "node_modules/svelte-check/node_modules/stylus": { + "version": "0.55.0", + "resolved": "https://registry.npmjs.org/stylus/-/stylus-0.55.0.tgz", + "integrity": "sha512-MuzIIVRSbc8XxHH7FjkvWqkIcr1BvoMZoR/oFuAJDlh7VSaNJzrB4uJ38GRQa+mWjLXODAMzeDe0xi9GYbGwnw==", + "dev": true, + "optional": true, + "peer": true, + "dependencies": { + "css": "^3.0.0", + "debug": "~3.1.0", + "glob": "^7.1.6", + "mkdirp": "~1.0.4", + "safer-buffer": "^2.1.2", + "sax": "~1.2.4", + "semver": "^6.3.0", + "source-map": "^0.7.3" + }, + "bin": { + "stylus": "bin/stylus" + }, + "engines": { + "node": "*" + } + }, "node_modules/svelte-check/node_modules/svelte-preprocess": { "version": "5.1.4", "resolved": "https://registry.npmjs.org/svelte-preprocess/-/svelte-preprocess-5.1.4.tgz", @@ -26454,15 +26396,14 @@ } }, "node_modules/svelte-eslint-parser": { - "version": "0.39.2", - "resolved": "https://registry.npmjs.org/svelte-eslint-parser/-/svelte-eslint-parser-0.39.2.tgz", - "integrity": "sha512-87UwLuWTtDIuzWOhOi1zBL5wYVd07M5BK1qZ57YmXJB5/UmjUNJqGy3XSOhPqjckY1dATNV9y+mx+nI0WH6HPA==", - "dev": true, + "version": "0.40.0", + "resolved": "https://registry.npmjs.org/svelte-eslint-parser/-/svelte-eslint-parser-0.40.0.tgz", + "integrity": "sha512-M+v1HhC5T1WKYVxWexUCS4o6oIBS88XKzOZuhl2ew+eGxol7eC21e+VE8TC4rXJ3iT3iXT0qlZsZcpKjVo5/zQ==", "dependencies": { "eslint-scope": "^7.2.2", "eslint-visitor-keys": "^3.4.3", "espree": "^9.6.1", - "postcss": "^8.4.38", + "postcss": "^8.4.39", "postcss-scss": "^4.0.9" }, "engines": { @@ -26472,7 +26413,7 @@ "url": "https://github.com/sponsors/ota-meshi" }, "peerDependencies": { - "svelte": "^3.37.0 || ^4.0.0 || ^5.0.0-next.115" + "svelte": "^3.37.0 || ^4.0.0 || ^5.0.0-next.181" }, "peerDependenciesMeta": { "svelte": { @@ -26495,14 +26436,12 @@ "node_modules/svelte-preprocess-filter": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/svelte-preprocess-filter/-/svelte-preprocess-filter-1.0.0.tgz", - "integrity": "sha512-92innv59nyEx24xbfcSurB5ocwC8qFdDtGli/JVMHzJsxyvV2yjQKIcbUqU9VIV5mKUWO2PoY93nncS2yF4ULQ==", - "dev": true + "integrity": "sha512-92innv59nyEx24xbfcSurB5ocwC8qFdDtGli/JVMHzJsxyvV2yjQKIcbUqU9VIV5mKUWO2PoY93nncS2yF4ULQ==" }, "node_modules/svelte-preprocess-less": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/svelte-preprocess-less/-/svelte-preprocess-less-0.4.0.tgz", "integrity": "sha512-fvRA4+PWkQe5bNpCGKfYjsxxq6hyJJNn6rq/DeT0H4u6qI4o7oG340UQZZlCNZAucYMXz7Y/R1DNi8g4QsCMjg==", - "dev": true, "dependencies": { "svelte-preprocess-filter": "^1.0.0" } @@ -26511,7 +26450,6 @@ "version": "3.0.3", "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-3.0.3.tgz", "integrity": "sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g==", - "dev": true, "dependencies": { "@types/estree": "^1.0.0" } @@ -26520,7 +26458,6 @@ "version": "3.0.2", "resolved": "https://registry.npmjs.org/is-reference/-/is-reference-3.0.2.tgz", "integrity": "sha512-v3rht/LgVcsdZa3O2Nqs+NMowLOxeOm7Ay9+/ARQ2F+qEoANRcqrjAZKGN0v8ymUetZGgkp26LTnGT7H0Qo9Pg==", - "dev": true, "dependencies": { "@types/estree": "*" } @@ -26574,7 +26511,6 @@ "version": "2.2.1", "resolved": "https://registry.npmjs.org/tapable/-/tapable-2.2.1.tgz", "integrity": "sha512-GNzQvQTOIP6RyTfE2Qxb8ZVlNmw0n88vp1szwWRimP02mnTsx3Wtn5qRdqY9w2XduFNUgvOwhNnQsjwCp+kqaQ==", - "dev": true, "engines": { "node": ">=6" } @@ -26751,7 +26687,6 @@ "version": "5.31.1", "resolved": "https://registry.npmjs.org/terser/-/terser-5.31.1.tgz", "integrity": "sha512-37upzU1+viGvuFtBo9NPufCb9dwM0+l9hMxYyWfBA+fbwrPqNJAhbZ6W47bBFnZHKHTUBnMvi87434qq+qnxOg==", - "dev": true, "dependencies": { "@jridgewell/source-map": "^0.3.3", "acorn": "^8.8.2", @@ -26889,14 +26824,12 @@ "node_modules/terser/node_modules/commander": { "version": "2.20.3", "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", - "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==", - "dev": true + "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==" }, "node_modules/terser/node_modules/source-map": { "version": "0.6.1", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "dev": true, "engines": { "node": ">=0.10.0" } @@ -26905,7 +26838,6 @@ "version": "0.5.21", "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.21.tgz", "integrity": "sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==", - "dev": true, "dependencies": { "buffer-from": "^1.0.0", "source-map": "^0.6.0" @@ -26980,8 +26912,7 @@ "node_modules/text-table": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", - "integrity": "sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==", - "dev": true + "integrity": "sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==" }, "node_modules/throttleit": { "version": "1.0.1", @@ -27084,7 +27015,7 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz", "integrity": "sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog==", - "dev": true, + "devOptional": true, "engines": { "node": ">=4" } @@ -27093,7 +27024,6 @@ "version": "5.0.1", "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", - "dev": true, "dependencies": { "is-number": "^7.0.0" }, @@ -27158,7 +27088,6 @@ "version": "1.3.0", "resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-1.3.0.tgz", "integrity": "sha512-UQMIo7pb8WRomKR1/+MFVLTroIvDVtMX3K6OUir8ynLyzB8Jeriont2bTAtmNPa1ekAgN7YPDyf6V+ygrdU+eQ==", - "dev": true, "engines": { "node": ">=16" }, @@ -27331,7 +27260,7 @@ "version": "10.9.2", "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-10.9.2.tgz", "integrity": "sha512-f0FFpIdcHgn8zcPSbf1dRevwt047YMnaiJM3u2w2RewrB+fob/zePZcrOyQoLMMO7aBIddLcQIEK5dYjkLnGrQ==", - "dev": true, + "devOptional": true, "dependencies": { "@cspotcode/source-map-support": "^0.8.0", "@tsconfig/node10": "^1.0.7", @@ -27519,7 +27448,6 @@ "version": "0.4.0", "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==", - "dev": true, "dependencies": { "prelude-ls": "^1.2.1" }, @@ -27563,7 +27491,6 @@ "version": "1.0.2", "resolved": "https://registry.npmjs.org/typed-array-buffer/-/typed-array-buffer-1.0.2.tgz", "integrity": "sha512-gEymJYKZtKXzzBzM4jqa9w6Q1Jjm7x2d+sh19AdsD4wqnMPDYyvwpsIc2Q/835kHuo3BEQ7CjelGhfTsoBb2MQ==", - "dev": true, "dependencies": { "call-bind": "^1.0.7", "es-errors": "^1.3.0", @@ -27577,7 +27504,6 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/typed-array-byte-length/-/typed-array-byte-length-1.0.1.tgz", "integrity": "sha512-3iMJ9q0ao7WE9tWcaYKIptkNBuOIcZCCT0d4MRvuuH88fEoEH62IuQe0OtraD3ebQEoTRk8XCBoknUNc1Y67pw==", - "dev": true, "dependencies": { "call-bind": "^1.0.7", "for-each": "^0.3.3", @@ -27596,7 +27522,6 @@ "version": "1.0.2", "resolved": "https://registry.npmjs.org/typed-array-byte-offset/-/typed-array-byte-offset-1.0.2.tgz", "integrity": "sha512-Ous0vodHa56FviZucS2E63zkgtgrACj7omjwd/8lTEMEPFFyjfixMZ1ZXenpgCFBBt4EC1J2XsyVS2gkG0eTFA==", - "dev": true, "dependencies": { "available-typed-arrays": "^1.0.7", "call-bind": "^1.0.7", @@ -27616,7 +27541,6 @@ "version": "1.0.6", "resolved": "https://registry.npmjs.org/typed-array-length/-/typed-array-length-1.0.6.tgz", "integrity": "sha512-/OxDN6OtAk5KBpGb28T+HZc2M+ADtvRxXrKKbUwtsLgdoxgX13hyy7ek6bFRl5+aBs2yZzB0c4CnQfAtVypW/g==", - "dev": true, "dependencies": { "call-bind": "^1.0.7", "for-each": "^0.3.3", @@ -27647,7 +27571,6 @@ "version": "5.5.3", "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.5.3.tgz", "integrity": "sha512-/hreyEujaB0w76zKo6717l3L0o/qEUtRgdvUBvlkhoWeOVMjMuHNHk0BRBzikzuGDqNmPQbg5ifMEqsHLiIUcQ==", - "dev": true, "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" @@ -27689,7 +27612,6 @@ "version": "1.0.2", "resolved": "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.0.2.tgz", "integrity": "sha512-61pPlCD9h51VoreyJ0BReideM3MDKMKnh6+V9L08331ipq6Q8OFXZYiqP6n/tbHx4s5I9uRhcye6BrbkizkBDw==", - "dev": true, "dependencies": { "call-bind": "^1.0.2", "has-bigints": "^1.0.2", @@ -27879,7 +27801,6 @@ "version": "1.1.0", "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.1.0.tgz", "integrity": "sha512-EdRAaAyk2cUE1wOf2DkEhzxqOQvFOoRJFNS6NeyJ01Gp2beMRpBAINjM2iDXE3KCuKhwnvHIQCJm6ThL2Z+HzQ==", - "dev": true, "funding": [ { "type": "opencollective", @@ -27915,7 +27836,6 @@ "version": "4.4.1", "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", - "dev": true, "dependencies": { "punycode": "^2.1.0" } @@ -27961,7 +27881,7 @@ "version": "3.0.1", "resolved": "https://registry.npmjs.org/v8-compile-cache-lib/-/v8-compile-cache-lib-3.0.1.tgz", "integrity": "sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg==", - "dev": true + "devOptional": true }, "node_modules/v8-to-istanbul": { "version": "9.3.0", @@ -29172,7 +29092,6 @@ "version": "1.0.2", "resolved": "https://registry.npmjs.org/which-boxed-primitive/-/which-boxed-primitive-1.0.2.tgz", "integrity": "sha512-bwZdv0AKLpplFY2KZRX6TvyuN7ojjr7lwkg6ml0roIy9YeuSr7JS372qlNW18UQYzgYK9ziGcerWqZOmEn9VNg==", - "dev": true, "dependencies": { "is-bigint": "^1.0.1", "is-boolean-object": "^1.1.0", @@ -29193,7 +29112,6 @@ "version": "1.1.15", "resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.15.tgz", "integrity": "sha512-oV0jmFtUky6CXfkqehVvBP/LSWJ2sy4vWMioiENyJLePrBO/yKyV9OyJySfAKosh+RYkIl5zJCNZ8/4JncrpdA==", - "dev": true, "dependencies": { "available-typed-arrays": "^1.0.7", "call-bind": "^1.0.7", @@ -29228,7 +29146,6 @@ "version": "1.2.5", "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.5.tgz", "integrity": "sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==", - "dev": true, "engines": { "node": ">=0.10.0" } @@ -30255,13 +30172,12 @@ "version": "3.1.1", "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==", - "dev": true + "devOptional": true }, "node_modules/yaml": { "version": "1.10.2", "resolved": "https://registry.npmjs.org/yaml/-/yaml-1.10.2.tgz", "integrity": "sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg==", - "dev": true, "engines": { "node": ">= 6" } @@ -30305,7 +30221,7 @@ "version": "3.1.1", "resolved": "https://registry.npmjs.org/yn/-/yn-3.1.1.tgz", "integrity": "sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==", - "dev": true, + "devOptional": true, "engines": { "node": ">=6" } diff --git a/package.json b/package.json index b83105ac..6512b305 100644 --- a/package.json +++ b/package.json @@ -112,6 +112,7 @@ "@tmcw/togeojson": "^5.8.1", "@types/mapbox__sphericalmercator": "^1.2.3", "@vivaxy/png": "^1.3.0", + "@xmldom/xmldom": "^0.8.10", "axios": "1.7.2", "commander": "^12.1.0", From 4385260982777ba28110151f425171b6bf102a49 Mon Sep 17 00:00:00 2001 From: Victor Berchet Date: Thu, 11 Jul 2024 23:42:17 +0200 Subject: [PATCH 03/16] Check for updates Refactor connected components --- libs/windy-sounding/.gitignore | 3 +- libs/windy-sounding/package-lock.json | 21 + libs/windy-sounding/package.json | 4 + .../src/components/favorites.tsx | 12 +- .../windy-sounding/src/components/message.tsx | 15 + libs/windy-sounding/src/components/skewt.tsx | 75 +- .../src/components/wind-profile.tsx | 45 +- .../src/containers/containers.tsx | 825 +++++++++--------- libs/windy-sounding/src/env.d.ts | 2 + .../src/redux/forecast-slice.ts | 92 +- libs/windy-sounding/src/redux/meta.ts | 124 ++- libs/windy-sounding/src/redux/plugin-slice.ts | 103 ++- libs/windy-sounding/src/sounding.tsx | 34 +- libs/windy-sounding/src/styles.less | 8 + package-lock.json | 762 +++++++++++++--- package.json | 3 +- 16 files changed, 1393 insertions(+), 735 deletions(-) create mode 100644 libs/windy-sounding/src/components/message.tsx diff --git a/libs/windy-sounding/.gitignore b/libs/windy-sounding/.gitignore index 95e8d9f9..87244720 100644 --- a/libs/windy-sounding/.gitignore +++ b/libs/windy-sounding/.gitignore @@ -1 +1,2 @@ -/.env.local \ No newline at end of file +/.env.local +/types \ No newline at end of file diff --git a/libs/windy-sounding/package-lock.json b/libs/windy-sounding/package-lock.json index 650c4e5e..ff7ed3ea 100644 --- a/libs/windy-sounding/package-lock.json +++ b/libs/windy-sounding/package-lock.json @@ -15,7 +15,11 @@ "geojson": "^0.5.0", "preact": "^10.22.1", "react-redux": "^9.1.2", + "semver": "^7.6.2", "svelte": "^4.2.18" + }, + "devDependencies": { + "@types/semver": "^7.5.8" } }, "node_modules/@ampproject/remapping": { @@ -725,6 +729,12 @@ "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.5.tgz", "integrity": "sha512-/kYRxGDLWzHOB7q+wtSUQlFrtcdUccpfy+X+9iMBpHK8QLLhx2wIPYuS5DYtR9Wa/YlZAbIovy7qVdB1Aq6Lyw==" }, + "node_modules/@types/semver": { + "version": "7.5.8", + "resolved": "https://registry.npmjs.org/@types/semver/-/semver-7.5.8.tgz", + "integrity": "sha512-I8EUhyrgfLrcTkzV3TSsGyl1tSuPrEDzr0yd5m90UgNxQkyDXULk3b6MlQqTCpZpNtWe1K0hzclnZkTcLBe2UQ==", + "dev": true + }, "node_modules/@types/use-sync-external-store": { "version": "0.0.3", "resolved": "https://registry.npmjs.org/@types/use-sync-external-store/-/use-sync-external-store-0.0.3.tgz", @@ -1317,6 +1327,17 @@ "optional": true, "peer": true }, + "node_modules/semver": { + "version": "7.6.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.2.tgz", + "integrity": "sha512-FNAIBWCx9qcRhoHcgcJ0gvU7SN1lYU2ZXuSfl04bSC5OpvDHFyJCjdNHomPXxjQlCBU67YW64PzY7/VIEH7F2w==", + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, "node_modules/source-map": { "version": "0.6.1", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", diff --git a/libs/windy-sounding/package.json b/libs/windy-sounding/package.json index 125140d5..4a2649b2 100644 --- a/libs/windy-sounding/package.json +++ b/libs/windy-sounding/package.json @@ -18,6 +18,10 @@ "geojson": "^0.5.0", "preact": "^10.22.1", "react-redux": "^9.1.2", + "semver": "^7.6.2", "svelte": "^4.2.18" + }, + "devDependencies": { + "@types/semver": "^7.5.8" } } diff --git a/libs/windy-sounding/src/components/favorites.tsx b/libs/windy-sounding/src/components/favorites.tsx index a265c341..8e30f7f0 100644 --- a/libs/windy-sounding/src/components/favorites.tsx +++ b/libs/windy-sounding/src/components/favorites.tsx @@ -65,7 +65,7 @@ export function Favorites({ favorites, location, isMobile, onSelected, modelName data-icon-after="g" onClick={toggleModelSelect} > - {modelName} + {modelName}
- {currentFavorite} + {currentFavorite}
- + ☕️ {isModelExpanded && ( -
+
{models.map((model: string) => ( W.store.set('product', model)}> {model} @@ -91,7 +91,7 @@ export function Favorites({ favorites, location, isMobile, onSelected, modelName )} {isLocationExpanded && ( -
+
{favorites.length === 0 ? (

You do not have any favorites

) : ( @@ -113,7 +113,7 @@ export function Favorites({ favorites, location, isMobile, onSelected, modelName if (favorites.length == 0) { return (
- Add favorites to windy to quickly check different locations. + Add favorites to windy to quickly check different locations.
); } diff --git a/libs/windy-sounding/src/components/message.tsx b/libs/windy-sounding/src/components/message.tsx new file mode 100644 index 00000000..ecd569d9 --- /dev/null +++ b/libs/windy-sounding/src/components/message.tsx @@ -0,0 +1,15 @@ +type MessageProps = { + width: number; + height: number; + // text or jsx + message: any; +}; + +export function Message({ width, height, message }: MessageProps) { + return ( +
+ {/* the inner div is here so that there is only one direct child for styling */} +
{message}
+
+ ); +} diff --git a/libs/windy-sounding/src/components/skewt.tsx b/libs/windy-sounding/src/components/skewt.tsx index 1f3f9667..66568f6e 100644 --- a/libs/windy-sounding/src/components/skewt.tsx +++ b/libs/windy-sounding/src/components/skewt.tsx @@ -5,41 +5,32 @@ import type { Scale } from '../util/math.js'; import * as math from '../util/math.js'; import { Parcel } from './parcel.jsx'; -export type SkewTProps = - | { - isLoading?: true; - } - | { - isLoading?: false; - width: number; - height: number; - yPointer: number | undefined; - levels: number[]; - temps: number[]; - dewpoints: number[]; - ghs: number[]; - seaLevelPressure: number; - minPressure: number; - maxPressure: number; - minTemp: number; - maxTemp: number; - cloudCover: CloudCoverGenerator; - surfaceElevation: number; - parcel: atm.ParcelData | undefined; - formatAltitude: (altitude: number) => number; - formatTemp: (temp: number) => number; - tempUnit: string; - tempAxisStep: number; - ghUnit: string; - ghAxisStep: number; - showUpperClouds: boolean; - }; +export type SkewTProps = { + width: number; + height: number; + yPointer: number | undefined; + levels: number[]; + temps: number[]; + dewpoints: number[]; + ghs: number[]; + seaLevelPressure: number; + minPressure: number; + maxPressure: number; + minTemp: number; + maxTemp: number; + cloudCover: CloudCoverGenerator; + surfaceElevation: number; + parcel: atm.ParcelData | undefined; + formatAltitude: (altitude: number) => number; + formatTemp: (temp: number) => number; + tempUnit: string; + tempAxisStep: number; + ghUnit: string; + ghAxisStep: number; + showUpperClouds: boolean; +}; export function SkewT(props: SkewTProps) { - if (props.isLoading === true) { - return; - } - const { width, height, @@ -63,7 +54,7 @@ export function SkewT(props: SkewTProps) { ghAxisStep, showUpperClouds, yPointer, - } = props as SkewTProps & { isLoading: false }; + } = props; // The full height include the ticks at the bottom. @@ -170,20 +161,20 @@ export function SkewT(props: SkewTProps) { - {yPointer < surfacePx && ( + {yPointer !== undefined && yPointer < surfacePx && ( - + {formatAltitude(ghMeterToPxScale.invert(yPointer))} {formatTemp(tempAtCursor)} @@ -211,7 +202,7 @@ function DryAdiabatic({ pressureToPxScale: Scale; pathGenerator: (points: [x: number, y: number][]) => string; }) { - const points = []; + const points: [x: number, y: number][] = []; const stepPx = height / 15; for (let y = height; y > -stepPx; y -= stepPx) { const p = pressureToPxScale.invert(y); @@ -235,7 +226,7 @@ function WetAdiabatic({ pressureToPxScale: Scale; pathGenerator: (points: [x: number, y: number][]) => string; }) { - const points = []; + const points: [x: number, y: number][] = []; let previousPressure = pressure; const stepPx = height / 15; for (let y = height; y > -stepPx; y -= stepPx) { @@ -261,7 +252,7 @@ function IsoHume({ pressureToPxScale: Scale; pathGenerator: (points: [x: number, y: number][]) => string; }) { - const points = []; + const points: [x: number, y: number][] = []; const mixingRatio = atm.mixingRatio(atm.saturationVaporPressure(temp), pressure); const stepPx = height; for (let y = height; y > -stepPx; y -= stepPx) { @@ -340,7 +331,7 @@ function AltitudeAxis({ y = yNext; } - return {children}; + return {children}; } export type CloudsProp = { diff --git a/libs/windy-sounding/src/components/wind-profile.tsx b/libs/windy-sounding/src/components/wind-profile.tsx index 7b89a26f..8415ecb4 100644 --- a/libs/windy-sounding/src/components/wind-profile.tsx +++ b/libs/windy-sounding/src/components/wind-profile.tsx @@ -2,32 +2,23 @@ import { getPressureToGhScale } from '../util/atmosphere'; import * as math from '../util/math'; import { sampleAt } from '../util/math'; -export type WindProfileProps = - | { - isLoading?: true; - } - | { - isLoading?: false; - width: number; - height: number; - levels: number[]; - ghs: number[]; - minPressure: number; - maxPressure: number; - seaLevelPressure: number; - windByLevel: { speed: number; direction: number }[]; - unit: string; - format: (windSpeed: number) => number; - surfaceElevation: number; - isFixedRange: boolean; - yPointer: number | undefined; - }; +export type WindProfileProps = { + width: number; + height: number; + levels: number[]; + ghs: number[]; + minPressure: number; + maxPressure: number; + seaLevelPressure: number; + windByLevel: { speed: number; direction: number }[]; + unit: string; + format: (windSpeed: number) => number; + surfaceElevation: number; + isFixedRange: boolean; + yPointer: number | undefined; +}; export function WindProfile(props: WindProfileProps) { - if (props.isLoading === true) { - return; - } - const { width, height, @@ -42,7 +33,7 @@ export function WindProfile(props: WindProfileProps) { surfaceElevation, isFixedRange, yPointer, - } = props as WindProfileProps & { isLoading: false }; + } = props; const maxLevelIndex = levels.findIndex((level) => level < minPressure); const keepToIndex = maxLevelIndex == -1 ? levels.length - 1 : maxLevelIndex; @@ -93,9 +84,9 @@ export function WindProfile(props: WindProfileProps) { })} - {yPointer < surfacePx && ( + {yPointer !== undefined && yPointer < surfacePx && ( - + {format(windAtCursor)} diff --git a/libs/windy-sounding/src/containers/containers.tsx b/libs/windy-sounding/src/containers/containers.tsx index 261d3431..9c502296 100644 --- a/libs/windy-sounding/src/containers/containers.tsx +++ b/libs/windy-sounding/src/containers/containers.tsx @@ -1,379 +1,450 @@ import type { LatLon } from '@windy/interfaces'; import { intlFormatDistance } from 'date-fns/intlFormatDistance'; -import { useState } from 'preact/hooks'; -import { connect } from 'react-redux'; +import { useCallback, useState } from 'preact/hooks'; +import { useDispatch, useSelector, shallowEqual } from 'react-redux'; import { Favorites } from '../components/favorites.js'; import { LoadingIndicator } from '../components/loading.js'; +import { Message } from '../components/message.jsx'; import { SkewT, type SkewTProps } from '../components/skewt.js'; -import { WindProfile, type WindProfileProps } from '../components/wind-profile.jsx'; +import { WindProfile } from '../components/wind-profile.jsx'; import { pluginConfig } from '../config'; import flyxcIcon from '../img/jumoplane.svg'; import * as forecastSlice from '../redux/forecast-slice'; -import { centerMap, changeLocation } from '../redux/meta'; +import { centerMap, changeLocation, TimeStep, updateTime } from '../redux/meta'; import * as pluginSlice from '../redux/plugin-slice'; -import { type RootState } from '../redux/store'; +import { type AppDispatch, type RootState } from '../redux/store'; import * as unitsSlice from '../redux/units-slice'; import { formatTimestamp } from '../util/utils.js'; -function stateToSkewTProp(state: RootState, ownProps: SkewTProps) { - const pluginSel = pluginSlice.slice.selectors; - const unitsSel = unitsSlice.slice.selectors; - const forecastSel = forecastSlice.slice.selectors; +// Plugin - const modelName = pluginSel.selModelName(state); - const location = pluginSel.selLocation(state); - const timeMs = pluginSel.selTimeMs(state); +export function Plugin() { + const { + width, + startHeight, + status, + updateAvailable, + updateRequired, + fetchStatus, + availableVersion, + isWindyDataAvailable, + } = useSelector((state: RootState) => { + const pluginSel = pluginSlice.slice.selectors; + const forecastSel = forecastSlice.slice.selectors; + const modelName = pluginSel.selModelName(state); + const location = pluginSel.selLocation(state); + const timeMs = pluginSel.selTimeMs(state); + const isWindyDataAvailable = + forecastSel.selIsWindyDataAvailable(state, modelName, location) && + forecastSel.selIsWindyDataAvailableAt(state, modelName, location, timeMs); + return { + width: pluginSel.selWidth(state), + startHeight: pluginSel.selHeight(state), + status: pluginSel.selStatus(state), + updateAvailable: pluginSel.selUpdateAvailable(state), + updateRequired: pluginSel.selUpdateRequired(state), + fetchStatus: forecastSel.selFetchStatus(state, modelName, location), + availableVersion: pluginSel.selAvailableVersion(state), + modelName, + location, + isWindyDataAvailable, + }; + }, shallowEqual); - if (forecastSel.selWindyDataIsLoading(state, modelName, location)) { - return { isLoading: true }; - } + // Resizable height on mobile. + const [mobileHeight, setMobileHeight] = useState(); + const height = mobileHeight ?? startHeight; + let isDragging = false; + let yOnStartDrag = 0; + let heightOnStartDrag = 0; + + const dispatch: AppDispatch = useDispatch(); + const selectFavorite = useCallback((location: LatLon) => { + dispatch(changeLocation(location, true)); + centerMap(location); + }, []); + + const startResize = useCallback((e: PointerEvent) => { + isDragging = true; + yOnStartDrag = e.screenY; + heightOnStartDrag = height; + e.preventDefault(); + e.stopImmediatePropagation(); + }, []); - const { width, height, yPointer, minPressure, maxPressure } = ownProps as SkewTProps & { isLoading: false }; + const resize = useCallback((e: PointerEvent) => { + if (isDragging) { + const height = Math.min( + Math.max(heightOnStartDrag + yOnStartDrag - e.screenY, startHeight / 3), + startHeight * 1.2, + ); + setMobileHeight(Math.round(height)); + } + e.preventDefault(); + e.stopImmediatePropagation(); + }, []); - const periodValues = forecastSel.selPeriodValues(state, modelName, location); - const timeValues = forecastSel.selValuesAt(state, modelName, location, timeMs); - const isZoomedIn = pluginSel.selIsZoomedIn(state); + const endResize = useCallback((e: PointerEvent) => { + isDragging = false; + e.preventDefault(); + e.stopImmediatePropagation(); + }, []); + + let ignoreWheelEventUntilMs = 0; + const handleWheelEvent = useCallback((e: WheelEvent) => { + const timeMs = Date.now(); + if (timeMs > ignoreWheelEventUntilMs) { + const size = e.shiftKey || e.ctrlKey ? 'day' : 'hour'; + const step: TimeStep = { + direction: Math.sign(e.deltaY) > 0 ? 'forward' : 'backward', + size, + }; + dispatch(updateTime(step)); + ignoreWheelEventUntilMs = Date.now() + (size === 'day' ? 800 : 20); + } + e.stopImmediatePropagation(); + e.preventDefault(); + }, []); - const periodMaxTemp = forecastSel.selMaxPeriodTemp(state, modelName, location); - const maxTemp = periodMaxTemp + 8; - const minTemp = periodMaxTemp - 60; - const formatTemp = unitsSel.selTempFormatter(state); + const isDev = process.env.NODE_ENV === 'development'; - return { - width, - height, - yPointer, - levels: periodValues.levels, - temps: timeValues.temp, - dewpoints: timeValues.dewpoint, - ghs: timeValues.gh, - minPressure, - maxPressure, - seaLevelPressure: timeValues.seaLevelPressure, - minTemp, - maxTemp, - surfaceElevation: forecastSel.selElevation(state, modelName, location), - parcel: forecastSel.selDisplayParcel(state, modelName, location, timeMs) - ? forecastSel.selParcel(state, modelName, location, timeMs) - : undefined, - formatAltitude: unitsSel.selAltitudeFormatter(state), - formatTemp, - tempUnit: unitsSel.selTempUnit(state), - tempAxisStep: unitsSel.selTempUnit(state) === '°C' ? 10 : 20, - ghUnit: unitsSel.selAltitudeUnit(state), - ghAxisStep: unitsSel.selAltitudeUnit(state) === 'm' ? 1000 : 3000, - showUpperClouds: isZoomedIn, - cloudCover: forecastSel.selGetCloudCoverGenerator(state, modelName, location, timeMs), - }; -} + const showDetails = !updateRequired && fetchStatus === forecastSlice.FetchStatus.Loaded; -const ConnectedSkewT = connect(stateToSkewTProp)(SkewT); + const showLoading = + status !== pluginSlice.PluginStatus.Ready || + fetchStatus === forecastSlice.FetchStatus.Idle || + fetchStatus === forecastSlice.FetchStatus.Loading; -const stateToWindProp = (state: RootState, ownProps: WindProfileProps): WindProfileProps => { - const pluginSel = pluginSlice.slice.selectors; - const unitsSel = unitsSlice.slice.selectors; - const forecastSel = forecastSlice.slice.selectors; + let errorMessage: any; - const modelName = pluginSel.selModelName(state); - const location = pluginSel.selLocation(state); - const timeMs = pluginSel.selTimeMs(state); + switch (true) { + case updateRequired: + errorMessage = ( + <> +

Update to v{availableVersion} required.

+

+ You first need to uninstall the current version and then install v{availableVersion} from the plugin menu. +

+ + ); + break; + case fetchStatus === forecastSlice.FetchStatus.ErrorOutOfBounds: + errorMessage =

The selected location is out of model bounds.

; + break; + + case fetchStatus === forecastSlice.FetchStatus.Error: { + errorMessage =

Error :(

; + break; + } - if (forecastSel.selWindyDataIsLoading(state, modelName, location)) { - return { isLoading: true }; + case !isWindyDataAvailable: + errorMessage = ( + <> +

Weather data not available.

+

Windy premium users have access to extended forecasts.

+ + ); + break; } - const periodValues = forecastSel.selPeriodValues(state, modelName, location); - const timeValues = forecastSel.selValuesAt(state, modelName, location, timeMs); + return ( + <> +
+ flyXC + {isDev && ( + + dev + + )} + {pluginConfig.title} + + v{pluginConfig.version} + +
- const { width, height, minPressure, maxPressure, yPointer } = ownProps as WindProfileProps & { isLoading: false }; - return { - width, - height, - minPressure, - maxPressure, - seaLevelPressure: timeValues.seaLevelPressure, - levels: periodValues.levels, - ghs: timeValues.gh, - windByLevel: forecastSel.selWindDetailsByLevel(state, modelName, location, timeMs), - format: unitsSel.selWindSpeedFormatter(state), - unit: unitsSel.selWindSpeedUnit(state), - surfaceElevation: forecastSel.selElevation(state, modelName, location), - isFixedRange: pluginSel.selIsZoomedIn(state), - yPointer, - }; -}; +
+
+ {updateAvailable && ( +
+

Plugin update v{availableVersion} available!

+
+ )} + {showDetails &&
} + {errorMessage ? ( + + ) : ( + + + + + + + + + + + + + + + + {showLoading ? ( + + ) : ( + <> + + {W.rootScope.isMobileOrTablet && ( + startResize(e)} + onPointerUp={(e: any) => endResize(e)} + onPointerLeave={(e: any) => endResize(e)} + onPointerMove={(e: any) => resize(e)} + > + + + + + )} + + )} + + )} +
+
{showDetails && }
+
+

Please consider sponsoring the development of this plugin

+ + Buy Me A Coffee + +
+
+ + ); +} -const ConnectedWind = connect(stateToWindProp)(WindProfile); +// Graph -const stateToFavProp = (state: RootState) => { - const S = pluginSlice.slice.selectors; - return { - favorites: S.selFavorites(state), - location: S.selLocation(state), - isMobile: W.rootScope.isMobileOrTablet, - modelName: S.selModelName(state), - }; -}; +function Graph({ width, height, skewTWidthPercent }: { width: number; height: number; skewTWidthPercent: number }) { + const [yPointer, setYpointer] = useState(); + + const dispatch: AppDispatch = useDispatch(); + + const setIsZoomedIn = useCallback((expanded: boolean) => dispatch(pluginSlice.setIsZoomedIn(expanded)), []); + + const { minPressure, maxPressure, isZoomedIn } = useSelector((state: RootState) => { + const pluginSel = pluginSlice.slice.selectors; + const forecastSel = forecastSlice.slice.selectors; -export const ConnectedFavorites = connect(stateToFavProp)(Favorites); + const timeMs = pluginSel.selTimeMs(state); + const isZoomedIn = pluginSel.selIsZoomedIn(state); + const modelName = pluginSel.selModelName(state); + const location = pluginSel.selLocation(state); + const elevation = forecastSel.selElevation(state, modelName, location); + const minModelPressure = forecastSel.selMinModelPressure(state, modelName, location); + const pressureToGhScale = forecastSel.selPressureToGhScale(state, modelName, location, timeMs); + const minPressure = isZoomedIn + ? Math.round(Math.max(pressureToGhScale.invert(6500 + (elevation * 2) / 5), minModelPressure)) + : minModelPressure; + const maxPressure = Math.min(1000, Math.round(pressureToGhScale.invert((elevation * 4) / 5))); -enum AppStatus { - Loading, - Ready, - DataNotAvailable, - OutOfBounds, - Error, + return { isZoomedIn, minPressure, maxPressure }; + }, shallowEqual); + + const skewTWidth = Math.round((width * skewTWidthPercent) / 100); + const windWidth = width - skewTWidth - 5; + + const moveCursor = useCallback((y: number | undefined) => { + if (y === undefined) { + // Do not remove the pointer on mobile. + if (!W.rootScope.isMobileOrTablet) { + setYpointer(undefined); + } + } else { + setYpointer(y); + } + }, []); + + return ( + moveCursor(e.offsetY)} + onPointerDown={(e: any) => moveCursor(e.offsetY)} + onPointerLeave={() => moveCursor(undefined)} + > + + + + + setIsZoomedIn(!isZoomedIn)}> + + + + + ); } -type GraphProps = { +// SkewT + +type ChildGraphProps = { width: number; height: number; - skewTWidthPercent: number; - onWheel: (e: WheelEvent) => void; -} & ( - | { - status: AppStatus.Loading | AppStatus.DataNotAvailable | AppStatus.OutOfBounds | AppStatus.Error; - } - | { - status: AppStatus.Ready; - minPressure: number; - maxPressure: number; - isZoomedIn: boolean; - setIsZoomedIn: (expanded: boolean) => void; - modelName: string; - updateMs: number; - nextUpdateMs: number; - timeMs: number; - } -); + yPointer: number | undefined; + minPressure: number; + maxPressure: number; +}; -function stateToGraphProps(state: RootState, ownProps: GraphProps) { - const pluginSel = pluginSlice.slice.selectors; - const forecastSel = forecastSlice.slice.selectors; +function ConnectedSkewT(props: ChildGraphProps) { + const fetchStatus = useSelector((state: RootState) => { + const pluginSel = pluginSlice.slice.selectors; + const forecastSel = forecastSlice.slice.selectors; - const width = pluginSel.selWidth(state); - const height = pluginSel.selHeight(state); + const modelName = pluginSel.selModelName(state); + const location = pluginSel.selLocation(state); + return forecastSel.selFetchStatus(state, modelName, location); + }); - const modelName = pluginSel.selModelName(state); - const location = pluginSel.selLocation(state); - const timeMs = pluginSel.selTimeMs(state); + if (fetchStatus !== forecastSlice.FetchStatus.Loaded) { + return; + } - const props = { - status: AppStatus.Loading, - width, - height, - skewTWidthPercent: ownProps.skewTWidthPercent ?? 50, - onWheel: (e: WheelEvent) => e.preventDefault(), - }; + const stateProps: Omit = useSelector((state: RootState) => { + const pluginSel = pluginSlice.slice.selectors; + const unitsSel = unitsSlice.slice.selectors; + const forecastSel = forecastSlice.slice.selectors; - if (forecastSel.selWindyDataIsLoading(state, modelName, location)) { - return props; - } + const modelName = pluginSel.selModelName(state); + const location = pluginSel.selLocation(state); + const timeMs = pluginSel.selTimeMs(state); - props.onWheel = forecastSel.selWheelEventHandler(state, modelName, location); + const periodValues = forecastSel.selPeriodValues(state, modelName, location); + const timeValues = forecastSel.selValuesAt(state, modelName, location, timeMs); + const isZoomedIn = pluginSel.selIsZoomedIn(state); - if (forecastSel.selIsOutOfModelBounds(state, modelName, location)) { - return { - ...props, - status: AppStatus.OutOfBounds, - }; - } + const periodMaxTemp = forecastSel.selMaxPeriodTemp(state, modelName, location); + const maxTemp = periodMaxTemp + 8; + const minTemp = periodMaxTemp - 60; + const formatTemp = unitsSel.selTempFormatter(state); - if (!forecastSel.selAreValuesAvailableAt(state, modelName, location, timeMs)) { return { - ...props, - status: AppStatus.DataNotAvailable, + levels: periodValues.levels, + temps: timeValues.temp, + dewpoints: timeValues.dewpoint, + ghs: timeValues.gh, + seaLevelPressure: timeValues.seaLevelPressure, + minTemp, + maxTemp, + surfaceElevation: forecastSel.selElevation(state, modelName, location), + parcel: forecastSel.selDisplayParcel(state, modelName, location, timeMs) + ? forecastSel.selParcel(state, modelName, location, timeMs) + : undefined, + formatAltitude: unitsSel.selAltitudeFormatter(state), + formatTemp, + tempUnit: unitsSel.selTempUnit(state), + tempAxisStep: unitsSel.selTempUnit(state) === '°C' ? 10 : 20, + ghUnit: unitsSel.selAltitudeUnit(state), + ghAxisStep: unitsSel.selAltitudeUnit(state) === 'm' ? 1000 : 3000, + showUpperClouds: isZoomedIn, + cloudCover: forecastSel.selGetCloudCoverGenerator(state, modelName, location, timeMs), }; - } + }, shallowEqual); - const elevation = forecastSel.selElevation(state, modelName, location); - const minModelPressure = forecastSel.selMinModelPressure(state, modelName, location); - const pressureToGhScale = forecastSel.selPressureToGhScale(state, modelName, location, timeMs); - const minPressure = pluginSel.selIsZoomedIn(state) - ? Math.round(Math.max(pressureToGhScale.invert(6500 + (elevation * 2) / 5), minModelPressure)) - : minModelPressure; - const maxPressure = Math.min(1000, Math.round(pressureToGhScale.invert((elevation * 4) / 5))); - - return { - ...props, - status: AppStatus.Ready, - minPressure, - maxPressure, - isZoomedIn: pluginSel.selIsZoomedIn(state), - }; + return ; } -function stateToGraphDispatch(dispatch: any) { - return { - updateLocation: (latLon: LatLon) => { - dispatch(changeLocation(latLon)); - centerMap(latLon); - }, - - setIsZoomedIn(expanded: boolean) { - dispatch(pluginSlice.setIsZoomedIn(expanded)); - }, - }; -} - -let isDragging = false; +// Wind Profile -let yOnStartDrag = 0; -let heightOnStartDrag = 0; +function ConnectedWind(props: ChildGraphProps) { + const fetchStatus = useSelector((state: RootState) => { + const pluginSel = pluginSlice.slice.selectors; + const forecastSel = forecastSlice.slice.selectors; -export const Graph = connect( - stateToGraphProps, - stateToGraphDispatch, -)((props: GraphProps) => { - const { status, width, skewTWidthPercent, onWheel } = props; + const modelName = pluginSel.selModelName(state); + const location = pluginSel.selLocation(state); + return forecastSel.selFetchStatus(state, modelName, location); + }); - const [yPointer, setYpointer] = useState(); - const [mobileHeight, setMobileHeight] = useState(); + if (fetchStatus !== forecastSlice.FetchStatus.Loaded) { + return; + } - const height = mobileHeight ?? props.height; + const stateProps = useSelector((state: RootState) => { + const pluginSel = pluginSlice.slice.selectors; + const unitsSel = unitsSlice.slice.selectors; + const forecastSel = forecastSlice.slice.selectors; - if (status === AppStatus.Loading) { - return ( - <> - - - - - ); - } + const modelName = pluginSel.selModelName(state); + const location = pluginSel.selLocation(state); + const timeMs = pluginSel.selTimeMs(state); - if (status !== AppStatus.Ready) { - return ( - <> -
-
-

The selected location is out of model bounds.

-
-
- - ); - } + if (forecastSel.selFetchStatus(state, modelName, location) === forecastSlice.FetchStatus.Loading) { + return { isLoading: true }; + } - const { setIsZoomedIn, minPressure, maxPressure, isZoomedIn } = props as any; + const periodValues = forecastSel.selPeriodValues(state, modelName, location); + const timeValues = forecastSel.selValuesAt(state, modelName, location, timeMs); - const skewTWidth = Math.round((width * skewTWidthPercent) / 100); - const windWidth = width - skewTWidth - 5; + return { + seaLevelPressure: timeValues.seaLevelPressure, + levels: periodValues.levels, + ghs: timeValues.gh, + windByLevel: forecastSel.selWindDetailsByLevel(state, modelName, location, timeMs), + format: unitsSel.selWindSpeedFormatter(state), + unit: unitsSel.selWindSpeedUnit(state), + surfaceElevation: forecastSel.selElevation(state, modelName, location), + isFixedRange: pluginSel.selIsZoomedIn(state), + }; + }, shallowEqual); - // https://www.petercollingridge.co.uk/tutorials/svg/interactive/dragging/ - function dragStart(e: PointerEvent) { - isDragging = true; - yOnStartDrag = e.screenY; - heightOnStartDrag = height; - e.preventDefault(); - e.stopImmediatePropagation(); - } + return ; +} - function dragEnd(e: PointerEvent) { - isDragging = false; - e.preventDefault(); - e.stopImmediatePropagation(); - } +// Favorites - function drag(e: PointerEvent) { - if (isDragging) { - const height = Math.min( - Math.max(heightOnStartDrag + yOnStartDrag - e.screenY, props.height / 3), - props.height * 1.2, - ); - setMobileHeight(Math.round(height)); - } - e.preventDefault(); - e.stopImmediatePropagation(); - } +function ConnectedFavorites({ onSelected }: { onSelected: (location: LatLon) => void }) { + const props = useSelector((state: RootState) => { + const S = pluginSlice.slice.selectors; + return { + favorites: S.selFavorites(state), + location: S.selLocation(state), + isMobile: W.rootScope.isMobileOrTablet, + modelName: S.selModelName(state), + }; + }, shallowEqual); - function moveCursor(y: number | undefined) { - if (y === undefined) { - // Do not remove the pointer on mobile. - if (!W.rootScope.isMobileOrTablet) { - setYpointer(undefined); - } - } else { - setYpointer(y); - } - } + return ; +} - return ( - <> -
- - - - - - - - - - - - - - - - moveCursor(e.offsetY)} - onPointerDown={(e) => moveCursor(e.offsetY)} - onPointerLeave={() => moveCursor(undefined)} - > - - - - - setIsZoomedIn(!isZoomedIn)}> - - - - {W.rootScope.isMobileOrTablet && ( - dragStart(e)} - onPointerUp={(e) => dragEnd(e)} - onPointerLeave={(e) => dragEnd(e)} - onPointerMove={(e) => drag(e)} - > - - - - - )} - - - - ); -}); - -const stateToDetailsProps = (state: RootState) => { - const pluginSel = pluginSlice.slice.selectors; - const forecastSel = forecastSlice.slice.selectors; - - const modelName = pluginSel.selModelName(state); - const location = pluginSel.selLocation(state); - const timeMs = pluginSel.selTimeMs(state); - - return { - modelName: pluginSel.selModelName(state), - updateMs: forecastSel.selModelUpdateTimeMs(state, modelName, location), - nextUpdateMs: forecastSel.selModelNextUpdateTimeMs(state, modelName, location), - timeMs, - }; -}; +// Details (model info) /** * Display sounding details @@ -382,12 +453,28 @@ const stateToDetailsProps = (state: RootState) => { * - Run timestamp and duration before next run * - Current time */ -const Details = connect(stateToDetailsProps)(({ modelName, updateMs, nextUpdateMs, timeMs }: DetailsProps) => { +function Details() { + const { modelName, updateMs, nextUpdateMs, timeMs } = useSelector((state: RootState) => { + const pluginSel = pluginSlice.slice.selectors; + const forecastSel = forecastSlice.slice.selectors; + + const modelName = pluginSel.selModelName(state); + const location = pluginSel.selLocation(state); + const timeMs = pluginSel.selTimeMs(state); + + return { + modelName: pluginSel.selModelName(state), + updateMs: forecastSel.selModelUpdateTimeMs(state, modelName, location), + nextUpdateMs: forecastSel.selModelNextUpdateTimeMs(state, modelName, location), + timeMs, + }; + }, shallowEqual); + const nowMs = Date.now(); const distanceString = intlFormatDistance(nextUpdateMs, nowMs); return ( -
+
Model
{modelName}
@@ -400,33 +487,26 @@ const Details = connect(stateToDetailsProps)(({ modelName, updateMs, nextUpdateM
); -}); - -type WatermarkProps = { - updateMs: number; - nextUpdateMs: number; - timeMs: number; - x: number; - y: number; -}; +} -const stateToWatermarkProps = (state: RootState) => { - const pluginSel = pluginSlice.slice.selectors; - const forecastSel = forecastSlice.slice.selectors; +// Watermark - const modelName = pluginSel.selModelName(state); - const location = pluginSel.selLocation(state); - const timeMs = pluginSel.selTimeMs(state); +export function Watermark({ x, y }: { x: number; y: number }) { + const nowMs = Date.now(); - return { - updateMs: forecastSel.selModelUpdateTimeMs(state, modelName, location), - nextUpdateMs: forecastSel.selModelNextUpdateTimeMs(state, modelName, location), - timeMs, - }; -}; + const { updateMs, nextUpdateMs } = useSelector((state: RootState) => { + const pluginSel = pluginSlice.slice.selectors; + const forecastSel = forecastSlice.slice.selectors; + + const modelName = pluginSel.selModelName(state); + const location = pluginSel.selLocation(state); + + return { + updateMs: forecastSel.selModelUpdateTimeMs(state, modelName, location), + nextUpdateMs: forecastSel.selModelNextUpdateTimeMs(state, modelName, location), + }; + }, shallowEqual); -export const Watermark = connect(stateToWatermarkProps)(({ x, y, updateMs, nextUpdateMs }: WatermarkProps) => { - const nowMs = Date.now(); const distanceString = intlFormatDistance(nextUpdateMs, nowMs); return ( @@ -438,71 +518,8 @@ export const Watermark = connect(stateToWatermarkProps)(({ x, y, updateMs, nextU ); -}); - -function stateToAppDispatch(dispatch: any) { - return { - updateLocation: (latLon: LatLon) => { - dispatch(changeLocation(latLon)); - centerMap(latLon); - }, - }; } -type AppProps = { - updateLocation: (location: LatLon) => void; -}; - -export const App = connect( - null, - stateToAppDispatch, -)(({ updateLocation }: AppProps) => { - const isDev = process.env.NODE_ENV === 'development'; - return ( - <> -
- flyXC - {isDev && ( - - dev - - )} - {pluginConfig.title} - - v{pluginConfig.version} - -
- -
-
- -
-
- -
-
-

Please consider sponsoring the development of this plugin

- - Buy Me A Coffee - -
-
- - ); -}); - function openMenu(e: KeyboardEvent | MouseEvent) { if (!('key' in e) || e.key == 'Enter') { W.broadcast.emit('rqstOpen', 'menu'); diff --git a/libs/windy-sounding/src/env.d.ts b/libs/windy-sounding/src/env.d.ts index 3069bbf3..371da4f4 100644 --- a/libs/windy-sounding/src/env.d.ts +++ b/libs/windy-sounding/src/env.d.ts @@ -22,6 +22,8 @@ declare const W: { userFavs: typeof import('@windy/client/userFavs').default; picker: typeof import('@windy/client/picker'); broadcast: typeof import('@windy/client/broadcast').default; + http: typeof import('@windy/client/http'); + user: typeof import('@windy/client/user'); }; /* eslint-enable */ diff --git a/libs/windy-sounding/src/redux/forecast-slice.ts b/libs/windy-sounding/src/redux/forecast-slice.ts index ecc637e4..fbc83583 100644 --- a/libs/windy-sounding/src/redux/forecast-slice.ts +++ b/libs/windy-sounding/src/redux/forecast-slice.ts @@ -124,27 +124,17 @@ export const slice = createSlice({ }); }, selectors: { - // Computed selWindyDataUnsafe: (state: ForecastState, modelName: string, location: LatLon): Forecast | undefined => { const key = windyDataKey(modelName, location); return isDataCached(state, key) ? (state.data[key] as Forecast & { fetchStatus: FetchStatus.Loaded }) : undefined; }, - selIsOutOfModelBounds: (state: ForecastState, modelName: string, location: LatLon): boolean => { + selIsWindyDataAvailable: (state: ForecastState, modelName: string, location: LatLon): boolean => { const windyData = slice.getSelectors().selWindyDataUnsafe(state, modelName, location); - return windyData?.fetchStatus === FetchStatus.ErrorOutOfBounds; + return windyData?.fetchStatus === FetchStatus.Loaded; }, - - selWindyDataIsLoading: (state: ForecastState, modelName: string, location: LatLon): boolean => { - const windyData = slice.getSelectors().selWindyDataUnsafe(state, modelName, location); - return ( - windyData === undefined || - windyData.fetchStatus === FetchStatus.Loading || - windyData.fetchStatus === FetchStatus.Idle - ); - }, - selWindyDataIsLoaded(state: ForecastState, modelName: string, location: LatLon): boolean { + selFetchStatus: (state: ForecastState, modelName: string, location: LatLon): FetchStatus => { const windyData = slice.getSelectors().selWindyDataUnsafe(state, modelName, location); - return windyData !== undefined && windyData.fetchStatus === FetchStatus.Loaded; + return windyData === undefined ? FetchStatus.Error : windyData.fetchStatus; }, selModelUpdateTimeMs(state: ForecastState, modelName: string, location: LatLon): number { const windyData = getWindyDataOrThrow(state, modelName, location); @@ -230,7 +220,7 @@ export const slice = createSlice({ const periodValues = slice.getSelectors().selPeriodValues(state, modelName, location); return periodValues.maxSeaLevelPressure; }, - selAreValuesAvailableAt(state: ForecastState, modelName: string, location: LatLon, timeMs: number): boolean { + selIsWindyDataAvailableAt(state: ForecastState, modelName: string, location: LatLon, timeMs: number): boolean { const windyData = getWindyDataOrThrow(state, modelName, location); const maxTimeMs = Math.min( ...[windyData.meteogram.data.hours.at(-1), windyData.weather.data.ts.at(-1)].filter((v) => v !== undefined), @@ -302,48 +292,6 @@ export const slice = createSlice({ 40, ); }, - selUpdateTime( - state, - modelName: string, - location: LatLon, - ): ({ direction, stepIsDay }: { direction: number; stepIsDay: boolean }) => void { - const tzOffset = slice.getSelectors().selTzOffsetH(state, modelName, location); - return ({ direction, stepIsDay }: { direction: number; stepIsDay: boolean }) => { - let timeMs = windyStore.get('timestamp'); - if (stepIsDay) { - const date = new Date(timeMs); - const utcHours = date.getUTCHours(); - date.setUTCMinutes(0); - timeMs = date.getTime(); - // Jump to previous/next day at 13h. - const refTime = (13 - tzOffset + 24) % 24; - const deltaHours = (refTime - utcHours) * direction; - if (deltaHours <= 0) { - timeMs += direction * (24 + deltaHours) * 3600 * 1000; - } else { - timeMs += direction * deltaHours * 3600 * 1000; - } - } else { - timeMs += direction * 3600 * 1000; - } - - windyStore.set('timestamp', timeMs); - }; - }, - selWheelEventHandler(state: ForecastState, modelName: string, location: LatLon): (e: WheelEvent) => void { - let nextWheelMove = 0; - return (e: WheelEvent) => { - const updateTime = slice.getSelectors().selUpdateTime(state, modelName, location); - if (Date.now() > nextWheelMove) { - const stepIsDay: boolean = e.shiftKey || e.ctrlKey; - const direction: number = Math.sign(e.deltaY); - updateTime({ direction, stepIsDay }); - nextWheelMove = Date.now() + (stepIsDay ? 800 : 20); - } - e.stopImmediatePropagation(); - e.preventDefault(); - }; - }, }, }); @@ -372,17 +320,12 @@ class OutOfBoundsError extends Error { } export const fetchForecast = createAsyncThunk( - 'plugin/fetchForecast', + 'forecast/fetch', async (modelAndLocation: ModelAndLocation, api: { getState: () => RootState }) => { const { modelName, location } = modelAndLocation; - const key = windyDataKey(modelName, location); - - if (isDataCached(slice.selectSlice(api.getState()), key)) { - return slice.selectSlice(api.getState()).data[key]; - } const [meteogram, forecast] = await Promise.allSettled([ - // extended is required to get fulml length forecast for pro windy users + // extended is required to get full length forecast for pro windy users windyFetch.getMeteogramForecastData(modelName, { ...location, step: 1 }, { extended: 'true' }), windyFetch.getPointForecastData(modelName, { ...location }), ]); @@ -411,7 +354,7 @@ export const fetchForecast = createAsyncThunk { // Prevent fetching again while loading. - const key = windyDataKey(modelAndLocation.modelName, modelAndLocation.location); - const data = slice.selectSlice(api.getState()).data[key]; - return data?.fetchStatus != FetchStatus.Loading; + const { modelName, location } = modelAndLocation; + const windyData = slice.selectors.selWindyDataUnsafe(api.getState(), modelName, location); + return ( + windyData === undefined || + !(windyData.fetchStatus == FetchStatus.Loading || windyData.fetchStatus === FetchStatus.ErrorOutOfBounds) + ); }, }, ); @@ -436,8 +382,15 @@ function windyDataKey(modelName: string, location: LatLon): string { return `${modelName}-${windyUtils.latLon2str(location)}`; } +/** + * Checks if the data for a specific key is cached and up-to-date. + * + * Note that data are still cached when they are out of bounds. + * + * @param state - The state object containing forecast data. + * @param key - The key to identify the forecast data. + * */ function isDataCached(state: ForecastState, key: string) { - const nowMs = Date.now(); const forecast = state.data[key]; if (forecast == null) { return false; @@ -448,6 +401,7 @@ function isDataCached(state: ForecastState, key: string) { } if (forecast.fetchStatus === FetchStatus.Loaded) { + const nowMs = Date.now(); const requestMs = forecast.loadedMs; const dataAgeMin = (nowMs - requestMs) / (60 * 1000); return nowMs < forecast.nextUpdateMs || dataAgeMin < STALE_WINDY_DATA_CACHE_MIN; diff --git a/libs/windy-sounding/src/redux/meta.ts b/libs/windy-sounding/src/redux/meta.ts index a706010e..efe132d6 100644 --- a/libs/windy-sounding/src/redux/meta.ts +++ b/libs/windy-sounding/src/redux/meta.ts @@ -1,29 +1,57 @@ +import type { ThunkAction, UnknownAction } from '@reduxjs/toolkit'; import type { LatLon } from '@windy/interfaces'; import { pluginConfig } from '../config'; import * as forecastSlice from './forecast-slice'; import * as pluginSlice from './plugin-slice'; -import type { AppDispatch, RootState } from './store'; +import type { RootState } from './store'; const { map: windyMap, markers } = W.map; const windyRootScope = W.rootScope; -// Subscription +// Cross slice thunks -type Subscription = () => void; +export type TimeStep = { + direction: 'forward' | 'backward'; + size: 'hour' | 'day'; +}; -const subscriptions: Subscription[] = []; +export const updateTime = + (step: TimeStep): ThunkAction => + (dispatch, getState) => { + const stepDays = step.size === 'day'; + + const windyStore = W.store; + let timeMs = windyStore.get('timestamp'); + const stepHour = 3600 * 1000 * (step.direction === 'forward' ? 1 : -1); + + if (stepDays) { + const state = getState(); + const pluginSel = pluginSlice.slice.selectors; + const forecastSel = forecastSlice.slice.selectors; + const modelName = pluginSel.selModelName(state); + const location = pluginSel.selLocation(state); + const isWindyDataAvailable = forecastSlice.slice.selectors.selIsWindyDataAvailable(state, modelName, location); + + if (isWindyDataAvailable) { + // Step to the next/previous at 13h when we know the local TZ offset. + const date = new Date(timeMs); + date.setUTCMinutes(0); + timeMs = date.getTime(); + const utcOffset = forecastSel.selTzOffsetH(state, modelName, location); + const currentHour = (date.getUTCHours() + utcOffset) % 24; + const deltaHours = (13 - currentHour) * (step.direction === 'forward' ? 1 : -1); + timeMs += stepHour * (deltaHours > 0 ? deltaHours : 24 + deltaHours); + } else { + // Step +/- 24 when TZ offset is not known + timeMs += stepHour * 24; + } + } else { + timeMs += stepHour; + } -export function addSubscription(fn: Subscription) { - subscriptions.push(fn); -} - -export function cancelAllSubscriptions() { - for (const fn of subscriptions) { - fn(); - } - subscriptions.length = 0; -} + windyStore.set('timestamp', timeMs); + }; /** * Thunk to set the location. @@ -32,22 +60,29 @@ export function cancelAllSubscriptions() { * - Move the marker * - Fetch the forecast */ -export const changeLocation = (location: LatLon) => (dispatch: AppDispatch, getState: () => RootState) => { - const modelName = pluginSlice.slice.selectors.selModelName(getState()); - dispatch(pluginSlice.setLocation(location)); - dispatch(forecastSlice.fetchForecast({ modelName, location })); +export const changeLocation = + (location: LatLon, fetchData: boolean): ThunkAction => + (dispatch, getState) => { + const modelName = pluginSlice.slice.selectors.selModelName(getState()); + dispatch(pluginSlice.setLocation(location)); + + if (fetchData) { + dispatch(forecastSlice.fetchForecast({ modelName, location })); + } - changeMarkerLocation(location); + maybeCreateAndMoveMarker(location); - updateUrl(getState()); -}; + updateUrl(getState()); + }; -export const changeModel = (modelName: string) => (dispatch: AppDispatch, getState: () => RootState) => { - const location = pluginSlice.slice.selectors.selLocation(getState()); - dispatch(pluginSlice.setModelName(modelName)); - dispatch(forecastSlice.fetchForecast({ modelName, location })); - updateUrl(getState()); -}; +export const changeModel = + (modelName: string): ThunkAction => + (dispatch, getState) => { + const location = pluginSlice.slice.selectors.selLocation(getState()); + dispatch(pluginSlice.setModelName(modelName)); + dispatch(forecastSlice.fetchForecast({ modelName, location })); + updateUrl(getState()); + }; function updateUrl(state: RootState) { const location = pluginSlice.slice.selectors.selLocation(state); @@ -57,8 +92,8 @@ function updateUrl(state: RootState) { let marker: L.Marker | undefined; -export function changeMarkerLocation(latLon: LatLon) { - const { lon: lng, lat } = latLon; +export function maybeCreateAndMoveMarker(location: LatLon) { + const { lon: lng, lat } = location; if (marker) { marker.setLatLng({ lat, lng }); return; @@ -73,14 +108,18 @@ export function changeMarkerLocation(latLon: LatLon) { ).addTo(windyMap); } -export function removeMarker() { +export function maybeRemoveMarker() { if (marker) { windyMap.removeLayer(marker); marker = undefined; } } -export function centerMap(latLon: LatLon) { +/** + * Centers the map view at a specified location, adjusting for mobile/tablet view if necessary. + * @param location - The latitude and longitude coordinates to center the map at. + */ +export function centerMap(location: LatLon) { if (windyRootScope.isMobileOrTablet) { const pluginContent = document.querySelector('#plugin-windy-plugin-sounding') as HTMLDivElement; if (!pluginContent) { @@ -91,9 +130,26 @@ export function centerMap(latLon: LatLon) { const mapHeight = windyMap.getSize().y; const bounds = windyMap.getBounds(); const deltaLat = bounds.getSouth() - bounds.getNorth(); - const centerLat = latLon.lat + ((deltaLat / mapHeight) * pluginHeight) / 2; - windyMap.panTo({ lng: latLon.lon, lat: centerLat }); + const centerLat = location.lat + ((deltaLat / mapHeight) * pluginHeight) / 2; + windyMap.panTo({ lng: location.lon, lat: centerLat }); } else { - windyMap.panTo({ lng: latLon.lon, lat: latLon.lat }); + windyMap.panTo({ lng: location.lon, lat: location.lat }); + } +} + +// Subscription + +type Subscription = () => void; + +const subscriptions: Subscription[] = []; + +export function addSubscription(fn: Subscription) { + subscriptions.push(fn); +} + +export function cancelAllSubscriptions() { + for (const fn of subscriptions) { + fn(); } + subscriptions.length = 0; } diff --git a/libs/windy-sounding/src/redux/plugin-slice.ts b/libs/windy-sounding/src/redux/plugin-slice.ts index 19be3eeb..e5bb0cd4 100644 --- a/libs/windy-sounding/src/redux/plugin-slice.ts +++ b/libs/windy-sounding/src/redux/plugin-slice.ts @@ -1,10 +1,23 @@ -import { createSlice } from '@reduxjs/toolkit'; -import type { Fav, LatLon } from '@windy/interfaces'; +import { createAsyncThunk, createSlice } from '@reduxjs/toolkit'; +import type { CompiledExternalPluginConfig, Fav, LatLon } from '@windy/interfaces'; import { getFavLabel } from '../util/utils'; +import type { RootState } from './store'; +import type { HttpPayload } from '@windy/http'; +import type { PluginConfig } from '../types'; +import { SemVer } from 'semver'; +import { changeLocation } from './meta'; const windyStore = W.store; +const UPDATE_REQUIRED_AFTER_DAYS = 7; + +export enum PluginStatus { + Idle = 'idle', + Booting = 'booting', + Ready = 'ready', +} + // Some models do not have the required parameters for soundings (i.e. surface only) export const SUPPORTED_MODEL_PREFIXES = ['ecmwf', 'gfs', 'nam', 'icon', 'hrrr', 'ukv', 'arome']; const DEFAULT_MODEL = 'ecmwf'; @@ -18,6 +31,10 @@ type PluginState = { width: number; height: number; location: LatLon; + status: PluginStatus; + updateAvailable: boolean; + updateRequired: boolean; + availableVersion: string; }; const initialState: PluginState = { @@ -28,6 +45,10 @@ const initialState: PluginState = { location: { lat: 0, lon: 0 }, modelName: windyStore.get('product'), timeMs: windyStore.get('timestamp'), + status: PluginStatus.Idle, + updateAvailable: false, + updateRequired: false, + availableVersion: '', }; export const slice = createSlice({ @@ -48,7 +69,7 @@ export const slice = createSlice({ state.modelName = modelName; }, setTimeMs: (state, action: { payload: number }) => { - state.timeMs = action.payload; + state.timeMs = Math.round(action.payload); }, setWidth: (state, action: { payload: number }) => { state.width = action.payload; @@ -59,6 +80,27 @@ export const slice = createSlice({ setLocation: (state, action: { payload: LatLon }) => { state.location = action.payload; }, + setStatus: (state, action: { payload: PluginStatus }) => { + state.status = action.payload; + }, + setUpdateAvailable: (state, action: { payload: boolean }) => { + state.updateAvailable = action.payload; + }, + setUpdateRequired: (state, action: { payload: boolean }) => { + state.updateRequired = action.payload; + }, + setAvailableVersion: (state, action: { payload: string }) => { + state.availableVersion = action.payload; + }, + }, + extraReducers: (builder) => { + builder.addCase(fetchPluginConfig.fulfilled, (state, action) => { + state.status = PluginStatus.Ready; + }); + + builder.addCase(fetchPluginConfig.pending, (state, action) => { + state.status = PluginStatus.Booting; + }); }, selectors: { // Values @@ -69,17 +111,54 @@ export const slice = createSlice({ selIsZoomedIn: (state): boolean => state.isZoomedIn, selLocation: (state): LatLon => state.location, selFavorites: (state): Fav[] => state.favorites, + selStatus: (state): PluginStatus => state.status, + selUpdateAvailable: (state): boolean => state.updateAvailable, + selUpdateRequired: (state): boolean => state.updateRequired, + selAvailableVersion: (state): string => state.availableVersion, }, }); -export const { - setIsZoomedIn: setIsZoomedIn, - setFavorites, - setModelName, - setTimeMs, - setWidth, - setHeight, - setLocation, -} = slice.actions; +export const fetchPluginConfig = createAsyncThunk( + 'plugin/fetchPluginConfig', + async (localPluginConfig: PluginConfig, api) => { + const payload: HttpPayload = await W.http.get('/articles/plugins/list'); + const remoteConfig = findConfig(payload.data, localPluginConfig.name); + if (!remoteConfig) { + throw new Error(`plugin "${localPluginConfig.name}" not found`); + } + + if (new SemVer(localPluginConfig.version).compare(remoteConfig.version) == -1) { + const updateRequired = + new Date(remoteConfig.builtReadable).getTime() - localPluginConfig.built > + UPDATE_REQUIRED_AFTER_DAYS * 24 * 3600 * 1000; + api.dispatch(slice.actions.setUpdateAvailable(true)); + api.dispatch(slice.actions.setUpdateRequired(updateRequired)); + } + api.dispatch(slice.actions.setAvailableVersion(remoteConfig.version)); + api.dispatch(changeLocation(api.getState().plugin.location, true)); + }, +); + +/** + * Finds and returns a specific plugin configuration by name. + * + * @param configs - The array of plugin configurations to search through. + * @param pluginName - The name of the plugin to find. + * @returns The found plugin configuration, or undefined if not found. + */ +function findConfig( + configs: CompiledExternalPluginConfig[], + pluginName: string, +): CompiledExternalPluginConfig | undefined { + for (const config of configs) { + if (config.name === pluginName) { + return config; + } + } + return; +} + +export const { setIsZoomedIn, setFavorites, setModelName, setTimeMs, setWidth, setHeight, setLocation, setStatus } = + slice.actions; export const { reducer } = slice; diff --git a/libs/windy-sounding/src/sounding.tsx b/libs/windy-sounding/src/sounding.tsx index 463a784e..675d9128 100644 --- a/libs/windy-sounding/src/sounding.tsx +++ b/libs/windy-sounding/src/sounding.tsx @@ -5,16 +5,18 @@ import { render } from 'preact'; import { Provider } from 'react-redux'; import { pluginConfig } from './config.js'; -import { App } from './containers/containers'; +import { Plugin } from './containers/containers'; import { addSubscription, cancelAllSubscriptions, centerMap, changeLocation, changeModel, - removeMarker, + maybeRemoveMarker, + updateTime, } from './redux/meta'; import * as pluginSlice from './redux/plugin-slice'; +import * as forecastSlice from './redux/forecast-slice'; import { store } from './redux/store'; import styles from './styles.less?inline'; import { injectStyles } from './util/utils'; @@ -36,7 +38,7 @@ export const mountPlugin = (container: HTMLElement) => { injectStyles(styles); render( - + , container, ); @@ -53,8 +55,13 @@ export const mountPlugin = (container: HTMLElement) => { 'swipe', (e: CustomEvent) => { const { right, left } = e.detail.directions; - const direction = left ? -1 : right ? 1 : 0; - pluginSlice.slice.selectors.selUpdateTime(store.getState())({ direction, stepIsDay: true }); + const direction = left ? 'backward' : right ? 'forward' : undefined; + const state = store.getState(); + const model = pluginSlice.slice.selectors.selModelName(state); + const location = pluginSlice.slice.selectors.selLocation(state); + if (direction !== undefined) { + store.dispatch(updateTime({ direction, size: 'day' })); + } }, { signal: controller.signal }, ); @@ -83,19 +90,19 @@ export const mountPlugin = (container: HTMLElement) => { addSubscription(() => windyStore.off(productChangedEventId)); const singleClickIdEventId = singleclick.on(pluginConfig.name, (location: LatLon) => { - dispatch(changeLocation(location)); + dispatch(changeLocation(location, true)); }); addSubscription(() => singleclick.off(singleClickIdEventId)); // Use the picker events on desktop. if (!windyRootScope.isMobileOrTablet) { const pickerOpenedEventId = windyPicker.on('pickerOpened', (location: LatLon) => { - dispatch(changeLocation(location)); + dispatch(changeLocation(location, true)); }); addSubscription(() => windyPicker.off(pickerOpenedEventId)); const pickerMovedEventId = windyPicker.on('pickerMoved', (location: LatLon) => { - dispatch(changeLocation(location)); + dispatch(changeLocation(location, true)); }); addSubscription(() => windyPicker.off(pickerMovedEventId)); } @@ -119,18 +126,21 @@ export const openPlugin = ({ lat, lon, modelName }: { lat: number; lon: number; dispatch(pluginSlice.setFavorites(favs.getArray())); dispatch(pluginSlice.setModelName(modelName)); dispatch(pluginSlice.setTimeMs(windyStore.get('timestamp'))); - dispatch(changeLocation(location)); - + dispatch(changeLocation(location, false)); setSizeFrom(appContainer); + + if (pluginSlice.slice.selectors.selStatus(store.getState()) === pluginSlice.PluginStatus.Idle) { + dispatch(pluginSlice.fetchPluginConfig(pluginConfig)); + } }; // Called when closed export const destroyPlugin = () => { cancelAllSubscriptions(); - removeMarker(); + maybeRemoveMarker(); }; -function setSizeFrom(container) { +function setSizeFrom(container: HTMLElement) { const padding = W.rootScope.isMobileOrTablet ? 0 : 50; const width = container.clientWidth - padding; const height = Math.min(width, window.innerHeight * 0.7); diff --git a/libs/windy-sounding/src/styles.less b/libs/windy-sounding/src/styles.less index 0729a604..08b746cb 100644 --- a/libs/windy-sounding/src/styles.less +++ b/libs/windy-sounding/src/styles.less @@ -5,6 +5,13 @@ grid-template-rows: auto 1fr; } +// Update available +#wsp-update { + background-color: var(--color-warning-moderate); + color: var(--color-black); + text-align:center; +} + // flyXC icon on desktop. #wsp-icon { position: relative; @@ -116,6 +123,7 @@ display: grid; align-items: center; text-align: center; + border: 1px solid lightgray; } svg { diff --git a/package-lock.json b/package-lock.json index 0669dcf8..3852e21b 100644 --- a/package-lock.json +++ b/package-lock.json @@ -28,7 +28,6 @@ "@tmcw/togeojson": "^5.8.1", "@types/mapbox__sphericalmercator": "^1.2.3", "@vivaxy/png": "^1.3.0", - "@windycom/plugin-devtools": "^2.0.0", "@xmldom/xmldom": "^0.8.10", "axios": "1.7.2", "commander": "^12.1.0", @@ -106,6 +105,8 @@ "@types/node": "20.12.11", "@types/node-os-utils": "^1.3.4", "@types/pbf": "^3.0.5", + "@types/react": "^18.3.3", + "@types/react-redux": "^7.1.33", "@types/validator": "^13.11.9", "@types/xmldom": "^0.1.34", "@typescript-eslint/eslint-plugin": "^7.3.0", @@ -114,6 +115,7 @@ "@vitejs/plugin-react": "^4.2.0", "@vitest/coverage-v8": "^1.0.4", "@vitest/ui": "^1.3.1", + "@windycom/plugin-devtools": "^2.0.0", "cypress": "13.13.0", "dotenv-webpack": "^8.1.0", "eslint": "~8.57.0", @@ -241,6 +243,7 @@ "version": "2.3.0", "resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.3.0.tgz", "integrity": "sha512-30iZtAPgz+LTIYoeivqYo853f02jBYSd5uGnGpkFV0M3xOt9aN73erkgYAmZU43x4VfqcnLxW9Kpg3R5LC4YYw==", + "dev": true, "dependencies": { "@jridgewell/gen-mapping": "^0.3.5", "@jridgewell/trace-mapping": "^0.3.24" @@ -294,7 +297,7 @@ "version": "7.24.7", "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.24.7.tgz", "integrity": "sha512-BcYH1CVJBO9tvyIZ2jVeXgSIMvGZ2FDRvDdOIVQyuklNKSsx+eppDEBq/g47Ayw+RqNFE+URvOShmf+f/qwAlA==", - "devOptional": true, + "dev": true, "dependencies": { "@babel/highlight": "^7.24.7", "picocolors": "^1.0.0" @@ -307,7 +310,7 @@ "version": "7.24.7", "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.24.7.tgz", "integrity": "sha512-qJzAIcv03PyaWqxRgO4mSU3lihncDT296vnyuE2O8uA4w3UHWI4S3hgeZd1L8W1Bft40w9JxJ2b412iDUFFRhw==", - "devOptional": true, + "dev": true, "engines": { "node": ">=6.9.0" } @@ -316,7 +319,7 @@ "version": "7.24.7", "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.24.7.tgz", "integrity": "sha512-nykK+LEK86ahTkX/3TgauT0ikKoNCfKHEaZYTUVupJdTLzGNvrblu4u6fa7DhZONAltdf8e662t/abY8idrd/g==", - "devOptional": true, + "dev": true, "dependencies": { "@ampproject/remapping": "^2.2.0", "@babel/code-frame": "^7.24.7", @@ -346,7 +349,7 @@ "version": "7.24.7", "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.24.7.tgz", "integrity": "sha512-oipXieGC3i45Y1A41t4tAqpnEZWgB/lC6Ehh6+rOviR5XWpTtMmLN+fGjz9vOiNRt0p6RtO6DtD0pdU3vpqdSA==", - "devOptional": true, + "dev": true, "dependencies": { "@babel/types": "^7.24.7", "@jridgewell/gen-mapping": "^0.3.5", @@ -386,7 +389,7 @@ "version": "7.24.7", "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.24.7.tgz", "integrity": "sha512-ctSdRHBi20qWOfy27RUb4Fhp07KSJ3sXcuSvTrXrc4aG8NSYDo1ici3Vhg9bg69y5bj0Mr1lh0aeEgTvc12rMg==", - "devOptional": true, + "dev": true, "dependencies": { "@babel/compat-data": "^7.24.7", "@babel/helper-validator-option": "^7.24.7", @@ -458,7 +461,7 @@ "version": "7.24.7", "resolved": "https://registry.npmjs.org/@babel/helper-environment-visitor/-/helper-environment-visitor-7.24.7.tgz", "integrity": "sha512-DoiN84+4Gnd0ncbBOM9AZENV4a5ZiL39HYMyZJGZ/AZEykHYdJw0wW3kdcsh9/Kn+BRXHLkkklZ51ecPKmI1CQ==", - "devOptional": true, + "dev": true, "dependencies": { "@babel/types": "^7.24.7" }, @@ -470,7 +473,7 @@ "version": "7.24.7", "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.24.7.tgz", "integrity": "sha512-FyoJTsj/PEUWu1/TYRiXTIHc8lbw+TDYkZuoE43opPS5TrI7MyONBE1oNvfguEXAD9yhQRrVBnXdXzSLQl9XnA==", - "devOptional": true, + "dev": true, "dependencies": { "@babel/template": "^7.24.7", "@babel/types": "^7.24.7" @@ -483,7 +486,7 @@ "version": "7.24.7", "resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.24.7.tgz", "integrity": "sha512-MJJwhkoGy5c4ehfoRyrJ/owKeMl19U54h27YYftT0o2teQ3FJ3nQUf/I3LlJsX4l3qlw7WRXUmiyajvHXoTubQ==", - "devOptional": true, + "dev": true, "dependencies": { "@babel/types": "^7.24.7" }, @@ -508,7 +511,7 @@ "version": "7.24.7", "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.24.7.tgz", "integrity": "sha512-8AyH3C+74cgCVVXow/myrynrAGv+nTVg5vKu2nZph9x7RcRwzmh0VFallJuFTZ9mx6u4eSdXZfcOzSqTUm0HCA==", - "devOptional": true, + "dev": true, "dependencies": { "@babel/traverse": "^7.24.7", "@babel/types": "^7.24.7" @@ -521,7 +524,7 @@ "version": "7.24.7", "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.24.7.tgz", "integrity": "sha512-1fuJEwIrp+97rM4RWdO+qrRsZlAeL1lQJoPqtCYWv0NL115XM93hIH4CSRln2w52SqvmY5hqdtauB6QFCDiZNQ==", - "devOptional": true, + "dev": true, "dependencies": { "@babel/helper-environment-visitor": "^7.24.7", "@babel/helper-module-imports": "^7.24.7", @@ -595,7 +598,7 @@ "version": "7.24.7", "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.24.7.tgz", "integrity": "sha512-zBAIvbCMh5Ts+b86r/CjU+4XGYIs+R1j951gxI3KmmxBMhCg4oQMsv6ZXQ64XOm/cvzfU1FmoCyt6+owc5QMYg==", - "devOptional": true, + "dev": true, "dependencies": { "@babel/traverse": "^7.24.7", "@babel/types": "^7.24.7" @@ -621,7 +624,7 @@ "version": "7.24.7", "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.24.7.tgz", "integrity": "sha512-oy5V7pD+UvfkEATUKvIjvIAH/xCzfsFVw7ygW2SI6NClZzquT+mwdTfgfdbUiceh6iQO0CHtCPsyze/MZ2YbAA==", - "devOptional": true, + "dev": true, "dependencies": { "@babel/types": "^7.24.7" }, @@ -633,7 +636,7 @@ "version": "7.24.7", "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.24.7.tgz", "integrity": "sha512-7MbVt6xrwFQbunH2DNQsAP5sTGxfqQtErvBIvIMi6EQnbgUOuVYanvREcmFrOPhoXBrTtjhhP+lW+o5UfK+tDg==", - "devOptional": true, + "dev": true, "engines": { "node": ">=6.9.0" } @@ -642,7 +645,7 @@ "version": "7.24.7", "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.24.7.tgz", "integrity": "sha512-rR+PBcQ1SMQDDyF6X0wxtG8QyLCgUB0eRAGguqRLfkCA87l7yAP7ehq8SNj96OOGTO8OBV70KhuFYcIkHXOg0w==", - "devOptional": true, + "dev": true, "engines": { "node": ">=6.9.0" } @@ -651,7 +654,7 @@ "version": "7.24.7", "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.24.7.tgz", "integrity": "sha512-yy1/KvjhV/ZCL+SM7hBrvnZJ3ZuT9OuZgIJAGpPEToANvc3iM6iDvBnRjtElWibHU6n8/LPR/EjX9EtIEYO3pw==", - "devOptional": true, + "dev": true, "engines": { "node": ">=6.9.0" } @@ -675,7 +678,7 @@ "version": "7.24.7", "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.24.7.tgz", "integrity": "sha512-NlmJJtvcw72yRJRcnCmGvSi+3jDEg8qFu3z0AFoymmzLx5ERVWyzd9kVXr7Th9/8yIJi2Zc6av4Tqz3wFs8QWg==", - "devOptional": true, + "dev": true, "dependencies": { "@babel/template": "^7.24.7", "@babel/types": "^7.24.7" @@ -688,7 +691,7 @@ "version": "7.24.7", "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.24.7.tgz", "integrity": "sha512-EStJpq4OuY8xYfhGVXngigBJRWxftKX9ksiGDnmlY3o7B/V7KIAc9X4oiK87uPJSc/vs5L869bem5fhZa8caZw==", - "devOptional": true, + "dev": true, "dependencies": { "@babel/helper-validator-identifier": "^7.24.7", "chalk": "^2.4.2", @@ -703,7 +706,7 @@ "version": "7.24.7", "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.24.7.tgz", "integrity": "sha512-9uUYRm6OqQrCqQdG1iCBwBPZgN8ciDBro2nIOFaiRz1/BCxaI7CNvQbDHvsArAC7Tw9Hda/B3U+6ui9u4HWXPw==", - "devOptional": true, + "dev": true, "bin": { "parser": "bin/babel-parser.js" }, @@ -2131,7 +2134,7 @@ "version": "7.24.7", "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.24.7.tgz", "integrity": "sha512-jYqfPrU9JTF0PmPy1tLYHW4Mp4KlgxJD9l2nP9fD6yT/ICi554DmrWBAEYpIelzjHf1msDP3PxJIRt/nFNfBig==", - "devOptional": true, + "dev": true, "dependencies": { "@babel/code-frame": "^7.24.7", "@babel/parser": "^7.24.7", @@ -2145,7 +2148,7 @@ "version": "7.24.7", "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.24.7.tgz", "integrity": "sha512-yb65Ed5S/QAcewNPh0nZczy9JdYXkkAbIsEo+P7BE7yO3txAY30Y/oPa3QkQ5It3xVG2kpKMg9MsdxZaO31uKA==", - "devOptional": true, + "dev": true, "dependencies": { "@babel/code-frame": "^7.24.7", "@babel/generator": "^7.24.7", @@ -2166,7 +2169,7 @@ "version": "7.24.7", "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.24.7.tgz", "integrity": "sha512-XEFXSlxiG5td2EJRe8vOmRbaXVgfcBlszKujvVmWIK/UpywWljQCfzAv3RQCGujWQ1RD4YYWEAqDXfuJiy8f5Q==", - "devOptional": true, + "dev": true, "dependencies": { "@babel/helper-string-parser": "^7.24.7", "@babel/helper-validator-identifier": "^7.24.7", @@ -2293,7 +2296,7 @@ "version": "0.8.1", "resolved": "https://registry.npmjs.org/@cspotcode/source-map-support/-/source-map-support-0.8.1.tgz", "integrity": "sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==", - "devOptional": true, + "dev": true, "dependencies": { "@jridgewell/trace-mapping": "0.3.9" }, @@ -2305,7 +2308,7 @@ "version": "0.3.9", "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.9.tgz", "integrity": "sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ==", - "devOptional": true, + "dev": true, "dependencies": { "@jridgewell/resolve-uri": "^3.0.3", "@jridgewell/sourcemap-codec": "^1.4.10" @@ -2795,6 +2798,7 @@ "version": "4.4.0", "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.4.0.tgz", "integrity": "sha512-1/sA4dwrzBAyeUoQ6oxahHKmrZvsnLCg4RfxW3ZFGGmQkSNQPFNLV9CUEFQP1x9EYXHTo5p6xdhZM1Ne9p/AfA==", + "dev": true, "dependencies": { "eslint-visitor-keys": "^3.3.0" }, @@ -2809,6 +2813,7 @@ "version": "4.11.0", "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.11.0.tgz", "integrity": "sha512-G/M/tIiMrTAxEWRfLfQJMmGNX28IxBg4PBz8XqQhqUHLFI6TL2htpIB1iQCj144V5ee/JaKyT9/WZ0MGZWfA7A==", + "dev": true, "engines": { "node": "^12.0.0 || ^14.0.0 || >=16.0.0" } @@ -2817,6 +2822,7 @@ "version": "2.1.4", "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-2.1.4.tgz", "integrity": "sha512-269Z39MS6wVJtsoUl10L60WdkhJVdPG24Q4eZTH3nnF6lpvSShEK3wQjDX9JRWAUPvPh7COouPpU9IrqaZFvtQ==", + "dev": true, "dependencies": { "ajv": "^6.12.4", "debug": "^4.3.2", @@ -2839,6 +2845,7 @@ "version": "6.12.6", "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "dev": true, "dependencies": { "fast-deep-equal": "^3.1.1", "fast-json-stable-stringify": "^2.0.0", @@ -2853,12 +2860,14 @@ "node_modules/@eslint/eslintrc/node_modules/argparse": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", - "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==" + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", + "dev": true }, "node_modules/@eslint/eslintrc/node_modules/brace-expansion": { "version": "1.1.11", "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dev": true, "dependencies": { "balanced-match": "^1.0.0", "concat-map": "0.0.1" @@ -2868,6 +2877,7 @@ "version": "13.24.0", "resolved": "https://registry.npmjs.org/globals/-/globals-13.24.0.tgz", "integrity": "sha512-AhO5QUcj8llrbG09iWhPU2B204J1xnPeL8kQmVorSsy+Sjj1sk8gIyh6cUocGmH4L0UuhAJy+hJMRA4mgA4mFQ==", + "dev": true, "dependencies": { "type-fest": "^0.20.2" }, @@ -2882,6 +2892,7 @@ "version": "4.1.0", "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", + "dev": true, "dependencies": { "argparse": "^2.0.1" }, @@ -2892,12 +2903,14 @@ "node_modules/@eslint/eslintrc/node_modules/json-schema-traverse": { "version": "0.4.1", "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", - "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==" + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", + "dev": true }, "node_modules/@eslint/eslintrc/node_modules/minimatch": { "version": "3.1.2", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, "dependencies": { "brace-expansion": "^1.1.7" }, @@ -2909,6 +2922,7 @@ "version": "0.20.2", "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", + "dev": true, "engines": { "node": ">=10" }, @@ -2920,6 +2934,7 @@ "version": "8.57.0", "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.57.0.tgz", "integrity": "sha512-Ys+3g2TaW7gADOJzPt83SJtCDhMjndcDMFVQ/Tj9iA1BfJzFKD9mAUXT3OenpuPHbI6P/myECxRJrofUsDx/5g==", + "dev": true, "engines": { "node": "^12.22.0 || ^14.17.0 || >=16.0.0" } @@ -3037,7 +3052,8 @@ "node_modules/@fastify/deepmerge": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/@fastify/deepmerge/-/deepmerge-1.3.0.tgz", - "integrity": "sha512-J8TOSBq3SoZbDhM9+R/u77hP93gz/rajSA+K2kGyijPpORPWUXHUpTaleoj+92As0S9uPRP7Oi8IqMf0u+ro6A==" + "integrity": "sha512-J8TOSBq3SoZbDhM9+R/u77hP93gz/rajSA+K2kGyijPpORPWUXHUpTaleoj+92As0S9uPRP7Oi8IqMf0u+ro6A==", + "dev": true }, "node_modules/@floating-ui/core": { "version": "1.6.4", @@ -3218,6 +3234,7 @@ "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.14.tgz", "integrity": "sha512-3T8LkOmg45BV5FICb15QQMsyUSWrQ8AygVfC7ZG32zOalnqrilm018ZVCw0eapXux8FtA33q8PSRSstjee3jSg==", "deprecated": "Use @eslint/config-array instead", + "dev": true, "dependencies": { "@humanwhocodes/object-schema": "^2.0.2", "debug": "^4.3.1", @@ -3231,6 +3248,7 @@ "version": "1.1.11", "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dev": true, "dependencies": { "balanced-match": "^1.0.0", "concat-map": "0.0.1" @@ -3240,6 +3258,7 @@ "version": "3.1.2", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, "dependencies": { "brace-expansion": "^1.1.7" }, @@ -3251,6 +3270,7 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz", "integrity": "sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==", + "dev": true, "engines": { "node": ">=12.22" }, @@ -3263,7 +3283,8 @@ "version": "2.0.3", "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-2.0.3.tgz", "integrity": "sha512-93zYdMES/c1D69yZiKDBj0V24vqNzB/koF26KPaagAfd3P/4gUlh3Dys5ogAK+Exi9QyzlD8x/08Zt7wIKcDcA==", - "deprecated": "Use @eslint/object-schema instead" + "deprecated": "Use @eslint/object-schema instead", + "dev": true }, "node_modules/@ionic/core": { "version": "8.2.5", @@ -4057,6 +4078,7 @@ "version": "0.3.5", "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.5.tgz", "integrity": "sha512-IzL8ZoEDIBRWEzlCcRhOaCupYyN5gdIK+Q6fbFdPDg6HqX6jpkItn7DFIpW9LQzXG6Df9sA7+OKnq0qlz/GaQg==", + "dev": true, "dependencies": { "@jridgewell/set-array": "^1.2.1", "@jridgewell/sourcemap-codec": "^1.4.10", @@ -4070,6 +4092,7 @@ "version": "3.1.2", "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz", "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==", + "dev": true, "engines": { "node": ">=6.0.0" } @@ -4078,6 +4101,7 @@ "version": "1.2.1", "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.2.1.tgz", "integrity": "sha512-R8gLRTZeyp03ymzP/6Lil/28tGeGEzhx1q2k703KGWRAI1VdvPIXdG70VJc2pAMw3NA6JKL5hhFu1sJX0Mnn/A==", + "dev": true, "engines": { "node": ">=6.0.0" } @@ -4086,6 +4110,7 @@ "version": "0.3.6", "resolved": "https://registry.npmjs.org/@jridgewell/source-map/-/source-map-0.3.6.tgz", "integrity": "sha512-1ZJTZebgqllO79ue2bm3rIGud/bOe0pP5BjSRCRxxYkEZS8STV7zN84UBbiYu7jy+eCKSnVIUgoWWE/tt+shMQ==", + "dev": true, "dependencies": { "@jridgewell/gen-mapping": "^0.3.5", "@jridgewell/trace-mapping": "^0.3.25" @@ -4094,12 +4119,14 @@ "node_modules/@jridgewell/sourcemap-codec": { "version": "1.4.15", "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz", - "integrity": "sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==" + "integrity": "sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==", + "dev": true }, "node_modules/@jridgewell/trace-mapping": { "version": "0.3.25", "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.25.tgz", "integrity": "sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==", + "dev": true, "dependencies": { "@jridgewell/resolve-uri": "^3.1.0", "@jridgewell/sourcemap-codec": "^1.4.14" @@ -4313,6 +4340,7 @@ "version": "2.1.5", "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", + "dev": true, "dependencies": { "@nodelib/fs.stat": "2.0.5", "run-parallel": "^1.1.9" @@ -4325,6 +4353,7 @@ "version": "2.0.5", "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", + "dev": true, "engines": { "node": ">= 8" } @@ -4333,6 +4362,7 @@ "version": "1.2.8", "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", + "dev": true, "dependencies": { "@nodelib/fs.scandir": "2.1.5", "fastq": "^1.6.0" @@ -6149,6 +6179,7 @@ "version": "25.0.8", "resolved": "https://registry.npmjs.org/@rollup/plugin-commonjs/-/plugin-commonjs-25.0.8.tgz", "integrity": "sha512-ZEZWTK5n6Qde0to4vS9Mr5x/0UZoqCxPVR9KRUjU4kA2sO7GEUn1fop0DAwpO6z0Nw/kJON9bDmSxdWxO/TT1A==", + "dev": true, "dependencies": { "@rollup/pluginutils": "^5.0.1", "commondir": "^1.0.1", @@ -6173,6 +6204,7 @@ "version": "5.1.0", "resolved": "https://registry.npmjs.org/@rollup/pluginutils/-/pluginutils-5.1.0.tgz", "integrity": "sha512-XTIWOPPcpvyKI6L1NHo0lFlCyznUEyPmPY1mc3KpPVDYulHSTvyeLNVW00QTLIAFNhR3kYnJTQHeGqU4M3n09g==", + "dev": true, "dependencies": { "@types/estree": "^1.0.0", "estree-walker": "^2.0.2", @@ -6195,6 +6227,7 @@ "resolved": "https://registry.npmjs.org/glob/-/glob-8.1.0.tgz", "integrity": "sha512-r8hpEjiQEYlF2QU0df3dS+nxxSIreXQS1qRhMJM0Q5NDdR386C7jb7Hwwod8Fgiuex+k0GFjgft18yvxm5XoCQ==", "deprecated": "Glob versions prior to v9 are no longer supported", + "dev": true, "dependencies": { "fs.realpath": "^1.0.0", "inflight": "^1.0.4", @@ -6213,6 +6246,7 @@ "version": "5.1.6", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.1.6.tgz", "integrity": "sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g==", + "dev": true, "dependencies": { "brace-expansion": "^2.0.1" }, @@ -6224,6 +6258,7 @@ "version": "15.2.3", "resolved": "https://registry.npmjs.org/@rollup/plugin-node-resolve/-/plugin-node-resolve-15.2.3.tgz", "integrity": "sha512-j/lym8nf5E21LwBT4Df1VD6hRO2L2iwUeUmP7litikRsVp1H6NWx20NEp0Y7su+7XGc476GnXXc4kFeZNGmaSQ==", + "dev": true, "dependencies": { "@rollup/pluginutils": "^5.0.1", "@types/resolve": "1.20.2", @@ -6248,6 +6283,7 @@ "version": "5.1.0", "resolved": "https://registry.npmjs.org/@rollup/pluginutils/-/pluginutils-5.1.0.tgz", "integrity": "sha512-XTIWOPPcpvyKI6L1NHo0lFlCyznUEyPmPY1mc3KpPVDYulHSTvyeLNVW00QTLIAFNhR3kYnJTQHeGqU4M3n09g==", + "dev": true, "dependencies": { "@types/estree": "^1.0.0", "estree-walker": "^2.0.2", @@ -6320,6 +6356,7 @@ "version": "0.4.4", "resolved": "https://registry.npmjs.org/@rollup/plugin-terser/-/plugin-terser-0.4.4.tgz", "integrity": "sha512-XHeJC5Bgvs8LfukDwWZp7yeqin6ns8RTl2B9avbejt6tZqsqvVoWI7ZTQrcNsfKEDWBTnTxM8nMDkO2IFFbd0A==", + "dev": true, "dependencies": { "serialize-javascript": "^6.0.1", "smob": "^1.0.0", @@ -6341,6 +6378,7 @@ "version": "11.1.6", "resolved": "https://registry.npmjs.org/@rollup/plugin-typescript/-/plugin-typescript-11.1.6.tgz", "integrity": "sha512-R92yOmIACgYdJ7dJ97p4K69I8gg6IEHt8M7dUBxN3W6nrO8uUxX5ixl0yU/N3aZTi8WhPuICvOHXQvF6FaykAA==", + "dev": true, "dependencies": { "@rollup/pluginutils": "^5.1.0", "resolve": "^1.22.1" @@ -6366,6 +6404,7 @@ "version": "5.1.0", "resolved": "https://registry.npmjs.org/@rollup/pluginutils/-/pluginutils-5.1.0.tgz", "integrity": "sha512-XTIWOPPcpvyKI6L1NHo0lFlCyznUEyPmPY1mc3KpPVDYulHSTvyeLNVW00QTLIAFNhR3kYnJTQHeGqU4M3n09g==", + "dev": true, "dependencies": { "@types/estree": "^1.0.0", "estree-walker": "^2.0.2", @@ -6387,6 +6426,7 @@ "version": "4.2.1", "resolved": "https://registry.npmjs.org/@rollup/pluginutils/-/pluginutils-4.2.1.tgz", "integrity": "sha512-iKnFXr7NkdZAIHiIWE+BX5ULi/ucVFYWD6TbAV+rZctiRTY2PL6tsIKhoIOaoskiWAkgu+VsbXgUVDNLHf+InQ==", + "dev": true, "dependencies": { "estree-walker": "^2.0.1", "picomatch": "^2.2.2" @@ -6402,6 +6442,7 @@ "cpu": [ "arm" ], + "dev": true, "optional": true, "os": [ "android" @@ -6414,6 +6455,7 @@ "cpu": [ "arm64" ], + "dev": true, "optional": true, "os": [ "android" @@ -6426,6 +6468,7 @@ "cpu": [ "arm64" ], + "dev": true, "optional": true, "os": [ "darwin" @@ -6438,6 +6481,7 @@ "cpu": [ "x64" ], + "dev": true, "optional": true, "os": [ "darwin" @@ -6450,6 +6494,7 @@ "cpu": [ "arm" ], + "dev": true, "optional": true, "os": [ "linux" @@ -6462,6 +6507,7 @@ "cpu": [ "arm" ], + "dev": true, "optional": true, "os": [ "linux" @@ -6474,6 +6520,7 @@ "cpu": [ "arm64" ], + "dev": true, "optional": true, "os": [ "linux" @@ -6486,6 +6533,7 @@ "cpu": [ "arm64" ], + "dev": true, "optional": true, "os": [ "linux" @@ -6498,6 +6546,7 @@ "cpu": [ "ppc64" ], + "dev": true, "optional": true, "os": [ "linux" @@ -6510,6 +6559,7 @@ "cpu": [ "riscv64" ], + "dev": true, "optional": true, "os": [ "linux" @@ -6522,6 +6572,7 @@ "cpu": [ "s390x" ], + "dev": true, "optional": true, "os": [ "linux" @@ -6534,6 +6585,7 @@ "cpu": [ "x64" ], + "dev": true, "optional": true, "os": [ "linux" @@ -6546,6 +6598,7 @@ "cpu": [ "x64" ], + "dev": true, "optional": true, "os": [ "linux" @@ -6558,6 +6611,7 @@ "cpu": [ "arm64" ], + "dev": true, "optional": true, "os": [ "win32" @@ -6570,6 +6624,7 @@ "cpu": [ "ia32" ], + "dev": true, "optional": true, "os": [ "win32" @@ -6582,6 +6637,7 @@ "cpu": [ "x64" ], + "dev": true, "optional": true, "os": [ "win32" @@ -7171,25 +7227,25 @@ "version": "1.0.11", "resolved": "https://registry.npmjs.org/@tsconfig/node10/-/node10-1.0.11.tgz", "integrity": "sha512-DcRjDCujK/kCk/cUe8Xz8ZSpm8mS3mNNpta+jGCA6USEDfktlNvm1+IuZ9eTcDbNk41BHwpHHeW+N1lKCz4zOw==", - "devOptional": true + "dev": true }, "node_modules/@tsconfig/node12": { "version": "1.0.11", "resolved": "https://registry.npmjs.org/@tsconfig/node12/-/node12-1.0.11.tgz", "integrity": "sha512-cqefuRsh12pWyGsIoBKJA9luFu3mRxCA+ORZvA4ktLSzIuCUtWVxGIuXigEwO5/ywWFMZ2QEGKWvkZG1zDMTag==", - "devOptional": true + "dev": true }, "node_modules/@tsconfig/node14": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/@tsconfig/node14/-/node14-1.0.3.tgz", "integrity": "sha512-ysT8mhdixWK6Hw3i1V2AeRqZ5WfXg1G43mqoYlM2nc6388Fq5jcXyr5mRsqViLx/GJYdoL0bfXD8nmF+Zn/Iow==", - "devOptional": true + "dev": true }, "node_modules/@tsconfig/node16": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/@tsconfig/node16/-/node16-1.0.4.tgz", "integrity": "sha512-vxhUy4J8lyeyinH7Azl1pdd43GJhZH/tP2weN8TntQblOY+A0XbT8DJk1/oCPuOOyg/Ja757rG0CgHcWC8OfMA==", - "devOptional": true + "dev": true }, "node_modules/@types/arcgis-rest-api": { "version": "10.4.8", @@ -7367,6 +7423,7 @@ "version": "7.4.3", "resolved": "https://registry.npmjs.org/@types/d3/-/d3-7.4.3.tgz", "integrity": "sha512-lZXZ9ckh5R8uiFVt8ogUNf+pIrK4EsWrx2Np75WvF/eTpJ0FMHNhjXk8CKEx/+gpHbNQyJWehbFaTvqmHWB3ww==", + "dev": true, "dependencies": { "@types/d3-array": "*", "@types/d3-axis": "*", @@ -7403,12 +7460,14 @@ "node_modules/@types/d3-array": { "version": "3.2.1", "resolved": "https://registry.npmjs.org/@types/d3-array/-/d3-array-3.2.1.tgz", - "integrity": "sha512-Y2Jn2idRrLzUfAKV2LyRImR+y4oa2AntrgID95SHJxuMUrkNXmanDSed71sRNZysveJVt1hLLemQZIady0FpEg==" + "integrity": "sha512-Y2Jn2idRrLzUfAKV2LyRImR+y4oa2AntrgID95SHJxuMUrkNXmanDSed71sRNZysveJVt1hLLemQZIady0FpEg==", + "dev": true }, "node_modules/@types/d3-axis": { "version": "3.0.6", "resolved": "https://registry.npmjs.org/@types/d3-axis/-/d3-axis-3.0.6.tgz", "integrity": "sha512-pYeijfZuBd87T0hGn0FO1vQ/cgLk6E1ALJjfkC0oJ8cbwkZl3TpgS8bVBLZN+2jjGgg38epgxb2zmoGtSfvgMw==", + "dev": true, "dependencies": { "@types/d3-selection": "*" } @@ -7417,6 +7476,7 @@ "version": "3.0.6", "resolved": "https://registry.npmjs.org/@types/d3-brush/-/d3-brush-3.0.6.tgz", "integrity": "sha512-nH60IZNNxEcrh6L1ZSMNA28rj27ut/2ZmI3r96Zd+1jrZD++zD3LsMIjWlvg4AYrHn/Pqz4CF3veCxGjtbqt7A==", + "dev": true, "dependencies": { "@types/d3-selection": "*" } @@ -7424,17 +7484,20 @@ "node_modules/@types/d3-chord": { "version": "3.0.6", "resolved": "https://registry.npmjs.org/@types/d3-chord/-/d3-chord-3.0.6.tgz", - "integrity": "sha512-LFYWWd8nwfwEmTZG9PfQxd17HbNPksHBiJHaKuY1XeqscXacsS2tyoo6OdRsjf+NQYeB6XrNL3a25E3gH69lcg==" + "integrity": "sha512-LFYWWd8nwfwEmTZG9PfQxd17HbNPksHBiJHaKuY1XeqscXacsS2tyoo6OdRsjf+NQYeB6XrNL3a25E3gH69lcg==", + "dev": true }, "node_modules/@types/d3-color": { "version": "3.1.3", "resolved": "https://registry.npmjs.org/@types/d3-color/-/d3-color-3.1.3.tgz", - "integrity": "sha512-iO90scth9WAbmgv7ogoq57O9YpKmFBbmoEoCHDB2xMBY0+/KVrqAaCDyCE16dUspeOvIxFFRI+0sEtqDqy2b4A==" + "integrity": "sha512-iO90scth9WAbmgv7ogoq57O9YpKmFBbmoEoCHDB2xMBY0+/KVrqAaCDyCE16dUspeOvIxFFRI+0sEtqDqy2b4A==", + "dev": true }, "node_modules/@types/d3-contour": { "version": "3.0.6", "resolved": "https://registry.npmjs.org/@types/d3-contour/-/d3-contour-3.0.6.tgz", "integrity": "sha512-BjzLgXGnCWjUSYGfH1cpdo41/hgdWETu4YxpezoztawmqsvCeep+8QGfiY6YbDvfgHz/DkjeIkkZVJavB4a3rg==", + "dev": true, "dependencies": { "@types/d3-array": "*", "@types/geojson": "*" @@ -7443,17 +7506,20 @@ "node_modules/@types/d3-delaunay": { "version": "6.0.4", "resolved": "https://registry.npmjs.org/@types/d3-delaunay/-/d3-delaunay-6.0.4.tgz", - "integrity": "sha512-ZMaSKu4THYCU6sV64Lhg6qjf1orxBthaC161plr5KuPHo3CNm8DTHiLw/5Eq2b6TsNP0W0iJrUOFscY6Q450Hw==" + "integrity": "sha512-ZMaSKu4THYCU6sV64Lhg6qjf1orxBthaC161plr5KuPHo3CNm8DTHiLw/5Eq2b6TsNP0W0iJrUOFscY6Q450Hw==", + "dev": true }, "node_modules/@types/d3-dispatch": { "version": "3.0.6", "resolved": "https://registry.npmjs.org/@types/d3-dispatch/-/d3-dispatch-3.0.6.tgz", - "integrity": "sha512-4fvZhzMeeuBJYZXRXrRIQnvUYfyXwYmLsdiN7XXmVNQKKw1cM8a5WdID0g1hVFZDqT9ZqZEY5pD44p24VS7iZQ==" + "integrity": "sha512-4fvZhzMeeuBJYZXRXrRIQnvUYfyXwYmLsdiN7XXmVNQKKw1cM8a5WdID0g1hVFZDqT9ZqZEY5pD44p24VS7iZQ==", + "dev": true }, "node_modules/@types/d3-drag": { "version": "3.0.7", "resolved": "https://registry.npmjs.org/@types/d3-drag/-/d3-drag-3.0.7.tgz", "integrity": "sha512-HE3jVKlzU9AaMazNufooRJ5ZpWmLIoc90A37WU2JMmeq28w1FQqCZswHZ3xR+SuxYftzHq6WU6KJHvqxKzTxxQ==", + "dev": true, "dependencies": { "@types/d3-selection": "*" } @@ -7461,17 +7527,20 @@ "node_modules/@types/d3-dsv": { "version": "3.0.7", "resolved": "https://registry.npmjs.org/@types/d3-dsv/-/d3-dsv-3.0.7.tgz", - "integrity": "sha512-n6QBF9/+XASqcKK6waudgL0pf/S5XHPPI8APyMLLUHd8NqouBGLsU8MgtO7NINGtPBtk9Kko/W4ea0oAspwh9g==" + "integrity": "sha512-n6QBF9/+XASqcKK6waudgL0pf/S5XHPPI8APyMLLUHd8NqouBGLsU8MgtO7NINGtPBtk9Kko/W4ea0oAspwh9g==", + "dev": true }, "node_modules/@types/d3-ease": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/@types/d3-ease/-/d3-ease-3.0.2.tgz", - "integrity": "sha512-NcV1JjO5oDzoK26oMzbILE6HW7uVXOHLQvHshBUW4UMdZGfiY6v5BeQwh9a9tCzv+CeefZQHJt5SRgK154RtiA==" + "integrity": "sha512-NcV1JjO5oDzoK26oMzbILE6HW7uVXOHLQvHshBUW4UMdZGfiY6v5BeQwh9a9tCzv+CeefZQHJt5SRgK154RtiA==", + "dev": true }, "node_modules/@types/d3-fetch": { "version": "3.0.7", "resolved": "https://registry.npmjs.org/@types/d3-fetch/-/d3-fetch-3.0.7.tgz", "integrity": "sha512-fTAfNmxSb9SOWNB9IoG5c8Hg6R+AzUHDRlsXsDZsNp6sxAEOP0tkP3gKkNSO/qmHPoBFTxNrjDprVHDQDvo5aA==", + "dev": true, "dependencies": { "@types/d3-dsv": "*" } @@ -7479,17 +7548,20 @@ "node_modules/@types/d3-force": { "version": "3.0.10", "resolved": "https://registry.npmjs.org/@types/d3-force/-/d3-force-3.0.10.tgz", - "integrity": "sha512-ZYeSaCF3p73RdOKcjj+swRlZfnYpK1EbaDiYICEEp5Q6sUiqFaFQ9qgoshp5CzIyyb/yD09kD9o2zEltCexlgw==" + "integrity": "sha512-ZYeSaCF3p73RdOKcjj+swRlZfnYpK1EbaDiYICEEp5Q6sUiqFaFQ9qgoshp5CzIyyb/yD09kD9o2zEltCexlgw==", + "dev": true }, "node_modules/@types/d3-format": { "version": "3.0.4", "resolved": "https://registry.npmjs.org/@types/d3-format/-/d3-format-3.0.4.tgz", - "integrity": "sha512-fALi2aI6shfg7vM5KiR1wNJnZ7r6UuggVqtDA+xiEdPZQwy/trcQaHnwShLuLdta2rTymCNpxYTiMZX/e09F4g==" + "integrity": "sha512-fALi2aI6shfg7vM5KiR1wNJnZ7r6UuggVqtDA+xiEdPZQwy/trcQaHnwShLuLdta2rTymCNpxYTiMZX/e09F4g==", + "dev": true }, "node_modules/@types/d3-geo": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/@types/d3-geo/-/d3-geo-3.1.0.tgz", "integrity": "sha512-856sckF0oP/diXtS4jNsiQw/UuK5fQG8l/a9VVLeSouf1/PPbBE1i1W852zVwKwYCBkFJJB7nCFTbk6UMEXBOQ==", + "dev": true, "dependencies": { "@types/geojson": "*" } @@ -7497,12 +7569,14 @@ "node_modules/@types/d3-hierarchy": { "version": "3.1.7", "resolved": "https://registry.npmjs.org/@types/d3-hierarchy/-/d3-hierarchy-3.1.7.tgz", - "integrity": "sha512-tJFtNoYBtRtkNysX1Xq4sxtjK8YgoWUNpIiUee0/jHGRwqvzYxkq0hGVbbOGSz+JgFxxRu4K8nb3YpG3CMARtg==" + "integrity": "sha512-tJFtNoYBtRtkNysX1Xq4sxtjK8YgoWUNpIiUee0/jHGRwqvzYxkq0hGVbbOGSz+JgFxxRu4K8nb3YpG3CMARtg==", + "dev": true }, "node_modules/@types/d3-interpolate": { "version": "3.0.4", "resolved": "https://registry.npmjs.org/@types/d3-interpolate/-/d3-interpolate-3.0.4.tgz", "integrity": "sha512-mgLPETlrpVV1YRJIglr4Ez47g7Yxjl1lj7YKsiMCb27VJH9W8NVM6Bb9d8kkpG/uAQS5AmbA48q2IAolKKo1MA==", + "dev": true, "dependencies": { "@types/d3-color": "*" } @@ -7510,27 +7584,32 @@ "node_modules/@types/d3-path": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/@types/d3-path/-/d3-path-3.1.0.tgz", - "integrity": "sha512-P2dlU/q51fkOc/Gfl3Ul9kicV7l+ra934qBFXCFhrZMOL6du1TM0pm1ThYvENukyOn5h9v+yMJ9Fn5JK4QozrQ==" + "integrity": "sha512-P2dlU/q51fkOc/Gfl3Ul9kicV7l+ra934qBFXCFhrZMOL6du1TM0pm1ThYvENukyOn5h9v+yMJ9Fn5JK4QozrQ==", + "dev": true }, "node_modules/@types/d3-polygon": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/@types/d3-polygon/-/d3-polygon-3.0.2.tgz", - "integrity": "sha512-ZuWOtMaHCkN9xoeEMr1ubW2nGWsp4nIql+OPQRstu4ypeZ+zk3YKqQT0CXVe/PYqrKpZAi+J9mTs05TKwjXSRA==" + "integrity": "sha512-ZuWOtMaHCkN9xoeEMr1ubW2nGWsp4nIql+OPQRstu4ypeZ+zk3YKqQT0CXVe/PYqrKpZAi+J9mTs05TKwjXSRA==", + "dev": true }, "node_modules/@types/d3-quadtree": { "version": "3.0.6", "resolved": "https://registry.npmjs.org/@types/d3-quadtree/-/d3-quadtree-3.0.6.tgz", - "integrity": "sha512-oUzyO1/Zm6rsxKRHA1vH0NEDG58HrT5icx/azi9MF1TWdtttWl0UIUsjEQBBh+SIkrpd21ZjEv7ptxWys1ncsg==" + "integrity": "sha512-oUzyO1/Zm6rsxKRHA1vH0NEDG58HrT5icx/azi9MF1TWdtttWl0UIUsjEQBBh+SIkrpd21ZjEv7ptxWys1ncsg==", + "dev": true }, "node_modules/@types/d3-random": { "version": "3.0.3", "resolved": "https://registry.npmjs.org/@types/d3-random/-/d3-random-3.0.3.tgz", - "integrity": "sha512-Imagg1vJ3y76Y2ea0871wpabqp613+8/r0mCLEBfdtqC7xMSfj9idOnmBYyMoULfHePJyxMAw3nWhJxzc+LFwQ==" + "integrity": "sha512-Imagg1vJ3y76Y2ea0871wpabqp613+8/r0mCLEBfdtqC7xMSfj9idOnmBYyMoULfHePJyxMAw3nWhJxzc+LFwQ==", + "dev": true }, "node_modules/@types/d3-scale": { "version": "4.0.8", "resolved": "https://registry.npmjs.org/@types/d3-scale/-/d3-scale-4.0.8.tgz", "integrity": "sha512-gkK1VVTr5iNiYJ7vWDI+yUFFlszhNMtVeneJ6lUTKPjprsvLLI9/tgEGiXJOnlINJA8FyA88gfnQsHbybVZrYQ==", + "dev": true, "dependencies": { "@types/d3-time": "*" } @@ -7538,17 +7617,20 @@ "node_modules/@types/d3-scale-chromatic": { "version": "3.0.3", "resolved": "https://registry.npmjs.org/@types/d3-scale-chromatic/-/d3-scale-chromatic-3.0.3.tgz", - "integrity": "sha512-laXM4+1o5ImZv3RpFAsTRn3TEkzqkytiOY0Dz0sq5cnd1dtNlk6sHLon4OvqaiJb28T0S/TdsBI3Sjsy+keJrw==" + "integrity": "sha512-laXM4+1o5ImZv3RpFAsTRn3TEkzqkytiOY0Dz0sq5cnd1dtNlk6sHLon4OvqaiJb28T0S/TdsBI3Sjsy+keJrw==", + "dev": true }, "node_modules/@types/d3-selection": { "version": "3.0.10", "resolved": "https://registry.npmjs.org/@types/d3-selection/-/d3-selection-3.0.10.tgz", - "integrity": "sha512-cuHoUgS/V3hLdjJOLTT691+G2QoqAjCVLmr4kJXR4ha56w1Zdu8UUQ5TxLRqudgNjwXeQxKMq4j+lyf9sWuslg==" + "integrity": "sha512-cuHoUgS/V3hLdjJOLTT691+G2QoqAjCVLmr4kJXR4ha56w1Zdu8UUQ5TxLRqudgNjwXeQxKMq4j+lyf9sWuslg==", + "dev": true }, "node_modules/@types/d3-shape": { "version": "3.1.6", "resolved": "https://registry.npmjs.org/@types/d3-shape/-/d3-shape-3.1.6.tgz", "integrity": "sha512-5KKk5aKGu2I+O6SONMYSNflgiP0WfZIQvVUMan50wHsLG1G94JlxEVnCpQARfTtzytuY0p/9PXXZb3I7giofIA==", + "dev": true, "dependencies": { "@types/d3-path": "*" } @@ -7556,22 +7638,26 @@ "node_modules/@types/d3-time": { "version": "3.0.3", "resolved": "https://registry.npmjs.org/@types/d3-time/-/d3-time-3.0.3.tgz", - "integrity": "sha512-2p6olUZ4w3s+07q3Tm2dbiMZy5pCDfYwtLXXHUnVzXgQlZ/OyPtUz6OL382BkOuGlLXqfT+wqv8Fw2v8/0geBw==" + "integrity": "sha512-2p6olUZ4w3s+07q3Tm2dbiMZy5pCDfYwtLXXHUnVzXgQlZ/OyPtUz6OL382BkOuGlLXqfT+wqv8Fw2v8/0geBw==", + "dev": true }, "node_modules/@types/d3-time-format": { "version": "4.0.3", "resolved": "https://registry.npmjs.org/@types/d3-time-format/-/d3-time-format-4.0.3.tgz", - "integrity": "sha512-5xg9rC+wWL8kdDj153qZcsJ0FWiFt0J5RB6LYUNZjwSnesfblqrI/bJ1wBdJ8OQfncgbJG5+2F+qfqnqyzYxyg==" + "integrity": "sha512-5xg9rC+wWL8kdDj153qZcsJ0FWiFt0J5RB6LYUNZjwSnesfblqrI/bJ1wBdJ8OQfncgbJG5+2F+qfqnqyzYxyg==", + "dev": true }, "node_modules/@types/d3-timer": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/@types/d3-timer/-/d3-timer-3.0.2.tgz", - "integrity": "sha512-Ps3T8E8dZDam6fUyNiMkekK3XUsaUEik+idO9/YjPtfj2qruF8tFBXS7XhtE4iIXBLxhmLjP3SXpLhVf21I9Lw==" + "integrity": "sha512-Ps3T8E8dZDam6fUyNiMkekK3XUsaUEik+idO9/YjPtfj2qruF8tFBXS7XhtE4iIXBLxhmLjP3SXpLhVf21I9Lw==", + "dev": true }, "node_modules/@types/d3-transition": { "version": "3.0.8", "resolved": "https://registry.npmjs.org/@types/d3-transition/-/d3-transition-3.0.8.tgz", "integrity": "sha512-ew63aJfQ/ms7QQ4X7pk5NxQ9fZH/z+i24ZfJ6tJSfqxJMrYLiK01EAs2/Rtw/JreGUsS3pLPNV644qXFGnoZNQ==", + "dev": true, "dependencies": { "@types/d3-selection": "*" } @@ -7580,6 +7666,7 @@ "version": "3.0.8", "resolved": "https://registry.npmjs.org/@types/d3-zoom/-/d3-zoom-3.0.8.tgz", "integrity": "sha512-iqMC4/YlFCSlO8+2Ii1GGGliCAY4XdeG748w5vQUbevlbDu0zSjH/+jojorQVBK/se0j6DUFNPBGSqD3YWYnDw==", + "dev": true, "dependencies": { "@types/d3-interpolate": "*", "@types/d3-selection": "*" @@ -7608,7 +7695,8 @@ "node_modules/@types/estree": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.5.tgz", - "integrity": "sha512-/kYRxGDLWzHOB7q+wtSUQlFrtcdUccpfy+X+9iMBpHK8QLLhx2wIPYuS5DYtR9Wa/YlZAbIovy7qVdB1Aq6Lyw==" + "integrity": "sha512-/kYRxGDLWzHOB7q+wtSUQlFrtcdUccpfy+X+9iMBpHK8QLLhx2wIPYuS5DYtR9Wa/YlZAbIovy7qVdB1Aq6Lyw==", + "dev": true }, "node_modules/@types/express": { "version": "4.17.21", @@ -7673,6 +7761,16 @@ "@types/node": "*" } }, + "node_modules/@types/hoist-non-react-statics": { + "version": "3.3.5", + "resolved": "https://registry.npmjs.org/@types/hoist-non-react-statics/-/hoist-non-react-statics-3.3.5.tgz", + "integrity": "sha512-SbcrWzkKBw2cdwRTwQAswfpB9g9LJWfjtUeW/jvNwbhC8cpmmNYVePa+ncbUe0rGTQ7G3Ff6mYUN2VMfLVr+Sg==", + "dev": true, + "dependencies": { + "@types/react": "*", + "hoist-non-react-statics": "^3.3.0" + } + }, "node_modules/@types/html-minifier": { "version": "3.5.3", "resolved": "https://registry.npmjs.org/@types/html-minifier/-/html-minifier-3.5.3.tgz", @@ -7774,12 +7872,14 @@ "node_modules/@types/json-schema": { "version": "7.0.15", "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.15.tgz", - "integrity": "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==" + "integrity": "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==", + "dev": true }, "node_modules/@types/json5": { "version": "0.0.29", "resolved": "https://registry.npmjs.org/@types/json5/-/json5-0.0.29.tgz", - "integrity": "sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ==" + "integrity": "sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ==", + "dev": true }, "node_modules/@types/long": { "version": "4.0.2", @@ -7832,10 +7932,17 @@ "integrity": "sha512-j3pOPiEcWZ34R6a6mN07mUkM4o4Lwf6hPNt8eilOeZhTFbxFXmKhvXl9Y28jotFPaI1bpPDJsbCprUoNke6OrA==", "dev": true }, + "node_modules/@types/prop-types": { + "version": "15.7.12", + "resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.12.tgz", + "integrity": "sha512-5zvhXYtRNRluoE/jAp4GVsSduVUzNWKkOZrCDBWYtE7biZywwdC2AcEzg+cSMLFRfVgeAFqpfNabiPjxFddV1Q==", + "dev": true + }, "node_modules/@types/pug": { "version": "2.0.10", "resolved": "https://registry.npmjs.org/@types/pug/-/pug-2.0.10.tgz", - "integrity": "sha512-Sk/uYFOBAB7mb74XcpizmH0KOR2Pv3D2Hmrh1Dmy5BmK3MpdSa5kqZcg6EKBdklU0bFXX9gCfzvpnyUehrPIuA==" + "integrity": "sha512-Sk/uYFOBAB7mb74XcpizmH0KOR2Pv3D2Hmrh1Dmy5BmK3MpdSa5kqZcg6EKBdklU0bFXX9gCfzvpnyUehrPIuA==", + "dev": true }, "node_modules/@types/qs": { "version": "6.9.15", @@ -7849,6 +7956,37 @@ "integrity": "sha512-hKormJbkJqzQGhziax5PItDUTMAM9uE2XXQmM37dyd4hVM+5aVl7oVxMVUiVQn2oCQFN/LKCZdvSM0pFRqbSmQ==", "dev": true }, + "node_modules/@types/react": { + "version": "18.3.3", + "resolved": "https://registry.npmjs.org/@types/react/-/react-18.3.3.tgz", + "integrity": "sha512-hti/R0pS0q1/xx+TsI73XIqk26eBsISZ2R0wUijXIngRK9R/e7Xw/cXVxQK7R5JjW+SV4zGcn5hXjudkN/pLIw==", + "dev": true, + "dependencies": { + "@types/prop-types": "*", + "csstype": "^3.0.2" + } + }, + "node_modules/@types/react-redux": { + "version": "7.1.33", + "resolved": "https://registry.npmjs.org/@types/react-redux/-/react-redux-7.1.33.tgz", + "integrity": "sha512-NF8m5AjWCkert+fosDsN3hAlHzpjSiXlVy9EgQEmLoBhaNXbmyeGs/aj5dQzKuF+/q+S7JQagorGDW8pJ28Hmg==", + "dev": true, + "dependencies": { + "@types/hoist-non-react-statics": "^3.3.0", + "@types/react": "*", + "hoist-non-react-statics": "^3.3.0", + "redux": "^4.0.0" + } + }, + "node_modules/@types/react-redux/node_modules/redux": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/redux/-/redux-4.2.1.tgz", + "integrity": "sha512-LAUYz4lc+Do8/g7aeRa8JkyDErK6ekstQaqWQrNRW//MY1TvCEpMtpTWvlQ+FPbWCx+Xixu/6SHt5N0HR+SB4w==", + "dev": true, + "dependencies": { + "@babel/runtime": "^7.9.2" + } + }, "node_modules/@types/relateurl": { "version": "0.2.33", "resolved": "https://registry.npmjs.org/@types/relateurl/-/relateurl-0.2.33.tgz", @@ -7882,7 +8020,8 @@ "node_modules/@types/resolve": { "version": "1.20.2", "resolved": "https://registry.npmjs.org/@types/resolve/-/resolve-1.20.2.tgz", - "integrity": "sha512-60BCwRFOZCQhDncwQdxxeOEEkbc5dIMccYLwbxsS4TUNeVECQ/pBJ0j09mrHOl/JJvpRPGwO9SvE4nR2Nb/a4Q==" + "integrity": "sha512-60BCwRFOZCQhDncwQdxxeOEEkbc5dIMccYLwbxsS4TUNeVECQ/pBJ0j09mrHOl/JJvpRPGwO9SvE4nR2Nb/a4Q==", + "dev": true }, "node_modules/@types/retry": { "version": "0.12.0", @@ -7895,6 +8034,7 @@ "resolved": "https://registry.npmjs.org/@types/rollup/-/rollup-0.54.0.tgz", "integrity": "sha512-oeYztLHhQ98jnr+u2cs1c3tHOGtpzrm9DJlIdEjznwoXWidUbrI+X6ib7zCkPIbB7eJ7VbbKNQ5n/bPnSg6Naw==", "deprecated": "This is a stub types definition for rollup (https://github.com/rollup/rollup). rollup provides its own type definitions, so you don't need @types/rollup installed!", + "dev": true, "dependencies": { "rollup": "*" } @@ -7902,7 +8042,8 @@ "node_modules/@types/semver": { "version": "7.5.8", "resolved": "https://registry.npmjs.org/@types/semver/-/semver-7.5.8.tgz", - "integrity": "sha512-I8EUhyrgfLrcTkzV3TSsGyl1tSuPrEDzr0yd5m90UgNxQkyDXULk3b6MlQqTCpZpNtWe1K0hzclnZkTcLBe2UQ==" + "integrity": "sha512-I8EUhyrgfLrcTkzV3TSsGyl1tSuPrEDzr0yd5m90UgNxQkyDXULk3b6MlQqTCpZpNtWe1K0hzclnZkTcLBe2UQ==", + "dev": true }, "node_modules/@types/send": { "version": "0.17.4", @@ -8260,7 +8401,8 @@ "node_modules/@ungap/structured-clone": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/@ungap/structured-clone/-/structured-clone-1.2.0.tgz", - "integrity": "sha512-zuVdFrMJiuCDQUMCzQaD6KL28MjnqqN8XnAqiEq9PNm/hCPTSGfrXCOfwj1ow4LFb/tNymJPwsNbVePc1xFqrQ==" + "integrity": "sha512-zuVdFrMJiuCDQUMCzQaD6KL28MjnqqN8XnAqiEq9PNm/hCPTSGfrXCOfwj1ow4LFb/tNymJPwsNbVePc1xFqrQ==", + "dev": true }, "node_modules/@vaadin/a11y-base": { "version": "24.3.15", @@ -8910,6 +9052,7 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/@windycom/plugin-devtools/-/plugin-devtools-2.0.0.tgz", "integrity": "sha512-S+67Xrkav0+pL/tk6OzwjGN40oiHjDiZpibO5KkskoNGSc6z4g8R++xQIV+Uw3FEMx7fi7JFqBSuZQz8zeM2eg==", + "dev": true, "dependencies": { "@rollup/plugin-commonjs": "^25.0.7", "@rollup/plugin-node-resolve": "^15.2.3", @@ -8947,6 +9090,7 @@ "version": "6.21.0", "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-6.21.0.tgz", "integrity": "sha512-oy9+hTPCUFpngkEZUSzbf9MxI65wbKFoQYsgPdILTfbUldp5ovUuphZVe4i30emU9M/kP+T64Di0mxl7dSw3MA==", + "dev": true, "dependencies": { "@eslint-community/regexpp": "^4.5.1", "@typescript-eslint/scope-manager": "6.21.0", @@ -8981,6 +9125,7 @@ "version": "6.21.0", "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-6.21.0.tgz", "integrity": "sha512-tbsV1jPne5CkFQCgPBcDOt30ItF7aJoZL997JSF7MhGQqOeT3svWRYxiqlfA5RUdlHN6Fi+EI9bxqbdyAUZjYQ==", + "dev": true, "dependencies": { "@typescript-eslint/scope-manager": "6.21.0", "@typescript-eslint/types": "6.21.0", @@ -9008,6 +9153,7 @@ "version": "6.21.0", "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-6.21.0.tgz", "integrity": "sha512-OwLUIWZJry80O99zvqXVEioyniJMa+d2GrqpUTqi5/v5D5rOrppJVBPa0yKCblcigC0/aYAzxxqQ1B+DS2RYsg==", + "dev": true, "dependencies": { "@typescript-eslint/types": "6.21.0", "@typescript-eslint/visitor-keys": "6.21.0" @@ -9024,6 +9170,7 @@ "version": "6.21.0", "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-6.21.0.tgz", "integrity": "sha512-rZQI7wHfao8qMX3Rd3xqeYSMCL3SoiSQLBATSiVKARdFGCYSRvmViieZjqc58jKgs8Y8i9YvVVhRbHSTA4VBag==", + "dev": true, "dependencies": { "@typescript-eslint/typescript-estree": "6.21.0", "@typescript-eslint/utils": "6.21.0", @@ -9050,6 +9197,7 @@ "version": "6.21.0", "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-6.21.0.tgz", "integrity": "sha512-1kFmZ1rOm5epu9NZEZm1kckCDGj5UJEf7P1kliH4LKu/RkwpsfqqGmY2OOcUs18lSlQBKLDYBOGxRVtrMN5lpg==", + "dev": true, "engines": { "node": "^16.0.0 || >=18.0.0" }, @@ -9062,6 +9210,7 @@ "version": "6.21.0", "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-6.21.0.tgz", "integrity": "sha512-6npJTkZcO+y2/kr+z0hc4HwNfrrP4kNYh57ek7yCNlrBjWQ1Y0OS7jiZTkgumrvkX5HkEKXFZkkdFNkaW2wmUQ==", + "dev": true, "dependencies": { "@typescript-eslint/types": "6.21.0", "@typescript-eslint/visitor-keys": "6.21.0", @@ -9089,6 +9238,7 @@ "version": "6.21.0", "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-6.21.0.tgz", "integrity": "sha512-NfWVaC8HP9T8cbKQxHcsJBY5YE1O33+jpMwN45qzWWaPDZgLIbo12toGMWnmhvCpd3sIxkpDw3Wv1B3dYrbDQQ==", + "dev": true, "dependencies": { "@eslint-community/eslint-utils": "^4.4.0", "@types/json-schema": "^7.0.12", @@ -9113,6 +9263,7 @@ "version": "6.21.0", "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-6.21.0.tgz", "integrity": "sha512-JJtkDduxLi9bivAB+cYOVMtbkqdPOhZ+ZI5LC47MIRrDV4Yn2o+ZnW10Nkmr28xRpSpdJ6Sm42Hjf2+REYXm0A==", + "dev": true, "dependencies": { "@typescript-eslint/types": "6.21.0", "eslint-visitor-keys": "^3.4.1" @@ -9129,6 +9280,7 @@ "version": "1.1.11", "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dev": true, "optional": true, "peer": true, "dependencies": { @@ -9141,6 +9293,7 @@ "resolved": "https://registry.npmjs.org/eslint-config-standard-with-typescript/-/eslint-config-standard-with-typescript-43.0.1.tgz", "integrity": "sha512-WfZ986+qzIzX6dcr4yGUyVb/l9N3Z8wPXCc5z/70fljs3UbWhhV+WxrfgsqMToRzuuyX9MqZ974pq2UPhDTOcA==", "deprecated": "Please use eslint-config-love, instead.", + "dev": true, "dependencies": { "@typescript-eslint/parser": "^6.4.0", "eslint-config-standard": "17.1.0" @@ -9159,6 +9312,7 @@ "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", "deprecated": "Glob versions prior to v9 are no longer supported", + "dev": true, "optional": true, "peer": true, "dependencies": { @@ -9180,6 +9334,7 @@ "version": "3.1.2", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, "optional": true, "peer": true, "dependencies": { @@ -9193,6 +9348,7 @@ "version": "4.2.0", "resolved": "https://registry.npmjs.org/less/-/less-4.2.0.tgz", "integrity": "sha512-P3b3HJDBtSzsXUl0im2L7gTO5Ubg8mEN6G8qoTS77iXxXX4Hvu4Qj540PZDvQ8V6DmX6iXo98k7Md0Cm1PrLaA==", + "dev": true, "dependencies": { "copy-anything": "^2.0.1", "parse-node-version": "^1.0.1", @@ -9218,6 +9374,7 @@ "version": "0.6.1", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true, "optional": true, "engines": { "node": ">=0.10.0" @@ -9227,6 +9384,7 @@ "version": "2.1.0", "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-2.1.0.tgz", "integrity": "sha512-LS9X+dc8KLxXCb8dni79fLIIUA5VyZoyjSMCwTluaXA0o27cCK0bhXkpgw+sTXVpPy/lSO57ilRixqk0vDmtRA==", + "dev": true, "optional": true, "dependencies": { "pify": "^4.0.1", @@ -9240,6 +9398,7 @@ "version": "5.7.2", "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz", "integrity": "sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==", + "dev": true, "optional": true, "bin": { "semver": "bin/semver" @@ -9249,6 +9408,7 @@ "version": "1.6.0", "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==", + "dev": true, "optional": true, "bin": { "mime": "cli.js" @@ -9261,6 +9421,7 @@ "version": "1.0.4", "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz", "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==", + "dev": true, "optional": true, "peer": true, "bin": { @@ -9274,6 +9435,7 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", + "dev": true, "optional": true, "peer": true }, @@ -9281,6 +9443,7 @@ "version": "4.0.1", "resolved": "https://registry.npmjs.org/pify/-/pify-4.0.1.tgz", "integrity": "sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==", + "dev": true, "optional": true, "engines": { "node": ">=6" @@ -9290,6 +9453,7 @@ "version": "3.3.2", "resolved": "https://registry.npmjs.org/prettier/-/prettier-3.3.2.tgz", "integrity": "sha512-rAVeHYMcv8ATV5d508CFdn+8/pHPpXeIid1DdrPwXnaAdH7cqjVbpJaT5eq4yRAFU/lsbwYwSF/n5iNrdJHPQA==", + "dev": true, "bin": { "prettier": "bin/prettier.cjs" }, @@ -9304,6 +9468,7 @@ "version": "3.2.5", "resolved": "https://registry.npmjs.org/prettier-plugin-svelte/-/prettier-plugin-svelte-3.2.5.tgz", "integrity": "sha512-vP/M/Goc8z4iVIvrwXwbrYVjJgA0Hf8PO1G4LBh/ocSt6vUP6sLvyu9F3ABEGr+dbKyxZjEKLkeFsWy/yYl0HQ==", + "dev": true, "peerDependencies": { "prettier": "^3.0.0", "svelte": "^3.2.0 || ^4.0.0-next.0 || ^5.0.0-next.0" @@ -9313,6 +9478,7 @@ "version": "4.18.1", "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.18.1.tgz", "integrity": "sha512-Elx2UT8lzxxOXMpy5HWQGZqkrQOtrVDDa/bm9l10+U4rQnVzbL/LgZ4NOM1MPIDyHk69W4InuYDF5dzRh4Kw1A==", + "dev": true, "dependencies": { "@types/estree": "1.0.5" }, @@ -9347,6 +9513,7 @@ "version": "1.2.4", "resolved": "https://registry.npmjs.org/sax/-/sax-1.2.4.tgz", "integrity": "sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw==", + "dev": true, "optional": true, "peer": true }, @@ -9354,6 +9521,7 @@ "version": "7.6.2", "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.2.tgz", "integrity": "sha512-FNAIBWCx9qcRhoHcgcJ0gvU7SN1lYU2ZXuSfl04bSC5OpvDHFyJCjdNHomPXxjQlCBU67YW64PzY7/VIEH7F2w==", + "dev": true, "bin": { "semver": "bin/semver.js" }, @@ -9365,6 +9533,7 @@ "version": "0.55.0", "resolved": "https://registry.npmjs.org/stylus/-/stylus-0.55.0.tgz", "integrity": "sha512-MuzIIVRSbc8XxHH7FjkvWqkIcr1BvoMZoR/oFuAJDlh7VSaNJzrB4uJ38GRQa+mWjLXODAMzeDe0xi9GYbGwnw==", + "dev": true, "optional": true, "peer": true, "dependencies": { @@ -9388,6 +9557,7 @@ "version": "3.1.0", "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", + "dev": true, "optional": true, "peer": true, "dependencies": { @@ -9398,6 +9568,7 @@ "version": "6.3.1", "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "dev": true, "optional": true, "peer": true, "bin": { @@ -9408,6 +9579,7 @@ "version": "5.1.4", "resolved": "https://registry.npmjs.org/svelte-preprocess/-/svelte-preprocess-5.1.4.tgz", "integrity": "sha512-IvnbQ6D6Ao3Gg6ftiM5tdbR6aAETwjhHV+UKGf5bHGYR69RQvF1ho0JKPcbUON4vy4R7zom13jPjgdOWCQ5hDA==", + "dev": true, "hasInstallScript": true, "dependencies": { "@types/pug": "^2.0.6", @@ -9566,6 +9738,7 @@ "version": "8.12.1", "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.12.1.tgz", "integrity": "sha512-tcpGyI9zbizT9JbV6oYE477V6mTlXvvi0T0G3SNIYE2apm/G5huBa1+K89VGeovbg+jycCrfhl3ADxErOuO6Jg==", + "dev": true, "bin": { "acorn": "bin/acorn" }, @@ -9596,6 +9769,7 @@ "version": "5.3.2", "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz", "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==", + "dev": true, "peerDependencies": { "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" } @@ -9604,7 +9778,7 @@ "version": "8.3.3", "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.3.3.tgz", "integrity": "sha512-MxXdReSRhGO7VlFe1bRG/oI7/mdLV9B9JJT0N8vZOhF7gFRR5l3M8W9G8JxmKV+JC5mGqJ0QvqfSOLsCPa4nUw==", - "devOptional": true, + "dev": true, "dependencies": { "acorn": "^8.11.0" }, @@ -9750,7 +9924,7 @@ "version": "3.2.1", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "devOptional": true, + "dev": true, "dependencies": { "color-convert": "^1.9.0" }, @@ -9762,7 +9936,7 @@ "version": "3.1.3", "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz", "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==", - "devOptional": true, + "dev": true, "dependencies": { "normalize-path": "^3.0.0", "picomatch": "^2.0.4" @@ -9795,7 +9969,7 @@ "version": "4.1.3", "resolved": "https://registry.npmjs.org/arg/-/arg-4.1.3.tgz", "integrity": "sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==", - "devOptional": true + "dev": true }, "node_modules/argparse": { "version": "1.0.10", @@ -9809,6 +9983,7 @@ "version": "5.3.0", "resolved": "https://registry.npmjs.org/aria-query/-/aria-query-5.3.0.tgz", "integrity": "sha512-b0P0sZPKtyu8HkeRAfCq0IfURZK+SuwMjY1UXGBU27wpAiTwQAIlq56IbIO+ytk/JjS1fMR14ee5WBBfKi5J6A==", + "dev": true, "dependencies": { "dequal": "^2.0.3" } @@ -9817,6 +9992,7 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/array-buffer-byte-length/-/array-buffer-byte-length-1.0.1.tgz", "integrity": "sha512-ahC5W1xgou+KTXix4sAO8Ki12Q+jf4i0+tmk3sC+zgcynshkHxzpXdImBehiUYKKKDwvfFiJl1tZt6ewscS1Mg==", + "dev": true, "dependencies": { "call-bind": "^1.0.5", "is-array-buffer": "^3.0.4" @@ -9837,6 +10013,7 @@ "version": "3.1.8", "resolved": "https://registry.npmjs.org/array-includes/-/array-includes-3.1.8.tgz", "integrity": "sha512-itaWrbYbqpGXkGhZPGUulwnhVf5Hpy1xiCFsGqyIGglbBxmG5vSjxQen3/WGOjPpNEv1RtBLKxbmVXm8HpJStQ==", + "dev": true, "dependencies": { "call-bind": "^1.0.7", "define-properties": "^1.2.1", @@ -9856,6 +10033,7 @@ "version": "2.1.0", "resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz", "integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==", + "dev": true, "engines": { "node": ">=8" } @@ -9864,6 +10042,7 @@ "version": "1.2.5", "resolved": "https://registry.npmjs.org/array.prototype.findlastindex/-/array.prototype.findlastindex-1.2.5.tgz", "integrity": "sha512-zfETvRFA8o7EiNn++N5f/kaCw221hrpGsDmcpndVupkPzEc1Wuf3VgC0qby1BbHs7f5DVYjgtEU2LLh5bqeGfQ==", + "dev": true, "dependencies": { "call-bind": "^1.0.7", "define-properties": "^1.2.1", @@ -9883,6 +10062,7 @@ "version": "1.3.2", "resolved": "https://registry.npmjs.org/array.prototype.flat/-/array.prototype.flat-1.3.2.tgz", "integrity": "sha512-djYB+Zx2vLewY8RWlNCUdHjDXs2XOgm602S9E7P/UpHgfeHL00cRiIF+IN/G/aUJ7kGPb6yO/ErDI5V2s8iycA==", + "dev": true, "dependencies": { "call-bind": "^1.0.2", "define-properties": "^1.2.0", @@ -9900,6 +10080,7 @@ "version": "1.3.2", "resolved": "https://registry.npmjs.org/array.prototype.flatmap/-/array.prototype.flatmap-1.3.2.tgz", "integrity": "sha512-Ewyx0c9PmpcsByhSW4r+9zDU7sGjFc86qf/kKtuSCRdhfbk0SNLLkaT5qvcHnRGgc5NP/ly/y+qkXkqONX54CQ==", + "dev": true, "dependencies": { "call-bind": "^1.0.2", "define-properties": "^1.2.0", @@ -9917,6 +10098,7 @@ "version": "1.0.3", "resolved": "https://registry.npmjs.org/arraybuffer.prototype.slice/-/arraybuffer.prototype.slice-1.0.3.tgz", "integrity": "sha512-bMxMKAjg13EBSVscxTaYA4mRc5t1UAXa2kXiGTNfZ079HIWXEkKmkgFrh/nJqamaLSrXO5H4WFFkPEaLJWbs3A==", + "dev": true, "dependencies": { "array-buffer-byte-length": "^1.0.1", "call-bind": "^1.0.5", @@ -10039,6 +10221,7 @@ "version": "2.1.2", "resolved": "https://registry.npmjs.org/atob/-/atob-2.1.2.tgz", "integrity": "sha512-Wm6ukoaOGJi/73p/cl2GvLjTI5JM1k/O14isD73YML8StrH/7/lRFgmg8nICZgD3bZZvjwCGxtMOD3wWNAu8cg==", + "dev": true, "optional": true, "peer": true, "bin": { @@ -10089,6 +10272,7 @@ "version": "1.0.7", "resolved": "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.7.tgz", "integrity": "sha512-wvUjBtSGN7+7SjNpq/9M2Tg350UZD3q62IFZLbRAR1bSMlCo1ZaeW+BJ+D090e4hIIZLBcTDWe4Mh4jvUDajzQ==", + "dev": true, "dependencies": { "possible-typed-array-names": "^1.0.0" }, @@ -10128,6 +10312,7 @@ "version": "4.0.0", "resolved": "https://registry.npmjs.org/axobject-query/-/axobject-query-4.0.0.tgz", "integrity": "sha512-+60uv1hiVFhHZeO+Lz0RYzsVHy5Wr1ayX0mwda9KPDVLNJgZ1T9Ny7VmFbLDzxsH0D87I86vgj3gFrjTJUYznw==", + "dev": true, "dependencies": { "dequal": "^2.0.3" } @@ -10555,7 +10740,7 @@ "version": "2.3.0", "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.3.0.tgz", "integrity": "sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==", - "devOptional": true, + "dev": true, "engines": { "node": ">=8" }, @@ -10695,6 +10880,7 @@ "version": "3.0.3", "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz", "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==", + "dev": true, "dependencies": { "fill-range": "^7.1.1" }, @@ -10712,6 +10898,7 @@ "version": "4.23.1", "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.23.1.tgz", "integrity": "sha512-TUfofFo/KsK/bWZ9TWQ5O26tsWW4Uhmt8IYklbnUa70udB6P2wA7w7o4PY4muaEPBQaAX+CEnmmIA41NVHtPVw==", + "dev": true, "funding": [ { "type": "opencollective", @@ -10807,6 +10994,7 @@ "version": "3.3.0", "resolved": "https://registry.npmjs.org/builtin-modules/-/builtin-modules-3.3.0.tgz", "integrity": "sha512-zhaCDicdLuWN5UbN5IMnFqNMhNfo919sH85y2/ea+5Yg9TsTkeZxpL+JLbp6cgYFS4sRLp3YV4S6yDuqVWHYOw==", + "dev": true, "engines": { "node": ">=6" }, @@ -10818,6 +11006,7 @@ "version": "5.1.0", "resolved": "https://registry.npmjs.org/builtins/-/builtins-5.1.0.tgz", "integrity": "sha512-SW9lzGTLvWTP1AY8xeAMZimqDrIaSdLQUcVr9DMef51niJ022Ri87SwRRKYm4A6iHfkPaiVUu/Duw2Wc4J7kKg==", + "dev": true, "dependencies": { "semver": "^7.0.0" } @@ -10826,6 +11015,7 @@ "version": "7.6.2", "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.2.tgz", "integrity": "sha512-FNAIBWCx9qcRhoHcgcJ0gvU7SN1lYU2ZXuSfl04bSC5OpvDHFyJCjdNHomPXxjQlCBU67YW64PzY7/VIEH7F2w==", + "dev": true, "bin": { "semver": "bin/semver.js" }, @@ -10892,6 +11082,7 @@ "version": "3.1.0", "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", + "dev": true, "engines": { "node": ">=6" } @@ -10930,6 +11121,7 @@ "version": "1.0.30001640", "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001640.tgz", "integrity": "sha512-lA4VMpW0PSUrFnkmVuEKBUovSWKhj7puyCg8StBChgu298N1AtuF1sKWEvfDuimSEDbhlb/KqPKC3fs1HbuQUA==", + "dev": true, "funding": [ { "type": "opencollective", @@ -10983,7 +11175,7 @@ "version": "2.4.2", "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", - "devOptional": true, + "dev": true, "dependencies": { "ansi-styles": "^3.2.1", "escape-string-regexp": "^1.0.5", @@ -11027,7 +11219,7 @@ "version": "3.6.0", "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.6.0.tgz", "integrity": "sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==", - "devOptional": true, + "dev": true, "dependencies": { "anymatch": "~3.1.2", "braces": "~3.0.2", @@ -11051,7 +11243,7 @@ "version": "5.1.2", "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", - "devOptional": true, + "dev": true, "dependencies": { "is-glob": "^4.0.1" }, @@ -11270,6 +11462,7 @@ "version": "1.0.4", "resolved": "https://registry.npmjs.org/code-red/-/code-red-1.0.4.tgz", "integrity": "sha512-7qJWqItLA8/VPVlKJlFXU+NBlo/qyfs39aJcuMT/2ere32ZqvF5OSxgdM5xOfJJ7O429gg2HM47y8v9P+9wrNw==", + "dev": true, "dependencies": { "@jridgewell/sourcemap-codec": "^1.4.15", "@types/estree": "^1.0.1", @@ -11282,6 +11475,7 @@ "version": "3.0.3", "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-3.0.3.tgz", "integrity": "sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g==", + "dev": true, "dependencies": { "@types/estree": "^1.0.0" } @@ -11316,7 +11510,7 @@ "version": "1.9.3", "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", - "devOptional": true, + "dev": true, "dependencies": { "color-name": "1.1.3" } @@ -11421,7 +11615,8 @@ "node_modules/commondir": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/commondir/-/commondir-1.0.1.tgz", - "integrity": "sha512-W9pAhw0ja1Edb5GVdIF1mjZw/ASI0AlShXM83UUGe2DVr5TdAPEA1OA8m/g8zWp9x6On7gqufY+FatDbC3MDQg==" + "integrity": "sha512-W9pAhw0ja1Edb5GVdIF1mjZw/ASI0AlShXM83UUGe2DVr5TdAPEA1OA8m/g8zWp9x6On7gqufY+FatDbC3MDQg==", + "dev": true }, "node_modules/composed-offset-position": { "version": "0.0.4", @@ -11577,7 +11772,7 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz", "integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==", - "devOptional": true + "dev": true }, "node_modules/cookie": { "version": "0.5.0", @@ -11599,6 +11794,7 @@ "version": "2.0.6", "resolved": "https://registry.npmjs.org/copy-anything/-/copy-anything-2.0.6.tgz", "integrity": "sha512-1j20GZTsvKNkc4BY3NpMOM8tt///wY3FpIzozTOFO2ffuZcV61nojHXVKIy3WM+7ADCy5FVhdZYHYDdgTU0yJw==", + "dev": true, "dependencies": { "is-what": "^3.14.1" }, @@ -11845,7 +12041,7 @@ "version": "1.1.1", "resolved": "https://registry.npmjs.org/create-require/-/create-require-1.1.1.tgz", "integrity": "sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==", - "devOptional": true + "dev": true }, "node_modules/cross-spawn": { "version": "7.0.3", @@ -11873,6 +12069,7 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/css/-/css-3.0.0.tgz", "integrity": "sha512-DG9pFfwOrzc+hawpmqX/dHYHJG+Bsdb0klhyi1sDneOgGOXy9wQIC8hzyVp1e4NRYDBdxcylvywPkkXCHAzTyQ==", + "dev": true, "optional": true, "peer": true, "dependencies": { @@ -12004,6 +12201,7 @@ "version": "2.3.1", "resolved": "https://registry.npmjs.org/css-tree/-/css-tree-2.3.1.tgz", "integrity": "sha512-6Fv1DV/TYw//QF5IzQdqsNDjx/wc8TrMBZsqjL9eW01tWb7R7k/mq+/VXfJCl7SoD5emsJop9cOByJZfs8hYIw==", + "dev": true, "dependencies": { "mdn-data": "2.0.30", "source-map-js": "^1.0.1" @@ -12028,6 +12226,7 @@ "version": "0.6.1", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true, "optional": true, "peer": true, "engines": { @@ -12038,6 +12237,7 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/cssesc/-/cssesc-3.0.0.tgz", "integrity": "sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==", + "dev": true, "bin": { "cssesc": "bin/cssesc" }, @@ -12177,6 +12377,12 @@ "node": ">=14" } }, + "node_modules/csstype": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.3.tgz", + "integrity": "sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==", + "dev": true + }, "node_modules/csv-parse": { "version": "5.5.6", "resolved": "https://registry.npmjs.org/csv-parse/-/csv-parse-5.5.6.tgz", @@ -12371,6 +12577,7 @@ "version": "7.9.0", "resolved": "https://registry.npmjs.org/d3/-/d3-7.9.0.tgz", "integrity": "sha512-e1U46jVP+w7Iut8Jt8ri1YsPOvFpg46k+K8TpCb0P+zjCkjkPnV7WzfDJzMHy1LnA+wj5pLT1wjO901gLXeEhA==", + "dev": true, "dependencies": { "d3-array": "3", "d3-axis": "3", @@ -12422,6 +12629,7 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/d3-axis/-/d3-axis-3.0.0.tgz", "integrity": "sha512-IH5tgjV4jE/GhHkRV0HiVYPDtvfjHQlQfJHs0usq7M30XcSBvOotpmH1IgkcXsO/5gEQZD43B//fc7SRT5S+xw==", + "dev": true, "engines": { "node": ">=12" } @@ -12430,6 +12638,7 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/d3-brush/-/d3-brush-3.0.0.tgz", "integrity": "sha512-ALnjWlVYkXsVIGlOsuWH1+3udkYFI48Ljihfnh8FZPF2QS9o+PzGLBslO0PjzVoHLZ2KCVgAM8NVkXPJB2aNnQ==", + "dev": true, "dependencies": { "d3-dispatch": "1 - 3", "d3-drag": "2 - 3", @@ -12445,6 +12654,7 @@ "version": "3.0.1", "resolved": "https://registry.npmjs.org/d3-chord/-/d3-chord-3.0.1.tgz", "integrity": "sha512-VE5S6TNa+j8msksl7HwjxMHDM2yNK3XCkusIlpX5kwauBfXuyLAtNg9jCp/iHH61tgI4sb6R/EIMWCqEIdjT/g==", + "dev": true, "dependencies": { "d3-path": "1 - 3" }, @@ -12456,6 +12666,7 @@ "version": "3.1.0", "resolved": "https://registry.npmjs.org/d3-color/-/d3-color-3.1.0.tgz", "integrity": "sha512-zg/chbXyeBtMQ1LbD/WSoW2DpC3I0mpmPdW+ynRTj/x2DAWYrIY7qeZIHidozwV24m4iavr15lNwIwLxRmOxhA==", + "dev": true, "engines": { "node": ">=12" } @@ -12464,6 +12675,7 @@ "version": "4.0.2", "resolved": "https://registry.npmjs.org/d3-contour/-/d3-contour-4.0.2.tgz", "integrity": "sha512-4EzFTRIikzs47RGmdxbeUvLWtGedDUNkTcmzoeyg4sP/dvCexO47AaQL7VKy/gul85TOxw+IBgA8US2xwbToNA==", + "dev": true, "dependencies": { "d3-array": "^3.2.0" }, @@ -12475,6 +12687,7 @@ "version": "6.0.4", "resolved": "https://registry.npmjs.org/d3-delaunay/-/d3-delaunay-6.0.4.tgz", "integrity": "sha512-mdjtIZ1XLAM8bm/hx3WwjfHt6Sggek7qH043O8KEjDXN40xi3vx/6pYSVTwLjEgiXQTbvaouWKynLBiUZ6SK6A==", + "dev": true, "dependencies": { "delaunator": "5" }, @@ -12486,6 +12699,7 @@ "version": "3.0.1", "resolved": "https://registry.npmjs.org/d3-dispatch/-/d3-dispatch-3.0.1.tgz", "integrity": "sha512-rzUyPU/S7rwUflMyLc1ETDeBj0NRuHKKAcvukozwhshr6g6c5d8zh4c2gQjY2bZ0dXeGLWc1PF174P2tVvKhfg==", + "dev": true, "engines": { "node": ">=12" } @@ -12494,6 +12708,7 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/d3-drag/-/d3-drag-3.0.0.tgz", "integrity": "sha512-pWbUJLdETVA8lQNJecMxoXfH6x+mO2UQo8rSmZ+QqxcbyA3hfeprFgIT//HW2nlHChWeIIMwS2Fq+gEARkhTkg==", + "dev": true, "dependencies": { "d3-dispatch": "1 - 3", "d3-selection": "3" @@ -12506,6 +12721,7 @@ "version": "3.0.1", "resolved": "https://registry.npmjs.org/d3-dsv/-/d3-dsv-3.0.1.tgz", "integrity": "sha512-UG6OvdI5afDIFP9w4G0mNq50dSOsXHJaRE8arAS5o9ApWnIElp8GZw1Dun8vP8OyHOZ/QJUKUJwxiiCCnUwm+Q==", + "dev": true, "dependencies": { "commander": "7", "iconv-lite": "0.6", @@ -12530,6 +12746,7 @@ "version": "7.2.0", "resolved": "https://registry.npmjs.org/commander/-/commander-7.2.0.tgz", "integrity": "sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw==", + "dev": true, "engines": { "node": ">= 10" } @@ -12538,6 +12755,7 @@ "version": "3.0.1", "resolved": "https://registry.npmjs.org/d3-ease/-/d3-ease-3.0.1.tgz", "integrity": "sha512-wR/XK3D3XcLIZwpbvQwQ5fK+8Ykds1ip7A2Txe0yxncXSdq1L9skcG7blcedkOX+ZcgxGAmLX1FrRGbADwzi0w==", + "dev": true, "engines": { "node": ">=12" } @@ -12546,6 +12764,7 @@ "version": "3.0.1", "resolved": "https://registry.npmjs.org/d3-fetch/-/d3-fetch-3.0.1.tgz", "integrity": "sha512-kpkQIM20n3oLVBKGg6oHrUchHM3xODkTzjMoj7aWQFq5QEM+R6E4WkzT5+tojDY7yjez8KgCBRoj4aEr99Fdqw==", + "dev": true, "dependencies": { "d3-dsv": "1 - 3" }, @@ -12557,6 +12776,7 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/d3-force/-/d3-force-3.0.0.tgz", "integrity": "sha512-zxV/SsA+U4yte8051P4ECydjD/S+qeYtnaIyAs9tgHCqfguma/aAQDjo85A9Z6EKhBirHRJHXIgJUlffT4wdLg==", + "dev": true, "dependencies": { "d3-dispatch": "1 - 3", "d3-quadtree": "1 - 3", @@ -12570,6 +12790,7 @@ "version": "3.1.0", "resolved": "https://registry.npmjs.org/d3-format/-/d3-format-3.1.0.tgz", "integrity": "sha512-YyUI6AEuY/Wpt8KWLgZHsIU86atmikuoOmCfommt0LYHiQSPjvX2AcFc38PX0CBpr2RCyZhjex+NS/LPOv6YqA==", + "dev": true, "engines": { "node": ">=12" } @@ -12578,6 +12799,7 @@ "version": "3.1.1", "resolved": "https://registry.npmjs.org/d3-geo/-/d3-geo-3.1.1.tgz", "integrity": "sha512-637ln3gXKXOwhalDzinUgY83KzNWZRKbYubaG+fGVuc/dxO64RRljtCTnf5ecMyE1RIdtqpkVcq0IbtU2S8j2Q==", + "dev": true, "dependencies": { "d3-array": "2.5.0 - 3" }, @@ -12589,6 +12811,7 @@ "version": "3.1.2", "resolved": "https://registry.npmjs.org/d3-hierarchy/-/d3-hierarchy-3.1.2.tgz", "integrity": "sha512-FX/9frcub54beBdugHjDCdikxThEqjnR93Qt7PvQTOHxyiNCAlvMrHhclk3cD5VeAaq9fxmfRp+CnWw9rEMBuA==", + "dev": true, "engines": { "node": ">=12" } @@ -12597,6 +12820,7 @@ "version": "3.0.1", "resolved": "https://registry.npmjs.org/d3-interpolate/-/d3-interpolate-3.0.1.tgz", "integrity": "sha512-3bYs1rOD33uo8aqJfKP3JWPAibgw8Zm2+L9vBKEHJ2Rg+viTR7o5Mmv5mZcieN+FRYaAOWX5SJATX6k1PWz72g==", + "dev": true, "dependencies": { "d3-color": "1 - 3" }, @@ -12608,6 +12832,7 @@ "version": "3.1.0", "resolved": "https://registry.npmjs.org/d3-path/-/d3-path-3.1.0.tgz", "integrity": "sha512-p3KP5HCf/bvjBSSKuXid6Zqijx7wIfNW+J/maPs+iwR35at5JCbLUT0LzF1cnjbCHWhqzQTIN2Jpe8pRebIEFQ==", + "dev": true, "engines": { "node": ">=12" } @@ -12616,6 +12841,7 @@ "version": "3.0.1", "resolved": "https://registry.npmjs.org/d3-polygon/-/d3-polygon-3.0.1.tgz", "integrity": "sha512-3vbA7vXYwfe1SYhED++fPUQlWSYTTGmFmQiany/gdbiWgU/iEyQzyymwL9SkJjFFuCS4902BSzewVGsHHmHtXg==", + "dev": true, "engines": { "node": ">=12" } @@ -12624,6 +12850,7 @@ "version": "3.0.1", "resolved": "https://registry.npmjs.org/d3-quadtree/-/d3-quadtree-3.0.1.tgz", "integrity": "sha512-04xDrxQTDTCFwP5H6hRhsRcb9xxv2RzkcsygFzmkSIOJy3PeRJP7sNk3VRIbKXcog561P9oU0/rVH6vDROAgUw==", + "dev": true, "engines": { "node": ">=12" } @@ -12632,6 +12859,7 @@ "version": "3.0.1", "resolved": "https://registry.npmjs.org/d3-random/-/d3-random-3.0.1.tgz", "integrity": "sha512-FXMe9GfxTxqd5D6jFsQ+DJ8BJS4E/fT5mqqdjovykEB2oFbTMDVdg1MGFxfQW+FBOGoB++k8swBrgwSHT1cUXQ==", + "dev": true, "engines": { "node": ">=12" } @@ -12640,6 +12868,7 @@ "version": "4.0.2", "resolved": "https://registry.npmjs.org/d3-scale/-/d3-scale-4.0.2.tgz", "integrity": "sha512-GZW464g1SH7ag3Y7hXjf8RoUuAFIqklOAq3MRl4OaWabTFJY9PN/E1YklhXLh+OQ3fM9yS2nOkCoS+WLZ6kvxQ==", + "dev": true, "dependencies": { "d3-array": "2.10.0 - 3", "d3-format": "1 - 3", @@ -12655,6 +12884,7 @@ "version": "3.1.0", "resolved": "https://registry.npmjs.org/d3-scale-chromatic/-/d3-scale-chromatic-3.1.0.tgz", "integrity": "sha512-A3s5PWiZ9YCXFye1o246KoscMWqf8BsD9eRiJ3He7C9OBaxKhAd5TFCdEx/7VbKtxxTsu//1mMJFrEt572cEyQ==", + "dev": true, "dependencies": { "d3-color": "1 - 3", "d3-interpolate": "1 - 3" @@ -12667,6 +12897,7 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/d3-selection/-/d3-selection-3.0.0.tgz", "integrity": "sha512-fmTRWbNMmsmWq6xJV8D19U/gw/bwrHfNXxrIN+HfZgnzqTHp9jOmKMhsTUjXOJnZOdZY9Q28y4yebKzqDKlxlQ==", + "dev": true, "engines": { "node": ">=12" } @@ -12675,6 +12906,7 @@ "version": "3.2.0", "resolved": "https://registry.npmjs.org/d3-shape/-/d3-shape-3.2.0.tgz", "integrity": "sha512-SaLBuwGm3MOViRq2ABk3eLoxwZELpH6zhl3FbAoJ7Vm1gofKx6El1Ib5z23NUEhF9AsGl7y+dzLe5Cw2AArGTA==", + "dev": true, "dependencies": { "d3-path": "^3.1.0" }, @@ -12686,6 +12918,7 @@ "version": "3.1.0", "resolved": "https://registry.npmjs.org/d3-time/-/d3-time-3.1.0.tgz", "integrity": "sha512-VqKjzBLejbSMT4IgbmVgDjpkYrNWUYJnbCGo874u7MMKIWsILRX+OpX/gTk8MqjpT1A/c6HY2dCA77ZN0lkQ2Q==", + "dev": true, "dependencies": { "d3-array": "2 - 3" }, @@ -12697,6 +12930,7 @@ "version": "4.1.0", "resolved": "https://registry.npmjs.org/d3-time-format/-/d3-time-format-4.1.0.tgz", "integrity": "sha512-dJxPBlzC7NugB2PDLwo9Q8JiTR3M3e4/XANkreKSUxF8vvXKqm1Yfq4Q5dl8budlunRVlUUaDUgFt7eA8D6NLg==", + "dev": true, "dependencies": { "d3-time": "1 - 3" }, @@ -12708,6 +12942,7 @@ "version": "3.0.1", "resolved": "https://registry.npmjs.org/d3-timer/-/d3-timer-3.0.1.tgz", "integrity": "sha512-ndfJ/JxxMd3nw31uyKoY2naivF+r29V+Lc0svZxe1JvvIRmi8hUsrMvdOwgS1o6uBHmiz91geQ0ylPP0aj1VUA==", + "dev": true, "engines": { "node": ">=12" } @@ -12716,6 +12951,7 @@ "version": "3.0.1", "resolved": "https://registry.npmjs.org/d3-transition/-/d3-transition-3.0.1.tgz", "integrity": "sha512-ApKvfjsSR6tg06xrL434C0WydLr7JewBB3V+/39RMHsaXTOG0zmt/OAXeng5M5LBm0ojmxJrpomQVZ1aPvBL4w==", + "dev": true, "dependencies": { "d3-color": "1 - 3", "d3-dispatch": "1 - 3", @@ -12734,6 +12970,7 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/d3-zoom/-/d3-zoom-3.0.0.tgz", "integrity": "sha512-b8AmV3kfQaqWAuacbPuNbL6vahnOJflOhexLzMMNLga62+/nh0JzvJ0aO/5a5MVgUFGS7Hu1P9P03o3fJkDCyw==", + "dev": true, "dependencies": { "d3-dispatch": "1 - 3", "d3-drag": "2 - 3", @@ -12784,6 +13021,7 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/data-view-buffer/-/data-view-buffer-1.0.1.tgz", "integrity": "sha512-0lht7OugA5x3iJLOWFhWK/5ehONdprk0ISXqVFn/NFrDu+cuc8iADFrGQz5BnRK7LLU3JmkbXSxaqX+/mXYtUA==", + "dev": true, "dependencies": { "call-bind": "^1.0.6", "es-errors": "^1.3.0", @@ -12800,6 +13038,7 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/data-view-byte-length/-/data-view-byte-length-1.0.1.tgz", "integrity": "sha512-4J7wRJD3ABAzr8wP+OcIcqq2dlUKp4DVflx++hs5h5ZKydWMI6/D/fAot+yh6g2tHh8fLFTvNOaVN357NvSrOQ==", + "dev": true, "dependencies": { "call-bind": "^1.0.7", "es-errors": "^1.3.0", @@ -12816,6 +13055,7 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/data-view-byte-offset/-/data-view-byte-offset-1.0.0.tgz", "integrity": "sha512-t/Ygsytq+R995EJ5PZlD4Cu56sWa8InXySaViRzw9apusqsOO2bQP+SbYzAhR0pFKoB+43lYy8rWban9JSuXnA==", + "dev": true, "dependencies": { "call-bind": "^1.0.6", "es-errors": "^1.3.0", @@ -12917,6 +13157,7 @@ "version": "0.2.2", "resolved": "https://registry.npmjs.org/decode-uri-component/-/decode-uri-component-0.2.2.tgz", "integrity": "sha512-FqUYQ+8o158GyGTrMFJms9qh3CqTKvAqgqsTnkLI8sKu0028orqBhxNMFkFen0zGyg6epACD32pjVk58ngIErQ==", + "dev": true, "optional": true, "peer": true, "engines": { @@ -12962,12 +13203,14 @@ "node_modules/deep-is": { "version": "0.1.4", "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz", - "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==" + "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==", + "dev": true }, "node_modules/deepmerge": { "version": "4.3.1", "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.3.1.tgz", "integrity": "sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A==", + "dev": true, "engines": { "node": ">=0.10.0" } @@ -13069,6 +13312,7 @@ "version": "1.2.1", "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.2.1.tgz", "integrity": "sha512-8QmQKqEASLd5nx0U1B1okLElbUuuttJ/AnYmRXbbbGDWh6uS208EjD4Xqq/I9wK7u0v6O08XhTWnt5XtEbR6Dg==", + "dev": true, "dependencies": { "define-data-property": "^1.0.1", "has-property-descriptors": "^1.0.0", @@ -13091,6 +13335,7 @@ "version": "5.0.1", "resolved": "https://registry.npmjs.org/delaunator/-/delaunator-5.0.1.tgz", "integrity": "sha512-8nvh+XBe96aCESrGOqMp/84b13H9cdKbG5P2ejQCh4d4sK9RL4371qou9drQjMhvnPmhWl5hnmqbEE0fXr9Xnw==", + "dev": true, "dependencies": { "robust-predicates": "^3.0.2" } @@ -13129,6 +13374,7 @@ "version": "2.0.3", "resolved": "https://registry.npmjs.org/dequal/-/dequal-2.0.3.tgz", "integrity": "sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA==", + "dev": true, "engines": { "node": ">=6" } @@ -13146,6 +13392,7 @@ "version": "6.1.0", "resolved": "https://registry.npmjs.org/detect-indent/-/detect-indent-6.1.0.tgz", "integrity": "sha512-reYkTUJAZb9gUuZ2RvVCNhVHdg62RHnJ7WJl8ftMi4diZ6NWlciOzQN88pUhSELEwflJht4oQDv0F0BMlwaYtA==", + "dev": true, "engines": { "node": ">=8" } @@ -13195,7 +13442,7 @@ "version": "4.0.2", "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz", "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==", - "devOptional": true, + "dev": true, "engines": { "node": ">=0.3.1" } @@ -13218,6 +13465,7 @@ "version": "3.0.1", "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz", "integrity": "sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==", + "dev": true, "dependencies": { "path-type": "^4.0.0" }, @@ -13241,6 +13489,7 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz", "integrity": "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==", + "dev": true, "dependencies": { "esutils": "^2.0.2" }, @@ -13474,7 +13723,8 @@ "node_modules/electron-to-chromium": { "version": "1.4.818", "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.818.tgz", - "integrity": "sha512-eGvIk2V0dGImV9gWLq8fDfTTsCAeMDwZqEPMr+jMInxZdnp9Us8UpovYpRCf9NQ7VOFgrN2doNSgvISbsbNpxA==" + "integrity": "sha512-eGvIk2V0dGImV9gWLq8fDfTTsCAeMDwZqEPMr+jMInxZdnp9Us8UpovYpRCf9NQ7VOFgrN2doNSgvISbsbNpxA==", + "dev": true }, "node_modules/elliptic": { "version": "6.5.5", @@ -13542,6 +13792,7 @@ "version": "5.17.0", "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.17.0.tgz", "integrity": "sha512-dwDPwZL0dmye8Txp2gzFmA6sxALaSvdRDjPH0viLcKrtlOL3tw62nWWweVD1SdILDTJrbrL6tdWVN58Wo6U3eA==", + "dev": true, "dependencies": { "graceful-fs": "^4.2.4", "tapable": "^2.2.0" @@ -13578,6 +13829,7 @@ "version": "0.1.8", "resolved": "https://registry.npmjs.org/errno/-/errno-0.1.8.tgz", "integrity": "sha512-dJ6oBr5SQ1VSd9qkk7ByRgb/1SH4JZjCHSW/mr63/QcXO9zLVxvJ6Oy13nio03rxpSnVDDjFor75SjVeZWPW/A==", + "dev": true, "optional": true, "dependencies": { "prr": "~1.0.1" @@ -13599,6 +13851,7 @@ "version": "1.23.3", "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.23.3.tgz", "integrity": "sha512-e+HfNH61Bj1X9/jLc5v1owaLYuHdeHHSQlkhCBiTK8rBvKaULl/beGMxwrMXjpYrv4pz22BlY570vVePA2ho4A==", + "dev": true, "dependencies": { "array-buffer-byte-length": "^1.0.1", "arraybuffer.prototype.slice": "^1.0.3", @@ -13683,6 +13936,7 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.0.0.tgz", "integrity": "sha512-MZ4iQ6JwHOBQjahnjwaC1ZtIBH+2ohjamzAO3oaHcXYup7qxjF2fixyH+Q71voWHeOkI2q/TnJao/KfXYIZWbw==", + "dev": true, "dependencies": { "es-errors": "^1.3.0" }, @@ -13694,6 +13948,7 @@ "version": "2.0.3", "resolved": "https://registry.npmjs.org/es-set-tostringtag/-/es-set-tostringtag-2.0.3.tgz", "integrity": "sha512-3T8uNMC3OQTHkFUsFq8r/BwAXLHvU/9O9mE0fBc/MY5iq/8H7ncvO947LmYA6ldWw9Uh8Yhf25zu6n7nML5QWQ==", + "dev": true, "dependencies": { "get-intrinsic": "^1.2.4", "has-tostringtag": "^1.0.2", @@ -13707,6 +13962,7 @@ "version": "1.0.2", "resolved": "https://registry.npmjs.org/es-shim-unscopables/-/es-shim-unscopables-1.0.2.tgz", "integrity": "sha512-J3yBRXCzDu4ULnQwxyToo/OjdMx6akgVC7K6few0a7F/0wLtmKKN7I73AH5T2836UuXRqN7Qg+IIUw/+YJksRw==", + "dev": true, "dependencies": { "hasown": "^2.0.0" } @@ -13715,6 +13971,7 @@ "version": "1.2.1", "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.1.tgz", "integrity": "sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==", + "dev": true, "dependencies": { "is-callable": "^1.1.4", "is-date-object": "^1.0.1", @@ -13730,7 +13987,8 @@ "node_modules/es6-promise": { "version": "3.3.1", "resolved": "https://registry.npmjs.org/es6-promise/-/es6-promise-3.3.1.tgz", - "integrity": "sha512-SOp9Phqvqn7jtEUxPWdWfWoLmyt2VaJ6MpvP9Comy1MceMXqE6bxvaTu4iaxpYYPzhny28Lc+M87/c2cPK6lDg==" + "integrity": "sha512-SOp9Phqvqn7jtEUxPWdWfWoLmyt2VaJ6MpvP9Comy1MceMXqE6bxvaTu4iaxpYYPzhny28Lc+M87/c2cPK6lDg==", + "dev": true }, "node_modules/esbuild": { "version": "0.21.5", @@ -13787,7 +14045,7 @@ "version": "1.0.5", "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", - "devOptional": true, + "dev": true, "engines": { "node": ">=0.8.0" } @@ -13827,6 +14085,7 @@ "version": "8.57.0", "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.57.0.tgz", "integrity": "sha512-dZ6+mexnaTIbSBZWgou51U6OmzIhYM2VcNdtiTtI7qPNZm35Akpr0f6vtw3w1Kmn5PYo+tZVfh13WrhpS6oLqQ==", + "dev": true, "dependencies": { "@eslint-community/eslint-utils": "^4.2.0", "@eslint-community/regexpp": "^4.6.1", @@ -13881,6 +14140,7 @@ "version": "0.5.1", "resolved": "https://registry.npmjs.org/eslint-compat-utils/-/eslint-compat-utils-0.5.1.tgz", "integrity": "sha512-3z3vFexKIEnjHE3zCMRo6fn/e44U7T1khUjg+Hp0ZQMCigh28rALD0nPFBcGZuiLC5rLZa2ubQHDRln09JfU2Q==", + "dev": true, "dependencies": { "semver": "^7.5.4" }, @@ -13895,6 +14155,7 @@ "version": "7.6.2", "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.2.tgz", "integrity": "sha512-FNAIBWCx9qcRhoHcgcJ0gvU7SN1lYU2ZXuSfl04bSC5OpvDHFyJCjdNHomPXxjQlCBU67YW64PzY7/VIEH7F2w==", + "dev": true, "bin": { "semver": "bin/semver.js" }, @@ -13918,6 +14179,7 @@ "version": "17.1.0", "resolved": "https://registry.npmjs.org/eslint-config-standard/-/eslint-config-standard-17.1.0.tgz", "integrity": "sha512-IwHwmaBNtDK4zDHQukFDW5u/aTb8+meQWZvNFWkiGmbWjD6bqyuSSBxxXKkCftCUzc1zwCH2m/baCNDLGmuO5Q==", + "dev": true, "funding": [ { "type": "github", @@ -13946,6 +14208,7 @@ "version": "0.3.9", "resolved": "https://registry.npmjs.org/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.9.tgz", "integrity": "sha512-WFj2isz22JahUv+B788TlO3N6zL3nNJGU8CcZbPZvVEkBPaJdCV4vy5wyghty5ROFbCRnm132v8BScu5/1BQ8g==", + "dev": true, "dependencies": { "debug": "^3.2.7", "is-core-module": "^2.13.0", @@ -13956,6 +14219,7 @@ "version": "3.2.7", "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", + "dev": true, "dependencies": { "ms": "^2.1.1" } @@ -13964,6 +14228,7 @@ "version": "3.6.1", "resolved": "https://registry.npmjs.org/eslint-import-resolver-typescript/-/eslint-import-resolver-typescript-3.6.1.tgz", "integrity": "sha512-xgdptdoi5W3niYeuQxKmzVDTATvLYqhpwmykwsh7f6HIOStGWEIL9iqZgQDF9u9OEzrRwR8no5q2VT+bjAujTg==", + "dev": true, "dependencies": { "debug": "^4.3.4", "enhanced-resolve": "^5.12.0", @@ -13988,6 +14253,7 @@ "version": "3.3.2", "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.2.tgz", "integrity": "sha512-oX2ruAFQwf/Orj8m737Y5adxDQO0LAB7/S5MnxCdTNDd4p6BsyIVsv9JQsATbTSq8KHRpLwIHbVlUNatxd+1Ow==", + "dev": true, "dependencies": { "@nodelib/fs.stat": "^2.0.2", "@nodelib/fs.walk": "^1.2.3", @@ -14003,6 +14269,7 @@ "version": "5.1.2", "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "dev": true, "dependencies": { "is-glob": "^4.0.1" }, @@ -14014,6 +14281,7 @@ "version": "2.8.1", "resolved": "https://registry.npmjs.org/eslint-module-utils/-/eslint-module-utils-2.8.1.tgz", "integrity": "sha512-rXDXR3h7cs7dy9RNpUlQf80nX31XWJEyGq1tRMo+6GsO5VmTe4UTwtmonAD4ZkAsrfMVDA2wlGJ3790Ys+D49Q==", + "dev": true, "dependencies": { "debug": "^3.2.7" }, @@ -14030,6 +14298,7 @@ "version": "3.2.7", "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", + "dev": true, "dependencies": { "ms": "^2.1.1" } @@ -14038,6 +14307,7 @@ "version": "7.8.0", "resolved": "https://registry.npmjs.org/eslint-plugin-es-x/-/eslint-plugin-es-x-7.8.0.tgz", "integrity": "sha512-7Ds8+wAAoV3T+LAKeu39Y5BzXCrGKrcISfgKEqTS4BDN8SFEDQd0S43jiQ8vIa3wUKD07qitZdfzlenSi8/0qQ==", + "dev": true, "funding": [ "https://github.com/sponsors/ota-meshi", "https://opencollective.com/eslint" @@ -14058,6 +14328,7 @@ "version": "2.29.1", "resolved": "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.29.1.tgz", "integrity": "sha512-BbPC0cuExzhiMo4Ff1BTVwHpjjv28C5R+btTOGaCRC7UEz801up0JadwkeSk5Ued6TG34uaczuVuH6qyy5YUxw==", + "dev": true, "dependencies": { "array-includes": "^3.1.7", "array.prototype.findlastindex": "^1.2.3", @@ -14088,6 +14359,7 @@ "version": "1.1.11", "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dev": true, "dependencies": { "balanced-match": "^1.0.0", "concat-map": "0.0.1" @@ -14097,6 +14369,7 @@ "version": "3.2.7", "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", + "dev": true, "dependencies": { "ms": "^2.1.1" } @@ -14105,6 +14378,7 @@ "version": "2.1.0", "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-2.1.0.tgz", "integrity": "sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==", + "dev": true, "dependencies": { "esutils": "^2.0.2" }, @@ -14116,6 +14390,7 @@ "version": "1.0.2", "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.2.tgz", "integrity": "sha512-g1MWMLBiz8FKi1e4w0UyVL3w+iJceWAFBAaBnnGKOpNa5f8TLktkbre1+s6oICydWAm+HRUGTmI+//xv2hvXYA==", + "dev": true, "dependencies": { "minimist": "^1.2.0" }, @@ -14127,6 +14402,7 @@ "version": "3.1.2", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, "dependencies": { "brace-expansion": "^1.1.7" }, @@ -14138,6 +14414,7 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", "integrity": "sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==", + "dev": true, "engines": { "node": ">=4" } @@ -14146,6 +14423,7 @@ "version": "3.15.0", "resolved": "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-3.15.0.tgz", "integrity": "sha512-2Ac2RgzDe/cn48GvOe3M+o82pEFewD3UPbyoUHHdKasHwJKjds4fLXWf/Ux5kATBKN20oaFGu+jbElp1pos0mg==", + "dev": true, "dependencies": { "@types/json5": "^0.0.29", "json5": "^1.0.2", @@ -14180,6 +14458,7 @@ "version": "16.6.2", "resolved": "https://registry.npmjs.org/eslint-plugin-n/-/eslint-plugin-n-16.6.2.tgz", "integrity": "sha512-6TyDmZ1HXoFQXnhCTUjVFULReoBPOAjpuiKELMkeP40yffI/1ZRO+d9ug/VC6fqISo2WkuIBk3cvuRPALaWlOQ==", + "dev": true, "dependencies": { "@eslint-community/eslint-utils": "^4.4.0", "builtins": "^5.0.1", @@ -14207,6 +14486,7 @@ "version": "1.1.11", "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dev": true, "dependencies": { "balanced-match": "^1.0.0", "concat-map": "0.0.1" @@ -14216,6 +14496,7 @@ "version": "13.24.0", "resolved": "https://registry.npmjs.org/globals/-/globals-13.24.0.tgz", "integrity": "sha512-AhO5QUcj8llrbG09iWhPU2B204J1xnPeL8kQmVorSsy+Sjj1sk8gIyh6cUocGmH4L0UuhAJy+hJMRA4mgA4mFQ==", + "dev": true, "dependencies": { "type-fest": "^0.20.2" }, @@ -14230,6 +14511,7 @@ "version": "3.1.2", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, "dependencies": { "brace-expansion": "^1.1.7" }, @@ -14241,6 +14523,7 @@ "version": "7.6.2", "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.2.tgz", "integrity": "sha512-FNAIBWCx9qcRhoHcgcJ0gvU7SN1lYU2ZXuSfl04bSC5OpvDHFyJCjdNHomPXxjQlCBU67YW64PzY7/VIEH7F2w==", + "dev": true, "bin": { "semver": "bin/semver.js" }, @@ -14252,6 +14535,7 @@ "version": "0.20.2", "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", + "dev": true, "engines": { "node": ">=10" }, @@ -14263,6 +14547,7 @@ "version": "6.4.0", "resolved": "https://registry.npmjs.org/eslint-plugin-promise/-/eslint-plugin-promise-6.4.0.tgz", "integrity": "sha512-/KWWRaD3fGkVCZsdR0RU53PSthFmoHVhZl+y9+6DqeDLSikLdlUVpVEAmI6iCRR5QyOjBYBqHZV/bdv4DJ4Gtw==", + "dev": true, "engines": { "node": "^12.22.0 || ^14.17.0 || >=16.0.0" }, @@ -14298,6 +14583,7 @@ "version": "2.42.0", "resolved": "https://registry.npmjs.org/eslint-plugin-svelte/-/eslint-plugin-svelte-2.42.0.tgz", "integrity": "sha512-mHP6z0DWq97KZvoQcApZHdF9m9epcDV/ICKufeEH18Vh+8vl7S+gwt8WdUohEqKNVMuXRkbvy1suMcVvUDiOGw==", + "dev": true, "dependencies": { "@eslint-community/eslint-utils": "^4.4.0", "@jridgewell/sourcemap-codec": "^1.4.15", @@ -14331,6 +14617,7 @@ "version": "7.6.2", "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.2.tgz", "integrity": "sha512-FNAIBWCx9qcRhoHcgcJ0gvU7SN1lYU2ZXuSfl04bSC5OpvDHFyJCjdNHomPXxjQlCBU67YW64PzY7/VIEH7F2w==", + "dev": true, "bin": { "semver": "bin/semver.js" }, @@ -14355,6 +14642,7 @@ "version": "7.2.2", "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.2.2.tgz", "integrity": "sha512-dOt21O7lTMhDM+X9mB4GX+DZrZtCUJPL/wlcTqxyrx5IvO0IYtILdtrQGQp+8n5S0gwSVmOf9NQrjMOgfQZlIg==", + "dev": true, "dependencies": { "esrecurse": "^4.3.0", "estraverse": "^5.2.0" @@ -14370,6 +14658,7 @@ "version": "3.4.3", "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz", "integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==", + "dev": true, "engines": { "node": "^12.22.0 || ^14.17.0 || >=16.0.0" }, @@ -14381,6 +14670,7 @@ "version": "6.12.6", "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "dev": true, "dependencies": { "fast-deep-equal": "^3.1.1", "fast-json-stable-stringify": "^2.0.0", @@ -14396,6 +14686,7 @@ "version": "4.3.0", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, "dependencies": { "color-convert": "^2.0.1" }, @@ -14409,12 +14700,14 @@ "node_modules/eslint/node_modules/argparse": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", - "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==" + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", + "dev": true }, "node_modules/eslint/node_modules/brace-expansion": { "version": "1.1.11", "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dev": true, "dependencies": { "balanced-match": "^1.0.0", "concat-map": "0.0.1" @@ -14424,6 +14717,7 @@ "version": "4.1.2", "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, "dependencies": { "ansi-styles": "^4.1.0", "supports-color": "^7.1.0" @@ -14439,6 +14733,7 @@ "version": "2.0.1", "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, "dependencies": { "color-name": "~1.1.4" }, @@ -14449,12 +14744,14 @@ "node_modules/eslint/node_modules/color-name": { "version": "1.1.4", "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true }, "node_modules/eslint/node_modules/escape-string-regexp": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", + "dev": true, "engines": { "node": ">=10" }, @@ -14466,6 +14763,7 @@ "version": "5.0.0", "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", + "dev": true, "dependencies": { "locate-path": "^6.0.0", "path-exists": "^4.0.0" @@ -14481,6 +14779,7 @@ "version": "13.24.0", "resolved": "https://registry.npmjs.org/globals/-/globals-13.24.0.tgz", "integrity": "sha512-AhO5QUcj8llrbG09iWhPU2B204J1xnPeL8kQmVorSsy+Sjj1sk8gIyh6cUocGmH4L0UuhAJy+hJMRA4mgA4mFQ==", + "dev": true, "dependencies": { "type-fest": "^0.20.2" }, @@ -14495,6 +14794,7 @@ "version": "4.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, "engines": { "node": ">=8" } @@ -14503,6 +14803,7 @@ "version": "4.1.0", "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", + "dev": true, "dependencies": { "argparse": "^2.0.1" }, @@ -14513,12 +14814,14 @@ "node_modules/eslint/node_modules/json-schema-traverse": { "version": "0.4.1", "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", - "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==" + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", + "dev": true }, "node_modules/eslint/node_modules/locate-path": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", + "dev": true, "dependencies": { "p-locate": "^5.0.0" }, @@ -14533,6 +14836,7 @@ "version": "3.1.2", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, "dependencies": { "brace-expansion": "^1.1.7" }, @@ -14544,6 +14848,7 @@ "version": "5.0.0", "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", + "dev": true, "dependencies": { "p-limit": "^3.0.2" }, @@ -14558,6 +14863,7 @@ "version": "7.2.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, "dependencies": { "has-flag": "^4.0.0" }, @@ -14569,6 +14875,7 @@ "version": "0.20.2", "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", + "dev": true, "engines": { "node": ">=10" }, @@ -14580,6 +14887,7 @@ "version": "9.6.1", "resolved": "https://registry.npmjs.org/espree/-/espree-9.6.1.tgz", "integrity": "sha512-oruZaFkjorTpF32kDSI5/75ViwGeZginGGy2NoOSg3Q9bnwlnmDm4HLnkl0RE3n+njDXR037aY1+x58Z/zFdwQ==", + "dev": true, "dependencies": { "acorn": "^8.9.0", "acorn-jsx": "^5.3.2", @@ -14608,6 +14916,7 @@ "version": "1.6.0", "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.6.0.tgz", "integrity": "sha512-ca9pw9fomFcKPvFLXhBKUK90ZvGibiGOvRJNbjljY7s7uq/5YO4BOzcYtJqExdx99rF6aAcnRxHmcUHcz6sQsg==", + "dev": true, "dependencies": { "estraverse": "^5.1.0" }, @@ -14619,6 +14928,7 @@ "version": "4.3.0", "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", + "dev": true, "dependencies": { "estraverse": "^5.2.0" }, @@ -14630,6 +14940,7 @@ "version": "5.3.0", "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", + "dev": true, "engines": { "node": ">=4.0" } @@ -14637,12 +14948,14 @@ "node_modules/estree-walker": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-2.0.2.tgz", - "integrity": "sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==" + "integrity": "sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==", + "dev": true }, "node_modules/esutils": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", + "dev": true, "engines": { "node": ">=0.10.0" } @@ -15023,12 +15336,14 @@ "node_modules/fast-json-stable-stringify": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", - "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==" + "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", + "dev": true }, "node_modules/fast-levenshtein": { "version": "2.0.6", "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", - "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==" + "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==", + "dev": true }, "node_modules/fast-xml-parser": { "version": "4.4.0", @@ -15055,6 +15370,7 @@ "version": "1.17.1", "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.17.1.tgz", "integrity": "sha512-sRVD3lWVIXWg6By68ZN7vho9a1pQcN/WBFaAAsDDFzlJjvoGx0P8z7V1t72grFJfJhu3YPZBuu25f7Kaw2jN1w==", + "dev": true, "dependencies": { "reusify": "^1.0.4" } @@ -15146,6 +15462,7 @@ "version": "6.0.1", "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz", "integrity": "sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==", + "dev": true, "dependencies": { "flat-cache": "^3.0.4" }, @@ -15178,6 +15495,7 @@ "version": "7.1.1", "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz", "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==", + "dev": true, "dependencies": { "to-regex-range": "^5.0.1" }, @@ -15256,6 +15574,7 @@ "version": "3.2.0", "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-3.2.0.tgz", "integrity": "sha512-CYcENa+FtcUKLmhhqyctpclsq7QF38pKjZHsGNiSQF5r4FtoKDWabFDl3hzaEQMvT1LHEysw5twgLvpYYb4vbw==", + "dev": true, "dependencies": { "flatted": "^3.2.9", "keyv": "^4.5.3", @@ -15284,7 +15603,8 @@ "node_modules/flatted": { "version": "3.3.1", "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.3.1.tgz", - "integrity": "sha512-X8cqMLLie7KsNUDSdzeN8FYK9rEt4Dt67OsG/DNGnYTSDBG4uFAJFBnUeiV+zCVAvwFy56IjM9sH51jVaEhNxw==" + "integrity": "sha512-X8cqMLLie7KsNUDSdzeN8FYK9rEt4Dt67OsG/DNGnYTSDBG4uFAJFBnUeiV+zCVAvwFy56IjM9sH51jVaEhNxw==", + "dev": true }, "node_modules/flight-recorder-manufacturers": { "version": "2.0.0", @@ -15325,6 +15645,7 @@ "version": "0.3.3", "resolved": "https://registry.npmjs.org/for-each/-/for-each-0.3.3.tgz", "integrity": "sha512-jqYfLp7mo9vIyQf8ykW2v7A+2N4QjeCeI5+Dz9XraiO1ign81wjiH7Fb9vSOWvQfNtmSa4H2RoQTrrXivdUZmw==", + "dev": true, "dependencies": { "is-callable": "^1.1.3" } @@ -15692,6 +16013,7 @@ "version": "2.3.3", "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", + "dev": true, "hasInstallScript": true, "optional": true, "os": [ @@ -15780,6 +16102,7 @@ "version": "1.1.6", "resolved": "https://registry.npmjs.org/function.prototype.name/-/function.prototype.name-1.1.6.tgz", "integrity": "sha512-Z5kx79swU5P27WEayXM1tBi5Ze/lbIyiNgU3qyXUOf9b2rgXYyF9Dy9Cx+IQv/Lc8WCG6L82zwUPpSS9hGehIg==", + "dev": true, "dependencies": { "call-bind": "^1.0.2", "define-properties": "^1.2.0", @@ -15797,6 +16120,7 @@ "version": "1.2.3", "resolved": "https://registry.npmjs.org/functions-have-names/-/functions-have-names-1.2.3.tgz", "integrity": "sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ==", + "dev": true, "funding": { "url": "https://github.com/sponsors/ljharb" } @@ -15882,7 +16206,7 @@ "version": "1.0.0-beta.2", "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz", "integrity": "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==", - "devOptional": true, + "dev": true, "engines": { "node": ">=6.9.0" } @@ -15994,6 +16318,7 @@ "version": "1.0.2", "resolved": "https://registry.npmjs.org/get-symbol-description/-/get-symbol-description-1.0.2.tgz", "integrity": "sha512-g0QYk1dZBxGwk+Ngc+ltRH2IBp2f7zBkBMBJZCDerh6EhlhSR6+9irMCuT/09zD6qkarHUSn529sK/yL4S27mg==", + "dev": true, "dependencies": { "call-bind": "^1.0.5", "es-errors": "^1.3.0", @@ -16010,6 +16335,7 @@ "version": "4.7.5", "resolved": "https://registry.npmjs.org/get-tsconfig/-/get-tsconfig-4.7.5.tgz", "integrity": "sha512-ZCuZCnlqNzjb4QprAzXKdpp/gh6KTxSJuw3IBsPnV/7fV4NxC9ckB+vPTt8w7fJA0TaSD7c55BR47JD6MEDyDw==", + "dev": true, "dependencies": { "resolve-pkg-maps": "^1.0.0" }, @@ -16067,6 +16393,7 @@ "version": "6.0.2", "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==", + "dev": true, "dependencies": { "is-glob": "^4.0.3" }, @@ -16113,7 +16440,7 @@ "version": "11.12.0", "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==", - "devOptional": true, + "dev": true, "engines": { "node": ">=4" } @@ -16122,6 +16449,7 @@ "version": "1.0.4", "resolved": "https://registry.npmjs.org/globalthis/-/globalthis-1.0.4.tgz", "integrity": "sha512-DpLKbNU4WylpxJykQujfCcwYWiV/Jhm50Goo0wrVILAv5jOr9d+H+UR3PhSCD2rCCEIg0uc+G+muBTwD54JhDQ==", + "dev": true, "dependencies": { "define-properties": "^1.2.1", "gopd": "^1.0.1" @@ -16137,6 +16465,7 @@ "version": "11.1.0", "resolved": "https://registry.npmjs.org/globby/-/globby-11.1.0.tgz", "integrity": "sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==", + "dev": true, "dependencies": { "array-union": "^2.1.0", "dir-glob": "^3.0.1", @@ -16156,6 +16485,7 @@ "version": "3.3.2", "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.2.tgz", "integrity": "sha512-oX2ruAFQwf/Orj8m737Y5adxDQO0LAB7/S5MnxCdTNDd4p6BsyIVsv9JQsATbTSq8KHRpLwIHbVlUNatxd+1Ow==", + "dev": true, "dependencies": { "@nodelib/fs.stat": "^2.0.2", "@nodelib/fs.walk": "^1.2.3", @@ -16171,6 +16501,7 @@ "version": "5.1.2", "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "dev": true, "dependencies": { "is-glob": "^4.0.1" }, @@ -16332,7 +16663,8 @@ "node_modules/graphemer": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/graphemer/-/graphemer-1.4.0.tgz", - "integrity": "sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==" + "integrity": "sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==", + "dev": true }, "node_modules/gtoken": { "version": "7.1.0", @@ -16392,6 +16724,7 @@ "version": "1.0.2", "resolved": "https://registry.npmjs.org/has-bigints/-/has-bigints-1.0.2.tgz", "integrity": "sha512-tSvCKtBr9lkF0Ex0aQiP9N+OpV4zi2r/Nee5VkRDbaqv35RLYMzbwQfFSZZH0kR+Rd6302UJZ2p/bJCEoR3VoQ==", + "dev": true, "funding": { "url": "https://github.com/sponsors/ljharb" } @@ -16400,7 +16733,7 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", - "devOptional": true, + "dev": true, "engines": { "node": ">=4" } @@ -16442,6 +16775,7 @@ "version": "1.0.2", "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.2.tgz", "integrity": "sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==", + "dev": true, "dependencies": { "has-symbols": "^1.0.3" }, @@ -16501,6 +16835,21 @@ "minimalistic-crypto-utils": "^1.0.1" } }, + "node_modules/hoist-non-react-statics": { + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/hoist-non-react-statics/-/hoist-non-react-statics-3.3.2.tgz", + "integrity": "sha512-/gGivxi8JPKWNm/W0jSmzcMPpfpPLc3dY/6GxhX2hQ9iGj3aDfklV4ET7NjKpSinLpJ5vafa9iiGIEZg10SfBw==", + "dev": true, + "dependencies": { + "react-is": "^16.7.0" + } + }, + "node_modules/hoist-non-react-statics/node_modules/react-is": { + "version": "16.13.1", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", + "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==", + "dev": true + }, "node_modules/hosted-git-info": { "version": "7.0.2", "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-7.0.2.tgz", @@ -16867,6 +17216,7 @@ "version": "0.6.3", "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz", "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==", + "dev": true, "dependencies": { "safer-buffer": ">= 2.1.2 < 3.0.0" }, @@ -16953,6 +17303,7 @@ "version": "5.3.1", "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.1.tgz", "integrity": "sha512-5Fytz/IraMjqpwfd34ke28PTVMjZjJG2MPn5t7OE4eUCUNf8BAa7b5WUS9/Qvr6mwOQS7Mk6vdsMno5he+T8Xw==", + "dev": true, "engines": { "node": ">= 4" } @@ -16961,6 +17312,7 @@ "version": "0.5.5", "resolved": "https://registry.npmjs.org/image-size/-/image-size-0.5.5.tgz", "integrity": "sha512-6TDAlDPZxUFCv+fuOkIoXT/V/f3Qbq8e37p+YOiYrUv3v9cc3/6x78VdfPgFVaB9dZYeLUfKgHRebpkm/oP2VQ==", + "dev": true, "optional": true, "bin": { "image-size": "bin/image-size.js" @@ -16982,12 +17334,13 @@ "version": "4.3.6", "resolved": "https://registry.npmjs.org/immutable/-/immutable-4.3.6.tgz", "integrity": "sha512-Ju0+lEMyzMVZarkTn/gqRpdqd5dOPaz1mCZ0SH3JV6iFw81PldE/PEB1hWVEA288HPt4WXW8O7AWxB10M+03QQ==", - "devOptional": true + "dev": true }, "node_modules/import-fresh": { "version": "3.3.0", "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz", "integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==", + "dev": true, "dependencies": { "parent-module": "^1.0.0", "resolve-from": "^4.0.0" @@ -17003,6 +17356,7 @@ "version": "4.0.0", "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", + "dev": true, "engines": { "node": ">=4" } @@ -17051,6 +17405,7 @@ "version": "0.1.4", "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==", + "dev": true, "engines": { "node": ">=0.8.19" } @@ -17092,6 +17447,7 @@ "version": "1.0.7", "resolved": "https://registry.npmjs.org/internal-slot/-/internal-slot-1.0.7.tgz", "integrity": "sha512-NGnrKwXzSms2qUUih/ILZ5JBqNTSa1+ZmP6flaIp6KmSElgE9qdndzS3cqjrDovwFdmwsGsLdeFgB6suw+1e9g==", + "dev": true, "dependencies": { "es-errors": "^1.3.0", "hasown": "^2.0.0", @@ -17160,6 +17516,7 @@ "version": "3.0.4", "resolved": "https://registry.npmjs.org/is-array-buffer/-/is-array-buffer-3.0.4.tgz", "integrity": "sha512-wcjaerHw0ydZwfhiKbXJWLDY8A7yV7KhjQOpb83hGgGfId/aQa4TOvwyzn2PuswW2gPCYEL/nEAiSVpdOj1lXw==", + "dev": true, "dependencies": { "call-bind": "^1.0.2", "get-intrinsic": "^1.2.1" @@ -17181,6 +17538,7 @@ "version": "1.0.4", "resolved": "https://registry.npmjs.org/is-bigint/-/is-bigint-1.0.4.tgz", "integrity": "sha512-zB9CruMamjym81i2JZ3UMn54PKGsQzsJeo6xvN3HJJ4CAsQNB6iRutp2To77OfCNuoxspsIhzaPoO1zyCEhFOg==", + "dev": true, "dependencies": { "has-bigints": "^1.0.1" }, @@ -17192,7 +17550,7 @@ "version": "2.1.0", "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", - "devOptional": true, + "dev": true, "dependencies": { "binary-extensions": "^2.0.0" }, @@ -17204,6 +17562,7 @@ "version": "1.1.2", "resolved": "https://registry.npmjs.org/is-boolean-object/-/is-boolean-object-1.1.2.tgz", "integrity": "sha512-gDYaKHJmnj4aWxyj6YHyXVpdQawtVLHU5cb+eztPGczf6cjuTdwve5ZIEfgXqH4e57An1D1AKf8CZ3kYrQRqYA==", + "dev": true, "dependencies": { "call-bind": "^1.0.2", "has-tostringtag": "^1.0.0" @@ -17219,6 +17578,7 @@ "version": "3.2.1", "resolved": "https://registry.npmjs.org/is-builtin-module/-/is-builtin-module-3.2.1.tgz", "integrity": "sha512-BSLE3HnV2syZ0FK0iMA/yUGplUeMmNz4AW5fnTunbCIqZi4vG3WjJT9FHMy5D69xmAYBHXQhJdALdpwVxV501A==", + "dev": true, "dependencies": { "builtin-modules": "^3.3.0" }, @@ -17233,6 +17593,7 @@ "version": "1.2.7", "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.7.tgz", "integrity": "sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA==", + "dev": true, "engines": { "node": ">= 0.4" }, @@ -17271,6 +17632,7 @@ "version": "2.14.0", "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.14.0.tgz", "integrity": "sha512-a5dFJih5ZLYlRtDc0dZWP7RiKr6xIKzmn/oAYCDvdLThadVgyJwlaoQPmRtMSpz+rk0OGAgIu+TcM9HUF0fk1A==", + "dev": true, "dependencies": { "hasown": "^2.0.2" }, @@ -17285,6 +17647,7 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/is-data-view/-/is-data-view-1.0.1.tgz", "integrity": "sha512-AHkaJrsUVW6wq6JS8y3JnM/GJF/9cf+k20+iDzlSaJrinEo5+7vRiteOSwBhHRiAyQATN1AmY4hwzxJKPmYf+w==", + "dev": true, "dependencies": { "is-typed-array": "^1.1.13" }, @@ -17299,6 +17662,7 @@ "version": "1.0.5", "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.5.tgz", "integrity": "sha512-9YQaSxsAiSwcvS33MBk3wTCVnWK+HhF8VZR2jRxehM16QcVOdHqPn4VPHmRK4lSr38n9JriurInLcP90xsYNfQ==", + "dev": true, "dependencies": { "has-tostringtag": "^1.0.0" }, @@ -17328,6 +17692,7 @@ "version": "2.1.1", "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", + "dev": true, "engines": { "node": ">=0.10.0" } @@ -17353,6 +17718,7 @@ "version": "4.0.3", "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", + "dev": true, "dependencies": { "is-extglob": "^2.1.1" }, @@ -17388,12 +17754,14 @@ "node_modules/is-module": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/is-module/-/is-module-1.0.0.tgz", - "integrity": "sha512-51ypPSPCoTEIN9dy5Oy+h4pShgJmPCygKfyRCISBI+JoWT/2oJvK8QPxmwv7b/p239jXrm9M1mlQbyKJ5A152g==" + "integrity": "sha512-51ypPSPCoTEIN9dy5Oy+h4pShgJmPCygKfyRCISBI+JoWT/2oJvK8QPxmwv7b/p239jXrm9M1mlQbyKJ5A152g==", + "dev": true }, "node_modules/is-negative-zero": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.3.tgz", "integrity": "sha512-5KoIu2Ngpyek75jXodFvnafB6DJgr3u8uuK0LEZJjrU19DrMD3EVERaR8sjz8CCGgpZvxPl9SuE1GMVPFHx1mw==", + "dev": true, "engines": { "node": ">= 0.4" }, @@ -17405,6 +17773,7 @@ "version": "7.0.0", "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", + "dev": true, "engines": { "node": ">=0.12.0" } @@ -17413,6 +17782,7 @@ "version": "1.0.7", "resolved": "https://registry.npmjs.org/is-number-object/-/is-number-object-1.0.7.tgz", "integrity": "sha512-k1U0IRzLMo7ZlYIfzRu23Oh6MiIFasgpb9X76eqfFZAqwH44UI4KTBvBYIZ1dSL9ZzChTB9ShHfLkR4pdW5krQ==", + "dev": true, "dependencies": { "has-tostringtag": "^1.0.0" }, @@ -17436,6 +17806,7 @@ "version": "3.0.3", "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-3.0.3.tgz", "integrity": "sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==", + "dev": true, "engines": { "node": ">=8" } @@ -17462,6 +17833,7 @@ "version": "1.2.1", "resolved": "https://registry.npmjs.org/is-reference/-/is-reference-1.2.1.tgz", "integrity": "sha512-U82MsXXiFIrjCK4otLT+o2NA2Cd2g5MLoOVXUZjIOhLurrRxpEXzI8O0KZHr3IjLvlAH1kTPYSuqer5T9ZVBKQ==", + "dev": true, "dependencies": { "@types/estree": "*" } @@ -17470,6 +17842,7 @@ "version": "1.1.4", "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.4.tgz", "integrity": "sha512-kvRdxDsxZjhzUX07ZnLydzS1TU/TJlTUHHY4YLL87e37oUA49DfkLqgy+VjFocowy29cKvcSiu+kIv728jTTVg==", + "dev": true, "dependencies": { "call-bind": "^1.0.2", "has-tostringtag": "^1.0.0" @@ -17494,6 +17867,7 @@ "version": "1.0.3", "resolved": "https://registry.npmjs.org/is-shared-array-buffer/-/is-shared-array-buffer-1.0.3.tgz", "integrity": "sha512-nA2hv5XIhLR3uVzDDfCIknerhx8XUKnstuOERPNNIinXG7v9u+ohXF67vxm4TPTEPU6lm61ZkwP3c9PCB97rhg==", + "dev": true, "dependencies": { "call-bind": "^1.0.7" }, @@ -17524,6 +17898,7 @@ "version": "1.0.7", "resolved": "https://registry.npmjs.org/is-string/-/is-string-1.0.7.tgz", "integrity": "sha512-tE2UXzivje6ofPW7l23cjDOMa09gb7xlAqG6jG5ej6uPV32TlWP3NKPigtaGeHNu9fohccRYvIiZMfOOnOYUtg==", + "dev": true, "dependencies": { "has-tostringtag": "^1.0.0" }, @@ -17538,6 +17913,7 @@ "version": "1.0.4", "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.4.tgz", "integrity": "sha512-C/CPBqKWnvdcxqIARxyOh4v1UUEOCHpgDa0WYgpKDFMszcrPcffg5uhwSgPCLD2WWxmq6isisz87tzT01tuGhg==", + "dev": true, "dependencies": { "has-symbols": "^1.0.2" }, @@ -17552,6 +17928,7 @@ "version": "1.1.13", "resolved": "https://registry.npmjs.org/is-typed-array/-/is-typed-array-1.1.13.tgz", "integrity": "sha512-uZ25/bUAlUY5fR4OKT4rZQEBrzQWYV9ZJYGGsUmEJ6thodVJ1HX64ePQ6Z0qPWP+m+Uq6e9UugrE38jeYsDSMw==", + "dev": true, "dependencies": { "which-typed-array": "^1.1.14" }, @@ -17593,6 +17970,7 @@ "version": "1.0.2", "resolved": "https://registry.npmjs.org/is-weakref/-/is-weakref-1.0.2.tgz", "integrity": "sha512-qctsuLZmIQ0+vSSMfoVvyFe2+GSEvnmZ2ezTup1SBse9+twCCeial6EEi3Nc2KFcf6+qz2FBPnjXsk8xhKSaPQ==", + "dev": true, "dependencies": { "call-bind": "^1.0.2" }, @@ -17603,7 +17981,8 @@ "node_modules/is-what": { "version": "3.14.1", "resolved": "https://registry.npmjs.org/is-what/-/is-what-3.14.1.tgz", - "integrity": "sha512-sNxgpk9793nzSs7bA6JQJGeIuRBQhAaNGG77kzYQgMkrID+lS6SlK07K5LaptscDlSaIgH+GPFzf+d75FVxozA==" + "integrity": "sha512-sNxgpk9793nzSs7bA6JQJGeIuRBQhAaNGG77kzYQgMkrID+lS6SlK07K5LaptscDlSaIgH+GPFzf+d75FVxozA==", + "dev": true }, "node_modules/is-wsl": { "version": "2.2.0", @@ -17620,7 +17999,8 @@ "node_modules/isarray": { "version": "2.0.5", "resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.5.tgz", - "integrity": "sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==" + "integrity": "sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==", + "dev": true }, "node_modules/isexe": { "version": "2.0.0", @@ -19985,6 +20365,7 @@ "version": "1.2.0", "resolved": "https://registry.npmjs.org/js-cleanup/-/js-cleanup-1.2.0.tgz", "integrity": "sha512-JeDD0yiiSt80fXzAVa/crrS0JDPQljyBG/RpOtaSbyDq03VHa9szJWMaWOYU/bcTn412uMN2MxApXq8v79cUiQ==", + "dev": true, "dependencies": { "magic-string": "^0.25.7", "perf-regexes": "^1.0.1", @@ -19998,6 +20379,7 @@ "version": "0.25.9", "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.25.9.tgz", "integrity": "sha512-RmF0AsMzgt25qzqqLc1+MbHmhdx0ojF2Fvs4XnOqz2ZOBXzzkEwc/dJQZCYHAn7v1jbVOjAZfK8msRn4BxO4VQ==", + "dev": true, "dependencies": { "sourcemap-codec": "^1.4.8" } @@ -20012,7 +20394,7 @@ "version": "4.0.0", "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", - "devOptional": true + "dev": true }, "node_modules/js-yaml": { "version": "3.14.1", @@ -20115,7 +20497,7 @@ "version": "2.5.2", "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz", "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==", - "devOptional": true, + "dev": true, "bin": { "jsesc": "bin/jsesc" }, @@ -20134,7 +20516,8 @@ "node_modules/json-buffer": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.1.tgz", - "integrity": "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==" + "integrity": "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==", + "dev": true }, "node_modules/json-parse-even-better-errors": { "version": "2.3.1", @@ -20157,7 +20540,8 @@ "node_modules/json-stable-stringify-without-jsonify": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", - "integrity": "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==" + "integrity": "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==", + "dev": true }, "node_modules/json-stringify-safe": { "version": "5.0.1", @@ -20282,6 +20666,7 @@ "version": "4.5.4", "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.4.tgz", "integrity": "sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==", + "dev": true, "dependencies": { "json-buffer": "3.0.1" } @@ -20307,7 +20692,8 @@ "node_modules/known-css-properties": { "version": "0.34.0", "resolved": "https://registry.npmjs.org/known-css-properties/-/known-css-properties-0.34.0.tgz", - "integrity": "sha512-tBECoUqNFbyAY4RrbqsBQqDFpGXAEbdD5QKr8kACx3+rnArmuuR22nKQWKazvp07N9yjTyDZaw/20UIH8tL9DQ==" + "integrity": "sha512-tBECoUqNFbyAY4RrbqsBQqDFpGXAEbdD5QKr8kACx3+rnArmuuR22nKQWKazvp07N9yjTyDZaw/20UIH8tL9DQ==", + "dev": true }, "node_modules/kolorist": { "version": "1.8.0", @@ -20384,6 +20770,7 @@ "version": "2.1.0", "resolved": "https://registry.npmjs.org/less-plugin-autoprefixer/-/less-plugin-autoprefixer-2.1.0.tgz", "integrity": "sha512-W7rOH0tgl+h9r1Uek6ozK8U8Hzw7MQi9DjY4D2nOHQfzVAOxgD6oitXzAl/Jfg5OKM/NnPpYvUeE/95EXBLdig==", + "dev": true, "dependencies": { "autoprefixer": "^9.5.1", "postcss": "^7.0.16" @@ -20396,6 +20783,7 @@ "version": "9.8.8", "resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-9.8.8.tgz", "integrity": "sha512-eM9d/swFopRt5gdJ7jrpCwgvEMIayITpojhkkSMRsFHYuH5bkSQ4p/9qTEHtmNudUZh22Tehu7I6CxAW0IXTKA==", + "dev": true, "dependencies": { "browserslist": "^4.12.0", "caniuse-lite": "^1.0.30001109", @@ -20416,12 +20804,14 @@ "node_modules/less-plugin-autoprefixer/node_modules/picocolors": { "version": "0.2.1", "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-0.2.1.tgz", - "integrity": "sha512-cMlDqaLEqfSaW8Z7N5Jw+lyIW869EzT73/F5lhtY9cLGoVxSXznfgfXMO0Z5K0o0Q2TkTXq+0KFsdnSe3jDViA==" + "integrity": "sha512-cMlDqaLEqfSaW8Z7N5Jw+lyIW869EzT73/F5lhtY9cLGoVxSXznfgfXMO0Z5K0o0Q2TkTXq+0KFsdnSe3jDViA==", + "dev": true }, "node_modules/less-plugin-autoprefixer/node_modules/postcss": { "version": "7.0.39", "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.39.tgz", "integrity": "sha512-yioayjNbHn6z1/Bywyb2Y4s3yvDAeXGOyxqD+LnVOinq6Mdmd++SW2wUNVzavyyHxd6+DxzWGIuosg6P1Rj8uA==", + "dev": true, "dependencies": { "picocolors": "^0.2.1", "source-map": "^0.6.1" @@ -20438,6 +20828,7 @@ "version": "0.6.1", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true, "engines": { "node": ">=0.10.0" } @@ -20512,6 +20903,7 @@ "version": "0.4.1", "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==", + "dev": true, "dependencies": { "prelude-ls": "^1.2.1", "type-check": "~0.4.0" @@ -20705,7 +21097,8 @@ "node_modules/locate-character": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/locate-character/-/locate-character-3.0.0.tgz", - "integrity": "sha512-SW13ws7BjaeJ6p7Q6CO2nchbYEc3X3J6WrmTTDto7yMPqVSZTUyY5Tjbid+Ab8gLnATtygYtiDIJGQRRn2ZOiA==" + "integrity": "sha512-SW13ws7BjaeJ6p7Q6CO2nchbYEc3X3J6WrmTTDto7yMPqVSZTUyY5Tjbid+Ab8gLnATtygYtiDIJGQRRn2ZOiA==", + "dev": true }, "node_modules/locate-path": { "version": "5.0.0", @@ -20771,7 +21164,8 @@ "node_modules/lodash.merge": { "version": "4.6.2", "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", - "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==" + "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==", + "dev": true }, "node_modules/lodash.once": { "version": "4.1.1", @@ -21000,7 +21394,7 @@ "version": "5.1.1", "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz", "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==", - "devOptional": true, + "dev": true, "dependencies": { "yallist": "^3.0.2" } @@ -21017,6 +21411,7 @@ "version": "0.30.5", "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.5.tgz", "integrity": "sha512-7xlpfBaQaP/T6Vh8MO/EqXSW5En6INHEvEXQiuff7Gku0PWjU3uf6w/j9o7O+SpB5fOAkrI5HeoNgwjEO0pFsA==", + "dev": true, "dependencies": { "@jridgewell/sourcemap-codec": "^1.4.15" }, @@ -21174,7 +21569,7 @@ "version": "1.3.6", "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz", "integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==", - "devOptional": true + "dev": true }, "node_modules/makeerror": { "version": "1.0.12", @@ -21215,7 +21610,8 @@ "node_modules/mdn-data": { "version": "2.0.30", "resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.0.30.tgz", - "integrity": "sha512-GaqWWShW4kv/G9IEucWScBx9G1/vsFZZJUO+tD26M8J8z3Kw5RDQjaoZe03YAClgeS/SWPOcb4nkFBTEi5DUEA==" + "integrity": "sha512-GaqWWShW4kv/G9IEucWScBx9G1/vsFZZJUO+tD26M8J8z3Kw5RDQjaoZe03YAClgeS/SWPOcb4nkFBTEi5DUEA==", + "dev": true }, "node_modules/media-typer": { "version": "0.3.0", @@ -21252,6 +21648,7 @@ "version": "1.4.1", "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", + "dev": true, "engines": { "node": ">= 8" } @@ -21277,6 +21674,7 @@ "version": "4.0.7", "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.7.tgz", "integrity": "sha512-LPP/3KorzCwBxfeUuZmaR6bG2kdeHSbe0P2tY3FLRU4vYrjYz5hI4QZwV0njUx3jeuKe67YukQ1LSPZBKDqO/Q==", + "dev": true, "dependencies": { "braces": "^3.0.3", "picomatch": "^2.3.1" @@ -21340,6 +21738,7 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/min-indent/-/min-indent-1.0.1.tgz", "integrity": "sha512-I9jwMn07Sy/IwOj3zVkVik2JTvgpaykDZEigL6Rx6N9LbMywwUSMtxET+7lVoDLLd3O3IXwJwvuuns8UB/HeAg==", + "dev": true, "engines": { "node": ">=4" } @@ -21427,6 +21826,7 @@ "version": "9.0.3", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.3.tgz", "integrity": "sha512-RHiac9mvaRw0x3AYRgDC1CxAP7HTcNrrECeA8YYJeWnpo+2Q5CegtZjaotWTWxDG3UeGA1coE05iH1mPjT/2mg==", + "dev": true, "dependencies": { "brace-expansion": "^2.0.1" }, @@ -21569,6 +21969,7 @@ "version": "3.3.7", "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.7.tgz", "integrity": "sha512-eSRppjcPIatRIMC1U6UngP8XFcz8MQWGQdt1MTBQ7NaAmvXDfvNxbvWV3x2y6CdEUciCSsDHDQZbhYaB8QEo2g==", + "dev": true, "funding": [ { "type": "github", @@ -21591,7 +21992,8 @@ "node_modules/natural-compare": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", - "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==" + "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==", + "dev": true }, "node_modules/ndjson": { "version": "2.0.0", @@ -21616,6 +22018,7 @@ "version": "3.3.1", "resolved": "https://registry.npmjs.org/needle/-/needle-3.3.1.tgz", "integrity": "sha512-6k0YULvhpw+RoLNiQCRKOl09Rv1dPLr8hHnVjHqdolKwDrdNyk+Hmrthi4lIGPPz3r39dLx0hsF5s40sZ3Us4Q==", + "dev": true, "optional": true, "dependencies": { "iconv-lite": "^0.6.3", @@ -21769,13 +22172,14 @@ "node_modules/node-releases": { "version": "2.0.14", "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.14.tgz", - "integrity": "sha512-y10wOWt8yZpqXmOgRo77WaHEmhYQYGNA6y421PKsKYWEK8aW+cqAphborZDhqfyKrbZEN92CN1X2KbafY2s7Yw==" + "integrity": "sha512-y10wOWt8yZpqXmOgRo77WaHEmhYQYGNA6y421PKsKYWEK8aW+cqAphborZDhqfyKrbZEN92CN1X2KbafY2s7Yw==", + "dev": true }, "node_modules/normalize-path": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", - "devOptional": true, + "dev": true, "engines": { "node": ">=0.10.0" } @@ -21784,6 +22188,7 @@ "version": "0.1.2", "resolved": "https://registry.npmjs.org/normalize-range/-/normalize-range-0.1.2.tgz", "integrity": "sha512-bdok/XvKII3nUpklnV6P2hxtMNrCboOjAcyBuQnWEhO665FwrSNRxU+AqpsyvO6LgGYPspN+lu5CLtw4jPRKNA==", + "dev": true, "engines": { "node": ">=0.10.0" } @@ -21842,7 +22247,8 @@ "node_modules/num2fraction": { "version": "1.2.2", "resolved": "https://registry.npmjs.org/num2fraction/-/num2fraction-1.2.2.tgz", - "integrity": "sha512-Y1wZESM7VUThYY+4W+X4ySH2maqcA+p7UR+w8VWNWVAd6lwuXXWz/w/Cz43J/dI2I+PS6wD5N+bJUF+gjWvIqg==" + "integrity": "sha512-Y1wZESM7VUThYY+4W+X4ySH2maqcA+p7UR+w8VWNWVAd6lwuXXWz/w/Cz43J/dI2I+PS6wD5N+bJUF+gjWvIqg==", + "dev": true }, "node_modules/nwsapi": { "version": "2.2.10", @@ -22042,6 +22448,7 @@ "version": "1.1.1", "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==", + "dev": true, "engines": { "node": ">= 0.4" } @@ -22055,6 +22462,7 @@ "version": "4.1.5", "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.5.tgz", "integrity": "sha512-byy+U7gp+FVwmyzKPYhW2h5l3crpmGsxl7X2s8y43IgxvG4g3QZ6CffDtsNQy1WsmZpQbO+ybo0AlW7TY6DcBQ==", + "dev": true, "dependencies": { "call-bind": "^1.0.5", "define-properties": "^1.2.1", @@ -22072,6 +22480,7 @@ "version": "2.0.8", "resolved": "https://registry.npmjs.org/object.fromentries/-/object.fromentries-2.0.8.tgz", "integrity": "sha512-k6E21FzySsSK5a21KRADBd/NGneRegFO5pLHfdQLpRDETUNJueLXs3WCzyQ3tFRDYgbq3KHGXfTbi2bs8WQ6rQ==", + "dev": true, "dependencies": { "call-bind": "^1.0.7", "define-properties": "^1.2.1", @@ -22089,6 +22498,7 @@ "version": "1.0.3", "resolved": "https://registry.npmjs.org/object.groupby/-/object.groupby-1.0.3.tgz", "integrity": "sha512-+Lhy3TQTuzXI5hevh8sBGqbmurHbbIjAi0Z4S63nthVLmLxfbj4T54a4CfZrXIrt9iP4mVAPYMo/v99taj3wjQ==", + "dev": true, "dependencies": { "call-bind": "^1.0.7", "define-properties": "^1.2.1", @@ -22102,6 +22512,7 @@ "version": "1.2.0", "resolved": "https://registry.npmjs.org/object.values/-/object.values-1.2.0.tgz", "integrity": "sha512-yBYjY9QX2hnRmZHAjG/f13MzmBzxzYgQhFrke06TTyKY5zSTEqkOeukBzIdVA3j3ulu8Qa3MbVFShV7T2RmGtQ==", + "dev": true, "dependencies": { "call-bind": "^1.0.7", "define-properties": "^1.2.1", @@ -22183,6 +22594,7 @@ "version": "1.5.2", "resolved": "https://registry.npmjs.org/opener/-/opener-1.5.2.tgz", "integrity": "sha512-ur5UIdyw5Y7yEj9wLzhqXiy6GZ3Mwx0yGI+5sMn2r0N0v3cKJvUmFH5yPP+WXh9e0xfyzyJX95D8l088DNFj7A==", + "dev": true, "bin": { "opener": "bin/opener-bin.js" } @@ -22191,6 +22603,7 @@ "version": "0.9.4", "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.4.tgz", "integrity": "sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g==", + "dev": true, "dependencies": { "deep-is": "^0.1.3", "fast-levenshtein": "^2.0.6", @@ -22407,6 +22820,7 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", + "dev": true, "dependencies": { "callsites": "^3.0.0" }, @@ -22464,6 +22878,7 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/parse-node-version/-/parse-node-version-1.0.1.tgz", "integrity": "sha512-3YHlOa/JgH6Mnpr05jP9eDG254US9ek25LyIxZlDItp2iJtwyaXQb57lBYLdT3MowkUFYEV2XXNAYIPlESvJlA==", + "dev": true, "engines": { "node": ">= 0.10" } @@ -22530,7 +22945,8 @@ "node_modules/path-parse": { "version": "1.0.7", "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", - "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==" + "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", + "dev": true }, "node_modules/path-scurry": { "version": "1.11.1", @@ -22564,6 +22980,7 @@ "version": "4.0.0", "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==", + "dev": true, "engines": { "node": ">=8" } @@ -22593,6 +23010,7 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/perf-regexes/-/perf-regexes-1.0.1.tgz", "integrity": "sha512-L7MXxUDtqr4PUaLFCDCXBfGV/6KLIuSEccizDI7JxT+c9x1G1v04BQ4+4oag84SHaCdrBgQAIs/Cqn+flwFPng==", + "dev": true, "engines": { "node": ">=6.14" } @@ -22607,6 +23025,7 @@ "version": "3.1.0", "resolved": "https://registry.npmjs.org/periscopic/-/periscopic-3.1.0.tgz", "integrity": "sha512-vKiQ8RRtkl9P+r/+oefh25C3fhybptkHKCZSPlcXiJux2tJF55GnEj3BVn4A5gKfq9NWWXXrxkHBwVPUfH0opw==", + "dev": true, "dependencies": { "@types/estree": "^1.0.0", "estree-walker": "^3.0.0", @@ -22617,6 +23036,7 @@ "version": "3.0.3", "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-3.0.3.tgz", "integrity": "sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g==", + "dev": true, "dependencies": { "@types/estree": "^1.0.0" } @@ -22625,6 +23045,7 @@ "version": "3.0.2", "resolved": "https://registry.npmjs.org/is-reference/-/is-reference-3.0.2.tgz", "integrity": "sha512-v3rht/LgVcsdZa3O2Nqs+NMowLOxeOm7Ay9+/ARQ2F+qEoANRcqrjAZKGN0v8ymUetZGgkp26LTnGT7H0Qo9Pg==", + "dev": true, "dependencies": { "@types/estree": "*" } @@ -22632,12 +23053,14 @@ "node_modules/picocolors": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.1.tgz", - "integrity": "sha512-anP1Z8qwhkbmu7MFP5iTt+wQKXgwzf7zTyGlcdzabySa9vd0Xt392U0rVmz9poOaBj0uHJKyyo9/upk0HrEQew==" + "integrity": "sha512-anP1Z8qwhkbmu7MFP5iTt+wQKXgwzf7zTyGlcdzabySa9vd0Xt392U0rVmz9poOaBj0uHJKyyo9/upk0HrEQew==", + "dev": true }, "node_modules/picomatch": { "version": "2.3.1", "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", + "dev": true, "engines": { "node": ">=8.6" }, @@ -22820,6 +23243,7 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/possible-typed-array-names/-/possible-typed-array-names-1.0.0.tgz", "integrity": "sha512-d7Uw+eZoloe0EHDIYoe+bQ5WXnGMOpmiZFTuMWCwpjzzkL2nTjcKiAk4hh8TjnGye2TwWOk3UXucZ+3rbmBa8Q==", + "dev": true, "engines": { "node": ">= 0.4" } @@ -22828,6 +23252,7 @@ "version": "8.4.39", "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.39.tgz", "integrity": "sha512-0vzE+lAiG7hZl1/9I8yzKLx3aR9Xbof3fBHKunvMfOCYAtMhrsnccJY2iTURb9EZd5+pLuiNV9/c/GZJOHsgIw==", + "dev": true, "funding": [ { "type": "opencollective", @@ -22970,6 +23395,7 @@ "version": "3.1.4", "resolved": "https://registry.npmjs.org/postcss-load-config/-/postcss-load-config-3.1.4.tgz", "integrity": "sha512-6DiM4E7v4coTE4uzA8U//WhtPwyhiim3eyjEMFCnUpzbrkK9wJHgKDT2mR+HbtSrd/NubVaYTOpSpjUl8NQeRg==", + "dev": true, "dependencies": { "lilconfig": "^2.0.5", "yaml": "^1.10.2" @@ -22998,6 +23424,7 @@ "version": "2.1.0", "resolved": "https://registry.npmjs.org/lilconfig/-/lilconfig-2.1.0.tgz", "integrity": "sha512-utWOt/GHzuUxnLKxB6dk81RoOeoNeHgbrXiuGk4yyF5qlRz+iIVWu56E2fqGHFrXz0QNUhLB/8nKqvRH66JKGQ==", + "dev": true, "engines": { "node": ">=10" } @@ -23393,6 +23820,7 @@ "version": "6.0.0", "resolved": "https://registry.npmjs.org/postcss-safe-parser/-/postcss-safe-parser-6.0.0.tgz", "integrity": "sha512-FARHN8pwH+WiS2OPCxJI8FuRJpTVnn6ZNFiqAM2aeW2LwTHWWmWgIyKC6cUo0L8aeKiF/14MNvnpls6R2PBeMQ==", + "dev": true, "engines": { "node": ">=12.0" }, @@ -23408,6 +23836,7 @@ "version": "4.0.9", "resolved": "https://registry.npmjs.org/postcss-scss/-/postcss-scss-4.0.9.tgz", "integrity": "sha512-AjKOeiwAitL/MXxQW2DliT28EKukvvbEWx3LBmJIRN8KfBGZbRTxNYW0kSqi1COiTZ57nZ9NW06S6ux//N1c9A==", + "dev": true, "funding": [ { "type": "opencollective", @@ -23433,6 +23862,7 @@ "version": "6.1.0", "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.1.0.tgz", "integrity": "sha512-UMz42UD0UY0EApS0ZL9o1XnLhSTtvvvLe5Dc2H2O56fvRZi+KulDyf5ctDhhtYJBGKStV2FL1fy6253cmLgqVQ==", + "dev": true, "dependencies": { "cssesc": "^3.0.0", "util-deprecate": "^1.0.2" @@ -23475,7 +23905,8 @@ "node_modules/postcss-value-parser": { "version": "4.2.0", "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-4.2.0.tgz", - "integrity": "sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==" + "integrity": "sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==", + "dev": true }, "node_modules/preact": { "version": "10.22.1", @@ -23530,6 +23961,7 @@ "version": "1.2.1", "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==", + "dev": true, "engines": { "node": ">= 0.8.0" } @@ -23710,6 +24142,7 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/prr/-/prr-1.0.1.tgz", "integrity": "sha512-yPw4Sng1gWghHQWj0B3ZggWUm4qVbPwPFcRG8KyxiU7J2OHFSoEHKS+EZ3fv5l1t9CyCiop6l/ZYeWbrgoQejw==", + "dev": true, "optional": true }, "node_modules/psl": { @@ -23732,6 +24165,7 @@ "version": "2.3.1", "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==", + "dev": true, "engines": { "node": ">=6" } @@ -23897,6 +24331,7 @@ "version": "1.2.3", "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", + "dev": true, "funding": [ { "type": "github", @@ -23935,6 +24370,7 @@ "version": "2.1.0", "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==", + "dev": true, "dependencies": { "safe-buffer": "^5.1.0" } @@ -24059,7 +24495,7 @@ "version": "3.6.0", "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", - "devOptional": true, + "dev": true, "dependencies": { "picomatch": "^2.2.1" }, @@ -24135,6 +24571,7 @@ "version": "1.5.2", "resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.5.2.tgz", "integrity": "sha512-NcDiDkTLuPR+++OCKB0nWafEmhg/Da8aUPLPMQbK+bxKKCm1/S5he+AqYa4PlMCVBalb4/yxIRub6qkEx5yJbw==", + "dev": true, "dependencies": { "call-bind": "^1.0.6", "define-properties": "^1.2.1", @@ -24271,6 +24708,7 @@ "version": "1.22.8", "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.8.tgz", "integrity": "sha512-oKWePCxqpd6FlLvGV1VU0x7bkPmmCNolxzjMf4NczoDnQcIWrAF+cPtZn5i6n+RfD2d9i0tzpKnG6Yk168yIyw==", + "dev": true, "dependencies": { "is-core-module": "^2.13.0", "path-parse": "^1.0.7", @@ -24308,6 +24746,7 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/resolve-pkg-maps/-/resolve-pkg-maps-1.0.0.tgz", "integrity": "sha512-seS2Tj26TBVOC2NIc2rOe2y2ZO7efxITtLZcGSOnHHNOQ7CkiUBfw0Iw2ck6xkIhPwLhKNLS8BO+hEpngQlqzw==", + "dev": true, "funding": { "url": "https://github.com/privatenumber/resolve-pkg-maps?sponsor=1" } @@ -24359,6 +24798,7 @@ "version": "1.0.4", "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==", + "dev": true, "engines": { "iojs": ">=1.0.0", "node": ">=0.10.0" @@ -24375,6 +24815,7 @@ "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", "deprecated": "Rimraf versions prior to v4 are no longer supported", + "dev": true, "dependencies": { "glob": "^7.1.3" }, @@ -24389,6 +24830,7 @@ "version": "1.1.11", "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dev": true, "dependencies": { "balanced-match": "^1.0.0", "concat-map": "0.0.1" @@ -24399,6 +24841,7 @@ "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", "deprecated": "Glob versions prior to v9 are no longer supported", + "dev": true, "dependencies": { "fs.realpath": "^1.0.0", "inflight": "^1.0.4", @@ -24418,6 +24861,7 @@ "version": "3.1.2", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, "dependencies": { "brace-expansion": "^1.1.7" }, @@ -24433,12 +24877,14 @@ "node_modules/robust-predicates": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/robust-predicates/-/robust-predicates-3.0.2.tgz", - "integrity": "sha512-IXgzBWvWQwE6PrDI05OvmXUIruQTcoMDzRsOd5CDvHCVLcLHMTSYvOK5Cm46kWqlV3yAbuSpBZdJ5oP5OUoStg==" + "integrity": "sha512-IXgzBWvWQwE6PrDI05OvmXUIruQTcoMDzRsOd5CDvHCVLcLHMTSYvOK5Cm46kWqlV3yAbuSpBZdJ5oP5OUoStg==", + "dev": true }, "node_modules/rollup": { "version": "2.79.1", "resolved": "https://registry.npmjs.org/rollup/-/rollup-2.79.1.tgz", "integrity": "sha512-uKxbd0IhMZOhjAiD5oAFp7BqvkA4Dv47qpOCtaNvng4HBwdbWtdOh8f5nZNuk2rp51PMGk3bzfWu5oayNEuYnw==", + "dev": true, "bin": { "rollup": "dist/bin/rollup" }, @@ -24453,6 +24899,7 @@ "version": "3.2.1", "resolved": "https://registry.npmjs.org/rollup-plugin-cleanup/-/rollup-plugin-cleanup-3.2.1.tgz", "integrity": "sha512-zuv8EhoO3TpnrU8MX8W7YxSbO4gmOR0ny06Lm3nkFfq0IVKdBUtHwhVzY1OAJyNCIAdLiyPnOrU0KnO0Fri1GQ==", + "dev": true, "dependencies": { "js-cleanup": "^1.2.0", "rollup-pluginutils": "^2.8.2" @@ -24517,6 +24964,7 @@ "version": "1.1.1", "resolved": "https://registry.npmjs.org/rollup-plugin-serve/-/rollup-plugin-serve-1.1.1.tgz", "integrity": "sha512-H0VarZRtFR0lfiiC9/P8jzCDvtFf1liOX4oSdIeeYqUCKrmFA7vNiQ0rg2D+TuoP7leaa/LBR8XBts5viF6lnw==", + "dev": true, "dependencies": { "mime": "^2", "opener": "1" @@ -24526,6 +24974,7 @@ "version": "2.6.0", "resolved": "https://registry.npmjs.org/mime/-/mime-2.6.0.tgz", "integrity": "sha512-USPkMeET31rOMiarsBNIHZKLGgvKc/LrjofAnBlOttf5ajRvqiRA8QsenbcooctK6d6Ts6aqZXBA+XbkKthiQg==", + "dev": true, "bin": { "mime": "cli.js" }, @@ -24537,6 +24986,7 @@ "version": "7.2.2", "resolved": "https://registry.npmjs.org/rollup-plugin-svelte/-/rollup-plugin-svelte-7.2.2.tgz", "integrity": "sha512-hgnIblTRewaBEVQD6N0Q43o+y6q1TmDRhBjaEzQCi50bs8TXqjc+d1zFZyE8tsfgcfNHZQzclh4RxlFUB85H8Q==", + "dev": true, "dependencies": { "@rollup/pluginutils": "^4.1.0", "resolve.exports": "^2.0.0" @@ -24553,6 +25003,7 @@ "version": "2.0.2", "resolved": "https://registry.npmjs.org/resolve.exports/-/resolve.exports-2.0.2.tgz", "integrity": "sha512-X2UW6Nw3n/aMgDVy+0rSqgHlv39WZAlZrXCdnbyEiKm17DSqHX4MmQMaST3FbeWR5FTuRcUwYAziZajji0Y7mg==", + "dev": true, "engines": { "node": ">=10" } @@ -24561,6 +25012,7 @@ "version": "0.11.2", "resolved": "https://registry.npmjs.org/rollup-plugin-swc3/-/rollup-plugin-swc3-0.11.2.tgz", "integrity": "sha512-o1ih9B806fV2wBSNk46T0cYfTF2eiiKmYXRpWw3K4j/Cp3tCAt10UCVsTqvUhGP58pcB3/GZcAVl5e7TCSKN6Q==", + "dev": true, "dependencies": { "@fastify/deepmerge": "^1.3.0", "@rollup/pluginutils": "^5.1.0", @@ -24579,6 +25031,7 @@ "version": "5.1.0", "resolved": "https://registry.npmjs.org/@rollup/pluginutils/-/pluginutils-5.1.0.tgz", "integrity": "sha512-XTIWOPPcpvyKI6L1NHo0lFlCyznUEyPmPY1mc3KpPVDYulHSTvyeLNVW00QTLIAFNhR3kYnJTQHeGqU4M3n09g==", + "dev": true, "dependencies": { "@types/estree": "^1.0.0", "estree-walker": "^2.0.2", @@ -24626,6 +25079,7 @@ "version": "2.8.2", "resolved": "https://registry.npmjs.org/rollup-pluginutils/-/rollup-pluginutils-2.8.2.tgz", "integrity": "sha512-EEp9NhnUkwY8aif6bxgovPHMoMoNr2FulJziTndpt5H9RdwC47GSGuII9XxpSdzVGM0GWrNPHV6ie1LTNJPaLQ==", + "dev": true, "dependencies": { "estree-walker": "^0.6.1" } @@ -24633,12 +25087,14 @@ "node_modules/rollup-pluginutils/node_modules/estree-walker": { "version": "0.6.1", "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-0.6.1.tgz", - "integrity": "sha512-SqmZANLWS0mnatqbSfRP5g8OXZC12Fgg1IwNtLsyHDzJizORW4khDfjPqJZsemPWBB2uqykUah5YpQ6epsqC/w==" + "integrity": "sha512-SqmZANLWS0mnatqbSfRP5g8OXZC12Fgg1IwNtLsyHDzJizORW4khDfjPqJZsemPWBB2uqykUah5YpQ6epsqC/w==", + "dev": true }, "node_modules/rollup-preserve-directives": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/rollup-preserve-directives/-/rollup-preserve-directives-1.1.1.tgz", "integrity": "sha512-+eQafbuEfDPfxQ9hQPlwaROfin4yiVRxap8hnrvvvcSGoukv1tTiYpAW9mvm3uR8J+fe4xd8FdVd5rz9q7jZ+Q==", + "dev": true, "dependencies": { "magic-string": "^0.30.5" }, @@ -24656,6 +25112,7 @@ "version": "1.2.0", "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==", + "dev": true, "funding": [ { "type": "github", @@ -24677,7 +25134,8 @@ "node_modules/rw": { "version": "1.3.3", "resolved": "https://registry.npmjs.org/rw/-/rw-1.3.3.tgz", - "integrity": "sha512-PdhdWy89SiZogBLaw42zdeqtRJ//zFd2PgQavcICDUgJT5oW10QCRKbJ6bg4r0/UY2M6BWd5tkxuGFRvCkgfHQ==" + "integrity": "sha512-PdhdWy89SiZogBLaw42zdeqtRJ//zFd2PgQavcICDUgJT5oW10QCRKbJ6bg4r0/UY2M6BWd5tkxuGFRvCkgfHQ==", + "dev": true }, "node_modules/rxjs": { "version": "7.8.1", @@ -24704,6 +25162,7 @@ "version": "1.1.2", "resolved": "https://registry.npmjs.org/safe-array-concat/-/safe-array-concat-1.1.2.tgz", "integrity": "sha512-vj6RsCsWBCf19jIeHEfkRMw8DPiBb+DMXklQ/1SGDHOMlHdPUkZXFQ2YdplS23zESTijAcurb1aSgJA3AgMu1Q==", + "dev": true, "dependencies": { "call-bind": "^1.0.7", "get-intrinsic": "^1.2.4", @@ -24726,6 +25185,7 @@ "version": "1.0.3", "resolved": "https://registry.npmjs.org/safe-regex-test/-/safe-regex-test-1.0.3.tgz", "integrity": "sha512-CdASjNJPvRa7roO6Ra/gLYBTzYzzPyyBXxIMdGW3USQLyjWEls2RgW5UBTXaQVp+OrpeCK3bLem8smtmheoRuw==", + "dev": true, "dependencies": { "call-bind": "^1.0.6", "es-errors": "^1.3.0", @@ -24747,6 +25207,7 @@ "version": "0.5.1", "resolved": "https://registry.npmjs.org/sander/-/sander-0.5.1.tgz", "integrity": "sha512-3lVqBir7WuKDHGrKRDn/1Ye3kwpXaDOMsiRP1wd6wpZW56gJhsbp5RqQpA6JG/P+pkXizygnr1dKR8vzWaVsfA==", + "dev": true, "dependencies": { "es6-promise": "^3.1.2", "graceful-fs": "^4.1.3", @@ -24758,6 +25219,7 @@ "version": "1.1.11", "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dev": true, "dependencies": { "balanced-match": "^1.0.0", "concat-map": "0.0.1" @@ -24768,6 +25230,7 @@ "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", "deprecated": "Glob versions prior to v9 are no longer supported", + "dev": true, "dependencies": { "fs.realpath": "^1.0.0", "inflight": "^1.0.4", @@ -24787,6 +25250,7 @@ "version": "3.1.2", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, "dependencies": { "brace-expansion": "^1.1.7" }, @@ -24799,6 +25263,7 @@ "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz", "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==", "deprecated": "Rimraf versions prior to v4 are no longer supported", + "dev": true, "dependencies": { "glob": "^7.1.3" }, @@ -24810,7 +25275,7 @@ "version": "1.77.6", "resolved": "https://registry.npmjs.org/sass/-/sass-1.77.6.tgz", "integrity": "sha512-ByXE1oLD79GVq9Ht1PeHWCPMPB8XHpBuz1r85oByKHjZY6qV6rWnQovQzXJXuQ/XyE1Oj3iPk3lo28uzaRA2/Q==", - "devOptional": true, + "dev": true, "dependencies": { "chokidar": ">=3.0.0 <4.0.0", "immutable": "^4.0.0", @@ -24926,6 +25391,7 @@ "version": "6.3.1", "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "dev": true, "bin": { "semver": "bin/semver.js" } @@ -24986,6 +25452,7 @@ "version": "6.0.2", "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-6.0.2.tgz", "integrity": "sha512-Saa1xPByTTq2gdeFZYLLo+RFE35NHZkAbqZeWNd3BpzppeVisAqpDjcp8dyf6uIvEqJRd46jemmyA4iFIeVk8g==", + "dev": true, "dependencies": { "randombytes": "^2.1.0" } @@ -25153,6 +25620,7 @@ "version": "2.0.2", "resolved": "https://registry.npmjs.org/set-function-name/-/set-function-name-2.0.2.tgz", "integrity": "sha512-7PGFlmtwsEADb0WYyvCMa1t+yke6daIG4Wirafur5kcf+MhUnPms1UeR0CKQdTZD81yESwMHbtn+TR+dMviakQ==", + "dev": true, "dependencies": { "define-data-property": "^1.1.4", "es-errors": "^1.3.0", @@ -25358,6 +25826,7 @@ "version": "1.0.2", "resolved": "https://registry.npmjs.org/skip-regex/-/skip-regex-1.0.2.tgz", "integrity": "sha512-pEjMUbwJ5Pl/6Vn6FsamXHXItJXSRftcibixDmNCWbWhic0hzHrwkMZo0IZ7fMRH9KxcWDFSkzhccB4285PutA==", + "dev": true, "engines": { "node": ">=4.2" } @@ -25366,6 +25835,7 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", + "dev": true, "engines": { "node": ">=8" } @@ -25420,7 +25890,8 @@ "node_modules/smob": { "version": "1.5.0", "resolved": "https://registry.npmjs.org/smob/-/smob-1.5.0.tgz", - "integrity": "sha512-g6T+p7QO8npa+/hNx9ohv1E5pVCmWrVCUzUXJyLdMmftX6ER0oiWY/w9knEonLpnOp6b6FenKnMfR8gqwWdwig==" + "integrity": "sha512-g6T+p7QO8npa+/hNx9ohv1E5pVCmWrVCUzUXJyLdMmftX6ER0oiWY/w9knEonLpnOp6b6FenKnMfR8gqwWdwig==", + "dev": true }, "node_modules/sockjs": { "version": "0.3.24", @@ -25437,6 +25908,7 @@ "version": "0.11.1", "resolved": "https://registry.npmjs.org/sorcery/-/sorcery-0.11.1.tgz", "integrity": "sha512-o7npfeJE6wi6J9l0/5LKshFzZ2rMatRiCDwYeDQaOzqdzRJwALhX7mk/A/ecg6wjMu7wdZbmXfD2S/vpOg0bdQ==", + "dev": true, "dependencies": { "@jridgewell/sourcemap-codec": "^1.4.14", "buffer-crc32": "^1.0.0", @@ -25451,6 +25923,7 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/buffer-crc32/-/buffer-crc32-1.0.0.tgz", "integrity": "sha512-Db1SbgBS/fg/392AblrMJk97KggmvYhr4pB5ZIMTWtaivCPMWLkmb7m21cJvpvgK+J3nsU2CmmixNBZx4vFj/w==", + "dev": true, "engines": { "node": ">=8.0.0" } @@ -25464,7 +25937,7 @@ "version": "0.7.4", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.4.tgz", "integrity": "sha512-l3BikUxvPOcn5E74dZiq5BGsTb5yEwhaTSzccU6t4sDOH8NWJCstKO5QT2CvtFoK6F0saL7p9xHAqHOlCPJygA==", - "devOptional": true, + "dev": true, "engines": { "node": ">= 8" } @@ -25473,6 +25946,7 @@ "version": "1.2.0", "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.0.tgz", "integrity": "sha512-itJW8lvSA0TXEphiRoawsCksnlf8SyvmFzIhltqAHluXd88pkCd+cXJVHTDwdCr0IzwptSm035IHQktUu1QUMg==", + "dev": true, "engines": { "node": ">=0.10.0" } @@ -25502,6 +25976,7 @@ "resolved": "https://registry.npmjs.org/source-map-resolve/-/source-map-resolve-0.6.0.tgz", "integrity": "sha512-KXBr9d/fO/bWo97NXsPIAW1bFSBOuCnjbNTBMO7N59hsv5i9yzRDfcYwwt0l04+VqnKC+EwzvJZIP/qkuMgR/w==", "deprecated": "See https://github.com/lydell/source-map-resolve#deprecated", + "dev": true, "optional": true, "peer": true, "dependencies": { @@ -25532,7 +26007,8 @@ "version": "1.4.8", "resolved": "https://registry.npmjs.org/sourcemap-codec/-/sourcemap-codec-1.4.8.tgz", "integrity": "sha512-9NykojV5Uih4lgo5So5dtw+f0JgJX30KCNI8gwhz2J9A15wD0Ml6tjHKwf6fTSa6fAdVBdZeNOs9eJ71qCk8vA==", - "deprecated": "Please use @jridgewell/sourcemap-codec instead" + "deprecated": "Please use @jridgewell/sourcemap-codec instead", + "dev": true }, "node_modules/spdy": { "version": "4.0.2", @@ -25827,6 +26303,7 @@ "version": "1.2.9", "resolved": "https://registry.npmjs.org/string.prototype.trim/-/string.prototype.trim-1.2.9.tgz", "integrity": "sha512-klHuCNxiMZ8MlsOihJhJEBJAiMVqU3Z2nEXWfWnIqjN0gEFS9J9+IxKozWWtQGcgoa1WUZzLjKPTr4ZHNFTFxw==", + "dev": true, "dependencies": { "call-bind": "^1.0.7", "define-properties": "^1.2.1", @@ -25844,6 +26321,7 @@ "version": "1.0.8", "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.8.tgz", "integrity": "sha512-p73uL5VCHCO2BZZ6krwwQE3kCzM7NKmis8S//xEC6fQonchbum4eP6kR4DLEjQFO3Wnj3Fuo8NM0kOSjVdHjZQ==", + "dev": true, "dependencies": { "call-bind": "^1.0.7", "define-properties": "^1.2.1", @@ -25857,6 +26335,7 @@ "version": "1.0.8", "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.8.tgz", "integrity": "sha512-UXSH262CSZY1tfu3G3Secr6uGLCFVPMhIqHjlgCUtCCcgihYc/xKs9djMTMUOb2j1mVSeU8EU6NWc/iQKU6Gfg==", + "dev": true, "dependencies": { "call-bind": "^1.0.7", "define-properties": "^1.2.1", @@ -25937,6 +26416,7 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/strip-indent/-/strip-indent-3.0.0.tgz", "integrity": "sha512-laJTa3Jb+VQpaC6DseHhF7dXVqHTfJPCRDaEbid/drOhgitgYku/letMUqOXFoWV0zIIUbjpdH2t+tYj4bQMRQ==", + "dev": true, "dependencies": { "min-indent": "^1.0.0" }, @@ -25948,6 +26428,7 @@ "version": "3.1.1", "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", + "dev": true, "engines": { "node": ">=8" }, @@ -26156,7 +26637,7 @@ "version": "5.5.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", - "devOptional": true, + "dev": true, "dependencies": { "has-flag": "^3.0.0" }, @@ -26168,6 +26649,7 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==", + "dev": true, "engines": { "node": ">= 0.4" }, @@ -26179,6 +26661,7 @@ "version": "4.2.18", "resolved": "https://registry.npmjs.org/svelte/-/svelte-4.2.18.tgz", "integrity": "sha512-d0FdzYIiAePqRJEb90WlJDkjUEx42xhivxN8muUBmfZnP+tzUgz12DJ2hRJi8sIHCME7jeK1PTMgKPSfTd8JrA==", + "dev": true, "dependencies": { "@ampproject/remapping": "^2.2.1", "@jridgewell/sourcemap-codec": "^1.4.15", @@ -26399,6 +26882,7 @@ "version": "0.40.0", "resolved": "https://registry.npmjs.org/svelte-eslint-parser/-/svelte-eslint-parser-0.40.0.tgz", "integrity": "sha512-M+v1HhC5T1WKYVxWexUCS4o6oIBS88XKzOZuhl2ew+eGxol7eC21e+VE8TC4rXJ3iT3iXT0qlZsZcpKjVo5/zQ==", + "dev": true, "dependencies": { "eslint-scope": "^7.2.2", "eslint-visitor-keys": "^3.4.3", @@ -26436,12 +26920,14 @@ "node_modules/svelte-preprocess-filter": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/svelte-preprocess-filter/-/svelte-preprocess-filter-1.0.0.tgz", - "integrity": "sha512-92innv59nyEx24xbfcSurB5ocwC8qFdDtGli/JVMHzJsxyvV2yjQKIcbUqU9VIV5mKUWO2PoY93nncS2yF4ULQ==" + "integrity": "sha512-92innv59nyEx24xbfcSurB5ocwC8qFdDtGli/JVMHzJsxyvV2yjQKIcbUqU9VIV5mKUWO2PoY93nncS2yF4ULQ==", + "dev": true }, "node_modules/svelte-preprocess-less": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/svelte-preprocess-less/-/svelte-preprocess-less-0.4.0.tgz", "integrity": "sha512-fvRA4+PWkQe5bNpCGKfYjsxxq6hyJJNn6rq/DeT0H4u6qI4o7oG340UQZZlCNZAucYMXz7Y/R1DNi8g4QsCMjg==", + "dev": true, "dependencies": { "svelte-preprocess-filter": "^1.0.0" } @@ -26450,6 +26936,7 @@ "version": "3.0.3", "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-3.0.3.tgz", "integrity": "sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g==", + "dev": true, "dependencies": { "@types/estree": "^1.0.0" } @@ -26458,6 +26945,7 @@ "version": "3.0.2", "resolved": "https://registry.npmjs.org/is-reference/-/is-reference-3.0.2.tgz", "integrity": "sha512-v3rht/LgVcsdZa3O2Nqs+NMowLOxeOm7Ay9+/ARQ2F+qEoANRcqrjAZKGN0v8ymUetZGgkp26LTnGT7H0Qo9Pg==", + "dev": true, "dependencies": { "@types/estree": "*" } @@ -26511,6 +26999,7 @@ "version": "2.2.1", "resolved": "https://registry.npmjs.org/tapable/-/tapable-2.2.1.tgz", "integrity": "sha512-GNzQvQTOIP6RyTfE2Qxb8ZVlNmw0n88vp1szwWRimP02mnTsx3Wtn5qRdqY9w2XduFNUgvOwhNnQsjwCp+kqaQ==", + "dev": true, "engines": { "node": ">=6" } @@ -26687,6 +27176,7 @@ "version": "5.31.1", "resolved": "https://registry.npmjs.org/terser/-/terser-5.31.1.tgz", "integrity": "sha512-37upzU1+viGvuFtBo9NPufCb9dwM0+l9hMxYyWfBA+fbwrPqNJAhbZ6W47bBFnZHKHTUBnMvi87434qq+qnxOg==", + "dev": true, "dependencies": { "@jridgewell/source-map": "^0.3.3", "acorn": "^8.8.2", @@ -26824,12 +27314,14 @@ "node_modules/terser/node_modules/commander": { "version": "2.20.3", "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", - "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==" + "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==", + "dev": true }, "node_modules/terser/node_modules/source-map": { "version": "0.6.1", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true, "engines": { "node": ">=0.10.0" } @@ -26838,6 +27330,7 @@ "version": "0.5.21", "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.21.tgz", "integrity": "sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==", + "dev": true, "dependencies": { "buffer-from": "^1.0.0", "source-map": "^0.6.0" @@ -26912,7 +27405,8 @@ "node_modules/text-table": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", - "integrity": "sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==" + "integrity": "sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==", + "dev": true }, "node_modules/throttleit": { "version": "1.0.1", @@ -27015,7 +27509,7 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz", "integrity": "sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog==", - "devOptional": true, + "dev": true, "engines": { "node": ">=4" } @@ -27024,6 +27518,7 @@ "version": "5.0.1", "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", + "dev": true, "dependencies": { "is-number": "^7.0.0" }, @@ -27088,6 +27583,7 @@ "version": "1.3.0", "resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-1.3.0.tgz", "integrity": "sha512-UQMIo7pb8WRomKR1/+MFVLTroIvDVtMX3K6OUir8ynLyzB8Jeriont2bTAtmNPa1ekAgN7YPDyf6V+ygrdU+eQ==", + "dev": true, "engines": { "node": ">=16" }, @@ -27260,7 +27756,7 @@ "version": "10.9.2", "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-10.9.2.tgz", "integrity": "sha512-f0FFpIdcHgn8zcPSbf1dRevwt047YMnaiJM3u2w2RewrB+fob/zePZcrOyQoLMMO7aBIddLcQIEK5dYjkLnGrQ==", - "devOptional": true, + "dev": true, "dependencies": { "@cspotcode/source-map-support": "^0.8.0", "@tsconfig/node10": "^1.0.7", @@ -27448,6 +27944,7 @@ "version": "0.4.0", "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==", + "dev": true, "dependencies": { "prelude-ls": "^1.2.1" }, @@ -27491,6 +27988,7 @@ "version": "1.0.2", "resolved": "https://registry.npmjs.org/typed-array-buffer/-/typed-array-buffer-1.0.2.tgz", "integrity": "sha512-gEymJYKZtKXzzBzM4jqa9w6Q1Jjm7x2d+sh19AdsD4wqnMPDYyvwpsIc2Q/835kHuo3BEQ7CjelGhfTsoBb2MQ==", + "dev": true, "dependencies": { "call-bind": "^1.0.7", "es-errors": "^1.3.0", @@ -27504,6 +28002,7 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/typed-array-byte-length/-/typed-array-byte-length-1.0.1.tgz", "integrity": "sha512-3iMJ9q0ao7WE9tWcaYKIptkNBuOIcZCCT0d4MRvuuH88fEoEH62IuQe0OtraD3ebQEoTRk8XCBoknUNc1Y67pw==", + "dev": true, "dependencies": { "call-bind": "^1.0.7", "for-each": "^0.3.3", @@ -27522,6 +28021,7 @@ "version": "1.0.2", "resolved": "https://registry.npmjs.org/typed-array-byte-offset/-/typed-array-byte-offset-1.0.2.tgz", "integrity": "sha512-Ous0vodHa56FviZucS2E63zkgtgrACj7omjwd/8lTEMEPFFyjfixMZ1ZXenpgCFBBt4EC1J2XsyVS2gkG0eTFA==", + "dev": true, "dependencies": { "available-typed-arrays": "^1.0.7", "call-bind": "^1.0.7", @@ -27541,6 +28041,7 @@ "version": "1.0.6", "resolved": "https://registry.npmjs.org/typed-array-length/-/typed-array-length-1.0.6.tgz", "integrity": "sha512-/OxDN6OtAk5KBpGb28T+HZc2M+ADtvRxXrKKbUwtsLgdoxgX13hyy7ek6bFRl5+aBs2yZzB0c4CnQfAtVypW/g==", + "dev": true, "dependencies": { "call-bind": "^1.0.7", "for-each": "^0.3.3", @@ -27612,6 +28113,7 @@ "version": "1.0.2", "resolved": "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.0.2.tgz", "integrity": "sha512-61pPlCD9h51VoreyJ0BReideM3MDKMKnh6+V9L08331ipq6Q8OFXZYiqP6n/tbHx4s5I9uRhcye6BrbkizkBDw==", + "dev": true, "dependencies": { "call-bind": "^1.0.2", "has-bigints": "^1.0.2", @@ -27801,6 +28303,7 @@ "version": "1.1.0", "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.1.0.tgz", "integrity": "sha512-EdRAaAyk2cUE1wOf2DkEhzxqOQvFOoRJFNS6NeyJ01Gp2beMRpBAINjM2iDXE3KCuKhwnvHIQCJm6ThL2Z+HzQ==", + "dev": true, "funding": [ { "type": "opencollective", @@ -27836,6 +28339,7 @@ "version": "4.4.1", "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", + "dev": true, "dependencies": { "punycode": "^2.1.0" } @@ -27881,7 +28385,7 @@ "version": "3.0.1", "resolved": "https://registry.npmjs.org/v8-compile-cache-lib/-/v8-compile-cache-lib-3.0.1.tgz", "integrity": "sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg==", - "devOptional": true + "dev": true }, "node_modules/v8-to-istanbul": { "version": "9.3.0", @@ -29092,6 +29596,7 @@ "version": "1.0.2", "resolved": "https://registry.npmjs.org/which-boxed-primitive/-/which-boxed-primitive-1.0.2.tgz", "integrity": "sha512-bwZdv0AKLpplFY2KZRX6TvyuN7ojjr7lwkg6ml0roIy9YeuSr7JS372qlNW18UQYzgYK9ziGcerWqZOmEn9VNg==", + "dev": true, "dependencies": { "is-bigint": "^1.0.1", "is-boolean-object": "^1.1.0", @@ -29112,6 +29617,7 @@ "version": "1.1.15", "resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.15.tgz", "integrity": "sha512-oV0jmFtUky6CXfkqehVvBP/LSWJ2sy4vWMioiENyJLePrBO/yKyV9OyJySfAKosh+RYkIl5zJCNZ8/4JncrpdA==", + "dev": true, "dependencies": { "available-typed-arrays": "^1.0.7", "call-bind": "^1.0.7", @@ -29146,6 +29652,7 @@ "version": "1.2.5", "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.5.tgz", "integrity": "sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==", + "dev": true, "engines": { "node": ">=0.10.0" } @@ -30172,12 +30679,13 @@ "version": "3.1.1", "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==", - "devOptional": true + "dev": true }, "node_modules/yaml": { "version": "1.10.2", "resolved": "https://registry.npmjs.org/yaml/-/yaml-1.10.2.tgz", "integrity": "sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg==", + "dev": true, "engines": { "node": ">= 6" } @@ -30221,7 +30729,7 @@ "version": "3.1.1", "resolved": "https://registry.npmjs.org/yn/-/yn-3.1.1.tgz", "integrity": "sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==", - "devOptional": true, + "dev": true, "engines": { "node": ">=6" } diff --git a/package.json b/package.json index 6512b305..2dcc7b76 100644 --- a/package.json +++ b/package.json @@ -48,6 +48,8 @@ "@types/node": "20.12.11", "@types/node-os-utils": "^1.3.4", "@types/pbf": "^3.0.5", + "@types/react": "^18.3.3", + "@types/react-redux": "^7.1.33", "@types/validator": "^13.11.9", "@types/xmldom": "^0.1.34", "@typescript-eslint/eslint-plugin": "^7.3.0", @@ -112,7 +114,6 @@ "@tmcw/togeojson": "^5.8.1", "@types/mapbox__sphericalmercator": "^1.2.3", "@vivaxy/png": "^1.3.0", - "@xmldom/xmldom": "^0.8.10", "axios": "1.7.2", "commander": "^12.1.0", From 5e5f987690d920eead3b34ddcfbf872c643f9f88 Mon Sep 17 00:00:00 2001 From: Victor Berchet Date: Sat, 13 Jul 2024 14:10:18 +0200 Subject: [PATCH 04/16] Add a link to the plugin menu --- libs/windy-sounding/CHANGELOG.md | 1 + libs/windy-sounding/src/containers/containers.tsx | 15 +++++++++++---- libs/windy-sounding/src/styles.less | 4 ++++ 3 files changed, 16 insertions(+), 4 deletions(-) diff --git a/libs/windy-sounding/CHANGELOG.md b/libs/windy-sounding/CHANGELOG.md index eb8c63fb..dd6f5012 100644 --- a/libs/windy-sounding/CHANGELOG.md +++ b/libs/windy-sounding/CHANGELOG.md @@ -3,6 +3,7 @@ ## 4.0.0-alpha.3 - Split the state into multiple slices +- Check for update ## 4.0.0-alpha.2 - July 10, 2024 diff --git a/libs/windy-sounding/src/containers/containers.tsx b/libs/windy-sounding/src/containers/containers.tsx index 9c502296..29822dd1 100644 --- a/libs/windy-sounding/src/containers/containers.tsx +++ b/libs/windy-sounding/src/containers/containers.tsx @@ -123,9 +123,10 @@ export function Plugin() { errorMessage = ( <>

Update to v{availableVersion} required.

-

- You first need to uninstall the current version and then install v{availableVersion} from the plugin menu. -

+

Uninstall the current version first to install v{availableVersion}

+
+ Update +
); break; @@ -174,7 +175,9 @@ export function Plugin() {
{updateAvailable && (
-

Plugin update v{availableVersion} available!

+

+ New plugin version {availableVersion} available! +

)} {showDetails &&
} @@ -525,3 +528,7 @@ function openMenu(e: KeyboardEvent | MouseEvent) { W.broadcast.emit('rqstOpen', 'menu'); } } + +function openPluginMenu() { + W.broadcast.emit('rqstOpen', 'external-plugins'); +} diff --git a/libs/windy-sounding/src/styles.less b/libs/windy-sounding/src/styles.less index 08b746cb..54de3186 100644 --- a/libs/windy-sounding/src/styles.less +++ b/libs/windy-sounding/src/styles.less @@ -106,6 +106,10 @@ padding: 0; } + a { + font-weight: bold; + } + #device-desktop & { display: grid; justify-items: stretch; From 088f2ac7230872e2b257d5ff77095e95b93e6c3e Mon Sep 17 00:00:00 2001 From: Victor Berchet Date: Sat, 13 Jul 2024 14:25:44 +0200 Subject: [PATCH 05/16] Do not fetch data before the plugin has booted --- libs/windy-sounding/.eslintrc.json | 2 +- .../src/containers/containers.tsx | 7 ++++--- .../src/redux/forecast-slice.ts | 13 +++++++----- libs/windy-sounding/src/redux/meta.ts | 7 ++----- libs/windy-sounding/src/redux/plugin-slice.ts | 20 ++++++------------- libs/windy-sounding/src/sounding.tsx | 10 +++++----- libs/windy-sounding/src/styles.less | 2 +- 7 files changed, 27 insertions(+), 34 deletions(-) diff --git a/libs/windy-sounding/.eslintrc.json b/libs/windy-sounding/.eslintrc.json index ad0f664a..32968025 100644 --- a/libs/windy-sounding/.eslintrc.json +++ b/libs/windy-sounding/.eslintrc.json @@ -1,6 +1,6 @@ { "extends": ["../../.eslintrc.json"], - "ignorePatterns": ["!**/*", "**/node_modules/*", "generate-manifest.js", "**/vite.config.ts"], + "ignorePatterns": ["!**/*", "/node_modules", "/generate-manifest.js", "/vite.config.ts", "/types"], "overrides": [ { "files": ["*.ts", "*.tsx", "*.js", "*.jsx"], diff --git a/libs/windy-sounding/src/containers/containers.tsx b/libs/windy-sounding/src/containers/containers.tsx index 29822dd1..79fb5c31 100644 --- a/libs/windy-sounding/src/containers/containers.tsx +++ b/libs/windy-sounding/src/containers/containers.tsx @@ -1,7 +1,7 @@ import type { LatLon } from '@windy/interfaces'; import { intlFormatDistance } from 'date-fns/intlFormatDistance'; import { useCallback, useState } from 'preact/hooks'; -import { useDispatch, useSelector, shallowEqual } from 'react-redux'; +import { shallowEqual, useDispatch, useSelector } from 'react-redux'; import { Favorites } from '../components/favorites.js'; import { LoadingIndicator } from '../components/loading.js'; @@ -11,7 +11,8 @@ import { WindProfile } from '../components/wind-profile.jsx'; import { pluginConfig } from '../config'; import flyxcIcon from '../img/jumoplane.svg'; import * as forecastSlice from '../redux/forecast-slice'; -import { centerMap, changeLocation, TimeStep, updateTime } from '../redux/meta'; +import type { TimeStep } from '../redux/meta'; +import { centerMap, changeLocation, updateTime } from '../redux/meta'; import * as pluginSlice from '../redux/plugin-slice'; import { type AppDispatch, type RootState } from '../redux/store'; import * as unitsSlice from '../redux/units-slice'; @@ -61,7 +62,7 @@ export function Plugin() { const dispatch: AppDispatch = useDispatch(); const selectFavorite = useCallback((location: LatLon) => { - dispatch(changeLocation(location, true)); + dispatch(changeLocation(location)); centerMap(location); }, []); diff --git a/libs/windy-sounding/src/redux/forecast-slice.ts b/libs/windy-sounding/src/redux/forecast-slice.ts index fbc83583..c674279e 100644 --- a/libs/windy-sounding/src/redux/forecast-slice.ts +++ b/libs/windy-sounding/src/redux/forecast-slice.ts @@ -13,9 +13,9 @@ import { type PeriodCloud, } from '../util/clouds'; import { sampleAt, type Scale, scaleLog } from '../util/math'; +import * as pluginSlice from './plugin-slice'; import type { AppThunkAPI, RootState } from './store'; -const windyStore = W.store; const windyUtils = W.utils; const windyFetch = W.fetch; const windySubscription = W.subscription; @@ -321,7 +321,7 @@ class OutOfBoundsError extends Error { export const fetchForecast = createAsyncThunk( 'forecast/fetch', - async (modelAndLocation: ModelAndLocation, api: { getState: () => RootState }) => { + async (modelAndLocation: ModelAndLocation) => { const { modelName, location } = modelAndLocation; const [meteogram, forecast] = await Promise.allSettled([ @@ -369,10 +369,13 @@ export const fetchForecast = createAsyncThunk { // Prevent fetching again while loading. const { modelName, location } = modelAndLocation; - const windyData = slice.selectors.selWindyDataUnsafe(api.getState(), modelName, location); + const state = api.getState(); + const pluginStatus = pluginSlice.slice.selectors.selStatus(state); + const windyData = slice.selectors.selWindyDataUnsafe(state, modelName, location); return ( - windyData === undefined || - !(windyData.fetchStatus == FetchStatus.Loading || windyData.fetchStatus === FetchStatus.ErrorOutOfBounds) + pluginStatus === pluginSlice.PluginStatus.Ready && + (windyData === undefined || + !(windyData.fetchStatus == FetchStatus.Loading || windyData.fetchStatus === FetchStatus.ErrorOutOfBounds)) ); }, }, diff --git a/libs/windy-sounding/src/redux/meta.ts b/libs/windy-sounding/src/redux/meta.ts index efe132d6..ccfa15a4 100644 --- a/libs/windy-sounding/src/redux/meta.ts +++ b/libs/windy-sounding/src/redux/meta.ts @@ -61,14 +61,11 @@ export const updateTime = * - Fetch the forecast */ export const changeLocation = - (location: LatLon, fetchData: boolean): ThunkAction => + (location: LatLon): ThunkAction => (dispatch, getState) => { const modelName = pluginSlice.slice.selectors.selModelName(getState()); dispatch(pluginSlice.setLocation(location)); - - if (fetchData) { - dispatch(forecastSlice.fetchForecast({ modelName, location })); - } + dispatch(forecastSlice.fetchForecast({ modelName, location })); maybeCreateAndMoveMarker(location); diff --git a/libs/windy-sounding/src/redux/plugin-slice.ts b/libs/windy-sounding/src/redux/plugin-slice.ts index e5bb0cd4..f60ea53a 100644 --- a/libs/windy-sounding/src/redux/plugin-slice.ts +++ b/libs/windy-sounding/src/redux/plugin-slice.ts @@ -1,12 +1,12 @@ import { createAsyncThunk, createSlice } from '@reduxjs/toolkit'; +import type { HttpPayload } from '@windy/http'; import type { CompiledExternalPluginConfig, Fav, LatLon } from '@windy/interfaces'; +import { SemVer } from 'semver'; -import { getFavLabel } from '../util/utils'; -import type { RootState } from './store'; -import type { HttpPayload } from '@windy/http'; import type { PluginConfig } from '../types'; -import { SemVer } from 'semver'; +import { getFavLabel } from '../util/utils'; import { changeLocation } from './meta'; +import type { RootState } from './store'; const windyStore = W.store; @@ -93,15 +93,6 @@ export const slice = createSlice({ state.availableVersion = action.payload; }, }, - extraReducers: (builder) => { - builder.addCase(fetchPluginConfig.fulfilled, (state, action) => { - state.status = PluginStatus.Ready; - }); - - builder.addCase(fetchPluginConfig.pending, (state, action) => { - state.status = PluginStatus.Booting; - }); - }, selectors: { // Values selWidth: (state): number => state.width, @@ -135,7 +126,8 @@ export const fetchPluginConfig = createAsyncThunk { addSubscription(() => windyStore.off(productChangedEventId)); const singleClickIdEventId = singleclick.on(pluginConfig.name, (location: LatLon) => { - dispatch(changeLocation(location, true)); + dispatch(changeLocation(location)); }); addSubscription(() => singleclick.off(singleClickIdEventId)); // Use the picker events on desktop. if (!windyRootScope.isMobileOrTablet) { const pickerOpenedEventId = windyPicker.on('pickerOpened', (location: LatLon) => { - dispatch(changeLocation(location, true)); + dispatch(changeLocation(location)); }); addSubscription(() => windyPicker.off(pickerOpenedEventId)); const pickerMovedEventId = windyPicker.on('pickerMoved', (location: LatLon) => { - dispatch(changeLocation(location, true)); + dispatch(changeLocation(location)); }); addSubscription(() => windyPicker.off(pickerMovedEventId)); } @@ -126,7 +126,7 @@ export const openPlugin = ({ lat, lon, modelName }: { lat: number; lon: number; dispatch(pluginSlice.setFavorites(favs.getArray())); dispatch(pluginSlice.setModelName(modelName)); dispatch(pluginSlice.setTimeMs(windyStore.get('timestamp'))); - dispatch(changeLocation(location, false)); + dispatch(changeLocation(location)); setSizeFrom(appContainer); if (pluginSlice.slice.selectors.selStatus(store.getState()) === pluginSlice.PluginStatus.Idle) { diff --git a/libs/windy-sounding/src/styles.less b/libs/windy-sounding/src/styles.less index 54de3186..ac9ef0f2 100644 --- a/libs/windy-sounding/src/styles.less +++ b/libs/windy-sounding/src/styles.less @@ -9,7 +9,7 @@ #wsp-update { background-color: var(--color-warning-moderate); color: var(--color-black); - text-align:center; + text-align: center; } // flyXC icon on desktop. From 7586c10fbe391af10f83754c08b57980a04054d9 Mon Sep 17 00:00:00 2001 From: Victor Berchet Date: Sat, 13 Jul 2024 14:33:20 +0200 Subject: [PATCH 06/16] Fix a bug when surface is below minPressure --- libs/windy-sounding/src/components/skewt.tsx | 8 ++++---- libs/windy-sounding/src/components/wind-profile.tsx | 7 ++++--- 2 files changed, 8 insertions(+), 7 deletions(-) diff --git a/libs/windy-sounding/src/components/skewt.tsx b/libs/windy-sounding/src/components/skewt.tsx index 66568f6e..b3a8c6b1 100644 --- a/libs/windy-sounding/src/components/skewt.tsx +++ b/libs/windy-sounding/src/components/skewt.tsx @@ -76,7 +76,7 @@ export function SkewT(props: SkewTProps) { (point: [x: number, y: number]): number => pressureToPxScale(point[1]), ); - const surfacePx = Math.round(ghMeterToPxScale(surfaceElevation)); + const ySurface = Math.min(height, Math.round(ghMeterToPxScale(surfaceElevation))); let tempAtCursor = 0; let dewPointAtCursor = 0; @@ -129,7 +129,7 @@ export function SkewT(props: SkewTProps) { tempToPxScale, unit: tempUnit, skew, - surfacePx, + surfacePx: ySurface, format: formatTemp, }} /> @@ -160,8 +160,8 @@ export function SkewT(props: SkewTProps) { - - {yPointer !== undefined && yPointer < surfacePx && ( + + {yPointer !== undefined && yPointer < ySurface && ( {formatAltitude(ghMeterToPxScale.invert(yPointer))} diff --git a/libs/windy-sounding/src/components/wind-profile.tsx b/libs/windy-sounding/src/components/wind-profile.tsx index 8415ecb4..bfe4420f 100644 --- a/libs/windy-sounding/src/components/wind-profile.tsx +++ b/libs/windy-sounding/src/components/wind-profile.tsx @@ -56,7 +56,8 @@ export function WindProfile(props: WindProfileProps) { (v: [x: number, y: number]) => pressureToPxScale(v[1]), ); - const surfacePx = Math.round(ghToPxScale(surfaceElevation)); + const ySurface = Math.min(height, Math.round(ghToPxScale(surfaceElevation))); + const surfacePressure = pressureToGhScale.invert(surfaceElevation); let yOffsetCursor = 4; @@ -83,8 +84,8 @@ export function WindProfile(props: WindProfileProps) { return ; })} - - {yPointer !== undefined && yPointer < surfacePx && ( + + {yPointer !== undefined && yPointer < ySurface && ( {format(windAtCursor)} From 6d36d5b3b2bcff6319ccd35b38bad0dd42a47210 Mon Sep 17 00:00:00 2001 From: Victor Berchet Date: Sat, 13 Jul 2024 14:42:13 +0200 Subject: [PATCH 07/16] Add support for the former URL scheme --- libs/windy-sounding/src/Plugin.svelte | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/libs/windy-sounding/src/Plugin.svelte b/libs/windy-sounding/src/Plugin.svelte index de63c53f..0d916713 100644 --- a/libs/windy-sounding/src/Plugin.svelte +++ b/libs/windy-sounding/src/Plugin.svelte @@ -5,9 +5,19 @@ let pluginElement: HTMLElement; export const onopen = (parameters: any) => { + // Legacys URL do not have the model. + // old format /:lat/:lon + // new format /:model/:lat/:lon + const isNumeric = (value: string) => value as any == parseFloat(value); + if (isNumeric(parameters?.modelName) && isNumeric(parameters?.lat)) { + parameters.lon = parameters.lat; + parameters.lat = parameters.model; + parameters.model = 'ecmwf'; + } + const mapCenter = W.map.map.getCenter(); const lat = Number(parameters?.lat ?? mapCenter.lat); - const lon = Number(parameters?.long ?? mapCenter.lng); + const lon = Number(parameters?.lon ?? mapCenter.lng); const modelName = parameters?.modelName ?? 'ecmwf'; openPlugin({ lat, lon, modelName }); }; From 622f9edb58ff9be1684675537409f35349d1a0b1 Mon Sep 17 00:00:00 2001 From: Victor Berchet Date: Sat, 13 Jul 2024 14:50:43 +0200 Subject: [PATCH 08/16] Update mobile style --- libs/windy-sounding/src/sounding.tsx | 2 +- libs/windy-sounding/src/styles.less | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/libs/windy-sounding/src/sounding.tsx b/libs/windy-sounding/src/sounding.tsx index 0a28e230..dff04d0e 100644 --- a/libs/windy-sounding/src/sounding.tsx +++ b/libs/windy-sounding/src/sounding.tsx @@ -52,7 +52,7 @@ export const mountPlugin = (container: HTMLElement) => { // Make minHorizontal big enough to avoid false positives. SwipeListener(appContainer, { minHorizontal: appContainer.offsetWidth / 6, mouse: false }); appContainer.addEventListener( - 'swipe', + 'swipe' as any, (e: CustomEvent) => { const { right, left } = e.detail.directions; const direction = left ? 'backward' : right ? 'forward' : undefined; diff --git a/libs/windy-sounding/src/styles.less b/libs/windy-sounding/src/styles.less index ac9ef0f2..7f193624 100644 --- a/libs/windy-sounding/src/styles.less +++ b/libs/windy-sounding/src/styles.less @@ -403,20 +403,20 @@ text-align: center; white-space: nowrap; - &:before { + &:before, &:after { display: inline-block; position: relative; top: -2px; } &:after { - display: inline-block; transform-origin: center center; transition: transform 0.3s; + transform: rotate(-90deg); } &.active::after { - transform: rotate(180deg); + transform: rotate(0); } small { From 0d3546ecda2db66e767bf4986b244d7b2ea1dad3 Mon Sep 17 00:00:00 2001 From: Victor Berchet Date: Sat, 13 Jul 2024 15:10:23 +0200 Subject: [PATCH 09/16] Fix crash on resize on mobile --- .../src/containers/containers.tsx | 42 +++++++++++-------- 1 file changed, 24 insertions(+), 18 deletions(-) diff --git a/libs/windy-sounding/src/containers/containers.tsx b/libs/windy-sounding/src/containers/containers.tsx index 79fb5c31..f4107839 100644 --- a/libs/windy-sounding/src/containers/containers.tsx +++ b/libs/windy-sounding/src/containers/containers.tsx @@ -66,25 +66,31 @@ export function Plugin() { centerMap(location); }, []); - const startResize = useCallback((e: PointerEvent) => { - isDragging = true; - yOnStartDrag = e.screenY; - heightOnStartDrag = height; - e.preventDefault(); - e.stopImmediatePropagation(); - }, []); + const startResize = useCallback( + (e: PointerEvent) => { + isDragging = true; + yOnStartDrag = e.screenY; + heightOnStartDrag = height; + e.preventDefault(); + e.stopImmediatePropagation(); + }, + [height], + ); - const resize = useCallback((e: PointerEvent) => { - if (isDragging) { - const height = Math.min( - Math.max(heightOnStartDrag + yOnStartDrag - e.screenY, startHeight / 3), - startHeight * 1.2, - ); - setMobileHeight(Math.round(height)); - } - e.preventDefault(); - e.stopImmediatePropagation(); - }, []); + const resize = useCallback( + (e: PointerEvent) => { + if (isDragging) { + const height = Math.min( + Math.max(heightOnStartDrag + yOnStartDrag - e.screenY, startHeight / 3), + startHeight * 1.2, + ); + setMobileHeight(Math.round(height)); + } + e.preventDefault(); + e.stopImmediatePropagation(); + }, + [startHeight], + ); const endResize = useCallback((e: PointerEvent) => { isDragging = false; From b92bc14e123ed97fbfbcb0d87c76f4793c860f6f Mon Sep 17 00:00:00 2001 From: Victor Berchet Date: Sat, 13 Jul 2024 16:07:04 +0200 Subject: [PATCH 10/16] Fix the display of a transient error --- .../windy-sounding/src/components/loading.tsx | 9 ++++--- .../src/containers/containers.tsx | 25 +++++------------- .../src/redux/forecast-slice.ts | 26 ++++++++++++------- libs/windy-sounding/src/redux/meta.ts | 4 +-- 4 files changed, 31 insertions(+), 33 deletions(-) diff --git a/libs/windy-sounding/src/components/loading.tsx b/libs/windy-sounding/src/components/loading.tsx index 2b8acb22..4714bada 100644 --- a/libs/windy-sounding/src/components/loading.tsx +++ b/libs/windy-sounding/src/components/loading.tsx @@ -1,8 +1,9 @@ -export function LoadingIndicator({ x, y }: { x: number; y: number }) { +export function LoadingIndicator({ width, height }: { width: number; height: number }) { return ( - - - + + + + )} {showDetails &&
} - {errorMessage ? ( + {errorMessage && !isLoading ? ( ) : ( @@ -217,8 +217,8 @@ export function Plugin() { - {showLoading ? ( - + {isLoading ? ( + ) : ( <> @@ -240,7 +240,9 @@ export function Plugin() { )}
-
{showDetails && }
+
+ +

Please consider sponsoring the development of this plugin

@@ -334,19 +336,6 @@ type ChildGraphProps = { }; function ConnectedSkewT(props: ChildGraphProps) { - const fetchStatus = useSelector((state: RootState) => { - const pluginSel = pluginSlice.slice.selectors; - const forecastSel = forecastSlice.slice.selectors; - - const modelName = pluginSel.selModelName(state); - const location = pluginSel.selLocation(state); - return forecastSel.selFetchStatus(state, modelName, location); - }); - - if (fetchStatus !== forecastSlice.FetchStatus.Loaded) { - return; - } - const stateProps: Omit = useSelector((state: RootState) => { const pluginSel = pluginSlice.slice.selectors; const unitsSel = unitsSlice.slice.selectors; diff --git a/libs/windy-sounding/src/redux/forecast-slice.ts b/libs/windy-sounding/src/redux/forecast-slice.ts index c674279e..afc5e900 100644 --- a/libs/windy-sounding/src/redux/forecast-slice.ts +++ b/libs/windy-sounding/src/redux/forecast-slice.ts @@ -124,16 +124,24 @@ export const slice = createSlice({ }); }, selectors: { - selWindyDataUnsafe: (state: ForecastState, modelName: string, location: LatLon): Forecast | undefined => { + /** + * Note: returned data could be loading, loaded, errored. + * + * @returns windy data or undefined. + */ + selMaybeWindyData: (state: ForecastState, modelName: string, location: LatLon): Forecast | undefined => { + return state.data[windyDataKey(modelName, location)]; + }, + selMaybeLoadedWindyData: (state: ForecastState, modelName: string, location: LatLon): Forecast | undefined => { const key = windyDataKey(modelName, location); - return isDataCached(state, key) ? (state.data[key] as Forecast & { fetchStatus: FetchStatus.Loaded }) : undefined; + return isDataCached(state, key) ? state.data[key] : undefined; }, selIsWindyDataAvailable: (state: ForecastState, modelName: string, location: LatLon): boolean => { - const windyData = slice.getSelectors().selWindyDataUnsafe(state, modelName, location); - return windyData?.fetchStatus === FetchStatus.Loaded; + const windyData = slice.getSelectors().selMaybeLoadedWindyData(state, modelName, location); + return windyData !== undefined; }, selFetchStatus: (state: ForecastState, modelName: string, location: LatLon): FetchStatus => { - const windyData = slice.getSelectors().selWindyDataUnsafe(state, modelName, location); + const windyData = slice.getSelectors().selMaybeWindyData(state, modelName, location); return windyData === undefined ? FetchStatus.Error : windyData.fetchStatus; }, selModelUpdateTimeMs(state: ForecastState, modelName: string, location: LatLon): number { @@ -305,7 +313,7 @@ function getWindyDataOrThrow( modelName: string, location: LatLon, ): Forecast & { fetchStatus: FetchStatus.Loaded } { - const windyData = slice.getSelectors().selWindyDataUnsafe(state, modelName, location); + const windyData = slice.getSelectors().selMaybeLoadedWindyData(state, modelName, location); if (windyData === undefined || windyData.fetchStatus !== FetchStatus.Loaded) { throw new Error('Data not loaded'); } @@ -323,7 +331,7 @@ export const fetchForecast = createAsyncThunk { const { modelName, location } = modelAndLocation; - + const forecastKey = windyDataKey(modelName, location); const [meteogram, forecast] = await Promise.allSettled([ // extended is required to get full length forecast for pro windy users windyFetch.getMeteogramForecastData(modelName, { ...location, step: 1 }, { extended: 'true' }), @@ -354,7 +362,7 @@ export const fetchForecast = createAsyncThunk => (dispatch, getState) => { const modelName = pluginSlice.slice.selectors.selModelName(getState()); - dispatch(pluginSlice.setLocation(location)); dispatch(forecastSlice.fetchForecast({ modelName, location })); + dispatch(pluginSlice.setLocation(location)); maybeCreateAndMoveMarker(location); @@ -76,8 +76,8 @@ export const changeModel = (modelName: string): ThunkAction => (dispatch, getState) => { const location = pluginSlice.slice.selectors.selLocation(getState()); - dispatch(pluginSlice.setModelName(modelName)); dispatch(forecastSlice.fetchForecast({ modelName, location })); + dispatch(pluginSlice.setModelName(modelName)); updateUrl(getState()); }; From ad60b9df02aa076bcfb1fe96de7494d93e081498 Mon Sep 17 00:00:00 2001 From: Victor Berchet Date: Sat, 13 Jul 2024 16:44:32 +0200 Subject: [PATCH 11/16] Memoize units selectors --- .../src/containers/containers.tsx | 20 +++---- libs/windy-sounding/src/redux/units-slice.ts | 56 +++++++++---------- 2 files changed, 36 insertions(+), 40 deletions(-) diff --git a/libs/windy-sounding/src/containers/containers.tsx b/libs/windy-sounding/src/containers/containers.tsx index a7e05f59..d40cba36 100644 --- a/libs/windy-sounding/src/containers/containers.tsx +++ b/libs/windy-sounding/src/containers/containers.tsx @@ -108,7 +108,7 @@ export function Plugin() { size, }; dispatch(updateTime(step)); - ignoreWheelEventUntilMs = Date.now() + (size === 'day' ? 800 : 20); + ignoreWheelEventUntilMs = Date.now() + (size === 'day' ? 500 : 10); } e.stopImmediatePropagation(); e.preventDefault(); @@ -338,7 +338,6 @@ type ChildGraphProps = { function ConnectedSkewT(props: ChildGraphProps) { const stateProps: Omit = useSelector((state: RootState) => { const pluginSel = pluginSlice.slice.selectors; - const unitsSel = unitsSlice.slice.selectors; const forecastSel = forecastSlice.slice.selectors; const modelName = pluginSel.selModelName(state); @@ -352,7 +351,7 @@ function ConnectedSkewT(props: ChildGraphProps) { const periodMaxTemp = forecastSel.selMaxPeriodTemp(state, modelName, location); const maxTemp = periodMaxTemp + 8; const minTemp = periodMaxTemp - 60; - const formatTemp = unitsSel.selTempFormatter(state); + const formatTemp = unitsSlice.selTempFormatter(state); return { levels: periodValues.levels, @@ -366,12 +365,12 @@ function ConnectedSkewT(props: ChildGraphProps) { parcel: forecastSel.selDisplayParcel(state, modelName, location, timeMs) ? forecastSel.selParcel(state, modelName, location, timeMs) : undefined, - formatAltitude: unitsSel.selAltitudeFormatter(state), + formatAltitude: unitsSlice.selAltitudeFormatter(state), formatTemp, - tempUnit: unitsSel.selTempUnit(state), - tempAxisStep: unitsSel.selTempUnit(state) === '°C' ? 10 : 20, - ghUnit: unitsSel.selAltitudeUnit(state), - ghAxisStep: unitsSel.selAltitudeUnit(state) === 'm' ? 1000 : 3000, + tempUnit: unitsSlice.selTempUnit(state), + tempAxisStep: unitsSlice.selTempUnit(state) === '°C' ? 10 : 20, + ghUnit: unitsSlice.selAltitudeUnit(state), + ghAxisStep: unitsSlice.selAltitudeUnit(state) === 'm' ? 1000 : 3000, showUpperClouds: isZoomedIn, cloudCover: forecastSel.selGetCloudCoverGenerator(state, modelName, location, timeMs), }; @@ -398,7 +397,6 @@ function ConnectedWind(props: ChildGraphProps) { const stateProps = useSelector((state: RootState) => { const pluginSel = pluginSlice.slice.selectors; - const unitsSel = unitsSlice.slice.selectors; const forecastSel = forecastSlice.slice.selectors; const modelName = pluginSel.selModelName(state); @@ -417,8 +415,8 @@ function ConnectedWind(props: ChildGraphProps) { levels: periodValues.levels, ghs: timeValues.gh, windByLevel: forecastSel.selWindDetailsByLevel(state, modelName, location, timeMs), - format: unitsSel.selWindSpeedFormatter(state), - unit: unitsSel.selWindSpeedUnit(state), + format: unitsSlice.selWindSpeedFormatter(state), + unit: unitsSlice.selWindSpeedUnit(state), surfaceElevation: forecastSel.selElevation(state, modelName, location), isFixedRange: pluginSel.selIsZoomedIn(state), }; diff --git a/libs/windy-sounding/src/redux/units-slice.ts b/libs/windy-sounding/src/redux/units-slice.ts index db9ad69a..109ba553 100644 --- a/libs/windy-sounding/src/redux/units-slice.ts +++ b/libs/windy-sounding/src/redux/units-slice.ts @@ -1,4 +1,4 @@ -import { createSlice } from '@reduxjs/toolkit'; +import { createSlice, createSelector } from '@reduxjs/toolkit'; import type { RootState } from './store'; @@ -28,36 +28,34 @@ export const slice = createSlice({ name: 'units', initialState, reducers: {}, - selectors: { - // Values - selTempUnit: (state): TempUnit => state.tempUnit, - selAltitudeUnit: (state): AltitudeUnit => state.altitudeUnit, - selWindSpeedUnit: (state): SpeedUnit => state.windSpeedUnit, - selPressureUnit: (state): PressureUnit => state.pressureUnit, - // Formatters - selTempFormatter: - (state): ((temp: number) => number) => - (temp: number) => - Math.round(windyMetrics.temp.conv[slice.getSelectors().selTempUnit(state)].conversion(temp)), - selAltitudeFormatter: - (state): ((altitude: number) => number) => - (altitude: number) => - Math.round( - windyMetrics.altitude.conv[slice.getSelectors().selAltitudeUnit(state)].conversion( - Math.round(altitude / 100) * 100, - ), - ), - selPressureFormatter: - (state): ((pressure: number) => number) => - (pressure: number) => - Math.round(windyMetrics.pressure.conv[slice.getSelectors().selPressureUnit(state)].conversion(pressure)), - selWindSpeedFormatter: - (state): ((windSpeed: number) => number) => - (windSpeed: number) => - Math.round(windyMetrics.wind.conv[slice.getSelectors().selWindSpeedUnit(state)].conversion(windSpeed)), - }, }); +export const selTempUnit = (state: RootState): TempUnit => state[slice.name].tempUnit; +export const selAltitudeUnit = (state: RootState): AltitudeUnit => state[slice.name].altitudeUnit; +export const selWindSpeedUnit = (state: RootState): SpeedUnit => state[slice.name].windSpeedUnit; +export const selPressureUnit = (state: RootState): PressureUnit => state[slice.name].pressureUnit; + +export const selTempFormatter = createSelector( + selTempUnit, + (unit) => (temp: number) => Math.round(windyMetrics.temp.conv[unit].conversion(temp)), +); + +export const selAltitudeFormatter = createSelector( + selAltitudeUnit, + (unit) => (altitude: number) => + Math.round(windyMetrics.altitude.conv[unit].conversion(Math.round(altitude / 100) * 100)), +); + +export const selPressureFormatter = createSelector( + selPressureUnit, + (unit) => (pressure: number) => Math.round(windyMetrics.pressure.conv[unit].conversion(pressure)), +); + +export const selWindSpeedFormatter = createSelector( + selWindSpeedUnit, + (unit) => (windSpeed: number) => Math.round(windyMetrics.wind.conv[unit].conversion(windSpeed)), +); + export const { reducer } = slice; export const selectors = slice.getSelectors((state: RootState) => state.units); From f8263caee9e8382aedaa47ed282402f487f15b40 Mon Sep 17 00:00:00 2001 From: Victor Berchet Date: Sat, 13 Jul 2024 16:52:51 +0200 Subject: [PATCH 12/16] Refactor plugin selectors --- .../src/containers/containers.tsx | 67 +++++++++---------- .../src/redux/forecast-slice.ts | 2 +- libs/windy-sounding/src/redux/meta.ts | 13 ++-- libs/windy-sounding/src/redux/plugin-slice.ts | 26 ++++--- libs/windy-sounding/src/redux/units-slice.ts | 2 +- libs/windy-sounding/src/sounding.tsx | 5 +- libs/windy-sounding/src/styles.less | 3 +- 7 files changed, 53 insertions(+), 65 deletions(-) diff --git a/libs/windy-sounding/src/containers/containers.tsx b/libs/windy-sounding/src/containers/containers.tsx index d40cba36..f4e5f4a9 100644 --- a/libs/windy-sounding/src/containers/containers.tsx +++ b/libs/windy-sounding/src/containers/containers.tsx @@ -31,22 +31,21 @@ export function Plugin() { availableVersion, isWindyDataAvailable, } = useSelector((state: RootState) => { - const pluginSel = pluginSlice.slice.selectors; const forecastSel = forecastSlice.slice.selectors; - const modelName = pluginSel.selModelName(state); - const location = pluginSel.selLocation(state); - const timeMs = pluginSel.selTimeMs(state); + const modelName = pluginSlice.selModelName(state); + const location = pluginSlice.selLocation(state); + const timeMs = pluginSlice.selTimeMs(state); const isWindyDataAvailable = forecastSel.selIsWindyDataAvailable(state, modelName, location) && forecastSel.selIsWindyDataAvailableAt(state, modelName, location, timeMs); return { - width: pluginSel.selWidth(state), - startHeight: pluginSel.selHeight(state), - status: pluginSel.selStatus(state), - updateAvailable: pluginSel.selUpdateAvailable(state), - updateRequired: pluginSel.selUpdateRequired(state), + width: pluginSlice.selWidth(state), + startHeight: pluginSlice.selHeight(state), + status: pluginSlice.selStatus(state), + updateAvailable: pluginSlice.selUpdateAvailable(state), + updateRequired: pluginSlice.selUpdateRequired(state), fetchStatus: forecastSel.selFetchStatus(state, modelName, location), - availableVersion: pluginSel.selAvailableVersion(state), + availableVersion: pluginSlice.selAvailableVersion(state), modelName, location, isWindyDataAvailable, @@ -269,13 +268,12 @@ function Graph({ width, height, skewTWidthPercent }: { width: number; height: nu const setIsZoomedIn = useCallback((expanded: boolean) => dispatch(pluginSlice.setIsZoomedIn(expanded)), []); const { minPressure, maxPressure, isZoomedIn } = useSelector((state: RootState) => { - const pluginSel = pluginSlice.slice.selectors; const forecastSel = forecastSlice.slice.selectors; - const timeMs = pluginSel.selTimeMs(state); - const isZoomedIn = pluginSel.selIsZoomedIn(state); - const modelName = pluginSel.selModelName(state); - const location = pluginSel.selLocation(state); + const timeMs = pluginSlice.selTimeMs(state); + const isZoomedIn = pluginSlice.selIsZoomedIn(state); + const modelName = pluginSlice.selModelName(state); + const location = pluginSlice.selLocation(state); const elevation = forecastSel.selElevation(state, modelName, location); const minModelPressure = forecastSel.selMinModelPressure(state, modelName, location); const pressureToGhScale = forecastSel.selPressureToGhScale(state, modelName, location, timeMs); @@ -337,16 +335,15 @@ type ChildGraphProps = { function ConnectedSkewT(props: ChildGraphProps) { const stateProps: Omit = useSelector((state: RootState) => { - const pluginSel = pluginSlice.slice.selectors; const forecastSel = forecastSlice.slice.selectors; - const modelName = pluginSel.selModelName(state); - const location = pluginSel.selLocation(state); - const timeMs = pluginSel.selTimeMs(state); + const modelName = pluginSlice.selModelName(state); + const location = pluginSlice.selLocation(state); + const timeMs = pluginSlice.selTimeMs(state); const periodValues = forecastSel.selPeriodValues(state, modelName, location); const timeValues = forecastSel.selValuesAt(state, modelName, location, timeMs); - const isZoomedIn = pluginSel.selIsZoomedIn(state); + const isZoomedIn = pluginSlice.selIsZoomedIn(state); const periodMaxTemp = forecastSel.selMaxPeriodTemp(state, modelName, location); const maxTemp = periodMaxTemp + 8; @@ -383,11 +380,10 @@ function ConnectedSkewT(props: ChildGraphProps) { function ConnectedWind(props: ChildGraphProps) { const fetchStatus = useSelector((state: RootState) => { - const pluginSel = pluginSlice.slice.selectors; const forecastSel = forecastSlice.slice.selectors; - const modelName = pluginSel.selModelName(state); - const location = pluginSel.selLocation(state); + const modelName = pluginSlice.selModelName(state); + const location = pluginSlice.selLocation(state); return forecastSel.selFetchStatus(state, modelName, location); }); @@ -396,12 +392,11 @@ function ConnectedWind(props: ChildGraphProps) { } const stateProps = useSelector((state: RootState) => { - const pluginSel = pluginSlice.slice.selectors; const forecastSel = forecastSlice.slice.selectors; - const modelName = pluginSel.selModelName(state); - const location = pluginSel.selLocation(state); - const timeMs = pluginSel.selTimeMs(state); + const modelName = pluginSlice.selModelName(state); + const location = pluginSlice.selLocation(state); + const timeMs = pluginSlice.selTimeMs(state); if (forecastSel.selFetchStatus(state, modelName, location) === forecastSlice.FetchStatus.Loading) { return { isLoading: true }; @@ -418,7 +413,7 @@ function ConnectedWind(props: ChildGraphProps) { format: unitsSlice.selWindSpeedFormatter(state), unit: unitsSlice.selWindSpeedUnit(state), surfaceElevation: forecastSel.selElevation(state, modelName, location), - isFixedRange: pluginSel.selIsZoomedIn(state), + isFixedRange: pluginSlice.selIsZoomedIn(state), }; }, shallowEqual); @@ -429,7 +424,7 @@ function ConnectedWind(props: ChildGraphProps) { function ConnectedFavorites({ onSelected }: { onSelected: (location: LatLon) => void }) { const props = useSelector((state: RootState) => { - const S = pluginSlice.slice.selectors; + const S = pluginSlice; return { favorites: S.selFavorites(state), location: S.selLocation(state), @@ -452,15 +447,14 @@ function ConnectedFavorites({ onSelected }: { onSelected: (location: LatLon) => */ function Details() { const { modelName, updateMs, nextUpdateMs, timeMs } = useSelector((state: RootState) => { - const pluginSel = pluginSlice.slice.selectors; const forecastSel = forecastSlice.slice.selectors; - const modelName = pluginSel.selModelName(state); - const location = pluginSel.selLocation(state); - const timeMs = pluginSel.selTimeMs(state); + const modelName = pluginSlice.selModelName(state); + const location = pluginSlice.selLocation(state); + const timeMs = pluginSlice.selTimeMs(state); return { - modelName: pluginSel.selModelName(state), + modelName: pluginSlice.selModelName(state), updateMs: forecastSel.selModelUpdateTimeMs(state, modelName, location), nextUpdateMs: forecastSel.selModelNextUpdateTimeMs(state, modelName, location), timeMs, @@ -492,11 +486,10 @@ export function Watermark({ x, y }: { x: number; y: number }) { const nowMs = Date.now(); const { updateMs, nextUpdateMs } = useSelector((state: RootState) => { - const pluginSel = pluginSlice.slice.selectors; const forecastSel = forecastSlice.slice.selectors; - const modelName = pluginSel.selModelName(state); - const location = pluginSel.selLocation(state); + const modelName = pluginSlice.selModelName(state); + const location = pluginSlice.selLocation(state); return { updateMs: forecastSel.selModelUpdateTimeMs(state, modelName, location), diff --git a/libs/windy-sounding/src/redux/forecast-slice.ts b/libs/windy-sounding/src/redux/forecast-slice.ts index afc5e900..5317ea7e 100644 --- a/libs/windy-sounding/src/redux/forecast-slice.ts +++ b/libs/windy-sounding/src/redux/forecast-slice.ts @@ -378,7 +378,7 @@ export const fetchForecast = createAsyncThunk => (dispatch, getState) => { - const modelName = pluginSlice.slice.selectors.selModelName(getState()); + const modelName = pluginSlice.selModelName(getState()); dispatch(forecastSlice.fetchForecast({ modelName, location })); dispatch(pluginSlice.setLocation(location)); @@ -75,15 +74,15 @@ export const changeLocation = export const changeModel = (modelName: string): ThunkAction => (dispatch, getState) => { - const location = pluginSlice.slice.selectors.selLocation(getState()); + const location = pluginSlice.selLocation(getState()); dispatch(forecastSlice.fetchForecast({ modelName, location })); dispatch(pluginSlice.setModelName(modelName)); updateUrl(getState()); }; function updateUrl(state: RootState) { - const location = pluginSlice.slice.selectors.selLocation(state); - const modelName = pluginSlice.slice.selectors.selModelName(state); + const location = pluginSlice.selLocation(state); + const modelName = pluginSlice.selModelName(state); W.location.setUrl(pluginConfig.name, { modelName, ...location }); } diff --git a/libs/windy-sounding/src/redux/plugin-slice.ts b/libs/windy-sounding/src/redux/plugin-slice.ts index f60ea53a..c70a5347 100644 --- a/libs/windy-sounding/src/redux/plugin-slice.ts +++ b/libs/windy-sounding/src/redux/plugin-slice.ts @@ -93,20 +93,6 @@ export const slice = createSlice({ state.availableVersion = action.payload; }, }, - selectors: { - // Values - selWidth: (state): number => state.width, - selHeight: (state): number => state.height, - selModelName: (state): string => state.modelName, - selTimeMs: (state): number => state.timeMs, - selIsZoomedIn: (state): boolean => state.isZoomedIn, - selLocation: (state): LatLon => state.location, - selFavorites: (state): Fav[] => state.favorites, - selStatus: (state): PluginStatus => state.status, - selUpdateAvailable: (state): boolean => state.updateAvailable, - selUpdateRequired: (state): boolean => state.updateRequired, - selAvailableVersion: (state): string => state.availableVersion, - }, }); export const fetchPluginConfig = createAsyncThunk( @@ -150,6 +136,18 @@ function findConfig( return; } +export const selWidth = (state: RootState): number => state[slice.name].width; +export const selHeight = (state: RootState): number => state[slice.name].height; +export const selModelName = (state: RootState): string => state[slice.name].modelName; +export const selTimeMs = (state: RootState): number => state[slice.name].timeMs; +export const selIsZoomedIn = (state: RootState): boolean => state[slice.name].isZoomedIn; +export const selLocation = (state: RootState): LatLon => state[slice.name].location; +export const selFavorites = (state: RootState): Fav[] => state[slice.name].favorites; +export const selStatus = (state: RootState): PluginStatus => state[slice.name].status; +export const selUpdateAvailable = (state: RootState): boolean => state[slice.name].updateAvailable; +export const selUpdateRequired = (state: RootState): boolean => state[slice.name].updateRequired; +export const selAvailableVersion = (state: RootState): string => state[slice.name].availableVersion; + export const { setIsZoomedIn, setFavorites, setModelName, setTimeMs, setWidth, setHeight, setLocation, setStatus } = slice.actions; diff --git a/libs/windy-sounding/src/redux/units-slice.ts b/libs/windy-sounding/src/redux/units-slice.ts index 109ba553..13887f56 100644 --- a/libs/windy-sounding/src/redux/units-slice.ts +++ b/libs/windy-sounding/src/redux/units-slice.ts @@ -1,4 +1,4 @@ -import { createSlice, createSelector } from '@reduxjs/toolkit'; +import { createSelector, createSlice } from '@reduxjs/toolkit'; import type { RootState } from './store'; diff --git a/libs/windy-sounding/src/sounding.tsx b/libs/windy-sounding/src/sounding.tsx index dff04d0e..10e511e1 100644 --- a/libs/windy-sounding/src/sounding.tsx +++ b/libs/windy-sounding/src/sounding.tsx @@ -56,9 +56,6 @@ export const mountPlugin = (container: HTMLElement) => { (e: CustomEvent) => { const { right, left } = e.detail.directions; const direction = left ? 'backward' : right ? 'forward' : undefined; - const state = store.getState(); - const model = pluginSlice.slice.selectors.selModelName(state); - const location = pluginSlice.slice.selectors.selLocation(state); if (direction !== undefined) { store.dispatch(updateTime({ direction, size: 'day' })); } @@ -129,7 +126,7 @@ export const openPlugin = ({ lat, lon, modelName }: { lat: number; lon: number; dispatch(changeLocation(location)); setSizeFrom(appContainer); - if (pluginSlice.slice.selectors.selStatus(store.getState()) === pluginSlice.PluginStatus.Idle) { + if (pluginSlice.selStatus(store.getState()) === pluginSlice.PluginStatus.Idle) { dispatch(pluginSlice.fetchPluginConfig(pluginConfig)); } }; diff --git a/libs/windy-sounding/src/styles.less b/libs/windy-sounding/src/styles.less index 7f193624..7cbbe7e1 100644 --- a/libs/windy-sounding/src/styles.less +++ b/libs/windy-sounding/src/styles.less @@ -403,7 +403,8 @@ text-align: center; white-space: nowrap; - &:before, &:after { + &:before, + &:after { display: inline-block; position: relative; top: -2px; From b364f69bc7152a5682bbf6031b4879108ace79d6 Mon Sep 17 00:00:00 2001 From: Victor Berchet Date: Sat, 13 Jul 2024 18:11:52 +0200 Subject: [PATCH 13/16] Memoize forecast selectors --- .../src/containers/containers.tsx | 59 +-- .../src/redux/forecast-slice.ts | 409 +++++++++--------- libs/windy-sounding/src/redux/meta.ts | 5 +- 3 files changed, 234 insertions(+), 239 deletions(-) diff --git a/libs/windy-sounding/src/containers/containers.tsx b/libs/windy-sounding/src/containers/containers.tsx index f4e5f4a9..099cfabf 100644 --- a/libs/windy-sounding/src/containers/containers.tsx +++ b/libs/windy-sounding/src/containers/containers.tsx @@ -31,20 +31,19 @@ export function Plugin() { availableVersion, isWindyDataAvailable, } = useSelector((state: RootState) => { - const forecastSel = forecastSlice.slice.selectors; const modelName = pluginSlice.selModelName(state); const location = pluginSlice.selLocation(state); const timeMs = pluginSlice.selTimeMs(state); const isWindyDataAvailable = - forecastSel.selIsWindyDataAvailable(state, modelName, location) && - forecastSel.selIsWindyDataAvailableAt(state, modelName, location, timeMs); + forecastSlice.selIsWindyDataAvailable(state, modelName, location) && + forecastSlice.selIsWindyDataAvailableAt(state, modelName, location, timeMs); return { width: pluginSlice.selWidth(state), startHeight: pluginSlice.selHeight(state), status: pluginSlice.selStatus(state), updateAvailable: pluginSlice.selUpdateAvailable(state), updateRequired: pluginSlice.selUpdateRequired(state), - fetchStatus: forecastSel.selFetchStatus(state, modelName, location), + fetchStatus: forecastSlice.selFetchStatus(state, modelName, location), availableVersion: pluginSlice.selAvailableVersion(state), modelName, location, @@ -268,15 +267,13 @@ function Graph({ width, height, skewTWidthPercent }: { width: number; height: nu const setIsZoomedIn = useCallback((expanded: boolean) => dispatch(pluginSlice.setIsZoomedIn(expanded)), []); const { minPressure, maxPressure, isZoomedIn } = useSelector((state: RootState) => { - const forecastSel = forecastSlice.slice.selectors; - const timeMs = pluginSlice.selTimeMs(state); const isZoomedIn = pluginSlice.selIsZoomedIn(state); const modelName = pluginSlice.selModelName(state); const location = pluginSlice.selLocation(state); - const elevation = forecastSel.selElevation(state, modelName, location); - const minModelPressure = forecastSel.selMinModelPressure(state, modelName, location); - const pressureToGhScale = forecastSel.selPressureToGhScale(state, modelName, location, timeMs); + const elevation = forecastSlice.selElevation(state, modelName, location); + const minModelPressure = forecastSlice.selMinModelPressure(state, modelName, location); + const pressureToGhScale = forecastSlice.selPressureToGhScale(state, modelName, location, timeMs); const minPressure = isZoomedIn ? Math.round(Math.max(pressureToGhScale.invert(6500 + (elevation * 2) / 5), minModelPressure)) : minModelPressure; @@ -335,17 +332,15 @@ type ChildGraphProps = { function ConnectedSkewT(props: ChildGraphProps) { const stateProps: Omit = useSelector((state: RootState) => { - const forecastSel = forecastSlice.slice.selectors; - const modelName = pluginSlice.selModelName(state); const location = pluginSlice.selLocation(state); const timeMs = pluginSlice.selTimeMs(state); - const periodValues = forecastSel.selPeriodValues(state, modelName, location); - const timeValues = forecastSel.selValuesAt(state, modelName, location, timeMs); + const periodValues = forecastSlice.selPeriodValues(state, modelName, location); + const timeValues = forecastSlice.selValuesAt(state, modelName, location, timeMs); const isZoomedIn = pluginSlice.selIsZoomedIn(state); - const periodMaxTemp = forecastSel.selMaxPeriodTemp(state, modelName, location); + const periodMaxTemp = forecastSlice.selMaxPeriodTemp(state, modelName, location); const maxTemp = periodMaxTemp + 8; const minTemp = periodMaxTemp - 60; const formatTemp = unitsSlice.selTempFormatter(state); @@ -358,9 +353,9 @@ function ConnectedSkewT(props: ChildGraphProps) { seaLevelPressure: timeValues.seaLevelPressure, minTemp, maxTemp, - surfaceElevation: forecastSel.selElevation(state, modelName, location), - parcel: forecastSel.selDisplayParcel(state, modelName, location, timeMs) - ? forecastSel.selParcel(state, modelName, location, timeMs) + surfaceElevation: forecastSlice.selElevation(state, modelName, location), + parcel: forecastSlice.selDisplayParcel(state, modelName, location, timeMs) + ? forecastSlice.selParcel(state, modelName, location, timeMs) : undefined, formatAltitude: unitsSlice.selAltitudeFormatter(state), formatTemp, @@ -369,7 +364,7 @@ function ConnectedSkewT(props: ChildGraphProps) { ghUnit: unitsSlice.selAltitudeUnit(state), ghAxisStep: unitsSlice.selAltitudeUnit(state) === 'm' ? 1000 : 3000, showUpperClouds: isZoomedIn, - cloudCover: forecastSel.selGetCloudCoverGenerator(state, modelName, location, timeMs), + cloudCover: forecastSlice.selGetCloudCoverGenerator(state, modelName, location, timeMs), }; }, shallowEqual); @@ -380,11 +375,9 @@ function ConnectedSkewT(props: ChildGraphProps) { function ConnectedWind(props: ChildGraphProps) { const fetchStatus = useSelector((state: RootState) => { - const forecastSel = forecastSlice.slice.selectors; - const modelName = pluginSlice.selModelName(state); const location = pluginSlice.selLocation(state); - return forecastSel.selFetchStatus(state, modelName, location); + return forecastSlice.selFetchStatus(state, modelName, location); }); if (fetchStatus !== forecastSlice.FetchStatus.Loaded) { @@ -392,27 +385,25 @@ function ConnectedWind(props: ChildGraphProps) { } const stateProps = useSelector((state: RootState) => { - const forecastSel = forecastSlice.slice.selectors; - const modelName = pluginSlice.selModelName(state); const location = pluginSlice.selLocation(state); const timeMs = pluginSlice.selTimeMs(state); - if (forecastSel.selFetchStatus(state, modelName, location) === forecastSlice.FetchStatus.Loading) { + if (forecastSlice.selFetchStatus(state, modelName, location) === forecastSlice.FetchStatus.Loading) { return { isLoading: true }; } - const periodValues = forecastSel.selPeriodValues(state, modelName, location); - const timeValues = forecastSel.selValuesAt(state, modelName, location, timeMs); + const periodValues = forecastSlice.selPeriodValues(state, modelName, location); + const timeValues = forecastSlice.selValuesAt(state, modelName, location, timeMs); return { seaLevelPressure: timeValues.seaLevelPressure, levels: periodValues.levels, ghs: timeValues.gh, - windByLevel: forecastSel.selWindDetailsByLevel(state, modelName, location, timeMs), + windByLevel: forecastSlice.selWindDetailsByLevel(state, modelName, location, timeMs), format: unitsSlice.selWindSpeedFormatter(state), unit: unitsSlice.selWindSpeedUnit(state), - surfaceElevation: forecastSel.selElevation(state, modelName, location), + surfaceElevation: forecastSlice.selElevation(state, modelName, location), isFixedRange: pluginSlice.selIsZoomedIn(state), }; }, shallowEqual); @@ -447,16 +438,14 @@ function ConnectedFavorites({ onSelected }: { onSelected: (location: LatLon) => */ function Details() { const { modelName, updateMs, nextUpdateMs, timeMs } = useSelector((state: RootState) => { - const forecastSel = forecastSlice.slice.selectors; - const modelName = pluginSlice.selModelName(state); const location = pluginSlice.selLocation(state); const timeMs = pluginSlice.selTimeMs(state); return { modelName: pluginSlice.selModelName(state), - updateMs: forecastSel.selModelUpdateTimeMs(state, modelName, location), - nextUpdateMs: forecastSel.selModelNextUpdateTimeMs(state, modelName, location), + updateMs: forecastSlice.selModelUpdateTimeMs(state, modelName, location), + nextUpdateMs: forecastSlice.selModelNextUpdateTimeMs(state, modelName, location), timeMs, }; }, shallowEqual); @@ -486,14 +475,12 @@ export function Watermark({ x, y }: { x: number; y: number }) { const nowMs = Date.now(); const { updateMs, nextUpdateMs } = useSelector((state: RootState) => { - const forecastSel = forecastSlice.slice.selectors; - const modelName = pluginSlice.selModelName(state); const location = pluginSlice.selLocation(state); return { - updateMs: forecastSel.selModelUpdateTimeMs(state, modelName, location), - nextUpdateMs: forecastSel.selModelNextUpdateTimeMs(state, modelName, location), + updateMs: forecastSlice.selModelUpdateTimeMs(state, modelName, location), + nextUpdateMs: forecastSlice.selModelNextUpdateTimeMs(state, modelName, location), }; }, shallowEqual); diff --git a/libs/windy-sounding/src/redux/forecast-slice.ts b/libs/windy-sounding/src/redux/forecast-slice.ts index 5317ea7e..7113f4fd 100644 --- a/libs/windy-sounding/src/redux/forecast-slice.ts +++ b/libs/windy-sounding/src/redux/forecast-slice.ts @@ -1,4 +1,4 @@ -import { createAsyncThunk, createSlice } from '@reduxjs/toolkit'; +import { createAsyncThunk, createSelector, createSlice } from '@reduxjs/toolkit'; import type { DataHash, LatLon, MeteogramDataPayload, WeatherDataPayload } from '@windy/interfaces'; import type { MeteogramLayers } from '@windy/types'; @@ -10,9 +10,8 @@ import { debugCloudCanvas, debugCloudTimeCursor, getCloudCoverGenerator, - type PeriodCloud, } from '../util/clouds'; -import { sampleAt, type Scale, scaleLog } from '../util/math'; +import { sampleAt, scaleLinear } from '../util/math'; import * as pluginSlice from './plugin-slice'; import type { AppThunkAPI, RootState } from './store'; @@ -43,7 +42,7 @@ const sfcProps = ['rainMm', 'seaLevelPressure'] as const; type SfcProps = (typeof sfcProps)[number]; type SfcPropsByTime = `${SfcProps}ByTime`; -type TimeValue = Record & Record; +type _TimeValue = Record & Record; export type PeriodValue = { maxTemp: number; @@ -123,203 +122,8 @@ export const slice = createSlice({ }; }); }, - selectors: { - /** - * Note: returned data could be loading, loaded, errored. - * - * @returns windy data or undefined. - */ - selMaybeWindyData: (state: ForecastState, modelName: string, location: LatLon): Forecast | undefined => { - return state.data[windyDataKey(modelName, location)]; - }, - selMaybeLoadedWindyData: (state: ForecastState, modelName: string, location: LatLon): Forecast | undefined => { - const key = windyDataKey(modelName, location); - return isDataCached(state, key) ? state.data[key] : undefined; - }, - selIsWindyDataAvailable: (state: ForecastState, modelName: string, location: LatLon): boolean => { - const windyData = slice.getSelectors().selMaybeLoadedWindyData(state, modelName, location); - return windyData !== undefined; - }, - selFetchStatus: (state: ForecastState, modelName: string, location: LatLon): FetchStatus => { - const windyData = slice.getSelectors().selMaybeWindyData(state, modelName, location); - return windyData === undefined ? FetchStatus.Error : windyData.fetchStatus; - }, - selModelUpdateTimeMs(state: ForecastState, modelName: string, location: LatLon): number { - const windyData = getWindyDataOrThrow(state, modelName, location); - return windyData.updateMs; - }, - selModelNextUpdateTimeMs(state: ForecastState, modelName: string, location: LatLon): number { - const windyData = getWindyDataOrThrow(state, modelName, location); - return windyData.nextUpdateMs; - }, - selTzOffsetH(state: ForecastState, modelName: string, location: LatLon): number { - const windyData = getWindyDataOrThrow(state, modelName, location); - return windyData.weather.celestial.TZoffset; - }, - selSunriseMs(state: ForecastState, modelName: string, location: LatLon): number { - const windyData = getWindyDataOrThrow(state, modelName, location); - return windyData.weather.celestial.sunriseTs; - }, - selSunsetMs(state: ForecastState, modelName: string, location: LatLon): number { - const windyData = getWindyDataOrThrow(state, modelName, location); - return windyData.weather.celestial.sunsetTs; - }, - // Levels in descending order - selLevels: (state: ForecastState, modelName: string, location: LatLon): number[] => { - const windyData = getWindyDataOrThrow(state, modelName, location); - return Object.keys(windyData.meteogram.data) - .filter((key: string) => key.startsWith('temp-') && key.endsWith('h')) - .map((key: string) => parseInt(key.slice(5, -1))) - .sort((a: number, b: number) => b - a); - }, - selMaxModelPressure: (state: ForecastState, modelName: string, location: LatLon): number => { - getWindyDataOrThrow(state, modelName, location); - const levels = slice.getSelectors().selLevels(state, modelName, location); - return Math.max(...levels); - }, - selMinModelPressure: (state: ForecastState, modelName: string, location: LatLon): number => { - getWindyDataOrThrow(state, modelName, location); - const levels = slice.getSelectors().selLevels(state, modelName, location); - return Math.min(...levels); - }, - selPeriodValues(state: ForecastState, modelName: string, location: LatLon): PeriodValue { - const windyData = getWindyDataOrThrow(state, modelName, location); - const levels = slice.getSelectors().selLevels(state, modelName, location); - return computePeriodValues(windyData, levels); - }, - selMaxPeriodTemp(state: ForecastState, modelName: string, location: LatLon): number { - getWindyDataOrThrow(state, modelName, location); - const periodValues = slice.getSelectors().selPeriodValues(state, modelName, location); - return periodValues.maxTemp; - }, - selMinPeriodTemp(state: ForecastState, modelName: string, location: LatLon): number { - getWindyDataOrThrow(state, modelName, location); - const periodValues = slice.getSelectors().selPeriodValues(state, modelName, location); - return periodValues.minTemp; - }, - selPeriodClouds(state: ForecastState, modelName: string, location: LatLon): PeriodCloud { - const windyData = getWindyDataOrThrow(state, modelName, location); - return computePeriodClouds(windyData.meteogram.data); - }, - selGetCloudCoverGenerator(state: ForecastState, modelName: string, location: LatLon, timeMs): CloudCoverGenerator { - const windyData = getWindyDataOrThrow(state, modelName, location); - const timesMs = windyData.meteogram.data.hours; - const { width, height, clouds } = slice.getSelectors().selPeriodClouds(state, modelName, location); - const timesIndex = Math.max( - 1, - timesMs.findIndex((ms) => ms > timeMs), - ); - const startMs = timesMs[timesIndex - 1]; - const endMs = timesMs[timesIndex]; - const timeRatio = Math.max(0, Math.min(1, (endMs - timeMs) / (endMs - startMs))); - const indexRatio = (timesIndex - timeRatio) / timesMs.length; - const x = Math.round(Math.round((width - 1) * indexRatio)); - if (DEBUG_CLOUDS && debugCloudCanvas && debugCloudTimeCursor) { - debugCloudTimeCursor.style.width = `${Math.round(debugCloudCanvas.width * indexRatio)}px`; - } - const cloudSliceAtMs: number[] = []; - for (let y = height - 1; y >= 0; y--) { - cloudSliceAtMs.push(clouds[x + y * width]); - } - return getCloudCoverGenerator(cloudSliceAtMs); - }, - selMaxSeaLevelPressure(state: ForecastState, modelName: string, location: LatLon): number { - getWindyDataOrThrow(state, modelName, location); - const periodValues = slice.getSelectors().selPeriodValues(state, modelName, location); - return periodValues.maxSeaLevelPressure; - }, - selIsWindyDataAvailableAt(state: ForecastState, modelName: string, location: LatLon, timeMs: number): boolean { - const windyData = getWindyDataOrThrow(state, modelName, location); - const maxTimeMs = Math.min( - ...[windyData.meteogram.data.hours.at(-1), windyData.weather.data.ts.at(-1)].filter((v) => v !== undefined), - ); - return timeMs <= maxTimeMs; - }, - selValuesAt(state: ForecastState, modelName: string, location: LatLon, timeMs: number): TimeValue { - const windyData = getWindyDataOrThrow(state, modelName, location); - const periodValues = slice.getSelectors().selPeriodValues(state, modelName, location); - const { timesMs } = periodValues; - timeMs = Math.max(timeMs, windyData.meteogram.data.hours[0], windyData.weather.data.ts[0]); - return { - temp: sampleAt(timesMs, periodValues.tempByTime, timeMs), - dewpoint: sampleAt(timesMs, periodValues.dewpointByTime, timeMs), - gh: sampleAt(timesMs, periodValues.ghByTime, timeMs), - rh: sampleAt(timesMs, periodValues.rhByTime, timeMs), - windU: sampleAt(timesMs, periodValues.windUByTime, timeMs), - windV: sampleAt(timesMs, periodValues.windVByTime, timeMs), - rainMm: sampleAt(timesMs, periodValues.rainMmByTime, timeMs), - seaLevelPressure: sampleAt(timesMs, periodValues.seaLevelPressureByTime, timeMs), - }; - }, - selWindDetailsByLevel( - state, - modelName: string, - location: LatLon, - timeMs: number, - ): { speed: number; direction: number }[] { - getWindyDataOrThrow(state, modelName, location); - const { windU, windV } = slice.getSelectors().selValuesAt(state, modelName, location, timeMs); - const details = []; - for (let i = 0; i < windU.length; i++) { - const { wind: speed, dir: direction } = windyUtils.wind2obj([windU[i], windV[i]]); - details.push({ speed, direction }); - } - return details; - }, - selElevation(state: ForecastState, modelName: string, location: LatLon): number { - const windyData = getWindyDataOrThrow(state, modelName, location); - const { weather, meteogram } = windyData; - return meteogram.header.elevation ?? weather.header.elevation ?? meteogram.header.modelElevation; - }, - selPressureToGhScale(state: ForecastState, modelName: string, location: LatLon, timeMs: number): Scale { - getWindyDataOrThrow(state, modelName, location); - const levels = slice.getSelectors().selLevels(state, modelName, location); - const { gh, seaLevelPressure } = slice.getSelectors().selValuesAt(state, modelName, location, timeMs); - return atm.getPressureToGhScale(levels, gh, seaLevelPressure); - }, - selDisplayParcel(state: ForecastState, modelName: string, location: LatLon, timeMs: number): boolean { - const startMs = slice.getSelectors().selSunriseMs(state, modelName, location) + 2 * 3600 * 1000; - const endMs = slice.getSelectors().selSunsetMs(state, modelName, location) - 3600 * 1000; - const durationMs = endMs - startMs; - return timeMs > startMs && (timeMs - startMs) % (24 * 3600 * 1000) < durationMs; - }, - selParcel(state: ForecastState, modelName: string, location: LatLon, timeMs: number): atm.ParcelData { - const timeValues = slice.getSelectors().selValuesAt(state, modelName, location, timeMs); - const periodValues = slice.getSelectors().selPeriodValues(state, modelName, location); - const pressureToGhScale = slice.getSelectors().selPressureToGhScale(state, modelName, location, timeMs); - const elevation = slice.getSelectors().selElevation(state, modelName, location); - const pressureToDewpointScale = scaleLog(periodValues.levels, timeValues.dewpoint); - - return atm.parcelTrajectory( - periodValues.levels, - timeValues.gh, - timeValues.temp, - 3, - elevation, - pressureToDewpointScale(pressureToGhScale.invert(elevation)), - 40, - ); - }, - }, }); -/** - * Throws when accessing data that are not loaded yet. - * - * @param state - */ -function getWindyDataOrThrow( - state: ForecastState, - modelName: string, - location: LatLon, -): Forecast & { fetchStatus: FetchStatus.Loaded } { - const windyData = slice.getSelectors().selMaybeLoadedWindyData(state, modelName, location); - if (windyData === undefined || windyData.fetchStatus !== FetchStatus.Loaded) { - throw new Error('Data not loaded'); - } - return windyData; -} - class OutOfBoundsError extends Error { constructor(message: string) { super(message); @@ -379,7 +183,7 @@ export const fetchForecast = createAsyncThunk timeMs; +/** + * Note: returned data could be loading, loaded, errored. + * + * @returns windy data or undefined. + */ +export const selMaybeWindyData = (state: RootState, modelName: string, location: LatLon): Forecast | undefined => + state[slice.name].data[windyDataKey(modelName, location)]; + +export const selMaybeLoadedWindyData = ( + state: RootState, + modelName: string, + location: LatLon, +): Forecast | undefined => { + const key = windyDataKey(modelName, location); + return isDataCached(state[slice.name], key) ? state[slice.name].data[key] : undefined; +}; + +/** + * Throws when accessing data that are not loaded yet. + * + * @param state + */ +const selLoadedWindyDataOrThrow = ( + state: RootState, + modelName: string, + location: LatLon, +): Forecast & { fetchStatus: FetchStatus.Loaded } => { + const windyData = selMaybeLoadedWindyData(state, modelName, location); + if (windyData === undefined || windyData.fetchStatus !== FetchStatus.Loaded) { + throw new Error('Data not loaded'); + } + return windyData; +}; + +export const selIsWindyDataAvailable = (state: RootState, modelName: string, location: LatLon): boolean => { + const windyData = selMaybeLoadedWindyData(state, modelName, location); + return windyData !== undefined; +}; + +export const selFetchStatus = (state: RootState, modelName: string, location: LatLon): FetchStatus => { + const windyData = selMaybeWindyData(state, modelName, location); + return windyData === undefined ? FetchStatus.Error : windyData.fetchStatus; +}; + +export const selModelUpdateTimeMs = (state: RootState, modelName: string, location: LatLon): number => { + const windyData = selLoadedWindyDataOrThrow(state, modelName, location); + return windyData.updateMs; +}; + +export const selModelNextUpdateTimeMs = (state: RootState, modelName: string, location: LatLon): number => { + const windyData = selLoadedWindyDataOrThrow(state, modelName, location); + return windyData.nextUpdateMs; +}; + +export const selTzOffsetH = (state: RootState, modelName: string, location: LatLon): number => { + const windyData = selLoadedWindyDataOrThrow(state, modelName, location); + return windyData.weather.celestial.TZoffset; +}; + +export const selSunriseMs = (state: RootState, modelName: string, location: LatLon): number => { + const windyData = selLoadedWindyDataOrThrow(state, modelName, location); + return windyData.weather.celestial.sunriseTs; +}; + +export const selSunsetMs = (state: RootState, modelName: string, location: LatLon): number => { + const windyData = selLoadedWindyDataOrThrow(state, modelName, location); + return windyData.weather.celestial.sunsetTs; +}; + +export const selDescendingLevels = createSelector(selLoadedWindyDataOrThrow, (windyData) => + Object.keys(windyData.meteogram.data) + .filter((key: string) => key.startsWith('temp-') && key.endsWith('h')) + .map((key: string) => parseInt(key.slice(5, -1))) + .sort((a: number, b: number) => b - a), +); + +export const selMaxModelPressure = createSelector(selDescendingLevels, (descendingLevels) => descendingLevels[0]); + +export const selMinModelPressure = createSelector(selDescendingLevels, (descendingLevels) => descendingLevels.at(-1)); + +export const selPeriodValues = createSelector(selLoadedWindyDataOrThrow, selDescendingLevels, (windyData, levels) => + computePeriodValues(windyData, levels), +); + +export const selMaxPeriodTemp = createSelector(selPeriodValues, (periodValues) => periodValues.maxTemp); + +export const selMinPeriodTemp = createSelector(selPeriodValues, (periodValues) => periodValues.minTemp); + +export const selPeriodClouds = createSelector(selLoadedWindyDataOrThrow, (windyData) => + computePeriodClouds(windyData.meteogram.data), +); + +export const selGetCloudCoverGenerator = createSelector( + selLoadedWindyDataOrThrow, + selPeriodClouds, + selTimeMs, + (windyData, periodClouds, timeMs): CloudCoverGenerator => { + const timesMs = windyData.meteogram.data.hours; + const { width, height, clouds } = periodClouds; + const timesIndex = Math.max( + 1, + timesMs.findIndex((ms) => ms > timeMs), + ); + const startMs = timesMs[timesIndex - 1]; + const endMs = timesMs[timesIndex]; + const timeRatio = Math.max(0, Math.min(1, (endMs - timeMs) / (endMs - startMs))); + const indexRatio = (timesIndex - timeRatio) / timesMs.length; + const x = Math.round(Math.round((width - 1) * indexRatio)); + if (DEBUG_CLOUDS && debugCloudCanvas && debugCloudTimeCursor) { + debugCloudTimeCursor.style.width = `${Math.round(debugCloudCanvas.width * indexRatio)}px`; + } + const cloudSliceAtMs: number[] = []; + for (let y = height - 1; y >= 0; y--) { + cloudSliceAtMs.push(clouds[x + y * width]); + } + return getCloudCoverGenerator(cloudSliceAtMs); + }, +); + +export const selMaxSeaLevelPressure = createSelector( + selPeriodValues, + (periodValues) => periodValues.maxSeaLevelPressure, +); + +export const selIsWindyDataAvailableAt = ( + state: RootState, + modelName: string, + location: LatLon, + timeMs: number, +): boolean => { + const windyData = selLoadedWindyDataOrThrow(state, modelName, location); + const maxTimeMs = Math.min( + ...[windyData.meteogram.data.hours.at(-1), windyData.weather.data.ts.at(-1)].filter((v) => v !== undefined), + ); + return timeMs <= maxTimeMs; +}; + +export const selValuesAt = createSelector( + selLoadedWindyDataOrThrow, + selPeriodValues, + selTimeMs, + (windyData, periodValues, timeMs) => { + const { timesMs } = periodValues; + timeMs = Math.max(timeMs, windyData.meteogram.data.hours[0], windyData.weather.data.ts[0]); + return { + temp: sampleAt(timesMs, periodValues.tempByTime, timeMs), + dewpoint: sampleAt(timesMs, periodValues.dewpointByTime, timeMs), + gh: sampleAt(timesMs, periodValues.ghByTime, timeMs), + rh: sampleAt(timesMs, periodValues.rhByTime, timeMs), + windU: sampleAt(timesMs, periodValues.windUByTime, timeMs), + windV: sampleAt(timesMs, periodValues.windVByTime, timeMs), + rainMm: sampleAt(timesMs, periodValues.rainMmByTime, timeMs), + seaLevelPressure: sampleAt(timesMs, periodValues.seaLevelPressureByTime, timeMs), + }; + }, +); + +export const selWindDetailsByLevel = createSelector(selValuesAt, ({ windU, windV }) => { + const details = []; + for (let i = 0; i < windU.length; i++) { + const { wind: speed, dir: direction } = windyUtils.wind2obj([windU[i], windV[i]]); + details.push({ speed, direction }); + } + return details; +}); + +export const selElevation = (state: RootState, modelName: string, location: LatLon): number => { + const windyData = selLoadedWindyDataOrThrow(state, modelName, location); + const { weather, meteogram } = windyData; + return meteogram.header.elevation ?? weather.header.elevation ?? meteogram.header.modelElevation; +}; + +export const selPressureToGhScale = createSelector(selDescendingLevels, selValuesAt, (levels, values) => + atm.getPressureToGhScale(levels, values.gh, values.seaLevelPressure), +); + +export const selDisplayParcel = createSelector(selSunriseMs, selSunsetMs, selTimeMs, (sunriseMs, sunsetMs, timeMs) => { + const startMs = sunriseMs + 2 * 3600 * 1000; + const endMs = sunsetMs - 3600 * 1000; + const durationMs = endMs - startMs; + return timeMs > startMs && (timeMs - startMs) % (24 * 3600 * 1000) < durationMs; +}); + +export const selParcel = createSelector( + selValuesAt, + selPeriodValues, + selPressureToGhScale, + selElevation, + (timeValues, periodValues, pressureToGhScale, elevation) => { + const pressureToDewpointScale = scaleLinear(periodValues.levels, timeValues.dewpoint); + return atm.parcelTrajectory( + periodValues.levels, + timeValues.gh, + timeValues.temp, + 3, + elevation, + pressureToDewpointScale(pressureToGhScale.invert(elevation)), + 40, + ); + }, +); + export const { reducer } = slice; diff --git a/libs/windy-sounding/src/redux/meta.ts b/libs/windy-sounding/src/redux/meta.ts index f7b885e7..526b8811 100644 --- a/libs/windy-sounding/src/redux/meta.ts +++ b/libs/windy-sounding/src/redux/meta.ts @@ -27,17 +27,16 @@ export const updateTime = if (stepDays) { const state = getState(); - const forecastSel = forecastSlice.slice.selectors; const modelName = pluginSlice.selModelName(state); const location = pluginSlice.selLocation(state); - const isWindyDataAvailable = forecastSlice.slice.selectors.selIsWindyDataAvailable(state, modelName, location); + const isWindyDataAvailable = forecastSlice.selIsWindyDataAvailable(state, modelName, location); if (isWindyDataAvailable) { // Step to the next/previous at 13h when we know the local TZ offset. const date = new Date(timeMs); date.setUTCMinutes(0); timeMs = date.getTime(); - const utcOffset = forecastSel.selTzOffsetH(state, modelName, location); + const utcOffset = forecastSlice.selTzOffsetH(state, modelName, location); const currentHour = (date.getUTCHours() + utcOffset) % 24; const deltaHours = (13 - currentHour) * (step.direction === 'forward' ? 1 : -1); timeMs += stepHour * (deltaHours > 0 ? deltaHours : 24 + deltaHours); From 50e4182ff31f097c6bbd2b781586eefa78b1e1ac Mon Sep 17 00:00:00 2001 From: Victor Berchet Date: Sat, 13 Jul 2024 18:31:09 +0200 Subject: [PATCH 14/16] Fix out of bounds crash --- libs/windy-sounding/src/containers/containers.tsx | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/libs/windy-sounding/src/containers/containers.tsx b/libs/windy-sounding/src/containers/containers.tsx index 099cfabf..66429d6f 100644 --- a/libs/windy-sounding/src/containers/containers.tsx +++ b/libs/windy-sounding/src/containers/containers.tsx @@ -34,8 +34,9 @@ export function Plugin() { const modelName = pluginSlice.selModelName(state); const location = pluginSlice.selLocation(state); const timeMs = pluginSlice.selTimeMs(state); + const fetchStatus = forecastSlice.selFetchStatus(state, modelName, location); const isWindyDataAvailable = - forecastSlice.selIsWindyDataAvailable(state, modelName, location) && + fetchStatus == forecastSlice.FetchStatus.Loaded && forecastSlice.selIsWindyDataAvailableAt(state, modelName, location, timeMs); return { width: pluginSlice.selWidth(state), @@ -43,7 +44,7 @@ export function Plugin() { status: pluginSlice.selStatus(state), updateAvailable: pluginSlice.selUpdateAvailable(state), updateRequired: pluginSlice.selUpdateRequired(state), - fetchStatus: forecastSlice.selFetchStatus(state, modelName, location), + fetchStatus, availableVersion: pluginSlice.selAvailableVersion(state), modelName, location, From d0458fe44159a78bb3ef5a135e3b66dced361232 Mon Sep 17 00:00:00 2001 From: Victor Berchet Date: Sat, 13 Jul 2024 18:39:14 +0200 Subject: [PATCH 15/16] Misc minor fixes --- .github/workflows/upload-windy-sounding.yml | 2 +- libs/windy-sounding/project.json | 15 +++- .../windy-sounding/src/components/loading.tsx | 2 +- .../src/containers/containers.tsx | 22 +++-- .../src/redux/forecast-slice.ts | 87 ++++++++++++------- libs/windy-sounding/src/sounding.tsx | 1 - 6 files changed, 82 insertions(+), 47 deletions(-) diff --git a/.github/workflows/upload-windy-sounding.yml b/.github/workflows/upload-windy-sounding.yml index b7ebf458..bb195f4b 100644 --- a/.github/workflows/upload-windy-sounding.yml +++ b/.github/workflows/upload-windy-sounding.yml @@ -19,7 +19,7 @@ jobs: run: | npm ci --no-audit npm --prefix libs/windy-sounding ci --no-audit - npx nx prepare windy-sounding + npx nx build windy-sounding - name: Publish Plugin run: | npx nx upload windy-sounding diff --git a/libs/windy-sounding/project.json b/libs/windy-sounding/project.json index 38473e6e..d181cae6 100644 --- a/libs/windy-sounding/project.json +++ b/libs/windy-sounding/project.json @@ -63,8 +63,8 @@ "options": { "commands": [ "rm -rf dist/libs/windy-sounding", - "npx nx build windy-sounding --configuration=production", - "npx nx build windy-sounding --configuration=development", + "npx nx build windy-sounding --configuration=production --skip-nx-cache", + "npx nx build windy-sounding --configuration=development --skip-nx-cache", "BUILD_PLUGIN_CONFIG=true npx nx build windy-sounding --configuration production --skip-nx-cache", "node libs/windy-sounding/generate-manifest.js dist/libs/windy-sounding" ], @@ -72,6 +72,17 @@ } }, + "upload": { + "executor": "nx:run-commands", + "dependsOn": ["prepare"], + "options": { + "commands": [ + "libs/windy-sounding/upload.sh" + ], + "parallel": false + } + }, + "test": { "executor": "@nx/jest:jest", "outputs": ["{workspaceRoot}/coverage/{projectRoot}"], diff --git a/libs/windy-sounding/src/components/loading.tsx b/libs/windy-sounding/src/components/loading.tsx index 4714bada..5c9b8051 100644 --- a/libs/windy-sounding/src/components/loading.tsx +++ b/libs/windy-sounding/src/components/loading.tsx @@ -1,7 +1,7 @@ export function LoadingIndicator({ width, height }: { width: number; height: number }) { return ( - +

Update to v{availableVersion} required.

Uninstall the current version first to install v{availableVersion}

-
+
Update
@@ -186,7 +184,7 @@ export function Plugin() {

)} - {showDetails &&
} + {updateRequired ||
} {errorMessage && !isLoading ? ( ) : ( @@ -438,21 +436,23 @@ function ConnectedFavorites({ onSelected }: { onSelected: (location: LatLon) => * - Current time */ function Details() { - const { modelName, updateMs, nextUpdateMs, timeMs } = useSelector((state: RootState) => { + const { modelName, updateMs, nextUpdateMs, timeMs, runInfoAvailable } = useSelector((state: RootState) => { const modelName = pluginSlice.selModelName(state); const location = pluginSlice.selLocation(state); const timeMs = pluginSlice.selTimeMs(state); + const runInfoAvailable = forecastSlice.selIsWindyDataAvailable(state, modelName, location); return { modelName: pluginSlice.selModelName(state), - updateMs: forecastSlice.selModelUpdateTimeMs(state, modelName, location), - nextUpdateMs: forecastSlice.selModelNextUpdateTimeMs(state, modelName, location), + updateMs: runInfoAvailable ? forecastSlice.selModelUpdateTimeMs(state, modelName, location) : 0, + nextUpdateMs: runInfoAvailable ? forecastSlice.selModelNextUpdateTimeMs(state, modelName, location) : 0, timeMs, + runInfoAvailable, }; }, shallowEqual); const nowMs = Date.now(); - const distanceString = intlFormatDistance(nextUpdateMs, nowMs); + const distanceString = runInfoAvailable ? intlFormatDistance(nextUpdateMs, nowMs) : ''; return (
@@ -461,7 +461,11 @@ function Details() {
{modelName}
Run
- {formatTimestamp(updateMs)}, next {nextUpdateMs > nowMs ? `${distanceString}` : `overdue (${distanceString})`} + {runInfoAvailable + ? `${formatTimestamp(updateMs)}, next ${ + nextUpdateMs > nowMs ? distanceString : `overdue (${distanceString})` + }` + : `...`}
Sounding time
{formatTimestamp(timeMs)}
{' '} diff --git a/libs/windy-sounding/src/redux/forecast-slice.ts b/libs/windy-sounding/src/redux/forecast-slice.ts index 7113f4fd..3ebc39eb 100644 --- a/libs/windy-sounding/src/redux/forecast-slice.ts +++ b/libs/windy-sounding/src/redux/forecast-slice.ts @@ -2,15 +2,17 @@ import { createAsyncThunk, createSelector, createSlice } from '@reduxjs/toolkit' import type { DataHash, LatLon, MeteogramDataPayload, WeatherDataPayload } from '@windy/interfaces'; import type { MeteogramLayers } from '@windy/types'; -import * as atm from '../util/atmosphere'; +import type { ParcelData } from '../util/atmosphere'; +import { getElevation, getPressureToGhScale, parcelTrajectory } from '../util/atmosphere'; +import type { CloudCoverGenerator, PeriodCloud } from '../util/clouds'; import { - type CloudCoverGenerator, computePeriodClouds, DEBUG_CLOUDS, debugCloudCanvas, debugCloudTimeCursor, getCloudCoverGenerator, } from '../util/clouds'; +import type { Scale } from '../util/math'; import { sampleAt, scaleLinear } from '../util/math'; import * as pluginSlice from './plugin-slice'; import type { AppThunkAPI, RootState } from './store'; @@ -42,7 +44,7 @@ const sfcProps = ['rainMm', 'seaLevelPressure'] as const; type SfcProps = (typeof sfcProps)[number]; type SfcPropsByTime = `${SfcProps}ByTime`; -type _TimeValue = Record & Record; +type TimeValue = Record & Record; export type PeriodValue = { maxTemp: number; @@ -238,7 +240,7 @@ function extractMeteogramParamByLevel( if (value == null) { if (paramName === 'gh') { // Approximate gh when not provided by the model - return Math.round(atm.getElevation(level)); + return Math.round(getElevation(level)); } throw new Error('Unexpected null value'); } @@ -368,27 +370,36 @@ export const selSunsetMs = (state: RootState, modelName: string, location: LatLo return windyData.weather.celestial.sunsetTs; }; -export const selDescendingLevels = createSelector(selLoadedWindyDataOrThrow, (windyData) => +export const selDescendingLevels = createSelector(selLoadedWindyDataOrThrow, (windyData): number[] => Object.keys(windyData.meteogram.data) .filter((key: string) => key.startsWith('temp-') && key.endsWith('h')) .map((key: string) => parseInt(key.slice(5, -1))) .sort((a: number, b: number) => b - a), ); -export const selMaxModelPressure = createSelector(selDescendingLevels, (descendingLevels) => descendingLevels[0]); +export const selMaxModelPressure = createSelector( + selDescendingLevels, + (descendingLevels): number => descendingLevels[0], +); -export const selMinModelPressure = createSelector(selDescendingLevels, (descendingLevels) => descendingLevels.at(-1)); +export const selMinModelPressure = createSelector( + selDescendingLevels, + (descendingLevels): number => descendingLevels.at(-1) ?? 150, +); -export const selPeriodValues = createSelector(selLoadedWindyDataOrThrow, selDescendingLevels, (windyData, levels) => - computePeriodValues(windyData, levels), +export const selPeriodValues = createSelector( + selLoadedWindyDataOrThrow, + selDescendingLevels, + (windyData, levels): PeriodValue => computePeriodValues(windyData, levels), ); -export const selMaxPeriodTemp = createSelector(selPeriodValues, (periodValues) => periodValues.maxTemp); +export const selMaxPeriodTemp = createSelector(selPeriodValues, (periodValues): number => periodValues.maxTemp); -export const selMinPeriodTemp = createSelector(selPeriodValues, (periodValues) => periodValues.minTemp); +export const selMinPeriodTemp = createSelector(selPeriodValues, (periodValues): number => periodValues.minTemp); -export const selPeriodClouds = createSelector(selLoadedWindyDataOrThrow, (windyData) => - computePeriodClouds(windyData.meteogram.data), +export const selPeriodClouds = createSelector( + selLoadedWindyDataOrThrow, + (windyData): PeriodCloud => computePeriodClouds(windyData.meteogram.data), ); export const selGetCloudCoverGenerator = createSelector( @@ -420,7 +431,7 @@ export const selGetCloudCoverGenerator = createSelector( export const selMaxSeaLevelPressure = createSelector( selPeriodValues, - (periodValues) => periodValues.maxSeaLevelPressure, + (periodValues): number => periodValues.maxSeaLevelPressure, ); export const selIsWindyDataAvailableAt = ( @@ -440,7 +451,7 @@ export const selValuesAt = createSelector( selLoadedWindyDataOrThrow, selPeriodValues, selTimeMs, - (windyData, periodValues, timeMs) => { + (windyData, periodValues, timeMs): TimeValue => { const { timesMs } = periodValues; timeMs = Math.max(timeMs, windyData.meteogram.data.hours[0], windyData.weather.data.ts[0]); return { @@ -456,14 +467,17 @@ export const selValuesAt = createSelector( }, ); -export const selWindDetailsByLevel = createSelector(selValuesAt, ({ windU, windV }) => { - const details = []; - for (let i = 0; i < windU.length; i++) { - const { wind: speed, dir: direction } = windyUtils.wind2obj([windU[i], windV[i]]); - details.push({ speed, direction }); - } - return details; -}); +export const selWindDetailsByLevel = createSelector( + selValuesAt, + ({ windU, windV }): { speed: number; direction: number }[] => { + const details = []; + for (let i = 0; i < windU.length; i++) { + const { wind: speed, dir: direction } = windyUtils.wind2obj([windU[i], windV[i]]); + details.push({ speed, direction }); + } + return details; + }, +); export const selElevation = (state: RootState, modelName: string, location: LatLon): number => { const windyData = selLoadedWindyDataOrThrow(state, modelName, location); @@ -471,25 +485,32 @@ export const selElevation = (state: RootState, modelName: string, location: LatL return meteogram.header.elevation ?? weather.header.elevation ?? meteogram.header.modelElevation; }; -export const selPressureToGhScale = createSelector(selDescendingLevels, selValuesAt, (levels, values) => - atm.getPressureToGhScale(levels, values.gh, values.seaLevelPressure), +export const selPressureToGhScale = createSelector( + selDescendingLevels, + selValuesAt, + (levels, values): Scale => getPressureToGhScale(levels, values.gh, values.seaLevelPressure), ); -export const selDisplayParcel = createSelector(selSunriseMs, selSunsetMs, selTimeMs, (sunriseMs, sunsetMs, timeMs) => { - const startMs = sunriseMs + 2 * 3600 * 1000; - const endMs = sunsetMs - 3600 * 1000; - const durationMs = endMs - startMs; - return timeMs > startMs && (timeMs - startMs) % (24 * 3600 * 1000) < durationMs; -}); +export const selDisplayParcel = createSelector( + selSunriseMs, + selSunsetMs, + selTimeMs, + (sunriseMs, sunsetMs, timeMs): boolean => { + const startMs = sunriseMs + 2 * 3600 * 1000; + const endMs = sunsetMs - 3600 * 1000; + const durationMs = endMs - startMs; + return timeMs > startMs && (timeMs - startMs) % (24 * 3600 * 1000) < durationMs; + }, +); export const selParcel = createSelector( selValuesAt, selPeriodValues, selPressureToGhScale, selElevation, - (timeValues, periodValues, pressureToGhScale, elevation) => { + (timeValues, periodValues, pressureToGhScale, elevation): ParcelData => { const pressureToDewpointScale = scaleLinear(periodValues.levels, timeValues.dewpoint); - return atm.parcelTrajectory( + return parcelTrajectory( periodValues.levels, timeValues.gh, timeValues.temp, diff --git a/libs/windy-sounding/src/sounding.tsx b/libs/windy-sounding/src/sounding.tsx index 10e511e1..34ef0c6f 100644 --- a/libs/windy-sounding/src/sounding.tsx +++ b/libs/windy-sounding/src/sounding.tsx @@ -6,7 +6,6 @@ import { Provider } from 'react-redux'; import { pluginConfig } from './config.js'; import { Plugin } from './containers/containers'; -import * as forecastSlice from './redux/forecast-slice'; import { addSubscription, cancelAllSubscriptions, From e6f8cf47811a299d662f87411fb18cadeb5a046b Mon Sep 17 00:00:00 2001 From: Victor Berchet Date: Sat, 13 Jul 2024 18:40:00 +0200 Subject: [PATCH 16/16] Sounding release 4.0.0-alpha.3 --- libs/windy-sounding/CHANGELOG.md | 3 ++- libs/windy-sounding/package.json | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/libs/windy-sounding/CHANGELOG.md b/libs/windy-sounding/CHANGELOG.md index dd6f5012..b7b325aa 100644 --- a/libs/windy-sounding/CHANGELOG.md +++ b/libs/windy-sounding/CHANGELOG.md @@ -1,9 +1,10 @@ # Release history -## 4.0.0-alpha.3 +## 4.0.0-beta.1 - July 13, 2024 - Split the state into multiple slices - Check for update +- Perf improvements ## 4.0.0-alpha.2 - July 10, 2024 diff --git a/libs/windy-sounding/package.json b/libs/windy-sounding/package.json index 4a2649b2..c733d214 100644 --- a/libs/windy-sounding/package.json +++ b/libs/windy-sounding/package.json @@ -1,6 +1,6 @@ { "name": "windy-plugin-sounding", - "version": "4.0.0-alpha.2", + "version": "4.0.0-beta.1", "type": "module", "private": true, "description": "Soundings for paraglider pilots",